diff --git a/src/popup.vue b/src/popup.vue index ef295f7c..0934c57f 100644 --- a/src/popup.vue +++ b/src/popup.vue @@ -364,6 +364,7 @@ var translatorList = { "papago (Experimental)": "papago", "yandex (Experimental)": "yandex", "deepl (Experimental)": "deepl", + "baidu (Experimental)": "baidu", }; var translateActionList = { diff --git a/src/translator/baidu.js b/src/translator/baidu.js new file mode 100644 index 00000000..36d75fb5 --- /dev/null +++ b/src/translator/baidu.js @@ -0,0 +1,66 @@ +import BaseTranslator from "./baseTranslator"; + +import ky from "ky"; + +var baseUrl = "https://fanyi.baidu.com/transapi"; +var baiduLangCode = { + en: "en", + ja: "jp", + ko: "kor", + fr: "fra", + es: "spa", + th: "th", + ar: "ara", + ru: "ru", + pt: "pt", + de: "de", + it: "it", + el: "el", + nl: "nl", + pl: "pl", + bg: "bul", + et: "est", + da: "dan", + fi: "fin", + cs: "cs", + ro: "rom", + sl: "slo", + sv: "swe", + hu: "hu", + vi: "vie", + "zh-CN": "zh", + "zh-TW": "cht", +}; + +export default class baidu extends BaseTranslator { + static langCodeJson = baiduLangCode; + + static async requestTranslate(text, fromLang, targetLang) { + return await ky + .post(baseUrl, { + searchParams: { + from: fromLang, + to: targetLang, + }, + body: new URLSearchParams({ + from: fromLang, + to: targetLang, + query: text, + source: "txt", + }), + }) + .json(); + } + + static wrapResponse(res, fromLang, targetLang) { + var translatedText = res["data"][0]["result"] + .map((text) => text?.[1]) + .filter((text) => text) + .join(" "); + return { + translatedText, + detectedLang: res["from"], + transliteration: "", + }; + } +} diff --git a/src/translator/google.js b/src/translator/google.js index fe80b108..2edfa008 100644 --- a/src/translator/google.js +++ b/src/translator/google.js @@ -5,12 +5,16 @@ import ky from "ky"; const googleTranslateTKK = "448487.932609646"; const apiPath = "https://translate.googleapis.com/translate_a/t"; +var tokenUrl = "https://translate.google.com"; +var newGoogleUrl = + "https://translate.google.com/_/TranslateWebserverUi/data/batchexecute"; +var token; +var tokenTTL = 60 * 60 * 1000; //1hour + export default class google extends BaseTranslator { static async requestTranslate(text, fromLang, targetLang) { // code brought from https://github.com/translate-tools/core/blob/master/src/translators/GoogleTranslator/token.js - var tk = getToken(text, googleTranslateTKK); - return await ky(apiPath, { searchParams: { client: "te_lib", @@ -32,13 +36,11 @@ export default class google extends BaseTranslator { if (res && res[0] && res[0][0]) { var translatedText = fromLang == "auto" ? res[0][0] : res[0]; var detectedLang = fromLang == "auto" ? res[0][1] : fromLang; - //clear html tag and decode html entity var textDecoded = decode(translatedText); var textWithoutITag = textDecoded.replace(/().+?(<\/i>)/gi, " "); var textWithoutBTag = textWithoutITag.replace(/<\/?b[^>]*>/g, " "); var textWithTrim = textWithoutBTag.replace(/\s\s+/g, " ").trim(); - return { translatedText: textWithTrim, detectedLang, @@ -124,3 +126,66 @@ function getToken(query, windowTkk) { const normalizedResult = encondingRound % 1000000; return normalizedResult.toString() + "." + (normalizedResult ^ tkkIndex); } + +async function googleTranslateRequestV2(text, fromLang, targetLang) { + var { sid, bl, at } = await getTokenV2(); + + let req = JSON.stringify([ + [ + [ + "MkEWBc", + JSON.stringify([[text, fromLang, targetLang, true], [null]]), + null, + "generic", + ], + ], + ]); + return await ky + .post(newGoogleUrl, { + headers: { + "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", + }, + searchParams: { + rpcids: "MkEWBc", + "source-path": "/", + "f.sid": sid, + bl, + hl: "ko", + "soc-app": 1, + "soc-platform": 1, + "soc-device": 1, + _reqid: Math.floor(10000 + 10000 * Math.random()), + rt: "c", + }, + body: new URLSearchParams({ "f.req": req, at }), // + anonymous: true, + nocache: true, + }) + .text(); +} +function googleTranslateRequestWrapV2(res) { + var json = JSON.parse(JSON.parse(/\[.*\]/.exec(res))[0][2]); + var translatedText = json[1][0][0][5] + .map((text) => text?.[0]) + .filter((text) => text) + .join(" "); + + return { + translatedText, + detectedLang: json[0][2], + transliteration: json[1][0][0][1], + }; +} + +async function getTokenV2() { + if (token && token.time + tokenTTL > Date.now()) { + return token; + } + var res = await ky(tokenUrl).text(); + var sid = res.match(/"FdrFJe":"(.*?)"/)[1]; + let bl = res.match(/"cfb2h":"(.*?)"/)[1]; + let at = res.match(/"SNlM0e":"(.*?)"/)?.[1] || ""; + var time = Date.now(); + token = { sid, bl, at, time }; + return token; +} diff --git a/src/translator/index.js b/src/translator/index.js index 3a9dc27a..001faae1 100644 --- a/src/translator/index.js +++ b/src/translator/index.js @@ -3,5 +3,6 @@ import bing from "./bing.js"; import papago from "./papago.js"; import deepl from "./deepl.js"; import yandex from "./yandex.js"; +import baidu from "./baidu.js"; -export default { google, bing, papago, deepl, yandex }; +export default { google, bing, papago, deepl, yandex, baidu };