add more translators...

This commit is contained in:
Gabe Yuan
2023-10-20 17:44:48 +08:00
parent f3029a0f76
commit 507d54dba0
10 changed files with 651 additions and 44 deletions

257
src/apis/baidu.js Normal file
View File

@@ -0,0 +1,257 @@
import queryString from "query-string";
import { fetchPolyfill } from "../libs/fetch";
import { getBdauth, setBdauth } from "../libs/storage";
import { URL_BAIDU_WEB, URL_BAIDU_TRAN } from "../config";
/* eslint-disable */
function n(t, e) {
for (var n = 0; n < e.length - 2; n += 3) {
var r = e.charAt(n + 2);
(r = "a" <= r ? r.charCodeAt(0) - 87 : Number(r)),
(r = "+" === e.charAt(n + 1) ? t >>> r : t << r),
(t = "+" === e.charAt(n) ? (t + r) & 4294967295 : t ^ r);
}
return t;
}
function e(t, e) {
(null == e || e > t.length) && (e = t.length);
for (var n = 0, r = new Array(e); n < e; n++) r[n] = t[n];
return r;
}
/* eslint-disable */
function getSign(t, gtk, r = null) {
var o,
i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
if (null === i) {
var a = t.length;
a > 30 &&
(t = ""
.concat(t.substr(0, 10))
.concat(t.substr(Math.floor(a / 2) - 5, 10))
.concat(t.substr(-10, 10)));
} else {
for (
var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/),
c = 0,
u = s.length,
l = [];
c < u;
c++
)
"" !== s[c] &&
l.push.apply(
l,
(function (t) {
if (Array.isArray(t)) return e(t);
})((o = s[c].split(""))) ||
(function (t) {
if (
("undefined" != typeof Symbol && null != t[Symbol.iterator]) ||
null != t["@@iterator"]
)
return Array.from(t);
})(o) ||
(function (t, n) {
if (t) {
if ("string" == typeof t) return e(t, n);
var r = Object.prototype.toString.call(t).slice(8, -1);
return (
"Object" === r && t.constructor && (r = t.constructor.name),
"Map" === r || "Set" === r
? Array.from(t)
: "Arguments" === r ||
/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)
? e(t, n)
: void 0
);
}
})(o) ||
(function () {
throw new TypeError(
"Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
);
})()
),
c !== u - 1 && l.push(i[c]);
var p = l.length;
p > 30 &&
(t =
l.slice(0, 10).join("") +
l.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") +
l.slice(-10).join(""));
}
for (
var d = ""
.concat(String.fromCharCode(103))
.concat(String.fromCharCode(116))
.concat(String.fromCharCode(107)),
h = (null !== r ? r : (r = gtk || "") || "").split("."),
f = Number(h[0]) || 0,
m = Number(h[1]) || 0,
g = [],
y = 0,
v = 0;
v < t.length;
v++
) {
var _ = t.charCodeAt(v);
_ < 128
? (g[y++] = _)
: (_ < 2048
? (g[y++] = (_ >> 6) | 192)
: (55296 == (64512 & _) &&
v + 1 < t.length &&
56320 == (64512 & t.charCodeAt(v + 1))
? ((_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v))),
(g[y++] = (_ >> 18) | 240),
(g[y++] = ((_ >> 12) & 63) | 128))
: (g[y++] = (_ >> 12) | 224),
(g[y++] = ((_ >> 6) & 63) | 128)),
(g[y++] = (63 & _) | 128));
}
for (
var b = f,
w =
""
.concat(String.fromCharCode(43))
.concat(String.fromCharCode(45))
.concat(String.fromCharCode(97)) +
""
.concat(String.fromCharCode(94))
.concat(String.fromCharCode(43))
.concat(String.fromCharCode(54)),
k =
""
.concat(String.fromCharCode(43))
.concat(String.fromCharCode(45))
.concat(String.fromCharCode(51)) +
""
.concat(String.fromCharCode(94))
.concat(String.fromCharCode(43))
.concat(String.fromCharCode(98)) +
""
.concat(String.fromCharCode(43))
.concat(String.fromCharCode(45))
.concat(String.fromCharCode(102)),
x = 0;
x < g.length;
x++
)
b = n((b += g[x]), w);
return (
(b = n(b, k)),
(b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)),
"".concat((b %= 1e6).toString(), ".").concat(b ^ f)
);
}
const getCookie = async () => {
const res = await fetch(URL_BAIDU_WEB, {
headers: {
"Content-type": "text/html; charset=utf-8",
},
});
if (!res.ok) {
throw new Error(res.statusText);
}
return res.headers.get("set-cookie");
};
const getToken = async () => {
const cookie = await getCookie();
const res = await fetch(URL_BAIDU_WEB, {
headers: {
"Content-type": "text/html; charset=utf-8",
cookie,
},
});
if (!res.ok) {
throw new Error(res.statusText);
}
const text = await res.text();
const token = text.match(/token: '(.*)',/)[1];
const gtk = text.match(/gtk = "(.*)";/)[1];
const exp = Date.now() + 8 * 60 * 60 * 1000;
return { cookie, token, gtk, exp };
};
/**
* 闭包缓存token减少对storage查询
* @returns
*/
const _bdAuth = () => {
let store;
return async () => {
const now = Date.now();
// 查询内存缓存
if (store && store.exp > now) {
return store;
}
// 查询storage缓存
store = await getBdauth();
if (store && store.exp > now) {
return store;
}
// 缓存没有或失效,查询接口
store = await getToken();
await setBdauth(store);
return store;
};
};
const bdAuth = _bdAuth();
/**
* 腾讯翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
export const apiBaiduTranslate = async (
translator,
text,
to,
from,
{ useCache = true }
) => {
const { cookie, token, gtk } = await bdAuth();
const sign = getSign(text, gtk);
const data = {
from,
to,
query: text,
simple_means_flag: 3,
sign,
token,
domain: "common",
ts: Date.now(),
};
const res = await fetchPolyfill(`${URL_BAIDU_TRAN}?from=${from}&to=${to}`, {
headers: {
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
cookie,
},
method: "POST",
body: queryString.stringify(data),
useCache,
usePool: true,
translator,
});
const trText = res.trans_result?.data.map((item) => item.dst).join(" ");
const isSame = res.trans_result?.to === res.trans_result?.from;
return [trText, isSame, res];
};

77
src/apis/deepl.js Normal file
View File

@@ -0,0 +1,77 @@
import { fetchPolyfill } from "../libs/fetch";
import { URL_DEEPLFREE_TRAN } from "../config";
let id = 1e4 * Math.round(1e4 * Math.random());
/**
* DeepL翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
export const apiDeepLFreeTranslate = async (
translator,
text,
to,
from,
{ useCache = true }
) => {
const iCount = (text.match(/[i]/g) || []).length + 1;
let timestamp = Date.now();
timestamp = timestamp + (iCount - (timestamp % iCount));
id++;
let body = JSON.stringify({
jsonrpc: "2.0",
method: "LMT_handle_texts",
params: {
splitting: "newlines",
lang: {
target_lang: to,
source_lang_user_selected: from,
},
commonJobParams: {
wasSpoken: false,
transcribe_as: "",
},
id,
timestamp,
texts: [
{
text,
requestAlternatives: 3,
},
],
},
});
body = body.replace(
'method":"',
(id + 3) % 13 === 0 || (id + 5) % 29 === 0 ? 'method" : "' : 'method": "'
);
const res = await fetchPolyfill(URL_DEEPLFREE_TRAN, {
headers: {
"Content-Type": "application/json",
Accept: "*/*",
"x-app-os-name": "iOS",
"x-app-os-version": "16.3.0",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"x-app-device": "iPhone13,2",
"User-Agent": "DeepL-iOS/2.9.1 iOS 16.3.0 (iPhone13,2)",
"x-app-build": "510265",
"x-app-version": "2.9.1",
},
method: "POST",
body,
useCache,
usePool: true,
translator,
});
const trText = res.result?.texts.map((item) => item.text).join(" ");
const isSame = to === res.result?.lang;
return [trText, isSame];
};

