PageRenderTime 275ms CodeModel.GetById 80ms app.highlight 17ms RepoModel.GetById 175ms app.codeStats 0ms

/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
 27#ifndef LL_LLTRANSLATE_H
 28#define LL_LLTRANSLATE_H
 29
 30#include "llhttpclient.h"
 31#include "llbufferstream.h"
 32
 33namespace Json
 34{
 35    class Value;
 36}
 37
 38/**
 39 * Handler of an HTTP machine translation service.
 40 *
 41 * Derived classes know the service URL
 42 * and how to parse the translation result.
 43 */
 44class LLTranslationAPIHandler
 45{
 46public:
 47	/**
 48	 * Get URL for translation of the given string.
 49	 *
 50	 * Sending HTTP GET request to the URL will initiate translation.
 51	 *
 52	 * @param[out] url        Place holder for the result.
 53	 * @param      from_lang  Source language. Leave empty for auto-detection.
 54	 * @param      to_lang    Target language.
 55	 * @param      text       Text to translate.
 56	 */
 57	virtual void getTranslateURL(
 58		std::string &url,
 59		const std::string &from_lang,
 60		const std::string &to_lang,
 61		const std::string &text) const = 0;
 62
 63	/**
 64	 * Get URL to verify the given API key.
 65	 *
 66	 * Sending request to the URL verifies the key.
 67	 * Positive HTTP response (code 200) means that the key is valid.
 68	 *
 69	 * @param[out] url  Place holder for the URL.
 70	 * @param[in]  key  Key to verify.
 71	 */
 72	virtual void getKeyVerificationURL(
 73		std::string &url,
 74		const std::string &key) const = 0;
 75
 76	/**
 77	 * Parse translation response.
 78	 *
 79	 * @param[in,out] status        HTTP status. May be modified while parsing.
 80	 * @param         body          Response text.
 81	 * @param[out]    translation   Translated text.
 82	 * @param[out]    detected_lang Detected source language. May be empty.
 83	 * @param[out]    err_msg       Error message (in case of error).
 84	 */
 85	virtual bool parseResponse(
 86		int& status,
 87		const std::string& body,
 88		std::string& translation,
 89		std::string& detected_lang,
 90		std::string& err_msg) const = 0;
 91
 92	/**
 93	 * @return if the handler is configured to function properly
 94	 */
 95	virtual bool isConfigured() const = 0;
 96
 97	virtual ~LLTranslationAPIHandler() {}
 98
 99protected:
100	static const int STATUS_OK = 200;
101};
102
103/// Google Translate v2 API handler.
104class LLGoogleTranslationHandler : public LLTranslationAPIHandler
105{
106	LOG_CLASS(LLGoogleTranslationHandler);
107
108public:
109	/*virtual*/ void getTranslateURL(
110		std::string &url,
111		const std::string &from_lang,
112		const std::string &to_lang,
113		const std::string &text) const;
114	/*virtual*/ void getKeyVerificationURL(
115		std::string &url,
116		const std::string &key) const;
117	/*virtual*/ bool parseResponse(
118		int& status,
119		const std::string& body,
120		std::string& translation,
121		std::string& detected_lang,
122		std::string& err_msg) const;
123	/*virtual*/ bool isConfigured() const;
124
125private:
126	static void parseErrorResponse(
127		const Json::Value& root,
128		int& status,
129		std::string& err_msg);
130	static bool parseTranslation(
131		const Json::Value& root,
132		std::string& translation,
133		std::string& detected_lang);
134	static std::string getAPIKey();
135};
136
137/// Microsoft Translator v2 API handler.
138class LLBingTranslationHandler : public LLTranslationAPIHandler
139{
140	LOG_CLASS(LLBingTranslationHandler);
141
142public:
143	/*virtual*/ void getTranslateURL(
144		std::string &url,
145		const std::string &from_lang,
146		const std::string &to_lang,
147		const std::string &text) const;
148	/*virtual*/ void getKeyVerificationURL(
149		std::string &url,
150		const std::string &key) const;
151	/*virtual*/ bool parseResponse(
152		int& status,
153		const std::string& body,
154		std::string& translation,
155		std::string& detected_lang,
156		std::string& err_msg) const;
157	/*virtual*/ bool isConfigured() const;
158private:
159	static std::string getAPIKey();
160};
161
162/**
163 * Entry point for machine translation services.
164 *
165 * Basically, to translate a string, we need to know the URL
166 * of a translation service, have a valid API for the service
167 * and be given the target language.
168 *
169 * Callers specify the string to translate and the target language,
170 * LLTranslate takes care of the rest.
171 *
172 * API keys for translation are taken from saved settings.
173 */
174class LLTranslate
175{
176	LOG_CLASS(LLTranslate);
177
178public :
179
180	typedef enum e_service {
181		SERVICE_BING,
182		SERVICE_GOOGLE,
183	} EService;
184
185	/**
186	 * Subclasses are supposed to handle translation results (e.g. show them in chat)
187	 */
188	class TranslationReceiver: public LLHTTPClient::Responder
189	{
190	public:
191
192		/**
193		 * Using mHandler, parse incoming response.
194		 *
195		 * Calls either handleResponse() or handleFailure()
196		 * depending on the HTTP status code and parsing success.
197		 *
198		 * @see handleResponse()
199		 * @see handleFailure()
200		 * @see mHandler
201		 */
202		/*virtual*/ void completedRaw(
203			U32 http_status,
204			const std::string& reason,
205			const LLChannelDescriptors& channels,
206			const LLIOPipe::buffer_ptr_t& buffer);
207
208	protected:
209		friend class LLTranslate;
210
211		/// Remember source and target languages for subclasses to be able to filter inappropriate results.
212		TranslationReceiver(const std::string& from_lang, const std::string& to_lang);
213
214		/// Override point to handle successful translation.
215		virtual void handleResponse(const std::string &translation, const std::string &recognized_lang) = 0;
216
217		/// Override point to handle unsuccessful translation.
218		virtual void handleFailure(int status, const std::string& err_msg) = 0;
219
220		std::string mFromLang;
221		std::string mToLang;
222		const LLTranslationAPIHandler& mHandler;
223	};
224
225	/**
226	 * Subclasses are supposed to handle API key verification result.
227	 */
228	class KeyVerificationReceiver: public LLHTTPClient::Responder
229	{
230	public:
231		EService getService() const;
232
233	protected:
234		/**
235		 * Save the translation service the key belongs to.
236		 *
237		 * Subclasses need to know it.
238		 *
239		 * @see getService()
240		 */
241		KeyVerificationReceiver(EService service);
242
243		/**
244		 * Parse verification response.
245		 *
246		 * Calls setVerificationStatus() with the verification status,
247		 * which is true if HTTP status code is 200.
248		 *
249		 * @see setVerificationStatus()
250		 */
251		/*virtual*/ void completedRaw(
252			U32 http_status,
253			const std::string& reason,
254			const LLChannelDescriptors& channels,
255			const LLIOPipe::buffer_ptr_t& buffer);
256
257		/**
258		 * Override point for subclasses to handle key verification status.
259		 */
260		virtual void setVerificationStatus(bool ok) = 0;
261
262		EService mService;
263	};
264
265	typedef boost::intrusive_ptr<TranslationReceiver> TranslationReceiverPtr;
266	typedef boost::intrusive_ptr<KeyVerificationReceiver> KeyVerificationReceiverPtr;
267
268	/**
269	 * Translate given text.
270	 *
271	 * @param receiver   Object to pass translation result to.
272	 * @param from_lang  Source language. Leave empty for auto-detection.
273	 * @param to_lang    Target language.
274	 * @param mesg       Text to translate.
275	 */
276	static void translateMessage(TranslationReceiverPtr &receiver, const std::string &from_lang, const std::string &to_lang, const std::string &mesg);
277
278	/**
279	 * Verify given API key of a translation service.
280	 *
281	 * @param receiver  Object to pass verification result to.
282	 * @param key       Key to verify.
283	 */
284	static void verifyKey(KeyVerificationReceiverPtr& receiver, const std::string& key);
285
286	/**
287	 * @return translation target language
288	 */
289	static std::string getTranslateLanguage();
290
291	/**
292	 * @return true if translation is configured properly.
293	 */
294	static bool isTranslationConfigured();
295
296private:
297	static const LLTranslationAPIHandler& getPreferredHandler();
298	static const LLTranslationAPIHandler& getHandler(EService service);
299	static void sendRequest(const std::string& url, LLHTTPClient::ResponderPtr responder);
300};
301
302#endif