add more translators: baidu/tencent/deeplfree

This commit is contained in:
Gabe Yuan
2023-10-21 11:54:04 +08:00
parent 507d54dba0
commit 160fc218fc
9 changed files with 340 additions and 550 deletions

View File

@@ -11,19 +11,14 @@ import {
OPT_TRANS_OPENAI,
OPT_TRANS_CUSTOMIZE,
URL_CACHE_TRAN,
OPT_LANGS_SPECIAL,
PROMPT_PLACE_FROM,
PROMPT_PLACE_TO,
KV_SALT_SYNC,
URL_BAIDU_LANGDETECT,
URL_MICROSOFT_TRAN,
OPT_LANGS_BAIDU,
URL_TENCENT_TRANSMART,
OPT_LANGS_TENCENT,
OPT_LANGS_SPECIAL,
} from "../config";
import { tryDetectLang } from "../libs";
import { sha256 } from "../libs/utils";
import { apiDeepLFreeTranslate } from "./deepl";
import { apiBaiduTranslate } from "./baidu";
import { apiTencentTranslate } from "./tencent";
/**
* 同步数据
@@ -49,244 +44,6 @@ export const apiSyncData = async (url, key, data) =>
*/
export const apiFetch = (url) => fetchPolyfill(url);
/**
* 谷歌翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
const apiGoogleTranslate = async (
translator,
text,
to,
from,
{ url, key, useCache = true }
) => {
const params = {
client: "gtx",
dt: "t",
dj: 1,
ie: "UTF-8",
sl: from,
tl: to,
q: text,
};
const input = `${url}?${queryString.stringify(params)}`;
const res = await fetchPolyfill(input, {
headers: {
"Content-type": "application/json",
},
useCache,
usePool: true,
translator,
token: key,
});
const trText = res.sentences.map((item) => item.trans).join(" ");
const isSame = to === res.src;
return [trText, isSame];
};
/**
* 微软翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
const apiMicrosoftTranslate = async (
translator,
text,
to,
from,
{ useCache = true }
) => {
const params = {
from,
to,
"api-version": "3.0",
};
const input = `${URL_MICROSOFT_TRAN}?${queryString.stringify(params)}`;
const res = await fetchPolyfill(input, {
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify([{ Text: text }]),
useCache,
usePool: true,
translator,
});
const trText = res[0].translations[0].text;
const isSame = to === res[0].detectedLanguage?.language;
return [trText, isSame];
};
/**
* DeepL翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
const apiDeepLTranslate = async (
translator,
text,
to,
from,
{ url, key, useCache = true }
) => {
const data = {
text: [text],
target_lang: to,
// split_sentences: "0",
};
if (from) {
data.source_lang = from;
}
const res = await fetchPolyfill(url, {
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify(data),
useCache,
usePool: true,
translator,
token: key,
});
const trText = res.translations.map((item) => item.text).join(" ");
const isSame = to === res.translations[0].detected_source_language;
return [trText, isSame];
};
/**
* DeepLX翻译
* https://github.com/OwO-Network/DeepLX
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
const apiDeepLXTranslate = async (
translator,
text,
to,
from,
{ url, key, useCache = true }
) => {
const data = {
text,
target_lang: to,
};
if (from) {
data.source_lang = from;
}
const res = await fetchPolyfill(url, {
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify(data),
useCache,
usePool: true,
translator,
token: key,
});
const trText = res.data;
const isSame = to === res.source_lang;
return [trText, isSame];
};
/**
* OpenAI 翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
const apiOpenaiTranslate = async (
translator,
text,
to,
from,
{ url, key, model, prompt, useCache = true }
) => {
prompt = prompt
.replaceAll(PROMPT_PLACE_FROM, from)
.replaceAll(PROMPT_PLACE_TO, to);
const res = await fetchPolyfill(url, {
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify({
model: model,
messages: [
{
role: "system",
content: prompt,
},
{
role: "user",
content: text,
},
],
temperature: 0,
max_tokens: 256,
}),
useCache,
usePool: true,
translator,
token: key,
});
const trText = res?.choices?.[0].message.content;
const sLang = await tryDetectLang(text);
const tLang = await tryDetectLang(trText);
const isSame = text === trText || (sLang && tLang && sLang === tLang);
return [trText, isSame];
};
/**
* 自定义接口 翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
const apiCustomTranslate = async (
translator,
text,
to,
from,
{ url, key, useCache = true }
) => {
const res = await fetchPolyfill(url, {
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify({
text,
from,
to,
}),
useCache,
usePool: true,
translator,
token: key,
});
const trText = res.text;
const isSame = to === res.from;
return [trText, isSame];
};
/**
* 百度语言识别
* @param {*} text
@@ -311,6 +68,31 @@ export const apiBaiduLangdetect = async (text) => {
return "";
};
/**
* 腾讯语言识别
* @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 {*} param0
@@ -328,15 +110,31 @@ export const apiTranslate = async ({
let trText = "";
let isSame = false;
const transOpts = {
const from =
OPT_LANGS_SPECIAL[translator].get(fromLang) ??
OPT_LANGS_SPECIAL[translator].get("auto");
const to = OPT_LANGS_SPECIAL[translator].get(toLang);
if (!to) {
console.log(`[trans] target lang: ${toLang} not support`);
return [trText, isSame];
}
const cacheOpts = {
translator,
text,
fromLang,
toLang,
};
const transOpts = {
translator,
text,
from,
to,
};
const res = await fetchPolyfill(
`${URL_CACHE_TRAN}?${queryString.stringify(transOpts)}`,
`${URL_CACHE_TRAN}?${queryString.stringify(cacheOpts)}`,
{
useCache,
usePool,
@@ -347,30 +145,44 @@ export const apiTranslate = async ({
switch (translator) {
case OPT_TRANS_GOOGLE:
trText = res.sentences.map((item) => item.trans).join(" ");
isSame = to === res.src;
break;
case OPT_TRANS_MICROSOFT:
trText = res[0].translations[0].text;
isSame = toLang === res[0].detectedLanguage?.language;
trText = res[0].translations.map((item) => item.text).join(" ");
isSame = text === trText;
break;
case OPT_TRANS_DEEPL:
trText = res.translations.map((item) => item.text).join(" ");
isSame = to === res.translations[0].detected_source_language;
break;
case OPT_TRANS_DEEPLFREE:
trText = res.result?.texts.map((item) => item.text).join(" ");
isSame = to === res.result?.lang;
break;
case OPT_TRANS_DEEPLX:
trText = res.data;
isSame = to === res.source_lang;
break;
case OPT_TRANS_BAIDU:
trText = res.trans_result?.data.map((item) => item.dst).join(" ");
isSame = res.trans_result?.to === res.trans_result?.from;
break;
case OPT_TRANS_TENCENT:
trText = res.auto_translation;
isSame = text === trText;
break;
case OPT_TRANS_OPENAI:
trText = res?.choices?.[0].message.content;
isSame = text === trText;
break;
case OPT_TRANS_CUSTOMIZE:
trText = res.text;
isSame = to === res.from;
break;
default:
break;
}
return [trText, isSame];
return [trText, isSame, res];
};