View File

@@ -4,18 +4,26 @@ import {
OPT_TRANS_GOOGLE, OPT_TRANS_GOOGLE,
OPT_TRANS_MICROSOFT, OPT_TRANS_MICROSOFT,
OPT_TRANS_DEEPL, OPT_TRANS_DEEPL,
OPT_TRANS_DEEPLFREE,
OPT_TRANS_DEEPLX, OPT_TRANS_DEEPLX,
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
OPT_TRANS_OPENAI, OPT_TRANS_OPENAI,
OPT_TRANS_CUSTOMIZE, OPT_TRANS_CUSTOMIZE,
URL_CACHE_TRAN,
OPT_LANGS_SPECIAL, OPT_LANGS_SPECIAL,
PROMPT_PLACE_FROM, PROMPT_PLACE_FROM,
PROMPT_PLACE_TO, PROMPT_PLACE_TO,
KV_SALT_SYNC, KV_SALT_SYNC,
URL_BAIDU_LANGDETECT, URL_BAIDU_LANGDETECT,
URL_MICROSOFT_TRAN,
OPT_LANGS_BAIDU, OPT_LANGS_BAIDU,
} from "../config"; } from "../config";
import { tryDetectLang } from "../libs"; import { tryDetectLang } from "../libs";
import { sha256 } from "../libs/utils"; import { sha256 } from "../libs/utils";
import { apiDeepLFreeTranslate } from "./deepl";
import { apiBaiduTranslate } from "./baidu";
import { apiTencentTranslate } from "./tencent";
/** /**
* 同步数据 * 同步数据
@@ -92,14 +100,14 @@ const apiMicrosoftTranslate = async (
text, text,
to, to,
from, from,
{ url, useCache = true } { useCache = true }
) => { ) => {
const params = { const params = {
from, from,
to, to,
"api-version": "3.0", "api-version": "3.0",
}; };
const input = `${url}?${queryString.stringify(params)}`; const input = `${URL_MICROSOFT_TRAN}?${queryString.stringify(params)}`;
const res = await fetchPolyfill(input, { const res = await fetchPolyfill(input, {
headers: { headers: {
"Content-type": "application/json", "Content-type": "application/json",
@@ -308,36 +316,61 @@ export const apiBaiduLangdetect = async (text) => {
* @param {*} param0 * @param {*} param0
* @returns * @returns
*/ */
export const apiTranslate = ({ export const apiTranslate = async ({
translator, translator,
text, text,
fromLang, fromLang,
toLang, toLang,
apiSetting, apiSetting = {},
useCache = true,
usePool = true,
}) => { }) => {
const from = OPT_LANGS_SPECIAL[translator].get(fromLang); let trText = "";
const to = OPT_LANGS_SPECIAL[translator].get(toLang); let isSame = false;
if (!to) { const transOpts = {
return ["", from === to]; translator,
text,
fromLang,
toLang,
};
const res = await fetchPolyfill(
`${URL_CACHE_TRAN}?${queryString.stringify(transOpts)}`,
{
useCache,
usePool,
transOpts,
apiSetting,
} }
);
const callApi = (api) => api(translator, text, to, from, apiSetting);
switch (translator) { switch (translator) {
case OPT_TRANS_GOOGLE: case OPT_TRANS_GOOGLE:
return callApi(apiGoogleTranslate); break;
case OPT_TRANS_MICROSOFT: case OPT_TRANS_MICROSOFT:
return callApi(apiMicrosoftTranslate); trText = res[0].translations[0].text;
isSame = toLang === res[0].detectedLanguage?.language;
break;
case OPT_TRANS_DEEPL: case OPT_TRANS_DEEPL:
return callApi(apiDeepLTranslate); break;
case OPT_TRANS_DEEPLFREE:
break;
case OPT_TRANS_DEEPLX: case OPT_TRANS_DEEPLX:
return callApi(apiDeepLXTranslate); break;
case OPT_TRANS_BAIDU:
break;
case OPT_TRANS_TENCENT:
trText = res.auto_translation;
isSame = text === trText;
break;
case OPT_TRANS_OPENAI: case OPT_TRANS_OPENAI:
return callApi(apiOpenaiTranslate); break;
case OPT_TRANS_CUSTOMIZE: case OPT_TRANS_CUSTOMIZE:
return callApi(apiCustomTranslate); break;
default: default:
return ["", false]; break;
} }
return [trText, isSame];
}; };

