diff options
| author | Marie <github@yuugi.dev> | 2025-03-06 01:03:02 +0100 |
|---|---|---|
| committer | Marie <github@yuugi.dev> | 2025-03-06 01:03:02 +0100 |
| commit | 40599190f731fb2ce81fe547438eab0e17837852 (patch) | |
| tree | c0265d6cf173de1a6e56306c00f9f2cde6e1ad73 /packages/backend/src/server | |
| parent | merge: Update sfm-js to latest version (!933) (diff) | |
| download | sharkey-40599190f731fb2ce81fe547438eab0e17837852.tar.gz sharkey-40599190f731fb2ce81fe547438eab0e17837852.tar.bz2 sharkey-40599190f731fb2ce81fe547438eab0e17837852.zip | |
add: libretranslate
Diffstat (limited to 'packages/backend/src/server')
3 files changed, 98 insertions, 34 deletions
diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index 436dcf27cb..d581c07e8c 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -459,6 +459,14 @@ export const meta = { type: 'string', optional: false, nullable: true, }, + libreTranslateURL: { + type: 'string', + optional: false, nullable: true, + }, + libreTranslateKey: { + type: 'string', + optional: false, nullable: true, + }, defaultDarkTheme: { type: 'string', optional: false, nullable: true, @@ -652,7 +660,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- defaultLike: instance.defaultLike, enableEmail: instance.enableEmail, enableServiceWorker: instance.enableServiceWorker, - translatorAvailable: instance.deeplAuthKey != null, + translatorAvailable: instance.deeplAuthKey != null || instance.libreTranslateURL != null || instance.deeplFreeMode && instance.deeplFreeInstance != null, cacheRemoteFiles: instance.cacheRemoteFiles, cacheRemoteSensitiveFiles: instance.cacheRemoteSensitiveFiles, pinnedUsers: instance.pinnedUsers, @@ -700,6 +708,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- deeplIsPro: instance.deeplIsPro, deeplFreeMode: instance.deeplFreeMode, deeplFreeInstance: instance.deeplFreeInstance, + libreTranslateURL: instance.libreTranslateURL, + libreTranslateKey: instance.libreTranslateKey, enableIpLogging: instance.enableIpLogging, enableActiveEmailValidation: instance.enableActiveEmailValidation, enableVerifymailApi: instance.enableVerifymailApi, diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index b3733d3d39..f6ce86790a 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -107,6 +107,8 @@ export const paramDef = { deeplIsPro: { type: 'boolean' }, deeplFreeMode: { type: 'boolean' }, deeplFreeInstance: { type: 'string', nullable: true }, + libreTranslateURL: { type: 'string', nullable: true }, + libreTranslateKey: { type: 'string', nullable: true }, enableEmail: { type: 'boolean' }, email: { type: 'string', nullable: true }, smtpSecure: { type: 'boolean' }, @@ -577,6 +579,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } } + if (ps.libreTranslateURL !== undefined) { + if (ps.libreTranslateURL === '') { + set.libreTranslateURL = null; + } else { + set.libreTranslateURL = ps.libreTranslateURL; + } + } + + if (ps.libreTranslateKey !== undefined) { + if (ps.libreTranslateKey === '') { + set.libreTranslateKey = null; + } else { + set.libreTranslateKey = ps.libreTranslateKey; + } + } + if (ps.enableIpLogging !== undefined) { set.enableIpLogging = ps.enableIpLogging; } diff --git a/packages/backend/src/server/api/endpoints/notes/translate.ts b/packages/backend/src/server/api/endpoints/notes/translate.ts index 61a511510c..b59977b7dd 100644 --- a/packages/backend/src/server/api/endpoints/notes/translate.ts +++ b/packages/backend/src/server/api/endpoints/notes/translate.ts @@ -93,11 +93,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- return; } - if (this.serverSettings.deeplAuthKey == null && !this.serverSettings.deeplFreeMode) { + if (this.serverSettings.deeplAuthKey == null && !this.serverSettings.deeplFreeMode && !this.serverSettings.libreTranslateURL) { throw new ApiError(meta.errors.unavailable); } - if (this.serverSettings.deeplFreeMode && !this.serverSettings.deeplFreeInstance) { + if (this.serverSettings.deeplFreeMode && !this.serverSettings.deeplFreeInstance && !this.serverSettings.libreTranslateURL) { throw new ApiError(meta.errors.unavailable); } @@ -105,40 +105,76 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (targetLang.includes('-')) targetLang = targetLang.split('-')[0]; const params = new URLSearchParams(); - if (this.serverSettings.deeplAuthKey) params.append('auth_key', this.serverSettings.deeplAuthKey); - params.append('text', note.text); - params.append('target_lang', targetLang); - const endpoint = this.serverSettings.deeplFreeMode && this.serverSettings.deeplFreeInstance ? this.serverSettings.deeplFreeInstance : this.serverSettings.deeplIsPro ? 'https://api.deepl.com/v2/translate' : 'https://api-free.deepl.com/v2/translate'; + // DeepL/DeepLX handling + if (this.serverSettings.deeplAuthKey != null || this.serverSettings.deeplFreeMode) { + if (this.serverSettings.deeplAuthKey) params.append('auth_key', this.serverSettings.deeplAuthKey); + params.append('text', note.text); + params.append('target_lang', targetLang); + const endpoint = this.serverSettings.deeplFreeMode && this.serverSettings.deeplFreeInstance ? this.serverSettings.deeplFreeInstance : this.serverSettings.deeplIsPro ? 'https://api.deepl.com/v2/translate' : 'https://api-free.deepl.com/v2/translate'; - const res = await this.httpRequestService.send(endpoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Accept: 'application/json, */*', - }, - body: params.toString(), - }); - if (this.serverSettings.deeplAuthKey) { - const json = (await res.json()) as { - translations: { - detected_source_language: string; - text: string; - }[]; - }; + const res = await this.httpRequestService.send(endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Accept: 'application/json, */*', + }, + body: params.toString(), + }); + if (this.serverSettings.deeplAuthKey) { + const json = (await res.json()) as { + translations: { + detected_source_language: string; + text: string; + }[]; + }; + + return { + sourceLang: json.translations[0].detected_source_language, + text: json.translations[0].text, + }; + } else { + const json = (await res.json()) as { + code: number, + message: string, + data: string, + source_lang: string, + target_lang: string, + alternatives: string[], + }; + + const languageNames = new Intl.DisplayNames(['en'], { + type: 'language', + }); + + return { + sourceLang: languageNames.of(json.source_lang), + text: json.data, + }; + } + } + + // LibreTranslate handling + if (this.serverSettings.libreTranslateURL) { + const res = await this.httpRequestService.send(this.serverSettings.libreTranslateURL, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json, */*', + }, + body: JSON.stringify({ + q: note.text, + source: 'auto', + target: targetLang, + format: 'text', + api_key: this.serverSettings.libreTranslateKey ?? '', + }), + }); - return { - sourceLang: json.translations[0].detected_source_language, - text: json.translations[0].text, - }; - } else { const json = (await res.json()) as { - code: number, - message: string, - data: string, - source_lang: string, - target_lang: string, alternatives: string[], + detectedLanguage: { [key: string]: string | number }, + translatedText: string, }; const languageNames = new Intl.DisplayNames(['en'], { @@ -146,8 +182,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); return { - sourceLang: languageNames.of(json.source_lang), - text: json.data, + sourceLang: languageNames.of(json.detectedLanguage.language as string), + text: json.translatedText, }; } }); |