From f00e8ffa4d570ff7757cb825a09e5d57e854d870 Mon Sep 17 00:00:00 2001 From: Gabe Yuan Date: Fri, 12 Apr 2024 11:31:01 +0800 Subject: [PATCH] feat: add niutrans api --- src/apis/index.js | 9 +++++ src/config/i18n.js | 4 +++ src/config/index.js | 18 ++++++++++ src/hooks/Api.js | 14 ++++++-- src/hooks/Translate.js | 6 ++-- src/libs/req.js | 25 ++++++++++++++ src/views/Options/Apis.js | 70 +++++++++++++++++++++++++++++++-------- 7 files changed, 129 insertions(+), 17 deletions(-) diff --git a/src/apis/index.js b/src/apis/index.js index 2cd94ba4..def89f00 100644 --- a/src/apis/index.js +++ b/src/apis/index.js @@ -6,6 +6,7 @@ import { OPT_TRANS_DEEPL, OPT_TRANS_DEEPLFREE, OPT_TRANS_DEEPLX, + OPT_TRANS_NIUTRANS, OPT_TRANS_BAIDU, OPT_TRANS_TENCENT, OPT_TRANS_OPENAI, @@ -219,6 +220,14 @@ export const apiTranslate = async ({ trText = res.data; isSame = to === res.source_lang; break; + case OPT_TRANS_NIUTRANS: + const json = JSON.parse(res); + if (json.error_msg) { + throw new Error(json.error_msg); + } + trText = json.tgt_text; + isSame = to === json.from; + break; case OPT_TRANS_BAIDU: // trText = res.trans_result?.data.map((item) => item.dst).join(" "); // isSame = res.trans_result?.to === res.trans_result?.from; diff --git a/src/config/i18n.js b/src/config/i18n.js index 8f8ed3e3..d238ae8c 100644 --- a/src/config/i18n.js +++ b/src/config/i18n.js @@ -819,4 +819,8 @@ export const I18N = { zh: `网页修复选择器`, en: `Fixer Selector`, }, + reg_niutrans: { + zh: `获取小牛翻译密钥`, + en: `Get NiuTrans APIKey`, + }, }; diff --git a/src/config/index.js b/src/config/index.js index fd430b69..5365773e 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -90,6 +90,8 @@ export const URL_BAIDU_TRANSAPI = "https://fanyi.baidu.com/transapi"; export const URL_BAIDU_TRANSAPI_V2 = "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 URL_NIUTRANS_REG = + "https://niutrans.com/login?active=3&userSource=kiss-translator"; export const DEFAULT_USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"; @@ -99,6 +101,7 @@ export const OPT_TRANS_MICROSOFT = "Microsoft"; export const OPT_TRANS_DEEPL = "DeepL"; export const OPT_TRANS_DEEPLX = "DeepLX"; export const OPT_TRANS_DEEPLFREE = "DeepLFree"; +export const OPT_TRANS_NIUTRANS = "NiuTrans"; export const OPT_TRANS_BAIDU = "Baidu"; export const OPT_TRANS_TENCENT = "Tencent"; export const OPT_TRANS_OPENAI = "OpenAI"; @@ -117,6 +120,7 @@ export const OPT_TRANS_ALL = [ OPT_TRANS_DEEPL, OPT_TRANS_DEEPLFREE, OPT_TRANS_DEEPLX, + OPT_TRANS_NIUTRANS, OPT_TRANS_OPENAI, OPT_TRANS_GEMINI, OPT_TRANS_CLOUDFLAREAI, @@ -193,6 +197,12 @@ export const OPT_LANGS_SPECIAL = { ["zh-CN", "ZH"], ["zh-TW", "ZH"], ]), + [OPT_TRANS_NIUTRANS]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key]), + ["auto", "auto"], + ["zh-CN", "zh"], + ["zh-TW", "cht"], + ]), [OPT_TRANS_BAIDU]: new Map([ ...OPT_LANGS_FROM.map(([key]) => [key, key]), ["zh-CN", "zh"], @@ -469,6 +479,14 @@ export const DEFAULT_TRANS_APIS = { fetchLimit: 1, fetchInterval: 500, }, + [OPT_TRANS_NIUTRANS]: { + url: "https://api.niutrans.com/NiuTransServer/translation", + key: "", + dictNo: "", + memoryNo: "", + fetchLimit: DEFAULT_FETCH_LIMIT, + fetchInterval: DEFAULT_FETCH_INTERVAL, + }, [OPT_TRANS_OPENAI]: { url: "https://api.openai.com/v1/chat/completions", key: "", diff --git a/src/hooks/Api.js b/src/hooks/Api.js index 6fa8c868..95756571 100644 --- a/src/hooks/Api.js +++ b/src/hooks/Api.js @@ -8,7 +8,10 @@ export function useApi(translator) { const updateApi = useCallback( async (obj) => { - const api = transApis[translator] || {}; + const api = { + ...DEFAULT_TRANS_APIS[translator], + ...(transApis[translator] || {}), + }; Object.assign(transApis, { [translator]: { ...api, ...obj } }); await updateSetting({ transApis }); }, @@ -20,5 +23,12 @@ export function useApi(translator) { await updateSetting({ transApis }); }, [translator, transApis, updateSetting]); - return { api: transApis[translator] || {}, updateApi, resetApi }; + return { + api: { + ...DEFAULT_TRANS_APIS[translator], + ...(transApis[translator] || {}), + }, + updateApi, + resetApi, + }; } diff --git a/src/hooks/Translate.js b/src/hooks/Translate.js index 79d1cde6..a2f89ef2 100644 --- a/src/hooks/Translate.js +++ b/src/hooks/Translate.js @@ -39,8 +39,10 @@ export function useTranslate(q, rule, setting) { text: q, fromLang, toLang, - apiSetting: - setting.transApis?.[translator] || DEFAULT_TRANS_APIS[translator], + apiSetting: { + ...DEFAULT_TRANS_APIS[translator], + ...(setting.transApis[translator] || {}), + }, }); setText(trText); setSamelang(isSame); diff --git a/src/libs/req.js b/src/libs/req.js index 31b15d49..5c462d9c 100644 --- a/src/libs/req.js +++ b/src/libs/req.js @@ -5,6 +5,7 @@ import { OPT_TRANS_DEEPL, OPT_TRANS_DEEPLFREE, OPT_TRANS_DEEPLX, + OPT_TRANS_NIUTRANS, OPT_TRANS_BAIDU, OPT_TRANS_TENCENT, OPT_TRANS_OPENAI, @@ -145,6 +146,27 @@ const genDeeplX = ({ text, from, to, url, key }) => { return [url, init]; }; +const genNiuTrans = ({ text, from, to, url, key, dictNo, memoryNo }) => { + const data = { + from, + to, + apikey: key, + src_text: text, + dictNo, + memoryNo, + }; + + const init = { + headers: { + "Content-type": "application/json", + }, + method: "POST", + body: JSON.stringify(data), + }; + + return [url, init]; +}; + const genTencent = ({ text, from, to }) => { const data = { header: { @@ -287,6 +309,7 @@ export const newTransReq = ({ translator, text, from, to }, apiSetting) => { case OPT_TRANS_OPENAI: case OPT_TRANS_GEMINI: case OPT_TRANS_CLOUDFLAREAI: + case OPT_TRANS_NIUTRANS: args.key = keyPick(translator, args.key); break; default: @@ -303,6 +326,8 @@ export const newTransReq = ({ translator, text, from, to }, apiSetting) => { return genDeeplFree(args); case OPT_TRANS_DEEPLX: return genDeeplX(args); + case OPT_TRANS_NIUTRANS: + return genNiuTrans(args); case OPT_TRANS_BAIDU: return genBaidu(args); case OPT_TRANS_TENCENT: diff --git a/src/views/Options/Apis.js b/src/views/Options/Apis.js index 2a022ac2..9bb43ac5 100644 --- a/src/views/Options/Apis.js +++ b/src/views/Options/Apis.js @@ -13,7 +13,9 @@ import { OPT_TRANS_GEMINI, OPT_TRANS_CLOUDFLAREAI, OPT_TRANS_CUSTOMIZE, + OPT_TRANS_NIUTRANS, URL_KISS_PROXY, + URL_NIUTRANS_REG, DEFAULT_FETCH_LIMIT, DEFAULT_FETCH_INTERVAL, } from "../../config"; @@ -62,14 +64,24 @@ function TestButton({ translator, api }) { alert.error( <>
{i18n("test_failed")}
-
-            {msg}
-          
+ {msg === err.message ? ( +
+ {msg} +
+ ) : ( +
+              {msg}
+            
+ )} ); } finally { @@ -98,6 +110,8 @@ function ApiFields({ translator }) { prompt = "", fetchLimit = DEFAULT_FETCH_LIMIT, fetchInterval = DEFAULT_FETCH_INTERVAL, + dictNo = "", + memoryNo = "", } = api; const handleChange = (e) => { @@ -128,8 +142,23 @@ function ApiFields({ translator }) { OPT_TRANS_OPENAI, OPT_TRANS_GEMINI, OPT_TRANS_CLOUDFLAREAI, + OPT_TRANS_NIUTRANS, ]; + const keyHelper = + translator === OPT_TRANS_NIUTRANS ? ( + <> + {i18n("mulkeys_help")} + + {i18n("reg_niutrans")} + + + ) : mulkeysTranslators.includes(translator) ? ( + i18n("mulkeys_help") + ) : ( + "" + ); + return ( {!buildinTranslators.includes(translator) && ( @@ -148,11 +177,7 @@ function ApiFields({ translator }) { value={key} onChange={handleChange} multiline={mulkeysTranslators.includes(translator)} - helperText={ - mulkeysTranslators.includes(translator) - ? i18n("mulkeys_help") - : "" - } + helperText={keyHelper} /> )} @@ -177,6 +202,25 @@ function ApiFields({ translator }) { )} + {translator === OPT_TRANS_NIUTRANS && ( + <> + + + + )} +