diff options
Diffstat (limited to 'indra/newview')
| -rwxr-xr-x | indra/newview/CMakeLists.txt | 12 | ||||
| -rwxr-xr-x | indra/newview/llfloatermarketplacelistings.cpp | 2 | ||||
| -rwxr-xr-x | indra/newview/llfloateroutbox.cpp | 4 | ||||
| -rwxr-xr-x | indra/newview/llfloatertranslationsettings.cpp | 64 | ||||
| -rwxr-xr-x | indra/newview/llfloatertranslationsettings.h | 2 | ||||
| -rwxr-xr-x | indra/newview/llmarketplacefunctions.cpp | 42 | ||||
| -rwxr-xr-x | indra/newview/llmarketplacefunctions.h | 14 | ||||
| -rwxr-xr-x | indra/newview/lltranslate.cpp | 384 | ||||
| -rwxr-xr-x | indra/newview/lltranslate.h | 215 | ||||
| -rwxr-xr-x | indra/newview/llviewermessage.cpp | 64 | 
10 files changed, 386 insertions, 417 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 979b182662..7eb4174b7f 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2224,7 +2224,7 @@ if (LL_TESTS)  #    llmediadataclient.cpp      lllogininstance.cpp  #    llremoteparcelrequest.cpp -    lltranslate.cpp +#    lltranslate.cpp      llviewerhelputil.cpp      llversioninfo.cpp      llworldmap.cpp @@ -2245,11 +2245,11 @@ if (LL_TESTS)      ${CURL_LIBRARIES}      ) -  set_source_files_properties( -    lltranslate.cpp -    PROPERTIES -    LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}" -  ) +#  set_source_files_properties( +#    lltranslate.cpp +#    PROPERTIES +#    LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}" +#  )    set_source_files_properties(      llmediadataclient.cpp diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index b2d36479cd..18f0bc4498 100755 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -572,7 +572,7 @@ void LLFloaterMarketplaceListings::updateView()          std::string title;          std::string tooltip; -        const LLSD& subs = getMarketplaceStringSubstitutions(); +        const LLSD& subs = LLMarketplaceData::getMarketplaceStringSubstitutions();          // Update the top message or flip to the tabs and folders view          // *TODO : check those messages and create better appropriate ones in strings.xml diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp index b7b1634a5f..f61b50003d 100755 --- a/indra/newview/llfloateroutbox.cpp +++ b/indra/newview/llfloateroutbox.cpp @@ -397,7 +397,7 @@ void LLFloaterOutbox::updateView()  		std::string outbox_title;  		std::string outbox_tooltip; -		const LLSD& subs = getMarketplaceStringSubstitutions(); +		const LLSD& subs = LLMarketplaceData::getMarketplaceStringSubstitutions();  		U32 mkt_status = LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus();  		if (mOutboxId.notNull()) @@ -544,7 +544,7 @@ void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)  	}  	else if (status == MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS)  	{ -		const LLSD& subs = getMarketplaceStringSubstitutions(); +		const LLSD& subs = LLMarketplaceData::getMarketplaceStringSubstitutions();  		LLNotificationsUtil::add("OutboxImportHadErrors", subs);  	} diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index 965d29b09c..b1316e386d 100755 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -42,41 +42,6 @@  #include "llnotificationsutil.h"  #include "llradiogroup.h" -class EnteredKeyVerifier : public LLTranslate::KeyVerificationReceiver -{ -public: -	EnteredKeyVerifier(LLTranslate::EService service, bool alert) -	:	LLTranslate::KeyVerificationReceiver(service) -	,	mAlert(alert) -	{ -	} - -private: -	/*virtual*/ void setVerificationStatus(bool ok) -	{ -		LLFloaterTranslationSettings* floater = -			LLFloaterReg::getTypedInstance<LLFloaterTranslationSettings>("prefs_translation"); - -		if (!floater) -		{ -			LL_WARNS() << "Cannot find translation settings floater" << LL_ENDL; -			return; -		} - -		switch (getService()) -		{ -		case LLTranslate::SERVICE_BING: -			floater->setBingVerified(ok, mAlert); -			break; -		case LLTranslate::SERVICE_GOOGLE: -			floater->setGoogleVerified(ok, mAlert); -			break; -		} -	} - -	bool mAlert; -}; -  LLFloaterTranslationSettings::LLFloaterTranslationSettings(const LLSD& key)  :	LLFloater(key)  ,	mMachineTranslationCB(NULL) @@ -231,11 +196,34 @@ void LLFloaterTranslationSettings::updateControlsEnabledState()  	mOKBtn->setEnabled(!on || service_verified);  } +/*static*/ +void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, bool alert) +{ +    LLFloaterTranslationSettings* floater = +        LLFloaterReg::getTypedInstance<LLFloaterTranslationSettings>("prefs_translation"); + +    if (!floater) +    { +        LL_WARNS() << "Cannot find translation settings floater" << LL_ENDL; +        return; +    } + +    switch (service) +    { +    case LLTranslate::SERVICE_BING: +        floater->setBingVerified(ok, alert); +        break; +    case LLTranslate::SERVICE_GOOGLE: +        floater->setGoogleVerified(ok, alert); +        break; +    } +} + +  void LLFloaterTranslationSettings::verifyKey(int service, const std::string& key, bool alert)  { -	LLTranslate::KeyVerificationReceiverPtr receiver = -		new EnteredKeyVerifier((LLTranslate::EService) service, alert); -	LLTranslate::verifyKey(receiver, key); +    LLTranslate::verifyKey(static_cast<LLTranslate::EService>(service), key, +        boost::bind(&LLFloaterTranslationSettings::setVerificationStatus, _1, _2, alert));  }  void LLFloaterTranslationSettings::onEditorFocused(LLFocusableElement* control) diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h index b9bfd6265a..2a15eacded 100755 --- a/indra/newview/llfloatertranslationsettings.h +++ b/indra/newview/llfloatertranslationsettings.h @@ -61,6 +61,8 @@ private:  	void onBtnGoogleVerify();  	void onBtnOK(); +    static void setVerificationStatus(int service, bool alert, bool ok); +  	LLCheckBoxCtrl* mMachineTranslationCB;  	LLComboBox* mLanguageCombo;  	LLLineEditor* mBingAPIKeyEditor; diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index f2f18cd6a2..cff8446545 100755 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -146,28 +146,6 @@ namespace {  } -LLSD getMarketplaceStringSubstitutions() -{ -    std::string marketplace_url = getMarketplaceURL("MarketplaceURL"); -    std::string marketplace_url_create = getMarketplaceURL("MarketplaceURL_CreateStore"); -    std::string marketplace_url_dashboard = getMarketplaceURL("MarketplaceURL_Dashboard"); -    std::string marketplace_url_imports = getMarketplaceURL("MarketplaceURL_Imports"); -    std::string marketplace_url_info = getMarketplaceURL("MarketplaceURL_LearnMore"); - -    LLSD marketplace_sub_map; - -    marketplace_sub_map["[MARKETPLACE_URL]"] = marketplace_url; -    marketplace_sub_map["[MARKETPLACE_CREATE_STORE_URL]"] = marketplace_url_create; -    marketplace_sub_map["[MARKETPLACE_LEARN_MORE_URL]"] = marketplace_url_info; -    marketplace_sub_map["[MARKETPLACE_DASHBOARD_URL]"] = marketplace_url_dashboard; -    marketplace_sub_map["[MARKETPLACE_IMPORTS_URL]"] = marketplace_url_imports; - -    return marketplace_sub_map; -} - - -// SLM Responders End -///////////////////////////////////////////////////////////////////////////////  #if 1  namespace LLMarketplaceImport @@ -720,6 +698,26 @@ LLMarketplaceData::~LLMarketplaceData()  	gInventory.removeObserver(mInventoryObserver);  } + +LLSD LLMarketplaceData::getMarketplaceStringSubstitutions() +{ +    std::string marketplace_url = getMarketplaceURL("MarketplaceURL"); +    std::string marketplace_url_create = getMarketplaceURL("MarketplaceURL_CreateStore"); +    std::string marketplace_url_dashboard = getMarketplaceURL("MarketplaceURL_Dashboard"); +    std::string marketplace_url_imports = getMarketplaceURL("MarketplaceURL_Imports"); +    std::string marketplace_url_info = getMarketplaceURL("MarketplaceURL_LearnMore"); + +    LLSD marketplace_sub_map; + +    marketplace_sub_map["[MARKETPLACE_URL]"] = marketplace_url; +    marketplace_sub_map["[MARKETPLACE_CREATE_STORE_URL]"] = marketplace_url_create; +    marketplace_sub_map["[MARKETPLACE_LEARN_MORE_URL]"] = marketplace_url_info; +    marketplace_sub_map["[MARKETPLACE_DASHBOARD_URL]"] = marketplace_url_dashboard; +    marketplace_sub_map["[MARKETPLACE_IMPORTS_URL]"] = marketplace_url_imports; + +    return marketplace_sub_map; +} +  void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type& cb)  {  	if (mStatusUpdatedSignal == NULL) diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index f9e2ac98d0..9d795c6ced 100755 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -37,8 +37,6 @@  #include "llstring.h" -LLSD getMarketplaceStringSubstitutions(); -  namespace MarketplaceErrorCodes  { @@ -183,6 +181,8 @@ class LLSLMDeleteListingsResponder;  class LLMarketplaceData      : public LLSingleton<LLMarketplaceData>  { +    friend class LLSingleton < LLMarketplaceData > ; +  public:  	friend class LLSLMGetMerchantResponder;      friend class LLSLMGetListingsResponder; @@ -192,9 +192,8 @@ public:      friend class LLSLMAssociateListingsResponder;      friend class LLSLMDeleteListingsResponder; -	LLMarketplaceData(); -    virtual ~LLMarketplaceData(); -     +    static LLSD getMarketplaceStringSubstitutions(); +      // Public SLM API : Initialization and status  	typedef boost::signals2::signal<void ()> status_updated_signal_t;      void initializeSLM(const status_updated_signal_t::slot_type& cb); @@ -241,8 +240,11 @@ public:      // Used to decide when to run a validation on listing folders      void setValidationWaiting(const LLUUID& folder_id, S32 count);      void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1); -     +  private: +    LLMarketplaceData(); +    virtual ~LLMarketplaceData(); +      // Modify Marketplace data set  : each method returns true if the function succeeds, false if error      // Used internally only by SLM Responders when data are received from the SLM Server      bool addListing(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id, bool is_listed, const std::string& edit_url, S32 count); diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index c0ba0a1f39..1ca2011a70 100755 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -35,31 +35,254 @@  #include "llui.h"  #include "llversioninfo.h"  #include "llviewercontrol.h" - +#include "llcoros.h"  #include "reader.h" +#include "llcorehttputil.h" + + +/** +* Handler of an HTTP machine translation service. +* +* Derived classes know the service URL +* and how to parse the translation result. +*/ +class LLTranslationAPIHandler +{ +public: +    typedef std::pair<std::string, std::string> LanguagePair_t; + +    /** +    * 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 std::string getTranslateURL( +        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 std::string getKeyVerificationURL( +        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, +        std::string& translation, +        std::string& detected_lang, +        std::string& err_msg) const = 0; + +    /** +    * @return if the handler is configured to function properly +    */ +    virtual bool isConfigured() const = 0; + +    virtual void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) = 0; +    virtual void translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure); + + +    virtual ~LLTranslationAPIHandler() {} + +    void verifyKeyCoro(LLTranslate::EService service, std::string key, LLTranslate::KeyVerificationResult_fn fnc); +    void translateMessageCoro(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure); +}; + +void LLTranslationAPIHandler::translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure) +{ +    LLCoros::instance().launch("Translation", boost::bind(&LLTranslationAPIHandler::translateMessageCoro, +        this, fromTo, msg, success, failure)); + +} + + +void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std::string key, LLTranslate::KeyVerificationResult_fn fnc) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getMerchantStatusCoro", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); +    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); +    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); + + +    std::string user_agent = llformat("%s %d.%d.%d (%d)", +        LLVersionInfo::getChannel().c_str(), +        LLVersionInfo::getMajor(), +        LLVersionInfo::getMinor(), +        LLVersionInfo::getPatch(), +        LLVersionInfo::getBuild()); + +    httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN); +    httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); +    httpOpts->setFollowRedirects(true); + +    std::string url = this->getKeyVerificationURL(key); +    if (url.empty()) +    { +        LL_INFOS("Translate") << "No translation URL" << LL_ENDL; +        return; +    } + +    LLSD result = httpAdapter->getAndYield(httpRequest, url, httpOpts, httpHeaders); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + +    bool bOk = true; +    if (!status) +        bOk = false; + +    if (!fnc.empty()) +        fnc(service, bOk); +} + +void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::string msg, +    LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getMerchantStatusCoro", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); +    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); +    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); + + +    std::string user_agent = llformat("%s %d.%d.%d (%d)", +        LLVersionInfo::getChannel().c_str(), +        LLVersionInfo::getMajor(), +        LLVersionInfo::getMinor(), +        LLVersionInfo::getPatch(), +        LLVersionInfo::getBuild()); + +    httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN); +    httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); + +    std::string url = this->getTranslateURL(fromTo.first, fromTo.second, msg); +    if (url.empty()) +    { +        LL_INFOS("Translate") << "No translation URL" << LL_ENDL; +        return; +    } + +    LLSD result = httpAdapter->getRawAndYield(httpRequest, url, httpOpts, httpHeaders); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + +    std::string translation, detected_lang, err_msg; + +    int parseResult = status.getType(); +    if (this->parseResponse(parseResult, result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asString(),  +        translation, detected_lang, err_msg)) +    { +        // Fix up the response +        LLStringUtil::replaceString(translation, "<", "<"); +        LLStringUtil::replaceString(translation, ">", ">"); +        LLStringUtil::replaceString(translation, """, "\""); +        LLStringUtil::replaceString(translation, "'", "'"); +        LLStringUtil::replaceString(translation, "&", "&"); +        LLStringUtil::replaceString(translation, "'", "'"); + +        if (!success.empty()) +            success(translation, detected_lang); +    } +    else +    { +        if (err_msg.empty()) +        { +            err_msg = LLTrans::getString("TranslationResponseParseError"); +        } + +        LL_WARNS() << "Translation request failed: " << err_msg << LL_ENDL; +        if (!failure.empty()) +            failure(status, err_msg); +    } + + +} + +//========================================================================= +/// Google Translate v2 API handler. +class LLGoogleTranslationHandler : public LLTranslationAPIHandler +{ +    LOG_CLASS(LLGoogleTranslationHandler); + +public: +    /*virtual*/ std::string getTranslateURL( +        const std::string &from_lang, +        const std::string &to_lang, +        const std::string &text) const; +    /*virtual*/ std::string getKeyVerificationURL( +        const std::string &key) const; +    /*virtual*/ bool parseResponse( +        int& status, +        const std::string& body, +        std::string& translation, +        std::string& detected_lang, +        std::string& err_msg) const; +    /*virtual*/ bool isConfigured() const; + +    /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc); + +private: +    static void parseErrorResponse( +        const Json::Value& root, +        int& status, +        std::string& err_msg); +    static bool parseTranslation( +        const Json::Value& root, +        std::string& translation, +        std::string& detected_lang); +    static std::string getAPIKey(); + +}; + +//-------------------------------------------------------------------------  // virtual -void LLGoogleTranslationHandler::getTranslateURL( -	std::string &url, +std::string LLGoogleTranslationHandler::getTranslateURL(  	const std::string &from_lang,  	const std::string &to_lang,  	const std::string &text) const  { -	url = std::string("https://www.googleapis.com/language/translate/v2?key=") +	std::string url = std::string("https://www.googleapis.com/language/translate/v2?key=")  		+ getAPIKey() + "&q=" + LLURI::escape(text) + "&target=" + to_lang;  	if (!from_lang.empty())  	{  		url += "&source=" + from_lang;  	} +    return url;  }  // virtual -void LLGoogleTranslationHandler::getKeyVerificationURL( -	std::string& url, +std::string LLGoogleTranslationHandler::getKeyVerificationURL(  	const std::string& key) const  { -	url = std::string("https://www.googleapis.com/language/translate/v2/languages?key=") +	std::string url = std::string("https://www.googleapis.com/language/translate/v2/languages?key=")  		+ key + "&target=en"; +    return url;  }  // virtual @@ -154,28 +377,66 @@ std::string LLGoogleTranslationHandler::getAPIKey()  	return gSavedSettings.getString("GoogleTranslateAPIKey");  } +/*virtual*/  +void LLGoogleTranslationHandler::verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) +{ +    LLCoros::instance().launch("Google /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro, +        this, LLTranslate::SERVICE_GOOGLE, key, fnc)); +} + + +//========================================================================= +/// Microsoft Translator v2 API handler. +class LLBingTranslationHandler : public LLTranslationAPIHandler +{ +    LOG_CLASS(LLBingTranslationHandler); + +public: +    /*virtual*/ std::string getTranslateURL( +        const std::string &from_lang, +        const std::string &to_lang, +        const std::string &text) const; +    /*virtual*/ std::string getKeyVerificationURL( +        const std::string &key) const; +    /*virtual*/ bool parseResponse( +        int& status, +        const std::string& body, +        std::string& translation, +        std::string& detected_lang, +        std::string& err_msg) const; +    /*virtual*/ bool isConfigured() const; + +    /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc); +private: +    static std::string getAPIKey(); +    static std::string getAPILanguageCode(const std::string& lang); + +}; + +//-------------------------------------------------------------------------  // virtual -void LLBingTranslationHandler::getTranslateURL( -	std::string &url, +std::string LLBingTranslationHandler::getTranslateURL(  	const std::string &from_lang,  	const std::string &to_lang,  	const std::string &text) const  { -	url = std::string("http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=") +	std::string url = std::string("http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=")  		+ getAPIKey() + "&text=" + LLURI::escape(text) + "&to=" + getAPILanguageCode(to_lang);  	if (!from_lang.empty())  	{  		url += "&from=" + getAPILanguageCode(from_lang);  	} +    return url;  } +  // virtual -void LLBingTranslationHandler::getKeyVerificationURL( -	std::string& url, +std::string LLBingTranslationHandler::getKeyVerificationURL(  	const std::string& key) const  { -	url = std::string("http://api.microsofttranslator.com/v2/Http.svc/GetLanguagesForTranslate?appId=") +	std::string url = std::string("http://api.microsofttranslator.com/v2/Http.svc/GetLanguagesForTranslate?appId=")  		+ key; +    return url;  }  // virtual @@ -242,96 +503,31 @@ std::string LLBingTranslationHandler::getAPILanguageCode(const std::string& lang  	return lang == "zh" ? "zh-CHT" : lang; // treat Chinese as Traditional Chinese  } -LLTranslate::TranslationReceiver::TranslationReceiver(const std::string& from_lang, const std::string& to_lang) -:	mFromLang(from_lang) -,	mToLang(to_lang) -,	mHandler(LLTranslate::getPreferredHandler()) +/*virtual*/ +void LLBingTranslationHandler::verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc)  { +    LLCoros::instance().launch("Bing /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro,  +        this, LLTranslate::SERVICE_BING, key, fnc));  } -// virtual -void LLTranslate::TranslationReceiver::completedRaw( -	const LLChannelDescriptors& channels, -	const LLIOPipe::buffer_ptr_t& buffer) +//========================================================================= +/*static*/ +void LLTranslate::translateMessage(const std::string &from_lang, const std::string &to_lang, +    const std::string &mesg, TranslationSuccess_fn success, TranslationFailure_fn failure)  { -	LLBufferStream istr(channels, buffer.get()); -	std::stringstream strstrm; -	strstrm << istr.rdbuf(); - -	const std::string body = strstrm.str(); -	std::string translation, detected_lang, err_msg; -	int status = getStatus(); -	LL_DEBUGS("Translate") << "HTTP status: " << status << " " << getReason() << LL_ENDL; -	LL_DEBUGS("Translate") << "Response body: " << body << LL_ENDL; -	if (mHandler.parseResponse(status, body, translation, detected_lang, err_msg)) -	{ -		// Fix up the response -		LLStringUtil::replaceString(translation, "<", "<"); -		LLStringUtil::replaceString(translation, ">",">"); -		LLStringUtil::replaceString(translation, ""","\""); -		LLStringUtil::replaceString(translation, "'","'"); -		LLStringUtil::replaceString(translation, "&","&"); -		LLStringUtil::replaceString(translation, "'","'"); - -		handleResponse(translation, detected_lang); -	} -	else -	{ -		if (err_msg.empty()) -		{ -			err_msg = LLTrans::getString("TranslationResponseParseError"); -		} +    LLTranslationAPIHandler& handler = getPreferredHandler(); -		LL_WARNS() << "Translation request failed: " << err_msg << LL_ENDL; -		handleFailure(status, err_msg); -	} +    handler.translateMessage(LLTranslationAPIHandler::LanguagePair_t(from_lang, to_lang), mesg, success, failure);  } -LLTranslate::KeyVerificationReceiver::KeyVerificationReceiver(EService service) -:	mService(service) +/*static*/ +void LLTranslate::verifyKey(EService service, const std::string &key, KeyVerificationResult_fn fnc)  { -} +    LLTranslationAPIHandler& handler = getHandler(service); -LLTranslate::EService LLTranslate::KeyVerificationReceiver::getService() const -{ -	return mService; +    handler.verifyKey(key, fnc);  } -// virtual -void LLTranslate::KeyVerificationReceiver::completedRaw( -	const LLChannelDescriptors& channels, -	const LLIOPipe::buffer_ptr_t& buffer) -{ -	bool ok = (getStatus() == HTTP_OK); -	setVerificationStatus(ok); -} - -//static -void LLTranslate::translateMessage( -	TranslationReceiverPtr &receiver, -	const std::string &from_lang, -	const std::string &to_lang, -	const std::string &mesg) -{ -	std::string url; -	receiver->mHandler.getTranslateURL(url, from_lang, to_lang, mesg); - -	LL_DEBUGS("Translate") << "Sending translation request: " << url << LL_ENDL; -	sendRequest(url, receiver); -} - -// static -void LLTranslate::verifyKey( -	KeyVerificationReceiverPtr& receiver, -	const std::string& key) -{ -	std::string url; -	const LLTranslationAPIHandler& handler = getHandler(receiver->getService()); -	handler.getKeyVerificationURL(url, key); - -	LL_DEBUGS("Translate") << "Sending key verification request: " << url << LL_ENDL; -	sendRequest(url, receiver); -}  //static  std::string LLTranslate::getTranslateLanguage() @@ -352,7 +548,7 @@ bool LLTranslate::isTranslationConfigured()  }  // static -const LLTranslationAPIHandler& LLTranslate::getPreferredHandler() +LLTranslationAPIHandler& LLTranslate::getPreferredHandler()  {  	EService service = SERVICE_BING; @@ -366,7 +562,7 @@ const LLTranslationAPIHandler& LLTranslate::getPreferredHandler()  }  // static -const LLTranslationAPIHandler& LLTranslate::getHandler(EService service) +LLTranslationAPIHandler& LLTranslate::getHandler(EService service)  {  	static LLGoogleTranslationHandler google;  	static LLBingTranslationHandler bing; diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index 972274714a..49a0105dbb 100755 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -29,134 +29,14 @@  #include "llhttpclient.h"  #include "llbufferstream.h" +#include <boost/function.hpp>  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, -		std::string& translation, -		std::string& detected_lang, -		std::string& err_msg) const = 0; - -	/** -	 * @return if the handler is configured to function properly -	 */ -	virtual bool isConfigured() const = 0; - -	virtual ~LLTranslationAPIHandler() {} -}; - -/// Google Translate v2 API handler. -class LLGoogleTranslationHandler : public LLTranslationAPIHandler -{ -	LOG_CLASS(LLGoogleTranslationHandler); - -public: -	/*virtual*/ void getTranslateURL( -		std::string &url, -		const std::string &from_lang, -		const std::string &to_lang, -		const std::string &text) const; -	/*virtual*/ void getKeyVerificationURL( -		std::string &url, -		const std::string &key) const; -	/*virtual*/ bool parseResponse( -		int& status, -		const std::string& body, -		std::string& translation, -		std::string& detected_lang, -		std::string& err_msg) const; -	/*virtual*/ bool isConfigured() const; - -private: -	static void parseErrorResponse( -		const Json::Value& root, -		int& status, -		std::string& err_msg); -	static bool parseTranslation( -		const Json::Value& root, -		std::string& translation, -		std::string& detected_lang); -	static std::string getAPIKey(); -}; - -/// Microsoft Translator v2 API handler. -class LLBingTranslationHandler : public LLTranslationAPIHandler -{ -	LOG_CLASS(LLBingTranslationHandler); - -public: -	/*virtual*/ void getTranslateURL( -		std::string &url, -		const std::string &from_lang, -		const std::string &to_lang, -		const std::string &text) const; -	/*virtual*/ void getKeyVerificationURL( -		std::string &url, -		const std::string &key) const; -	/*virtual*/ bool parseResponse( -		int& status, -		const std::string& body, -		std::string& translation, -		std::string& detected_lang, -		std::string& err_msg) const; -	/*virtual*/ bool isConfigured() const; -private: -	static std::string getAPIKey(); -	static std::string getAPILanguageCode(const std::string& lang); -}; - +class LLTranslationAPIHandler;  /**   * Entry point for machine translation services.   * @@ -180,84 +60,9 @@ 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( -			const LLChannelDescriptors& channels, -			const LLIOPipe::buffer_ptr_t& buffer); - -	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; -		std::string mToLang; -		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( -			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; -	}; - -	typedef LLPointer<TranslationReceiver> TranslationReceiverPtr; -	typedef LLPointer<KeyVerificationReceiver> KeyVerificationReceiverPtr; +    typedef boost::function<void(EService, bool)> KeyVerificationResult_fn; +    typedef boost::function<void(std::string , std::string )> TranslationSuccess_fn; +    typedef boost::function<void(int, std::string)> TranslationFailure_fn;  	/**  	 * Translate given text. @@ -267,15 +72,15 @@ public :  	 * @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); +    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(KeyVerificationReceiverPtr& receiver, const std::string& key); +    static void verifyKey(EService service, const std::string &key, KeyVerificationResult_fn fnc);  	/**  	 * @return translation target language @@ -288,8 +93,8 @@ public :  	static bool isTranslationConfigured();  private: -	static const LLTranslationAPIHandler& getPreferredHandler(); -	static const LLTranslationAPIHandler& getHandler(EService service); +	static LLTranslationAPIHandler& getPreferredHandler(); +	static LLTranslationAPIHandler& getHandler(EService service);  	static void sendRequest(const std::string& url, LLHTTPClient::ResponderPtr responder);  }; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 0643f7b1e3..4062228ae5 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3492,53 +3492,29 @@ void process_decline_callingcard(LLMessageSystem* msg, void**)  	LLNotificationsUtil::add("CallingCardDeclined");  } -class ChatTranslationReceiver : public LLTranslate::TranslationReceiver +void translateSuccess(LLChat chat, LLSD toastArgs, std::string originalMsg, std::string expectLang, std::string translation, const std::string detected_language)  { -public : -	ChatTranslationReceiver(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, -							const LLChat &chat, const LLSD &toast_args) -		: LLTranslate::TranslationReceiver(from_lang, to_lang), -		m_chat(chat), -		m_toastArgs(toast_args), -		m_origMesg(mesg) -	{ -	} - -	static ChatTranslationReceiver* build(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, const LLChat &chat, const LLSD &toast_args) -	{ -		return new ChatTranslationReceiver(from_lang, to_lang, mesg, chat, toast_args); -	} - -protected: -	void handleResponse(const std::string &translation, const std::string &detected_language) -	{ -		// filter out non-interesting responeses -		if ( !translation.empty() -			&& (mToLang != detected_language) -			&& (LLStringUtil::compareInsensitive(translation, m_origMesg) != 0) ) -		{ -			m_chat.mText += " (" + translation + ")"; -		} +    // filter out non-interesting responses   +    if (!translation.empty() +        && (expectLang != detected_language) +        && (LLStringUtil::compareInsensitive(translation, originalMsg) != 0)) +    { +        chat.mText += " (" + translation + ")"; +    } -		LLNotificationsUI::LLNotificationManager::instance().onChat(m_chat, m_toastArgs); -	} +    LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs); +} -	void handleFailure(int status, const std::string& err_msg) -	{ -		LL_WARNS() << "Translation failed for mesg " << m_origMesg << " toLang " << mToLang << " fromLang " << mFromLang << LL_ENDL; +void translateFailure(LLChat chat, LLSD toastArgs, int status, const std::string err_msg) +{ +    std::string msg = LLTrans::getString("TranslationFailed", LLSD().with("[REASON]", err_msg)); +    LLStringUtil::replaceString(msg, "\n", " "); // we want one-line error messages +    chat.mText += " (" + msg + ")"; -		std::string msg = LLTrans::getString("TranslationFailed", LLSD().with("[REASON]", err_msg)); -		LLStringUtil::replaceString(msg, "\n", " "); // we want one-line error messages -		m_chat.mText += " (" + msg + ")"; +    LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs); +} -		LLNotificationsUI::LLNotificationManager::instance().onChat(m_chat, m_toastArgs); -	} -private: -	LLChat m_chat; -	std::string m_origMesg; -	LLSD m_toastArgs;		 -};  void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  {  	LLChat	chat; @@ -3774,8 +3750,10 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  			const std::string from_lang = ""; // leave empty to trigger autodetect  			const std::string to_lang = LLTranslate::getTranslateLanguage(); -			LLTranslate::TranslationReceiverPtr result = ChatTranslationReceiver::build(from_lang, to_lang, mesg, chat, args); -			LLTranslate::translateMessage(result, from_lang, to_lang, mesg); +            LLTranslate::translateMessage(from_lang, to_lang, mesg, +                boost::bind(&translateSuccess, chat, args, mesg, from_lang, _1, _2), +                boost::bind(&translateFailure, chat, args, _1, _2)); +  		}  		else  		{  | 
