From 3fc3627f2d27b181269416f346f29d6451f7009a Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev
Date: Fri, 24 Feb 2023 11:59:48 +0200
Subject: SL-19209 WIP Switch MS Bing to MS Azure #2
---
indra/newview/app_settings/settings.xml | 17 +-
indra/newview/llfloatertranslationsettings.cpp | 120 +++++---
indra/newview/llfloatertranslationsettings.h | 18 +-
indra/newview/lltranslate.cpp | 317 +++++++++++++++------
indra/newview/lltranslate.h | 14 +-
.../xui/en/floater_translation_settings.xml | 95 ++++--
6 files changed, 420 insertions(+), 161 deletions(-)
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 411f77e6a7..ddd4f57f3f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12929,13 +12929,13 @@
TranslationService
GoogleTranslateAPIKey
", begin);
- err_msg = body.substr(begin, end-begin);
- LLStringUtil::replaceString(err_msg, "
", ""); // strip CR
return false;
}
- // Sample response: Hola
- size_t begin = body.find(">");
- if (begin == std::string::npos || begin >= (body.size() - 1))
- {
- begin = 0;
- }
- else
- {
- ++begin;
- }
+ //Example:
+ // "[{\"detectedLanguage\":{\"language\":\"en\",\"score\":1.0},\"translations\":[{\"text\":\"Hello, what is your name?\",\"to\":\"en\"}]}]"
- size_t end = body.find("", begin);
+ Json::Value root;
+ Json::Reader reader;
- detected_lang = ""; // unsupported by this API
- translation = body.substr(begin, end-begin);
- LLStringUtil::replaceString(translation, "
", ""); // strip CR
- return true;
+ if (!reader.parse(body, root))
+ {
+ err_msg = reader.getFormatedErrorMessages();
+ return false;
+ }
+
+ if (!root.isArray()) // empty response? should not happen
+ {
+ return false;
+ }
+
+ // Request succeeded, extract translation from the response.
+
+ const Json::Value& data = root[0U];
+ if (!data.isObject()
+ || !data.isMember("detectedLanguage")
+ || !data.isMember("translations"))
+ {
+ return false;
+ }
+
+ const Json::Value& detectedLanguage = data["detectedLanguage"];
+ if (!detectedLanguage.isObject() || !detectedLanguage.isMember("language"))
+ {
+ return false;
+ }
+ detected_lang = detectedLanguage["language"].asString();
+
+ const Json::Value& translations = data["translations"];
+ if (!translations.isArray() || translations.size() == 0)
+ {
+ return false;
+ }
+
+ const Json::Value& first = translations[0U];
+ if (!first.isObject() || !first.isMember("text"))
+ {
+ return false;
+ }
+
+ translation = first["text"].asString();
+
+ return true;
}
// virtual
bool LLAzureTranslationHandler::isConfigured() const
{
- return !getAPIKey().empty();
+ return !getAPIKey().isMap();
}
// static
-std::string LLAzureTranslationHandler::getAPIKey()
+LLSD LLAzureTranslationHandler::getAPIKey()
{
- return gSavedSettings.getString("BingTranslateAPIKey");
+ static LLCachedControl azure_key(gSavedSettings, "AzureTranslateAPIKey");
+ return azure_key;
}
// static
@@ -577,19 +696,38 @@ std::string LLAzureTranslationHandler::getAPILanguageCode(const std::string& lan
}
/*virtual*/
-void LLAzureTranslationHandler::verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc)
+void LLAzureTranslationHandler::verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc)
{
- LLCoros::instance().launch("Bing /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro,
- this, LLTranslate::SERVICE_BING, key, fnc));
+ LLCoros::instance().launch("Azure /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro,
+ this, LLTranslate::SERVICE_AZURE, key, fnc));
+}
+/*virtual*/
+void LLAzureTranslationHandler::initHttpHeader(
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& user_agent) const
+{
+ initHttpHeader(headers, user_agent, getAPIKey());
}
/*virtual*/
-void LLAzureTranslationHandler::initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const
+void LLAzureTranslationHandler::initHttpHeader(
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& user_agent,
+ const LLSD &key) const
{
headers->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_JSON);
- // Token based autorization exists
- //headers->append("Ocp-Apim-Subscription-Key", getAPIKey());
headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+
+ if (key.has("id"))
+ {
+ // Token based autorization
+ headers->append("Ocp-Apim-Subscription-Key", key["id"].asString());
+ }
+ if (key.has("region"))
+ {
+ // ex: "westeurope"
+ headers->append("Ocp-Apim-Subscription-Region", key["region"].asString());
+ }
}
LLSD LLAzureTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
@@ -599,9 +737,26 @@ LLSD LLAzureTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCorout
const std::string & url,
const std::string & msg) const
{
- LLSD body;
- body["text"] = "Hello, what is your name?";
- return adapter->postJsonAndSuspend(request, url, body, headers);
+ LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray);
+ LLCore::BufferArrayStream outs(rawbody.get());
+ outs << "[{\"text\":\"";
+ outs << msg;
+ outs << "\"}]";
+
+ return adapter->postRawAndSuspend(request, url, rawbody, options, headers);
+}
+
+LLSD LLAzureTranslationHandler::verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url) const
+{
+ LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray);
+ LLCore::BufferArrayStream outs(rawbody.get());
+ outs << "[{\"intentionally_invalid_400\"}]";
+
+ return adapter->postRawAndSuspend(request, url, rawbody, options, headers);
}
//=========================================================================
@@ -616,7 +771,7 @@ void LLTranslate::translateMessage(const std::string &from_lang, const std::stri
std::string LLTranslate::addNoTranslateTags(std::string mesg)
{
- if (getPreferredHandler().getCurrentService() != SERVICE_BING)
+ if (getPreferredHandler().getCurrentService() != SERVICE_AZURE)
{
return mesg;
}
@@ -637,7 +792,7 @@ std::string LLTranslate::addNoTranslateTags(std::string mesg)
std::string LLTranslate::removeNoTranslateTags(std::string mesg)
{
- if (getPreferredHandler().getCurrentService() != SERVICE_BING)
+ if (getPreferredHandler().getCurrentService() != SERVICE_AZURE)
{
return mesg;
}
@@ -667,7 +822,7 @@ std::string LLTranslate::removeNoTranslateTags(std::string mesg)
}
/*static*/
-void LLTranslate::verifyKey(EService service, const std::string &key, KeyVerificationResult_fn fnc)
+void LLTranslate::verifyKey(EService service, const LLSD &key, KeyVerificationResult_fn fnc)
{
LLTranslationAPIHandler& handler = getHandler(service);
@@ -696,7 +851,7 @@ bool LLTranslate::isTranslationConfigured()
// static
LLTranslationAPIHandler& LLTranslate::getPreferredHandler()
{
- EService service = SERVICE_BING;
+ EService service = SERVICE_AZURE;
std::string service_str = gSavedSettings.getString("TranslationService");
if (service_str == "google")
@@ -711,12 +866,12 @@ LLTranslationAPIHandler& LLTranslate::getPreferredHandler()
LLTranslationAPIHandler& LLTranslate::getHandler(EService service)
{
static LLGoogleTranslationHandler google;
- static LLAzureTranslationHandler bing;
+ static LLAzureTranslationHandler azure;
if (service == SERVICE_GOOGLE)
{
return google;
}
- return bing;
+ return azure;
}
diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h
index e0722fbd83..870fd54441 100644
--- a/indra/newview/lltranslate.h
+++ b/indra/newview/lltranslate.h
@@ -55,7 +55,7 @@ class LLTranslate
public :
typedef enum e_service {
- SERVICE_BING,
+ SERVICE_AZURE,
SERVICE_GOOGLE,
} EService;
@@ -74,12 +74,12 @@ public :
static void translateMessage(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, TranslationSuccess_fn success, TranslationFailure_fn failure);
/**
- * Verify given API key of a translation service.
- *
- * @param receiver Object to pass verification result to.
- * @param key Key to verify.
- */
- static void verifyKey(EService service, const std::string &key, KeyVerificationResult_fn fnc);
+ * Verify given API key of a translation service.
+ *
+ * @param receiver Object to pass verification result to.
+ * @param key Key to verify.
+ */
+ static void verifyKey(EService service, const LLSD &key, KeyVerificationResult_fn fnc);
/**
* @return translation target language
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 a212ce7889..b0e47798e9 100644
--- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml
@@ -1,7 +1,7 @@
- Bing appID not verified. Please try again.
+ Azure service identifier not verified. Please try again.
Google API key not verified. Please try again.
- Bing appID verified.
+ Azure service identifier verified.
Google API key verified.
+ name="azure" />
+ top_pad="115" />
+
+ Endpoint:
+
+
+
+
+
+
+
+
+
- Bing [http://www.bing.com/developers/createapp.aspx AppID]:
+ Azure Key:
+ width="90" />
+
+ Region:
+
+
Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API key]:
--
cgit v1.2.3