Textractor/extensions/bingtranslate.cpp
2021-06-05 08:15:19 -06:00

119 lines
3.8 KiB
C++

#include "qtcommon.h"
#include "network.h"
extern const wchar_t* TRANSLATION_ERROR;
extern Synchronized<std::wstring> translateTo, translateFrom, authKey;
const char* TRANSLATION_PROVIDER = "Bing Translate";
const char* GET_API_KEY_FROM = "https://www.microsoft.com/en-us/translator/business/trial/#get-started";
QStringList languages
{
"Afrikaans: af",
"Arabic: ar",
"Bangla: bn",
"Bosnian: bs",
"Bulgarian: bg",
"Cantonese (traditional): yue",
"Catalan: ca",
"Chinese (simplified): zh-Hans",
"Chinese (traditional): zh-Hant",
"Croatian: hr",
"Czech: cs",
"Danish: da",
"Dutch: nl",
"English: en",
"Estonian: et",
"Fijian: fj",
"Filipino: fil",
"Finnish: fi",
"French: fr",
"German: de",
"Greek: el",
"Haitian Creole: ht",
"Hebrew: he",
"Hindi: hi",
"Hmong Daw: mww",
"Hungarian: hu",
"Icelandic: is",
"Indonesian: id",
"Irish: ga",
"Italian: it",
"Japanese: ja",
"Kannada: kn",
"Klingon: tlh",
"Korean: ko",
"Latvian: lv",
"Lithuanian: lt",
"Malagasy: mg",
"Malay: ms",
"Malayalam: ml",
"Maltese: mt",
"Maori: mi",
"Norwegian: nb",
"Persian: fa",
"Polish: pl",
"Portuguese (Brazil): pt",
"Portuguese (Portugal): pt-pt",
"Punjabi: pa",
"Romanian: ro",
"Russian: ru",
"Samoan: sm",
"Serbian (Cyrillic): sr-Cyrl",
"Serbian (Latin): sr-Latn",
"Slovak: sk",
"Slovenian: sl",
"Spanish: es",
"Swahili: sw",
"Swedish: sv",
"Tahitian: ty",
"Tamil: ta",
"Telugu: te",
"Thai: th",
"Tongan: to",
"Turkish: tr",
"Ukrainian: uk",
"Urdu: ur",
"Vietnamese: vi",
"Welsh: cy",
"Yucatec Maya: yua"
};
std::wstring autoDetectLanguage = L"auto-detect";
bool translateSelectedOnly = false, rateLimitAll = true, rateLimitSelected = false, useCache = true, useFilter = true;
int tokenCount = 30, tokenRestoreDelay = 60000, maxSentenceSize = 1000;
std::pair<bool, std::wstring> Translate(const std::wstring& text)
{
if (!authKey->empty())
{
std::wstring translateFromComponent = translateFrom.Copy() == autoDetectLanguage ? L"" : L"&from=" + translateFrom.Copy();
if (HttpRequest httpRequest{
L"Mozilla/5.0 Textractor",
L"api.cognitive.microsofttranslator.com",
L"POST",
FormatString(L"/translate?api-version=3.0&to=%s%s", translateTo.Copy(), translateFromComponent).c_str(),
FormatString(R"([{"text":"%s"}])", JSON::Escape(WideStringToString(text))),
FormatString(L"Content-Type: application/json; charset=UTF-8\r\nOcp-Apim-Subscription-Key:%s", authKey.Copy()).c_str()
})
if (auto translation = Copy(JSON::Parse(httpRequest.response)[0][L"translations"][0][L"text"].String())) return { true, translation.value() };
else return { false, FormatString(L"%s: %s", TRANSLATION_ERROR, httpRequest.response) };
else return { false, FormatString(L"%s (code=%u)", TRANSLATION_ERROR, httpRequest.errorCode) };
}
static Synchronized<std::wstring> token;
if (token->empty()) if (HttpRequest httpRequest{ L"Mozilla/5.0 Textractor", L"www.bing.com", L"GET", L"translator" })
if (auto tokenPos = httpRequest.response.find(L"[" + std::to_wstring(time(nullptr) / 10)); tokenPos != std::string::npos)
token->assign(FormatString(L"&key=%s&token=%s", httpRequest.response.substr(tokenPos + 1, 13), httpRequest.response.substr(tokenPos + 16, 32)));
if (token->empty()) return { false, FormatString(L"%s: %s", TRANSLATION_ERROR, L"token missing") };
if (HttpRequest httpRequest{
L"Mozilla/5.0 Textractor",
L"www.bing.com",
L"POST",
FormatString(L"/ttranslatev3?fromLang=%s&to=%s&text=%s%s", translateFrom.Copy(), translateTo.Copy(), Escape(text), token.Copy()).c_str()
})
if (auto translation = Copy(JSON::Parse(httpRequest.response)[0][L"translations"][0][L"text"].String())) return { true, translation.value() };
else return { false, FormatString(L"%s: %s", TRANSLATION_ERROR, httpRequest.response) };
else return { false, FormatString(L"%s (code=%u)", TRANSLATION_ERROR, httpRequest.errorCode) };
}