Textractor/extensions/googletranslate.cpp

174 lines
4.5 KiB
C++
Raw Normal View History

2020-03-26 06:12:20 -06:00
#include "qtcommon.h"
2019-02-10 21:46:39 -05:00
#include "network.h"
2018-11-03 23:26:53 -04:00
#include <ctime>
2019-02-27 11:33:17 -05:00
extern const wchar_t* TRANSLATION_ERROR;
extern Synchronized<std::wstring> translateTo, apiKey;
const char* TRANSLATION_PROVIDER = "Google Translate";
const char* GET_API_KEY_FROM = "https://codelabs.developers.google.com/codelabs/cloud-translation-intro";
2018-11-03 23:26:53 -04:00
QStringList languages
{
"Afrikaans: af",
2020-03-26 06:12:20 -06:00
"Albanian: sq",
2020-03-27 05:55:11 -06:00
"Amharic: am",
"Arabic: ar",
"Armenian: hy",
"Azerbaijani: az",
"Basque: eu",
2018-11-03 23:26:53 -04:00
"Belarusian: be",
"Bengali: bn",
"Bosnian: bs",
"Bulgarian: bg",
"Catalan: ca",
2020-03-27 05:55:11 -06:00
"Cebuano: ceb",
"Chichewa: ny",
"Chinese (simplified): zh",
"Chinese (traditional): zh-TW",
2020-03-27 05:55:11 -06:00
"Corsican: co",
2018-11-03 23:26:53 -04:00
"Croatian: hr",
"Czech: cs",
"Danish: da",
"Dutch: nl",
"English: en",
2018-11-03 23:26:53 -04:00
"Esperanto: eo",
"Estonian: et",
"Filipino: tl",
"Finnish: fi",
"French: fr",
2020-03-27 05:55:11 -06:00
"Frisian: fy",
2018-11-03 23:26:53 -04:00
"Galician: gl",
2020-03-27 05:55:11 -06:00
"Georgian: ka",
2018-11-03 23:26:53 -04:00
"German: de",
"Greek: el",
2020-03-27 05:55:11 -06:00
"Gujarati: gu",
"Haitian Creole: ht",
"Hausa: ha",
"Hawaiian: haw",
2018-11-03 23:26:53 -04:00
"Hebrew: iw",
"Hindi: hi",
2020-03-27 05:55:11 -06:00
"Hmong: hmn",
2018-11-03 23:26:53 -04:00
"Hungarian: hu",
"Icelandic: is",
2020-03-27 05:55:11 -06:00
"Igbo: ig",
2018-11-03 23:26:53 -04:00
"Indonesian: id",
"Irish: ga",
"Italian: it",
"Japanese: ja",
2020-03-27 05:55:11 -06:00
"Javanese: jw",
"Kannada: kn",
"Kazakh: kk",
"Khmer: km",
"Kinyarwanda: rw",
2018-11-03 23:26:53 -04:00
"Korean: ko",
2020-03-27 05:55:11 -06:00
"Kurdish (Kurmanji): ku",
"Kyrgyz: ky",
"Lao: lo",
2018-11-03 23:26:53 -04:00
"Latin: la",
"Latvian: lv",
"Lithuanian: lt",
2020-03-27 05:55:11 -06:00
"Luxembourgish: lb",
2018-11-03 23:26:53 -04:00
"Macedonian: mk",
2020-03-27 05:55:11 -06:00
"Malagasy: mg",
2018-11-03 23:26:53 -04:00
"Malay: ms",
2020-03-27 05:55:11 -06:00
"Malayalam: ml",
2018-11-03 23:26:53 -04:00
"Maltese: mt",
2020-03-27 05:55:11 -06:00
"Maori: mi",
"Marathi: mr",
"Mongolian: mn",
"Myanmar (Burmese): my",
"Nepali: ne",
2018-11-03 23:26:53 -04:00
"Norwegian: no",
2020-03-27 05:55:11 -06:00
"Odia (Oriya): or",
"Pashto: ps",
2018-11-03 23:26:53 -04:00
"Persian: fa",
"Polish: pl",
"Portuguese: pt",
2020-03-27 05:55:11 -06:00
"Punjabi: pa",
2018-11-03 23:26:53 -04:00
"Romanian: ro",
"Russian: ru",
2020-03-27 05:55:11 -06:00
"Samoan: sm",
"Scots Gaelic: gd",
2018-11-03 23:26:53 -04:00
"Serbian: sr",
2020-03-27 05:55:11 -06:00
"Sesotho: st",
"Shona: sn",
"Sindhi: sd",
"Sinhala: si",
2018-11-03 23:26:53 -04:00
"Slovak: sk",
"Slovenian: sl",
"Somali: so",
"Spanish: es",
2020-03-27 05:55:11 -06:00
"Sundanese: su",
2018-11-03 23:26:53 -04:00
"Swahili: sw",
"Swedish: sv",
2020-03-27 05:55:11 -06:00
"Tajik: tg",
"Tamil: ta",
"Tatar: tt",
"Telugu: te",
2018-11-03 23:26:53 -04:00
"Thai: th",
"Turkish: tr",
2020-03-27 05:55:11 -06:00
"Turkmen: tk",
"Ukrainian: uk",
2018-11-03 23:26:53 -04:00
"Urdu: ur",
2020-03-27 05:55:11 -06:00
"Uyghur: ug",
"Uzbek: uz",
2018-11-03 23:26:53 -04:00
"Vietnamese: vi",
"Welsh: cy",
2020-03-27 05:55:11 -06:00
"Xhosa: xh",
2018-11-03 23:26:53 -04:00
"Yiddish: yi",
2020-03-27 05:55:11 -06:00
"Yoruba: yo",
2018-11-03 23:26:53 -04:00
"Zulu: zu"
};
bool translateSelectedOnly = false, rateLimitAll = true, rateLimitSelected = false, useCache = true;
int tokenCount = 30, tokenRestoreDelay = 60000, maxSentenceSize = 1000;
2020-03-26 06:12:20 -06:00
2020-04-25 20:39:12 -06:00
std::pair<bool, std::wstring> Translate(const std::wstring& text)
2018-11-03 23:26:53 -04:00
{
if (!apiKey->empty())
2020-03-26 06:12:20 -06:00
if (HttpRequest httpRequest{
L"Mozilla/5.0 Textractor",
L"translation.googleapis.com",
L"POST",
FormatString(L"/language/translate/v2?format=text&target=%s&key=%s", translateTo.Copy(), apiKey.Copy()).c_str(),
2020-12-14 06:26:01 -07:00
FormatString(R"({"q":["%s"]})", JSON::Escape(WideStringToString(text)))
2020-03-26 06:12:20 -06:00
})
2020-12-14 06:26:01 -07:00
if (auto translation = Copy(JSON::Parse(httpRequest.response)[L"data"][L"translations"][0][L"translatedText"].String())) return { true, translation.value() };
else return { false, FormatString(L"%s: %s", TRANSLATION_ERROR, httpRequest.response) };
2020-03-26 06:12:20 -06:00
else return { false, FormatString(L"%s (code=%u)", TRANSLATION_ERROR, httpRequest.errorCode) };
2020-12-14 06:26:01 -07:00
if (HttpRequest httpRequest{
L"Mozilla/5.0 Textractor",
L"translate.google.com",
L"POST",
L"/_/TranslateWebserverUi/data/batchexecute?rpcids=MkEWBc",
"f.req=" + Escape(WideStringToString(FormatString(LR"([[["MkEWBc","[[\"%s\",\"auto\",\"%s\",true],[null]]",null,"generic"]]])", JSON::Escape((JSON::Escape(text))), translateTo.Copy()))),
L"Content-Type: application/x-www-form-urlencoded"
})
2018-11-03 23:26:53 -04:00
{
2020-12-14 06:26:01 -07:00
if (auto start = httpRequest.response.find(L"[["); start != std::string::npos)
2019-06-13 04:01:29 -04:00
{
2020-12-14 06:26:01 -07:00
if (auto blob = Copy(JSON::Parse(httpRequest.response.substr(start))[0][2].String())) if (auto translations = Copy(JSON::Parse(blob.value())[1][0].Array()))
{
std::wstring translation;
if (translations->size() == 1)
2020-12-14 06:26:01 -07:00
{
if (translations = Copy(translations.value()[0][5].Array()))
for (const auto& sentence : translations.value())
if (sentence[0].String()) (translation += *sentence[0].String()) += L" ";
2020-12-14 06:26:01 -07:00
}
else
{
for (const auto& conjugation : translations.value())
if (auto sentence = conjugation[0].String()) if (auto gender = conjugation[2].String()) translation += FormatString(L"%s %s\n", *sentence, *gender);
}
if (!translation.empty()) return { true, translation };
return { false, FormatString(L"%s: %s", TRANSLATION_ERROR, blob.value()) };
}
2019-06-13 04:01:29 -04:00
}
2020-12-14 06:26:01 -07:00
return { false, FormatString(L"%s: %s", TRANSLATION_ERROR, httpRequest.response) };
2018-11-03 23:26:53 -04:00
}
2019-06-13 04:01:29 -04:00
else return { false, FormatString(L"%s (code=%u)", TRANSLATION_ERROR, httpRequest.errorCode) };
2018-12-18 16:32:28 -05:00
}