diff options
-rw-r--r-- | indra/newview/llfloatertranslationsettings.cpp | 12 | ||||
-rw-r--r-- | indra/newview/lltranslate.cpp | 12 | ||||
-rw-r--r-- | indra/newview/lltranslate.h | 109 | ||||
-rw-r--r-- | indra/newview/tests/lltranslate_test.cpp | 4 |
4 files changed, 123 insertions, 14 deletions
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index ac3e7ac8fa..ac4514b438 100644 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -253,14 +253,18 @@ void LLFloaterTranslationSettings::onEditorFocused(LLFocusableElement* control) void LLFloaterTranslationSettings::onBingKeyEdited() { - mBingAPIKeyEditor->setTentative(FALSE); - setBingVerified(false, false); + if (mBingAPIKeyEditor->isDirty()) + { + setBingVerified(false, false); + } } void LLFloaterTranslationSettings::onGoogleKeyEdited() { - mGoogleAPIKeyEditor->setTentative(FALSE); - setGoogleVerified(false, false); + if (mGoogleAPIKeyEditor->isDirty()) + { + setGoogleVerified(false, false); + } } void LLFloaterTranslationSettings::onBtnBingVerify() diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 7b99c20a58..7eb54271f4 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -117,6 +117,8 @@ bool LLGoogleTranslationHandler::parseTranslation( std::string& translation, std::string& detected_lang) { + // JsonCpp is prone to aborting the program on failed assertions, + // so be super-careful and verify the response format. const Json::Value& data = root.get("data", 0); if (!data.isObject() || !data.isMember("translations")) { @@ -147,7 +149,7 @@ std::string LLGoogleTranslationHandler::getAPIKey() } // virtual -void LLBingTranslarionHandler::getTranslateURL( +void LLBingTranslationHandler::getTranslateURL( std::string &url, const std::string &from_lang, const std::string &to_lang, @@ -162,7 +164,7 @@ void LLBingTranslarionHandler::getTranslateURL( } // virtual -void LLBingTranslarionHandler::getKeyVerificationURL( +void LLBingTranslationHandler::getKeyVerificationURL( std::string& url, const std::string& key) const { @@ -171,7 +173,7 @@ void LLBingTranslarionHandler::getKeyVerificationURL( } // virtual -bool LLBingTranslarionHandler::parseResponse( +bool LLBingTranslationHandler::parseResponse( int& status, const std::string& body, std::string& translation, @@ -217,7 +219,7 @@ bool LLBingTranslarionHandler::parseResponse( } // static -std::string LLBingTranslarionHandler::getAPIKey() +std::string LLBingTranslationHandler::getAPIKey() { return gSavedSettings.getString("BingTranslateAPIKey"); } @@ -347,7 +349,7 @@ const LLTranslationAPIHandler& LLTranslate::getPreferredHandler() const LLTranslationAPIHandler& LLTranslate::getHandler(EService service) { static LLGoogleTranslationHandler google; - static LLBingTranslarionHandler bing; + static LLBingTranslationHandler bing; if (service == SERVICE_GOOGLE) { diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index 672a56af8b..c2330daa81 100644 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -35,19 +35,53 @@ namespace Json class Value; } +/** + * Handler of an HTTP machine translation service. + * + * Derived classes know the service URL + * and how to parse the translation result. + */ class LLTranslationAPIHandler { public: + /** + * Get URL for translation of the given string. + * + * Sending HTTP GET request to the URL will initiate translation. + * + * @param[out] url Place holder for the result. + * @param from_lang Source language. Leave empty for auto-detection. + * @param to_lang Target language. + * @param text Text to translate. + */ virtual void getTranslateURL( std::string &url, const std::string &from_lang, const std::string &to_lang, const std::string &text) const = 0; + /** + * Get URL to verify the given API key. + * + * Sending request to the URL verifies the key. + * Positive HTTP response (code 200) means that the key is valid. + * + * @param[out] url Place holder for the URL. + * @param[in] key Key to verify. + */ virtual void getKeyVerificationURL( std::string &url, const std::string &key) const = 0; + /** + * Parse translation response. + * + * @param[in,out] status HTTP status. May be modified while parsing. + * @param body Response text. + * @param[out] translation Translated text. + * @param[out] detected_lang Detected source language. May be empty. + * @param[out] err_msg Error message (in case of error). + */ virtual bool parseResponse( int& status, const std::string& body, @@ -61,6 +95,7 @@ protected: static const int STATUS_OK = 200; }; +/// Google Translate v2 API handler. class LLGoogleTranslationHandler : public LLTranslationAPIHandler { LOG_CLASS(LLGoogleTranslationHandler); @@ -93,9 +128,10 @@ private: static std::string getAPIKey(); }; -class LLBingTranslarionHandler : public LLTranslationAPIHandler +/// Microsoft Translator v2 API handler. +class LLBingTranslationHandler : public LLTranslationAPIHandler { - LOG_CLASS(LLBingTranslarionHandler); + LOG_CLASS(LLBingTranslationHandler); public: /*virtual*/ void getTranslateURL( @@ -116,7 +152,18 @@ private: static std::string getAPIKey(); }; - +/** + * Entry point for machine translation services. + * + * Basically, to translate a string, we need to know the URL + * of a translation service, have a valid API for the service + * and be given the target language. + * + * Callers specify the string to translate and the target language, + * LLTranslate takes care of the rest. + * + * API keys for translation are taken from saved settings. + */ class LLTranslate { LOG_CLASS(LLTranslate); @@ -128,9 +175,23 @@ public : SERVICE_GOOGLE, } EService; + /** + * Subclasses are supposed to handle translation results (e.g. show them in chat) + */ class TranslationReceiver: public LLHTTPClient::Responder { public: + + /** + * Using mHandler, parse incoming response. + * + * Calls either handleResponse() or handleFailure() + * depending on the HTTP status code and parsing success. + * + * @see handleResponse() + * @see handleFailure() + * @see mHandler + */ /*virtual*/ void completedRaw( U32 http_status, const std::string& reason, @@ -140,9 +201,13 @@ public : protected: friend class LLTranslate; + /// Remember source and target languages for subclasses to be able to filter inappropriate results. TranslationReceiver(const std::string& from_lang, const std::string& to_lang); + /// Override point to handle successful translation. virtual void handleResponse(const std::string &translation, const std::string &recognized_lang) = 0; + + /// Override point to handle unsuccessful translation. virtual void handleFailure(int status, const std::string& err_msg) = 0; std::string mFromLang; @@ -150,18 +215,41 @@ public : const LLTranslationAPIHandler& mHandler; }; + /** + * Subclasses are supposed to handle API key verification result. + */ class KeyVerificationReceiver: public LLHTTPClient::Responder { public: EService getService() const; protected: + /** + * Save the translation service the key belongs to. + * + * Subclasses need to know it. + * + * @see getService() + */ KeyVerificationReceiver(EService service); + + /** + * Parse verification response. + * + * Calls setVerificationStatus() with the verification status, + * which is true if HTTP status code is 200. + * + * @see setVerificationStatus() + */ /*virtual*/ void completedRaw( U32 http_status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); + + /** + * Override point for subclasses to handle key verification status. + */ virtual void setVerificationStatus(bool ok) = 0; EService mService; @@ -170,7 +258,22 @@ public : typedef boost::intrusive_ptr<TranslationReceiver> TranslationReceiverPtr; typedef boost::intrusive_ptr<KeyVerificationReceiver> KeyVerificationReceiverPtr; + /** + * Translate given text. + * + * @param receiver Object to pass translation result to. + * @param from_lang Source language. Leave empty for auto-detection. + * @param to_lang Target language. + * @param mesg Text to translate. + */ static void translateMessage(TranslationReceiverPtr &receiver, const std::string &from_lang, const std::string &to_lang, const std::string &mesg); + + /** + * Verify given API key of a translation service. + * + * @param receiver Object to pass verification result to. + * @param key Key to verify. + */ static void verifyKey(KeyVerificationReceiverPtr& receiver, const std::string& key); static std::string getTranslateLanguage(); diff --git a/indra/newview/tests/lltranslate_test.cpp b/indra/newview/tests/lltranslate_test.cpp index da11b8394a..10e37fae97 100644 --- a/indra/newview/tests/lltranslate_test.cpp +++ b/indra/newview/tests/lltranslate_test.cpp @@ -105,7 +105,7 @@ namespace tut } LLGoogleTranslationHandler mGoogle; - LLBingTranslarionHandler mBing; + LLBingTranslationHandler mBing; }; typedef test_group<translate_test> translate_test_group_t; @@ -158,7 +158,7 @@ namespace tut void translate_test_object_t::test<7>() { test_translation(mGoogle, 400, - "{\"oops\": \"invalid\"}", + "{\"data\": {}}", "", "", ""); } |