diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/llfloatertranslationsettings.cpp | 29 | ||||
| -rw-r--r-- | indra/newview/llfloatertranslationsettings.h | 8 | ||||
| -rw-r--r-- | indra/newview/lltranslate.cpp | 168 | ||||
| -rw-r--r-- | indra/newview/lltranslate.h | 2 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_translation_settings.xml | 19 | 
5 files changed, 168 insertions, 58 deletions
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index 45f46aacf5..c99de47da0 100644 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -132,22 +132,22 @@ void LLFloaterTranslationSettings::onOpen(const LLSD& key)  	updateControlsEnabledState();  } -void LLFloaterTranslationSettings::setAzureVerified(bool ok, bool alert) +void LLFloaterTranslationSettings::setAzureVerified(bool ok, bool alert, S32 status)  {  	if (alert)  	{ -		showAlert(ok ? "azure_api_key_verified" : "azure_api_key_not_verified"); +		showAlert(ok ? "azure_api_key_verified" : "azure_api_key_not_verified", status);  	}  	mAzureKeyVerified = ok;  	updateControlsEnabledState();  } -void LLFloaterTranslationSettings::setGoogleVerified(bool ok, bool alert) +void LLFloaterTranslationSettings::setGoogleVerified(bool ok, bool alert, S32 status)  {  	if (alert)  	{ -		showAlert(ok ? "google_api_key_verified" : "google_api_key_not_verified"); +		showAlert(ok ? "google_api_key_verified" : "google_api_key_not_verified", status);  	}  	mGoogleKeyVerified = ok; @@ -179,10 +179,15 @@ std::string LLFloaterTranslationSettings::getEnteredGoogleKey() const  	return mGoogleAPIKeyEditor->getTentative() ? LLStringUtil::null : mGoogleAPIKeyEditor->getText();  } -void LLFloaterTranslationSettings::showAlert(const std::string& msg_name) const +void LLFloaterTranslationSettings::showAlert(const std::string& msg_name, S32 status) const  { +    LLStringUtil::format_map_t string_args; +    // For now just show an http error code, whole 'reason' string might be added later +    string_args["[STATUS]"] = llformat("%d", status); +    std::string message = getString(msg_name, string_args); +  	LLSD args; -	args["MESSAGE"] = getString(msg_name); +	args["MESSAGE"] = message;  	LLNotificationsUtil::add("GenericAlert", args);  } @@ -222,7 +227,7 @@ void LLFloaterTranslationSettings::updateControlsEnabledState()  }  /*static*/ -void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, bool alert) +void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, bool alert, S32 status)  {      LLFloaterTranslationSettings* floater =          LLFloaterReg::getTypedInstance<LLFloaterTranslationSettings>("prefs_translation"); @@ -236,10 +241,10 @@ void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, b      switch (service)      {      case LLTranslate::SERVICE_AZURE: -        floater->setAzureVerified(ok, alert); +        floater->setAzureVerified(ok, alert, status);          break;      case LLTranslate::SERVICE_GOOGLE: -        floater->setGoogleVerified(ok, alert); +        floater->setGoogleVerified(ok, alert, status);          break;      }  } @@ -248,7 +253,7 @@ void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, b  void LLFloaterTranslationSettings::verifyKey(int service, const LLSD& key, bool alert)  {      LLTranslate::verifyKey(static_cast<LLTranslate::EService>(service), key, -        boost::bind(&LLFloaterTranslationSettings::setVerificationStatus, _1, _2, alert)); +        boost::bind(&LLFloaterTranslationSettings::setVerificationStatus, _1, _2, alert, _3));  }  void LLFloaterTranslationSettings::onEditorFocused(LLFocusableElement* control) @@ -271,7 +276,7 @@ void LLFloaterTranslationSettings::onAzureKeyEdited()          || mAzureAPIEndpointEditor->getValue().isString())  	{          // todo: verify mAzureAPIEndpointEditor url -		setAzureVerified(false, false); +		setAzureVerified(false, false, 0);  	}  } @@ -279,7 +284,7 @@ void LLFloaterTranslationSettings::onGoogleKeyEdited()  {  	if (mGoogleAPIKeyEditor->isDirty())  	{ -		setGoogleVerified(false, false); +		setGoogleVerified(false, false, 0);  	}  } diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h index 52523f4d4a..f039d90e27 100644 --- a/indra/newview/llfloatertranslationsettings.h +++ b/indra/newview/llfloatertranslationsettings.h @@ -42,15 +42,15 @@ public:  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); -	void setAzureVerified(bool ok, bool alert); -	void setGoogleVerified(bool ok, bool alert); +	void setAzureVerified(bool ok, bool alert, S32 status); +	void setGoogleVerified(bool ok, bool alert, S32 status);  	void onClose(bool app_quitting);  private:  	std::string getSelectedService() const;  	LLSD getEnteredAzureKey() const;  	std::string getEnteredGoogleKey() const; -	void showAlert(const std::string& msg_name) const; +	void showAlert(const std::string& msg_name, S32 status) const;  	void updateControlsEnabledState();      void verifyKey(int service, const LLSD& key, bool alert = true); @@ -61,7 +61,7 @@ private:  	void onBtnGoogleVerify();  	void onBtnOK(); -    static void setVerificationStatus(int service, bool alert, bool ok); +    static void setVerificationStatus(int service, bool alert, bool ok, S32 status);  	LLCheckBoxCtrl* mMachineTranslationCB;  	LLComboBox* mLanguageCombo; diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 706b4cc6ee..b0c4418ae9 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -41,8 +41,8 @@  #include "llurlregistry.h" -static const std::string BING_NOTRANSLATE_OPENING_TAG("<div translate=\"no\">"); -static const std::string BING_NOTRANSLATE_CLOSING_TAG("</div>"); +static const std::string AZURE_NOTRANSLATE_OPENING_TAG("<div translate=\"no\">"); +static const std::string AZURE_NOTRANSLATE_CLOSING_TAG("</div>");  /**  * Handler of an HTTP machine translation service. @@ -103,6 +103,7 @@ public:      * @param[out]    err_msg       Error message (in case of error).      */      virtual bool parseResponse( +        const LLSD& http_response,          int& status,          const std::string& body,          std::string& translation, @@ -176,6 +177,13 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, LLSD          return;      } +    std::string::size_type delim_pos = url.find("://"); +    if (delim_pos == std::string::npos) +    { +        LL_INFOS("Translate") << "URL is missing a scheme" << LL_ENDL; +        return; +    } +      LLSD result = verifyAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url);      LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; @@ -190,7 +198,7 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, LLSD      if (!fnc.empty())      { -        fnc(service, bOk); +        fnc(service, bOk, parseResult);      }  } @@ -221,8 +229,8 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s          LL_INFOS("Translate") << "No translation URL" << LL_ENDL;          return;      } -    LL_INFOS() << "Message: " << msg << LL_ENDL; -    LL_INFOS() << "Requesting: " << url << LL_ENDL; +    LL_DEBUGS("Translate") << "Message: " << msg << LL_ENDL; +    LL_DEBUGS("Translate") << "Requesting: " << url << LL_ENDL;      LLSD result = sendMessageAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url, msg); @@ -245,7 +253,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s      try      { -        res = this->parseResponse(parseResult, body, translation, detected_lang, err_msg); +        res = this->parseResponse(httpResults, parseResult, body, translation, detected_lang, err_msg);      }      catch (std::out_of_range&)      { @@ -306,6 +314,7 @@ public:          const LLSD &response,          int status) const override;      bool parseResponse( +        const LLSD& http_response,          int& status,          const std::string& body,          std::string& translation, @@ -380,6 +389,7 @@ bool LLGoogleTranslationHandler::checkVerificationResponse(  // virtual  bool LLGoogleTranslationHandler::parseResponse( +    const LLSD& http_response,  	int& status,  	const std::string& body,  	std::string& translation, @@ -531,6 +541,7 @@ public:          const LLSD &response,          int status) const override;      bool parseResponse( +        const LLSD& http_response,          int& status,          const std::string& body,          std::string& translation, @@ -557,6 +568,8 @@ public:          LLCore::HttpHeaders::ptr_t headers,          const std::string & url) const override;  private: +    static std::string parseErrorResponse( +        const std::string& body);      static LLSD getAPIKey();      static std::string getAPILanguageCode(const std::string& lang); @@ -574,7 +587,7 @@ std::string LLAzureTranslationHandler::getTranslateURL(      if (key.isMap())      {          std::string endpoint = key["endpoint"].asString(); -        // todo: validate url +          if (*endpoint.rbegin() != '/')          {              endpoint += "/"; @@ -594,7 +607,6 @@ std::string LLAzureTranslationHandler::getKeyVerificationURL(      if (key.isMap())      {          std::string endpoint = key["endpoint"].asString(); -        // todo: validate url          if (*endpoint.rbegin() != '/')          {              endpoint += "/"; @@ -609,11 +621,48 @@ bool LLAzureTranslationHandler::checkVerificationResponse(      const LLSD &response,      int status) const  { -    return status == HTTP_BAD_REQUEST; // would have been 401 if id was wrong +    if (status == HTTP_UNAUTHORIZED) +    { +        LL_DEBUGS("Translate") << "Key unathorised" << LL_ENDL; +        return false; +    } + +    if (status == HTTP_NOT_FOUND) +    { +        LL_DEBUGS("Translate") << "Either endpoint doesn't have requested resource" << LL_ENDL; +        return false; +    } + +    if (status != HTTP_BAD_REQUEST) +    { +        LL_DEBUGS("Translate") << "Unexpected error code" << LL_ENDL; +        return false; +    } + +    if (!response.has("error_body")) +    { +        LL_DEBUGS("Translate") << "Unexpected response, no error returned" << LL_ENDL; +        return false; +    } + +    // Expected: "{\"error\":{\"code\":400000,\"message\":\"One of the request inputs is not valid.\"}}" +    // But for now just verify response is a valid json with an error + +    Json::Value root; +    Json::Reader reader; + +    if (!reader.parse(response["error_body"].asString(), root)) +    { +        LL_DEBUGS("Translate") << "Failed to parse error_body:" << reader.getFormatedErrorMessages() << LL_ENDL; +        return false; +    } + +    return true;  }  // virtual  bool LLAzureTranslationHandler::parseResponse( +    const LLSD& http_response,  	int& status,  	const std::string& body,  	std::string& translation, @@ -622,6 +671,8 @@ bool LLAzureTranslationHandler::parseResponse(  {  	if (status != HTTP_OK)  	{ +        if (http_response.has("error_body")) +        err_msg = parseErrorResponse(http_response["error_body"].asString());  		return false;  	} @@ -682,6 +733,36 @@ bool LLAzureTranslationHandler::isConfigured() const  	return !getAPIKey().isMap();  } +//static +std::string LLAzureTranslationHandler::parseErrorResponse( +    const std::string& body) +{ +    // Expected: "{\"error\":{\"code\":400000,\"message\":\"One of the request inputs is not valid.\"}}" +    // But for now just verify response is a valid json with an error + +    Json::Value root; +    Json::Reader reader; + +    if (!reader.parse(body, root)) +    { +        return std::string(); +    } + +    if (!root.isObject() || !root.isMember("error")) +    { +        return std::string(); +    } + +    const Json::Value& error_map = root["error"]; + +    if (!error_map.isObject() || !error_map.isMember("message")) +    { +        return std::string(); +    } + +    return error_map["message"].asString(); +} +  // static  LLSD LLAzureTranslationHandler::getAPIKey()  { @@ -771,54 +852,65 @@ void LLTranslate::translateMessage(const std::string &from_lang, const std::stri  std::string LLTranslate::addNoTranslateTags(std::string mesg)  { -    if (getPreferredHandler().getCurrentService() != SERVICE_AZURE) +    if (getPreferredHandler().getCurrentService() == SERVICE_GOOGLE)      {          return mesg;      } -    std::string upd_msg(mesg); -    LLUrlMatch match; -    S32 dif = 0; -    //surround all links (including SLURLs) with 'no-translate' tags to prevent unnecessary translation -    while (LLUrlRegistry::instance().findUrl(mesg, match)) +    if (getPreferredHandler().getCurrentService() == SERVICE_AZURE)      { -        upd_msg.insert(dif + match.getStart(), BING_NOTRANSLATE_OPENING_TAG); -        upd_msg.insert(dif + BING_NOTRANSLATE_OPENING_TAG.size() + match.getEnd() + 1, BING_NOTRANSLATE_CLOSING_TAG); -        mesg.erase(match.getStart(), match.getEnd() - match.getStart()); -        dif += match.getEnd() - match.getStart() + BING_NOTRANSLATE_OPENING_TAG.size() + BING_NOTRANSLATE_CLOSING_TAG.size(); +        // https://learn.microsoft.com/en-us/azure/cognitive-services/translator/prevent-translation +        std::string upd_msg(mesg); +        LLUrlMatch match; +        S32 dif = 0; +        //surround all links (including SLURLs) with 'no-translate' tags to prevent unnecessary translation +        while (LLUrlRegistry::instance().findUrl(mesg, match)) +        { +            upd_msg.insert(dif + match.getStart(), AZURE_NOTRANSLATE_OPENING_TAG); +            upd_msg.insert(dif + AZURE_NOTRANSLATE_OPENING_TAG.size() + match.getEnd() + 1, AZURE_NOTRANSLATE_CLOSING_TAG); +            mesg.erase(match.getStart(), match.getEnd() - match.getStart()); +            dif += match.getEnd() - match.getStart() + AZURE_NOTRANSLATE_OPENING_TAG.size() + AZURE_NOTRANSLATE_CLOSING_TAG.size(); +        } +        return upd_msg;      } -    return upd_msg; +    return mesg;  }  std::string LLTranslate::removeNoTranslateTags(std::string mesg)  { -    if (getPreferredHandler().getCurrentService() != SERVICE_AZURE) +    if (getPreferredHandler().getCurrentService() == SERVICE_GOOGLE)      {          return mesg;      } -    std::string upd_msg(mesg); -    LLUrlMatch match; -    S32 opening_tag_size = BING_NOTRANSLATE_OPENING_TAG.size(); -    S32 closing_tag_size = BING_NOTRANSLATE_CLOSING_TAG.size(); -    S32 dif = 0; -    //remove 'no-translate' tags we added to the links before -    while (LLUrlRegistry::instance().findUrl(mesg, match)) + +    if (getPreferredHandler().getCurrentService() == SERVICE_AZURE)      { -        if (upd_msg.substr(dif + match.getStart() - opening_tag_size, opening_tag_size) == BING_NOTRANSLATE_OPENING_TAG) +        std::string upd_msg(mesg); +        LLUrlMatch match; +        S32 opening_tag_size = AZURE_NOTRANSLATE_OPENING_TAG.size(); +        S32 closing_tag_size = AZURE_NOTRANSLATE_CLOSING_TAG.size(); +        S32 dif = 0; +        //remove 'no-translate' tags we added to the links before +        while (LLUrlRegistry::instance().findUrl(mesg, match))          { -            upd_msg.erase(dif + match.getStart() - opening_tag_size, opening_tag_size); -            dif -= opening_tag_size; - -            if (upd_msg.substr(dif + match.getEnd() + 1, closing_tag_size) == BING_NOTRANSLATE_CLOSING_TAG) +            if (upd_msg.substr(dif + match.getStart() - opening_tag_size, opening_tag_size) == AZURE_NOTRANSLATE_OPENING_TAG)              { -                upd_msg.replace(dif + match.getEnd() + 1, closing_tag_size, " "); -                dif -= closing_tag_size - 1; +                upd_msg.erase(dif + match.getStart() - opening_tag_size, opening_tag_size); +                dif -= opening_tag_size; + +                if (upd_msg.substr(dif + match.getEnd() + 1, closing_tag_size) == AZURE_NOTRANSLATE_CLOSING_TAG) +                { +                    upd_msg.replace(dif + match.getEnd() + 1, closing_tag_size, " "); +                    dif -= closing_tag_size - 1; +                }              } +            mesg.erase(match.getStart(), match.getUrl().size()); +            dif += match.getUrl().size();          } -        mesg.erase(match.getStart(), match.getUrl().size()); -        dif += match.getUrl().size(); +        return upd_msg;      } -    return upd_msg; + +    return mesg;  }  /*static*/ diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index 870fd54441..1de5c02f74 100644 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -59,7 +59,7 @@ public :  		SERVICE_GOOGLE,  	} EService; -    typedef boost::function<void(EService, bool)> KeyVerificationResult_fn; +    typedef boost::function<void(EService, bool, S32)> KeyVerificationResult_fn;      typedef boost::function<void(std::string , std::string )> TranslationSuccess_fn;      typedef boost::function<void(int, std::string)> TranslationFailure_fn; diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml index b0e47798e9..d095451685 100644 --- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml @@ -9,8 +9,8 @@   title="CHAT TRANSLATION SETTINGS"   width="485"> - <string name="azure_api_key_not_verified">Azure service identifier not verified. Please try again.</string> - <string name="google_api_key_not_verified">Google API key not verified. Please try again.</string> + <string name="azure_api_key_not_verified">Azure service identifier not verified. Status: [STATUS]. Please check your settings and try again.</string> + <string name="google_api_key_not_verified">Google API key not verified. Status: [STATUS]. Please check your key and try again.</string>   <string name="azure_api_key_verified">Azure service identifier verified.</string>   <string name="google_api_key_verified">Google API key verified.</string> @@ -148,6 +148,19 @@   </radio_group>    <text +   follows="top|right" +   height="20" +   layout="topleft" +   left="185" +   length="1" +   name="google_links_text" +   top_pad="-142" +   type="string" +   width="100"> +    [https://learn.microsoft.com/en-us/azure/cognitive-services/translator/create-translator-resource Setup] +  </text> + +  <text     type="string"     length="1"     follows="top|right" @@ -155,7 +168,7 @@     layout="topleft"     left="70"     name="azure_api_endoint_label" -   top_pad="-115" +   top_pad="8"     width="85">      Endpoint:    </text>  | 