73
src/apis/tencent.js Normal file
View File

@@ -0,0 +1,73 @@
import { URL_TENCENT_TRANSMART, OPT_LANGS_TENCENT } from "../config";
import { fetchPolyfill } from "../libs/fetch";
/**
* 腾讯语言识别
* @param {*} text
* @returns
*/
export const apiTencentLangdetect = async (text) => {
const body = JSON.stringify({
header: {
fn: "text_analysis",
},
text,
});
const res = await fetchPolyfill(URL_TENCENT_TRANSMART, {
headers: {
"Content-type": "application/json",
},
method: "POST",
body,
useCache: true,
});
return OPT_LANGS_TENCENT.get(res.language) ?? res.language;
};
/**
* 腾讯翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
export const apiTencentTranslate = async (
translator,
text,
to,
from,
{ useCache = true }
) => {
const data = {
header: {
fn: "auto_translation_block",
},
source: {
text_block: text,
},
target: {
lang: to,
},
};
if (from) {
data.source.lang = from;
}
const res = await fetchPolyfill(URL_TENCENT_TRANSMART, {
headers: {
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify(data),
useCache,
usePool: true,
translator,
});
const trText = res.auto_translation;
const isSame = text === trText;
return [trText, isSame];
};

View File

@@ -20,6 +20,7 @@ export {
}; };
export const STOKEY_MSAUTH = `${APP_NAME}_msauth`; export const STOKEY_MSAUTH = `${APP_NAME}_msauth`;
export const STOKEY_BDAUTH = `${APP_NAME}_bdauth`;
export const STOKEY_SETTING = `${APP_NAME}_setting`; export const STOKEY_SETTING = `${APP_NAME}_setting`;
export const STOKEY_RULES = `${APP_NAME}_rules`; export const STOKEY_RULES = `${APP_NAME}_rules`;
export const STOKEY_SYNC = `${APP_NAME}_sync`; export const STOKEY_SYNC = `${APP_NAME}_sync`;
@@ -67,21 +68,34 @@ export const URL_KISS_RULES_NEW_ISSUE =
"https://github.com/fishjar/kiss-rules/issues/new"; "https://github.com/fishjar/kiss-rules/issues/new";
export const URL_RAW_PREFIX = export const URL_RAW_PREFIX =
"https://raw.githubusercontent.com/fishjar/kiss-translator/master"; "https://raw.githubusercontent.com/fishjar/kiss-translator/master";
export const URL_CACHE_TRAN = `https://${APP_LCNAME}/translate`;
export const URL_MICROSOFT_TRAN =
"https://api-edge.cognitive.microsofttranslator.com/translate";
export const URL_MICROSOFT_AUTH = "https://edge.microsoft.com/translate/auth"; export const URL_MICROSOFT_AUTH = "https://edge.microsoft.com/translate/auth";
export const URL_BAIDU_LANGDETECT = "https://fanyi.baidu.com/langdetect"; export const URL_BAIDU_LANGDETECT = "https://fanyi.baidu.com/langdetect";
export const URL_BAIDU_WEB = "https://fanyi.baidu.com/";
export const URL_BAIDU_TRAN = "https://fanyi.baidu.com/v2transapi";
export const URL_DEEPLFREE_TRAN = "https://www2.deepl.com/jsonrpc";
export const URL_TENCENT_TRANSMART = "https://transmart.qq.com/api/imt";
export const OPT_TRANS_GOOGLE = "Google"; export const OPT_TRANS_GOOGLE = "Google";
export const OPT_TRANS_MICROSOFT = "Microsoft"; export const OPT_TRANS_MICROSOFT = "Microsoft";
export const OPT_TRANS_DEEPL = "DeepL"; export const OPT_TRANS_DEEPL = "DeepL";
export const OPT_TRANS_DEEPLX = "DeepLX"; export const OPT_TRANS_DEEPLX = "DeepLX";
export const OPT_TRANS_DEEPLFREE = "DeepLFree";
export const OPT_TRANS_BAIDU = "Baidu"; export const OPT_TRANS_BAIDU = "Baidu";
export const OPT_TRANS_TENCENT = "Tencent";
export const OPT_TRANS_OPENAI = "OpenAI"; export const OPT_TRANS_OPENAI = "OpenAI";
export const OPT_TRANS_CUSTOMIZE = "Custom"; export const OPT_TRANS_CUSTOMIZE = "Custom";
export const OPT_TRANS_ALL = [ export const OPT_TRANS_ALL = [
OPT_TRANS_GOOGLE, OPT_TRANS_GOOGLE,
OPT_TRANS_MICROSOFT, OPT_TRANS_MICROSOFT,
OPT_TRANS_DEEPL, OPT_TRANS_DEEPL,
OPT_TRANS_DEEPLFREE,
OPT_TRANS_DEEPLX, OPT_TRANS_DEEPLX,
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
OPT_TRANS_OPENAI, OPT_TRANS_OPENAI,
OPT_TRANS_CUSTOMIZE, OPT_TRANS_CUSTOMIZE,
]; ];
@@ -140,6 +154,12 @@ export const OPT_LANGS_SPECIAL = {
["zh-CN", "ZH"], ["zh-CN", "ZH"],
["zh-TW", "ZH"], ["zh-TW", "ZH"],
]), ]),
[OPT_TRANS_DEEPLFREE]: new Map([
...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]),
["auto", "auto"],
["zh-CN", "ZH"],
["zh-TW", "ZH"],
]),
[OPT_TRANS_DEEPLX]: new Map([ [OPT_TRANS_DEEPLX]: new Map([
...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]), ...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]),
["auto", ""], ["auto", ""],
@@ -173,6 +193,28 @@ export const OPT_LANGS_SPECIAL = {
["uk", "ukr"], ["uk", "ukr"],
["vi", "vie"], ["vi", "vie"],
]), ]),
[OPT_TRANS_TENCENT]: new Map([
["auto", "auto"],
["zh-CN", "zh"],
["zh-TW", "zh"],
["en", "en"],
["ar", "ar"],
["de", "de"],
["ru", "ru"],
["fr", "fr"],
["fi", "fil"],
["ko", "ko"],
["ms", "ms"],
["pt", "pt"],
["ja", "ja"],
["th", "th"],
["tr", "tr"],
["es", "es"],
["it", "it"],
["hi", "hi"],
["id", "id"],
["vi", "vi"],
]),
[OPT_TRANS_OPENAI]: new Map( [OPT_TRANS_OPENAI]: new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
), ),
@@ -188,6 +230,13 @@ export const OPT_LANGS_BAIDU = new Map(
k, k,
]) ])
); );
export const OPT_LANGS_TENCENT = new Map(
Array.from(OPT_LANGS_SPECIAL[OPT_TRANS_TENCENT].entries()).map(([k, v]) => [
v,
k,
])
);
OPT_LANGS_TENCENT.set("zh", "zh-CN");
export const OPT_STYLE_NONE = "style_none"; // 无 export const OPT_STYLE_NONE = "style_none"; // 无
export const OPT_STYLE_LINE = "under_line"; // 下划线 export const OPT_STYLE_LINE = "under_line"; // 下划线
@@ -285,10 +334,6 @@ export const DEFAULT_TRANS_APIS = {
url: "https://translate.googleapis.com/translate_a/single", url: "https://translate.googleapis.com/translate_a/single",
key: "", key: "",
}, },
[OPT_TRANS_MICROSOFT]: {
url: "https://api-edge.cognitive.microsofttranslator.com/translate",
authUrl: "https://edge.microsoft.com/translate/auth",
},
[OPT_TRANS_DEEPL]: { [OPT_TRANS_DEEPL]: {
url: "https://api-free.deepl.com/v2/translate", url: "https://api-free.deepl.com/v2/translate",
key: "", key: "",

View File

@@ -32,7 +32,8 @@ export function useTranslate(q, rule, setting) {
text: q, text: q,
fromLang, fromLang,
toLang, toLang,
apiSetting: (setting.transApis || DEFAULT_TRANS_APIS)[translator], apiSetting:
setting.transApis?.[translator] || DEFAULT_TRANS_APIS[translator],
}); });
setText(trText); setText(trText);
setSamelang(isSame); setSamelang(isSame);

View File

@@ -1,3 +1,4 @@
import queryString from "query-string";
import { isExt, isGm } from "./client"; import { isExt, isGm } from "./client";
import { sendBgMsg } from "./msg"; import { sendBgMsg } from "./msg";
import { taskPool } from "./pool"; import { taskPool } from "./pool";
@@ -6,11 +7,20 @@ import {
MSG_FETCH_LIMIT, MSG_FETCH_LIMIT,
MSG_FETCH_CLEAR, MSG_FETCH_CLEAR,
CACHE_NAME, CACHE_NAME,
OPT_TRANS_GOOGLE,
OPT_TRANS_MICROSOFT, OPT_TRANS_MICROSOFT,
OPT_TRANS_DEEPL, OPT_TRANS_DEEPL,
OPT_TRANS_DEEPLFREE,
OPT_TRANS_DEEPLX,
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
OPT_TRANS_OPENAI, OPT_TRANS_OPENAI,
OPT_TRANS_CUSTOMIZE,
DEFAULT_FETCH_INTERVAL, DEFAULT_FETCH_INTERVAL,
DEFAULT_FETCH_LIMIT, DEFAULT_FETCH_LIMIT,
OPT_LANGS_SPECIAL,
URL_MICROSOFT_TRAN,
URL_TENCENT_TRANSMART,
} from "../config"; } from "../config";
import { msAuth } from "./auth"; import { msAuth } from "./auth";
import { isBg } from "./browser"; import { isBg } from "./browser";
@@ -53,7 +63,8 @@ export const fetchGM = async (input, { method = "GET", headers, body } = {}) =>
* @param {*} request * @param {*} request
* @returns * @returns
*/ */
const newCacheReq = async (request) => { const newCacheReq = async (input, init) => {
let request = new Request(input, init);
if (request.method !== "GET") { if (request.method !== "GET") {
const body = await request.text(); const body = await request.text();
const cacheUrl = new URL(request.url); const cacheUrl = new URL(request.url);
@@ -64,22 +75,116 @@ const newCacheReq = async (request) => {
return request; return request;
}; };
const newTransReq = (
{ translator, text, fromLang, toLang },
{ url, key } = {}
) => {
// console.log({ translator, text, fromLang, toLang }, { url, key });
let params;
let data;
let input;
let init;
const from = OPT_LANGS_SPECIAL[translator].get(fromLang) ?? "";
const to = OPT_LANGS_SPECIAL[translator].get(toLang);
if (!to) {
throw new Error(`[trans] target lang: ${toLang} not support`);
}
switch (translator) {
case OPT_TRANS_GOOGLE:
break;
case OPT_TRANS_MICROSOFT:
params = {
from,
to,
"api-version": "3.0",
};
input = `${URL_MICROSOFT_TRAN}?${queryString.stringify(params)}`;
init = {
headers: {
"Content-type": "application/json",
Authorization: `Bearer ${key}`,
},
method: "POST",
body: JSON.stringify([{ Text: text }]),
};
break;
case OPT_TRANS_DEEPL:
break;
case OPT_TRANS_DEEPLFREE:
break;
case OPT_TRANS_DEEPLX:
break;
case OPT_TRANS_BAIDU:
break;
case OPT_TRANS_TENCENT:
data = {
header: {
fn: "auto_translation_block",
},
source: {
text_block: text,
},
target: {
lang: to,
},
};
if (from) {
data.source.lang = from;
}
input = URL_TENCENT_TRANSMART;
init = {
headers: {
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify(data),
};
break;
case OPT_TRANS_OPENAI:
break;
case OPT_TRANS_CUSTOMIZE:
break;
default:
break;
}
if (!input) {
throw new Error(`[trans] translator: ${translator} not support`);
}
return [input, init];
};
/** /**
* 发起请求 * 发起请求
* @param {*} param0 * @param {*} param0
* @returns * @returns
*/ */
export const fetchApi = async ({ input, init = {}, translator, token }) => { export const fetchApi = async ({
input,
init,
transOpts,
apiSetting,
token,
}) => {
if (token) { if (token) {
if (translator === OPT_TRANS_DEEPL) { apiSetting.key = token;
init.headers["Authorization"] = `DeepL-Auth-Key ${token}`; // DeepL
} else if (translator === OPT_TRANS_OPENAI) {
init.headers["Authorization"] = `Bearer ${token}`; // OpenAI
init.headers["api-key"] = token; // Azure OpenAI
} else {
init.headers["Authorization"] = `Bearer ${token}`; // Microsoft & others
} }
if (transOpts?.translator) {
[input, init] = newTransReq(transOpts, apiSetting);
} }
// if (token) {
// if (translator === OPT_TRANS_DEEPL) {
// init.headers["Authorization"] = `DeepL-Auth-Key ${token}`; // DeepL
// } else if (translator === OPT_TRANS_OPENAI) {
// init.headers["Authorization"] = `Bearer ${token}`; // OpenAI
// init.headers["api-key"] = token; // Azure OpenAI
// } else {
// init.headers["Authorization"] = `Bearer ${token}`; // Microsoft & others
// }
// }
if (isGm) { if (isGm) {
let info; let info;
@@ -109,8 +214,8 @@ export const fetchApi = async ({ input, init = {}, translator, token }) => {
*/ */
export const fetchPool = taskPool( export const fetchPool = taskPool(
fetchApi, fetchApi,
async ({ translator }) => { async ({ transOpts }) => {
if (translator === OPT_TRANS_MICROSOFT) { if (transOpts?.translator === OPT_TRANS_MICROSOFT) {
const [token] = await msAuth(); const [token] = await msAuth();
return { token }; return { token };
} }
@@ -128,9 +233,9 @@ export const fetchPool = taskPool(
*/ */
export const fetchData = async ( export const fetchData = async (
input, input,
{ useCache, usePool, translator, token, ...init } = {} { useCache, usePool, transOpts, apiSetting, ...init } = {}
) => { ) => {
const cacheReq = await newCacheReq(new Request(input, init)); const cacheReq = await newCacheReq(input, init);
let res; let res;
// 查询缓存 // 查询缓存
@@ -146,9 +251,9 @@ export const fetchData = async (
if (!res) { if (!res) {
// 发送请求 // 发送请求
if (usePool) { if (usePool) {
res = await fetchPool.push({ input, init, translator, token }); res = await fetchPool.push({ input, init, transOpts, apiSetting });
} else { } else {
res = await fetchApi({ input, init, translator, token }); res = await fetchApi({ input, init, transOpts, apiSetting });
} }
if (!res?.ok) { if (!res?.ok) {
@@ -180,7 +285,7 @@ export const fetchData = async (
* @returns * @returns
*/ */
export const fetchPolyfill = async (input, opts) => { export const fetchPolyfill = async (input, opts) => {
if (!input.trim()) { if (!input?.trim()) {
throw new Error("URL is empty"); throw new Error("URL is empty");
} }

View File

@@ -4,6 +4,7 @@ import {
STOKEY_FAB, STOKEY_FAB,
STOKEY_SYNC, STOKEY_SYNC,
STOKEY_MSAUTH, STOKEY_MSAUTH,
STOKEY_BDAUTH,
STOKEY_RULESCACHE_PREFIX, STOKEY_RULESCACHE_PREFIX,
STOKEY_WEBFIXCACHE_PREFIX, STOKEY_WEBFIXCACHE_PREFIX,
DEFAULT_SETTING, DEFAULT_SETTING,
@@ -134,6 +135,12 @@ export const updateSync = (obj) => putObj(STOKEY_SYNC, obj);
export const getMsauth = () => getObj(STOKEY_MSAUTH); export const getMsauth = () => getObj(STOKEY_MSAUTH);
export const setMsauth = (val) => setObj(STOKEY_MSAUTH, val); export const setMsauth = (val) => setObj(STOKEY_MSAUTH, val);
/**
* baidu auth
*/
export const getBdauth = () => getObj(STOKEY_BDAUTH);
export const setBdauth = (val) => setObj(STOKEY_BDAUTH, val);
/** /**
* 存入默认数据 * 存入默认数据
*/ */

View File

@@ -360,9 +360,8 @@ export class Translator {
triggerTime, triggerTime,
transSign, transSign,
} = this._inputRule; } = this._inputRule;
const apiSetting = (this._setting.transApis || DEFAULT_TRANS_APIS)[ const apiSetting =
translator this._setting.transApis?.[translator] || DEFAULT_TRANS_APIS[translator];
];
const { detectRemote } = this._setting; const { detectRemote } = this._setting;
let triggerShortcut = initTriggerShortcut; let triggerShortcut = initTriggerShortcut;

View File

@@ -5,6 +5,9 @@ import CircularProgress from "@mui/material/CircularProgress";
import { import {
OPT_TRANS_ALL, OPT_TRANS_ALL,
OPT_TRANS_MICROSOFT, OPT_TRANS_MICROSOFT,
OPT_TRANS_DEEPLFREE,
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
OPT_TRANS_OPENAI, OPT_TRANS_OPENAI,
OPT_TRANS_CUSTOMIZE, OPT_TRANS_CUSTOMIZE,
URL_KISS_PROXY, URL_KISS_PROXY,
@@ -71,9 +74,16 @@ function ApiFields({ translator }) {
}); });
}; };
const buildinTranslators = [
OPT_TRANS_MICROSOFT,
OPT_TRANS_DEEPLFREE,
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
];
return ( return (
<Stack spacing={3}> <Stack spacing={3}>
{translator !== OPT_TRANS_MICROSOFT && ( {!buildinTranslators.includes(translator) && (
<> <>
<TextField <TextField
size="small" size="small"
@@ -113,7 +123,7 @@ function ApiFields({ translator }) {
<Stack direction="row" spacing={2}> <Stack direction="row" spacing={2}>
<TestButton translator={translator} api={api} /> <TestButton translator={translator} api={api} />
{translator !== OPT_TRANS_MICROSOFT && ( {!buildinTranslators.includes(translator) && (
<Button <Button
size="small" size="small"
variant="outlined" variant="outlined"