Skip to content

Commit fd4af07

Browse files
end-candleterales
andauthored
feat: add Baidu translation engine support (#768)
* feat: Added Baidu translation support * fix: Baidu translation results are not displayed correctly * Fix merge error in Turkish translation --------- Co-authored-by: Alex Terehov <[email protected]>
1 parent 6815d55 commit fd4af07

18 files changed

+134
-0
lines changed

locales/de.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Maximale Zeichenlänge für Hinweise die im Text angezeigt werden. Abgeschnitte Zeichen werden als (...) angezeigt",
3838
"config.annotations": "Hinweise im Text aktivieren",
3939
"config.auto_detection": "Automatische Erkennung von Übersetzung aktivieren",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "API key für die DeepL translate engine",
4143
"config.deepl_log": "DeepL debug logs anzeigen",
4244
"config.deepl_use_free_api_entry": "Kostenlose DeepL Version benutzen",

locales/en.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Max number of characters shown in the inline annotations. Excess characters will display as an ellipses (...)",
3838
"config.annotations": "Enable the inline annotations.",
3939
"config.auto_detection": "Enable locales auto detection for projects",
40+
"config.baidu_app_secret": "APP Secret to use Baidu translate engine",
41+
"config.baidu_appid": "APP ID to use Baidu translate engine",
4042
"config.deepl_api_key": "API key to use DeepL translate engine",
4143
"config.deepl_log": "Show DeepL engine debug logs",
4244
"config.deepl_use_free_api_entry": "Use DeepL Free API entry point",

locales/es.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Máximo número de caracteres que se mostrarán en las anotaciones en línea. Los restantes se mostrarán como elipses (...)",
3838
"config.annotations": "Habilitar las anotaciones en línea.",
3939
"config.auto_detection": "",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "API key para el traductor DeepL",
4143
"config.deepl_log": "Mostrar mensajes de depuración del motor DeepL",
4244
"config.deepl_use_free_api_entry": "",

locales/fr.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Nombre maximum de caractères à afficher dans les annotations. Le surplus sera affiché sous forme d'ellipse (...)",
3838
"config.annotations": "Activer les annotations.",
3939
"config.auto_detection": "Activer la détection automatique des langues pour les projets",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "Clé API pour utiliser le moteur de traduction DeepL",
4143
"config.deepl_log": "Montrer le journal de debug du moteur DeepL",
4244
"config.deepl_use_free_api_entry": "Utiliser le point d'entrée gratuite de DeepL",

locales/ja.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "インラインアノテーションの最大文字数です。超過している部分は(...)と表示されます。",
3838
"config.annotations": "インラインアノテーションを有効にする.",
3939
"config.auto_detection": "",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "",
4143
"config.deepl_log": "",
4244
"config.deepl_use_free_api_entry": "",

locales/nb-NO.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Maksimalt antall tegn vist i hjelpevindu. Resterende del vil bli vist som (...)",
3838
"config.annotations": "Slå på hjelpevindu",
3939
"config.auto_detection": "",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "",
4143
"config.deepl_log": "",
4244
"config.deepl_use_free_api_entry": "",

locales/nl-NL.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Max. aantal karakters zichtbaar binnen inline annotaties. Overschreden delen worden getoond als ellipses (...)",
3838
"config.annotations": "Inline annotaties inschakelen.",
3939
"config.auto_detection": "",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "",
4143
"config.deepl_log": "",
4244
"config.deepl_use_free_api_entry": "",

locales/pt-BR.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Número máximo de caracteres exibidos nas anotações inline. O restante será exibido em forma de reticências (...)",
3838
"config.annotations": "Habilitar anotações inline",
3939
"config.auto_detection": "",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "",
4143
"config.deepl_log": "",
4244
"config.deepl_use_free_api_entry": "",

locales/ru.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Максимальное количество символов, отображаемых во встроенных аннотациях. Лишние символы будут отображаться в виде многоточия (...)",
3838
"config.annotations": "Включить встроенные аннотации.",
3939
"config.auto_detection": "Включить автоматическое определение переводов для проектов",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "API ключ для использования DeepL",
4143
"config.deepl_log": "Отображать отладочные журналы DeepL",
4244
"config.deepl_use_free_api_entry": "Использовать бесплатную версию DeepL API",

locales/sv-SE.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Max antal bokstävers som visas i insatta anteckningen. Överflödiga bokstäver kommer visas som en ellips (…)",
3838
"config.annotations": "Aktivera insatta anteckningar.",
3939
"config.auto_detection": "",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "",
4143
"config.deepl_log": "",
4244
"config.deepl_use_free_api_entry": "",

locales/tr.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Satır aralığında gösterilen ek açıklamaların maksimum karakter uzunluğu. Fazladan karakterler noktalı şekilde görüntülenecektir (...)",
3838
"config.annotations": "Satır aralığında ek açıklamaları etkinleştir",
3939
"config.auto_detection": "Projeler için otomatik çeviri algılamasını etkinleştir",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "DeepL çeviri sistemini kullanmak için API anahtarı",
4143
"config.deepl_log": "DeepL sisteminin hata ayıklama kayıtlarını göster",
4244
"config.deepl_use_free_api_entry": "DeepL'in Bedava API giriş noktasını kullanın",

locales/uk-UA.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "Максимальна кількість символів, що відображаються у вбудованих анотаціях. Зайві символи будуть відображатися у вигляді трьох крапок (...)",
3838
"config.annotations": "Включити вбудовані анотації.",
3939
"config.auto_detection": "",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "Ключ для використання API DeepL",
4143
"config.deepl_log": "Відображати налагоджувальні журнали DeepL",
4244
"config.deepl_use_free_api_entry": "",

locales/zh-CN.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "内联注释显示的最大字符数。超出的部分将显示为省略号(...)",
3838
"config.annotations": "启用内联注释",
3939
"config.auto_detection": "",
40+
"config.baidu_app_secret": "百度平台分配的密钥",
41+
"config.baidu_appid": "百度平台APPID",
4042
"config.deepl_api_key": "",
4143
"config.deepl_log": "",
4244
"config.deepl_use_free_api_entry": "",

locales/zh-TW.json

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"config.annotation_max_length": "內聯註釋顯示的最大文字數。超出的部分將顯示為省略號(...)",
3838
"config.annotations": "啟用內聯註釋",
3939
"config.auto_detection": "",
40+
"config.baidu_app_secret": "",
41+
"config.baidu_appid": "",
4042
"config.deepl_api_key": "",
4143
"config.deepl_log": "",
4244
"config.deepl_use_free_api_entry": "",

package.json

+11
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,7 @@
10261026
"google-cn",
10271027
"deepl",
10281028
"libretranslate",
1029+
"baidu",
10291030
"openai"
10301031
]
10311032
},
@@ -1059,6 +1060,16 @@
10591060
"default": null,
10601061
"description": "%config.deepl_api_key%"
10611062
},
1063+
"i18n-ally.translate.baidu.appid": {
1064+
"type": "string",
1065+
"default": null,
1066+
"description": "%config.baidu_appid%"
1067+
},
1068+
"i18n-ally.translate.baidu.apiSecret": {
1069+
"type": "string",
1070+
"default": null,
1071+
"description": "%config.baidu_app_secret%"
1072+
},
10621073
"i18n-ally.translate.deepl.enableLog": {
10631074
"type": "boolean",
10641075
"default": false,

src/core/Config.ts

+8
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,14 @@ export class Config {
536536
.update(key, value, isGlobal)
537537
}
538538

539+
static get baiduApiSecret() {
540+
return this.getConfig<string | null | undefined>('translate.baidu.apiSecret')
541+
}
542+
543+
static get baiduAppid() {
544+
return this.getConfig<string | null | undefined>('translate.baidu.appid')
545+
}
546+
539547
static get googleApiKey() {
540548
return this.getConfig<string | null | undefined>('translate.google.apiKey')
541549
}

src/translators/engines/baidu.ts

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import crypto from 'crypto'
2+
import axios from 'axios'
3+
import qs from 'qs'
4+
import TranslateEngine, { TranslateOptions, TranslateResult } from './base'
5+
import { Config } from '~/core'
6+
7+
interface BaiduSignOptions {
8+
appid: string | null | undefined
9+
salt: string
10+
secret: string | null | undefined
11+
query: string
12+
}
13+
14+
export default class BaiduTranslate extends TranslateEngine {
15+
apiLink = 'https://fanyi.baidu.com'
16+
apiRoot = 'https://fanyi-api.baidu.com'
17+
18+
async translate(options: TranslateOptions) {
19+
let { from = 'auto', to = 'auto' } = options
20+
21+
from = this.convertToSupportedLocalesForGoogleCloud(from)
22+
to = this.convertToSupportedLocalesForGoogleCloud(to)
23+
24+
const appid = Config.baiduAppid
25+
const secret = Config.baiduApiSecret
26+
const salt = Date.now().toString()
27+
const sign = this.getSign({ appid, secret, query: options.text, salt })
28+
29+
const form = {
30+
q: options.text,
31+
appid,
32+
salt,
33+
from,
34+
to,
35+
sign,
36+
}
37+
38+
const { data } = await axios({
39+
method: 'GET',
40+
url: `${this.apiRoot}/api/trans/vip/translate?${qs.stringify(form)}`,
41+
})
42+
43+
return this.transform(data, options)
44+
}
45+
46+
convertToSupportedLocalesForGoogleCloud(locale: string): string {
47+
return locale.replace(/-/g, '_').split('_')[0]
48+
}
49+
50+
getSign({ appid, salt, query, secret }: BaiduSignOptions): string {
51+
if (appid && salt) {
52+
const string = appid + query + salt + secret
53+
const md5 = crypto.createHash('md5')
54+
md5.update(string)
55+
return md5.digest('hex')
56+
}
57+
return ''
58+
}
59+
60+
transform(response: any, options: TranslateOptions): TranslateResult {
61+
const { text } = options
62+
63+
const r: TranslateResult = {
64+
text,
65+
to: response.to,
66+
from: response.from,
67+
response,
68+
linkToResult: `${this.apiLink}/#${response.from}/${response.to}/${text}`,
69+
}
70+
71+
try {
72+
const result: string[] = []
73+
response.trans_result.forEach((v: any) => {
74+
result.push(v.dst)
75+
})
76+
r.result = result
77+
}
78+
catch (e) {}
79+
80+
if (!r.result) r.error = new Error((`[${response.error_code}] ${response.error_msg}`) || 'No result')
81+
82+
return r
83+
}
84+
}

src/translators/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import GoogleTranslateEngine from './engines/google'
33
import GoogleTranslateCnEngine from './engines/google-cn'
44
import DeepLTranslateEngine from './engines/deepl'
55
import LibreTranslateEngine from './engines/libretranslate'
6+
import BaiduTranslate from './engines/baidu'
67
import OpenAITranslateEngine from './engines/openai'
78

89
export class Translator {
@@ -11,6 +12,7 @@ export class Translator {
1112
'google-cn': new GoogleTranslateCnEngine(),
1213
'deepl': new DeepLTranslateEngine(),
1314
'libretranslate': new LibreTranslateEngine(),
15+
'baidu': new BaiduTranslate(),
1416
'openai': new OpenAITranslateEngine(),
1517
}
1618

@@ -26,6 +28,7 @@ export {
2628
GoogleTranslateCnEngine,
2729
DeepLTranslateEngine,
2830
LibreTranslateEngine,
31+
BaiduTranslate,
2932
OpenAITranslateEngine,
3033
}
3134

0 commit comments

Comments
 (0)