/indra/newview/lltranslate.h

https://bitbucket.org/lindenlab/viewer-beta/ · C Header · 302 lines · 133 code · 36 blank · 133 comment · 0 complexity · 72407e904e3d03f875061eac0f933a43 MD5 · raw file

  1. /**
  2. * @file lltranslate.h
  3. * @brief Human language translation class and JSON response receiver.
  4. *
  5. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLTRANSLATE_H
  27. #define LL_LLTRANSLATE_H
  28. #include "llhttpclient.h"
  29. #include "llbufferstream.h"
  30. namespace Json
  31. {
  32. class Value;
  33. }
  34. /**
  35. * Handler of an HTTP machine translation service.
  36. *
  37. * Derived classes know the service URL
  38. * and how to parse the translation result.
  39. */
  40. class LLTranslationAPIHandler
  41. {
  42. public:
  43. /**
  44. * Get URL for translation of the given string.
  45. *
  46. * Sending HTTP GET request to the URL will initiate translation.
  47. *
  48. * @param[out] url Place holder for the result.
  49. * @param from_lang Source language. Leave empty for auto-detection.
  50. * @param to_lang Target language.
  51. * @param text Text to translate.
  52. */
  53. virtual void getTranslateURL(
  54. std::string &url,
  55. const std::string &from_lang,
  56. const std::string &to_lang,
  57. const std::string &text) const = 0;
  58. /**
  59. * Get URL to verify the given API key.
  60. *
  61. * Sending request to the URL verifies the key.
  62. * Positive HTTP response (code 200) means that the key is valid.
  63. *
  64. * @param[out] url Place holder for the URL.
  65. * @param[in] key Key to verify.
  66. */
  67. virtual void getKeyVerificationURL(
  68. std::string &url,
  69. const std::string &key) const = 0;
  70. /**
  71. * Parse translation response.
  72. *
  73. * @param[in,out] status HTTP status. May be modified while parsing.
  74. * @param body Response text.
  75. * @param[out] translation Translated text.
  76. * @param[out] detected_lang Detected source language. May be empty.
  77. * @param[out] err_msg Error message (in case of error).
  78. */
  79. virtual bool parseResponse(
  80. int& status,
  81. const std::string& body,
  82. std::string& translation,
  83. std::string& detected_lang,
  84. std::string& err_msg) const = 0;
  85. /**
  86. * @return if the handler is configured to function properly
  87. */
  88. virtual bool isConfigured() const = 0;
  89. virtual ~LLTranslationAPIHandler() {}
  90. protected:
  91. static const int STATUS_OK = 200;
  92. };
  93. /// Google Translate v2 API handler.
  94. class LLGoogleTranslationHandler : public LLTranslationAPIHandler
  95. {
  96. LOG_CLASS(LLGoogleTranslationHandler);
  97. public:
  98. /*virtual*/ void getTranslateURL(
  99. std::string &url,
  100. const std::string &from_lang,
  101. const std::string &to_lang,
  102. const std::string &text) const;
  103. /*virtual*/ void getKeyVerificationURL(
  104. std::string &url,
  105. const std::string &key) const;
  106. /*virtual*/ bool parseResponse(
  107. int& status,
  108. const std::string& body,
  109. std::string& translation,
  110. std::string& detected_lang,
  111. std::string& err_msg) const;
  112. /*virtual*/ bool isConfigured() const;
  113. private:
  114. static void parseErrorResponse(
  115. const Json::Value& root,
  116. int& status,
  117. std::string& err_msg);
  118. static bool parseTranslation(
  119. const Json::Value& root,
  120. std::string& translation,
  121. std::string& detected_lang);
  122. static std::string getAPIKey();
  123. };
  124. /// Microsoft Translator v2 API handler.
  125. class LLBingTranslationHandler : public LLTranslationAPIHandler
  126. {
  127. LOG_CLASS(LLBingTranslationHandler);
  128. public:
  129. /*virtual*/ void getTranslateURL(
  130. std::string &url,
  131. const std::string &from_lang,
  132. const std::string &to_lang,
  133. const std::string &text) const;
  134. /*virtual*/ void getKeyVerificationURL(
  135. std::string &url,
  136. const std::string &key) const;
  137. /*virtual*/ bool parseResponse(
  138. int& status,
  139. const std::string& body,
  140. std::string& translation,
  141. std::string& detected_lang,
  142. std::string& err_msg) const;
  143. /*virtual*/ bool isConfigured() const;
  144. private:
  145. static std::string getAPIKey();
  146. };
  147. /**
  148. * Entry point for machine translation services.
  149. *
  150. * Basically, to translate a string, we need to know the URL
  151. * of a translation service, have a valid API for the service
  152. * and be given the target language.
  153. *
  154. * Callers specify the string to translate and the target language,
  155. * LLTranslate takes care of the rest.
  156. *
  157. * API keys for translation are taken from saved settings.
  158. */
  159. class LLTranslate
  160. {
  161. LOG_CLASS(LLTranslate);
  162. public :
  163. typedef enum e_service {
  164. SERVICE_BING,
  165. SERVICE_GOOGLE,
  166. } EService;
  167. /**
  168. * Subclasses are supposed to handle translation results (e.g. show them in chat)
  169. */
  170. class TranslationReceiver: public LLHTTPClient::Responder
  171. {
  172. public:
  173. /**
  174. * Using mHandler, parse incoming response.
  175. *
  176. * Calls either handleResponse() or handleFailure()
  177. * depending on the HTTP status code and parsing success.
  178. *
  179. * @see handleResponse()
  180. * @see handleFailure()
  181. * @see mHandler
  182. */
  183. /*virtual*/ void completedRaw(
  184. U32 http_status,
  185. const std::string& reason,
  186. const LLChannelDescriptors& channels,
  187. const LLIOPipe::buffer_ptr_t& buffer);
  188. protected:
  189. friend class LLTranslate;
  190. /// Remember source and target languages for subclasses to be able to filter inappropriate results.
  191. TranslationReceiver(const std::string& from_lang, const std::string& to_lang);
  192. /// Override point to handle successful translation.
  193. virtual void handleResponse(const std::string &translation, const std::string &recognized_lang) = 0;
  194. /// Override point to handle unsuccessful translation.
  195. virtual void handleFailure(int status, const std::string& err_msg) = 0;
  196. std::string mFromLang;
  197. std::string mToLang;
  198. const LLTranslationAPIHandler& mHandler;
  199. };
  200. /**
  201. * Subclasses are supposed to handle API key verification result.
  202. */
  203. class KeyVerificationReceiver: public LLHTTPClient::Responder
  204. {
  205. public:
  206. EService getService() const;
  207. protected:
  208. /**
  209. * Save the translation service the key belongs to.
  210. *
  211. * Subclasses need to know it.
  212. *
  213. * @see getService()
  214. */
  215. KeyVerificationReceiver(EService service);
  216. /**
  217. * Parse verification response.
  218. *
  219. * Calls setVerificationStatus() with the verification status,
  220. * which is true if HTTP status code is 200.
  221. *
  222. * @see setVerificationStatus()
  223. */
  224. /*virtual*/ void completedRaw(
  225. U32 http_status,
  226. const std::string& reason,
  227. const LLChannelDescriptors& channels,
  228. const LLIOPipe::buffer_ptr_t& buffer);
  229. /**
  230. * Override point for subclasses to handle key verification status.
  231. */
  232. virtual void setVerificationStatus(bool ok) = 0;
  233. EService mService;
  234. };
  235. typedef boost::intrusive_ptr<TranslationReceiver> TranslationReceiverPtr;
  236. typedef boost::intrusive_ptr<KeyVerificationReceiver> KeyVerificationReceiverPtr;
  237. /**
  238. * Translate given text.
  239. *
  240. * @param receiver Object to pass translation result to.
  241. * @param from_lang Source language. Leave empty for auto-detection.
  242. * @param to_lang Target language.
  243. * @param mesg Text to translate.
  244. */
  245. static void translateMessage(TranslationReceiverPtr &receiver, const std::string &from_lang, const std::string &to_lang, const std::string &mesg);
  246. /**
  247. * Verify given API key of a translation service.
  248. *
  249. * @param receiver Object to pass verification result to.
  250. * @param key Key to verify.
  251. */
  252. static void verifyKey(KeyVerificationReceiverPtr& receiver, const std::string& key);
  253. /**
  254. * @return translation target language
  255. */
  256. static std::string getTranslateLanguage();
  257. /**
  258. * @return true if translation is configured properly.
  259. */
  260. static bool isTranslationConfigured();
  261. private:
  262. static const LLTranslationAPIHandler& getPreferredHandler();
  263. static const LLTranslationAPIHandler& getHandler(EService service);
  264. static void sendRequest(const std::string& url, LLHTTPClient::ResponderPtr responder);
  265. };
  266. #endif