Merge pull request #3219 from SillyTavern/pt-br Translate: Split Portuguese languages
Signed| @@ -18,7 +18,7 @@ | ||
| 18 | 18 | "@popperjs/core": "^2.11.8", |
| 19 | 19 | "@zeldafan0225/ai_horde": "^5.1.0", |
| 20 | 20 | "archiver": "^7.0.1", |
| 21 | 21 | "bing-translate-api": "^24.90.12", |
| 22 | 22 | "body-parser": "^1.20.2", |
| 23 | 23 | "bowser": "^2.11.0", |
| 24 | 24 | "command-exists": "^1.2.9", |
| @@ -2161,9 +2161,9 @@ | ||
| 2161 | 2161 | } |
| 2162 | 2162 | }, |
| 2163 | 2163 | "node_modules/bing-translate-api": { |
| 2164 | 2164 | "version": "24.90.12", |
| 2165 | 2165 | "resolved": "https://registry.npmjs.org/bing-translate-api/-/bing-translate-api-24.90.12.tgz", |
| 2166 | 2166 | "integrity": "sha512-DaYqa7iupfj+fj/KeaeZSp5FUY/ZR4sZ6jqoTP0RHkYOUfo7wwoxlhYDkh4VcvBBzuVORnBEgdXBVQrfM4kk7gJJ8XUehnxzOhHU91oy86xEtp8OOMjVEjCZJX042fKxoO19NNvxJ5omeCcxQNFoPbDqVpBJwqiGVquL0oPdQm1Q==", |
| 2167 | 2167 | "license": "MIT", |
| 2168 | 2168 | "dependencies": { |
| 2169 | 2169 | "got": "^11.8.6" |
| @@ -8,7 +8,7 @@ | ||
| 8 | 8 | "@popperjs/core": "^2.11.8", |
| 9 | 9 | "@zeldafan0225/ai_horde": "^5.1.0", |
| 10 | 10 | "archiver": "^7.0.1", |
| 11 | 11 | "bing-translate-api": "^24.90.12", |
| 12 | 12 | "body-parser": "^1.20.2", |
| 13 | 13 | "bowser": "^2.11.0", |
| 14 | 14 | "command-exists": "^1.2.9", |
| @@ -106,7 +106,8 @@ const languageCodes = { | ||
| 106 | 106 | 'Pashto': 'ps', |
| 107 | 107 | 'Persian': 'fa', |
| 108 | 108 | 'Polish': 'pl', |
| 109 | 109 | 'Portuguese (Portugal, Brazil)': 'pt-PT', |
| 110 | + 'Portuguese (Brazil)': 'pt-BR', | |
| 110 | 111 | 'Punjabi': 'pa', |
| 111 | 112 | 'Romanian': 'ro', |
| 112 | 113 | 'Russian': 'ru', |
| @@ -1,10 +1,10 @@ | ||
| 1 | -import https from 'node:https'; | |
| 2 | 1 | import { createRequire } from 'node:module'; |
| 3 | 2 | |
| 4 | 3 | import fetch from 'node-fetch'; |
| 5 | 4 | import express from 'express'; |
| 6 | 5 | import bingTranslateApi{ translate as bingTranslate } from 'bing-translate-api'; |
| 7 | 6 | import iconv from 'iconv-lite'; |
| 7 | +import urlJoin from 'url-join'; | |
| 8 | 8 | |
| 9 | 9 | import { readSecret, SECRET_KEYS } from './secrets.js'; |
| 10 | 10 | import { getConfigValue, uuidv4 } from '../util.js'; |
| @@ -12,6 +12,7 @@ import { jsonParser } from '../express-common.js'; | ||
| 12 | 12 | |
| 13 | 13 | const DEEPLX_URL_DEFAULT = 'http://127.0.0.1:1188/translate'; |
| 14 | 14 | const ONERING_URL_DEFAULT = 'http://127.0.0.1:4990/translate'; |
| 15 | +const LINGVA_DEFAULT = 'https://lingva.ml/api/v1'; | |
| 15 | 16 | |
| 16 | 17 | export const router = express.Router(); |
| 17 | 18 | |
| @@ -56,6 +57,10 @@ router.post('/libre', jsonParser, async (request, response) => { | ||
| 56 | 57 | request.body.lang = 'zt'; |
| 57 | 58 | } |
| 58 | 59 | |
| 60 | + if (request.body.lang === 'pt-BR' || request.body.lang === 'pt-PT') { | |
| 61 | + request.body.lang = 'pt'; | |
| 62 | + } | |
| 63 | + | |
| 59 | 64 | const text = request.body.text; |
| 60 | 65 | const lang = request.body.lang; |
| 61 | 66 | |
| @@ -81,7 +86,7 @@ router.post('/libre', jsonParser, async (request, response) => { | ||
| 81 | 86 | if (!result.ok) { |
| 82 | 87 | const error = await result.text(); |
| 83 | 88 | console.log('LibreTranslate error: ', result.statusText, error); |
| 84 | 89 | return response.sendStatus(result.status500); |
| 85 | 90 | } |
| 86 | 91 | |
| 87 | 92 | /** @type {any} */ |
| @@ -130,6 +135,14 @@ router.post('/google', jsonParser, async (request, response) => { | ||
| 130 | 135 | |
| 131 | 136 | router.post('/yandex', jsonParser, async (request, response) => { |
| 132 | 137 | try { |
| 138 | + if (request.body.lang === 'pt-PT') { | |
| 139 | + request.body.lang = 'pt'; | |
| 140 | + } | |
| 141 | + | |
| 142 | + if (request.body.lang === 'zh-CN' || request.body.lang === 'zh-TW') { | |
| 143 | + request.body.lang = 'zh'; | |
| 144 | + } | |
| 145 | + | |
| 133 | 146 | const chunks = request.body.chunks; |
| 134 | 147 | const lang = request.body.lang; |
| 135 | 148 | |
| @@ -178,13 +191,26 @@ router.post('/yandex', jsonParser, async (request, response) => { | ||
| 178 | 191 | |
| 179 | 192 | router.post('/lingva', jsonParser, async (request, response) => { |
| 180 | 193 | try { |
| 181 | 194 | const baseUrlsecretUrl = readSecret(request.user.directories, SECRET_KEYS.LINGVA_URL); |
| 195 | + const baseUrl = secretUrl || LINGVA_DEFAULT; | |
| 196 | + | |
| 197 | + if (!secretUrl && baseUrl === LINGVA_DEFAULT) { | |
| 198 | + console.log('Lingva URL is using default value.', LINGVA_DEFAULT); | |
| 199 | + } | |
| 182 | 200 | |
| 183 | 201 | if (!baseUrl) { |
| 184 | 202 | console.log('Lingva URL is not configured.'); |
| 185 | 203 | return response.sendStatus(400); |
| 186 | 204 | } |
| 187 | 205 | |
| 206 | + if (request.body.lang === 'zh-CN' || request.body.lang === 'zh-TW') { | |
| 207 | + request.body.lang = 'zh'; | |
| 208 | + } | |
| 209 | + | |
| 210 | + if (request.body.lang === 'pt-BR' || request.body.lang === 'pt-PT') { | |
| 211 | + request.body.lang = 'pt'; | |
| 212 | + } | |
| 213 | + | |
| 188 | 214 | const text = request.body.text; |
| 189 | 215 | const lang = request.body.lang; |
| 190 | 216 | |
| @@ -193,29 +219,24 @@ router.post('/lingva', jsonParser, async (request, response) => { | ||
| 193 | 219 | } |
| 194 | 220 | |
| 195 | 221 | console.log('Input text: ' + text); |
| 196 | - const url = `${baseUrl}/auto/${lang}/${encodeURIComponent(text)}`; | |
| 197 | 222 | |
| 198 | - https.get(url, (resp) => { | |
| 223 | + try { | |
| 199 | - let data = ''; | |
| 224 | + const url = urlJoin(baseUrl, 'auto', lang, encodeURIComponent(text)); | |
| 225 | + const result = await fetch(url); | |
| 200 | 226 | |
| 201 | - resp.on('data', (chunk) => { | |
| 227 | + if (!result.ok) { | |
| 202 | - data += chunk; | |
| 228 | + const error = await result.text(); | |
| 203 | - }); | |
| 229 | + console.log('Lingva error: ', result.statusText, error); | |
| 230 | + } | |
| 204 | 231 | |
| 205 | - resp.on('end', () => { | |
| 232 | + /** @type {any} */ | |
| 206 | - try { | |
| 233 | + const data = await result.json(); | |
| 207 | - const result = JSON.parse(data); | |
| 234 | + console.log('Translated text: ' + data.translation); | |
| 208 | - console.log('Translated text: ' + result.translation); | |
| 235 | + return response.send(data.translation); | |
| 209 | - return response.send(result.translation); | |
| 210 | 236 | } catch (error) { |
| 211 | 237 | console.log('Translation error:', error); |
| 212 | 238 | return response.sendStatus(500); |
| 213 | 239 | } |
| 214 | - }); | |
| 215 | - }).on('error', (err) => { | |
| 216 | - console.log('Translation error: ' + err.message); | |
| 217 | - return response.sendStatus(500); | |
| 218 | - }); | |
| 219 | 240 | } catch (error) { |
| 220 | 241 | console.log('Translation error', error); |
| 221 | 242 | return response.sendStatus(500); |
| @@ -248,8 +269,7 @@ router.post('/deepl', jsonParser, async (request, response) => { | ||
| 248 | 269 | params.append('text', text); |
| 249 | 270 | params.append('target_lang', lang); |
| 250 | 271 | |
| 251 | 272 | if (['de', 'fr', 'it', 'es', 'nl', 'ja', 'ru', 'pt-BR', 'pt-PT'].includes(lang)) { |
| 252 | - // We don't specify a Portuguese variant, so ignore formality for it. | |
| 253 | 273 | params.append('formality', formality); |
| 254 | 274 | } |
| 255 | 275 | |
| @@ -267,7 +287,7 @@ router.post('/deepl', jsonParser, async (request, response) => { | ||
| 267 | 287 | if (!result.ok) { |
| 268 | 288 | const error = await result.text(); |
| 269 | 289 | console.log('DeepL error: ', result.statusText, error); |
| 270 | 290 | return response.sendStatus(result.status500); |
| 271 | 291 | } |
| 272 | 292 | |
| 273 | 293 | /** @type {any} */ |
| @@ -294,6 +314,10 @@ router.post('/onering', jsonParser, async (request, response) => { | ||
| 294 | 314 | console.log('OneRing URL is using default value.', ONERING_URL_DEFAULT); |
| 295 | 315 | } |
| 296 | 316 | |
| 317 | + if (request.body.lang === 'pt-BR' || request.body.lang === 'pt-PT') { | |
| 318 | + request.body.lang = 'pt'; | |
| 319 | + } | |
| 320 | + | |
| 297 | 321 | const text = request.body.text; |
| 298 | 322 | const from_lang = request.body.from_lang; |
| 299 | 323 | const to_lang = request.body.to_lang; |
| @@ -320,7 +344,7 @@ router.post('/onering', jsonParser, async (request, response) => { | ||
| 320 | 344 | if (!result.ok) { |
| 321 | 345 | const error = await result.text(); |
| 322 | 346 | console.log('OneRing error: ', result.statusText, error); |
| 323 | 347 | return response.sendStatus(result.status500); |
| 324 | 348 | } |
| 325 | 349 | |
| 326 | 350 | /** @type {any} */ |
| @@ -376,7 +400,7 @@ router.post('/deeplx', jsonParser, async (request, response) => { | ||
| 376 | 400 | if (!result.ok) { |
| 377 | 401 | const error = await result.text(); |
| 378 | 402 | console.log('DeepLX error: ', result.statusText, error); |
| 379 | 403 | return response.sendStatus(result.status500); |
| 380 | 404 | } |
| 381 | 405 | |
| 382 | 406 | /** @type {any} */ |
| @@ -391,6 +415,7 @@ router.post('/deeplx', jsonParser, async (request, response) => { | ||
| 391 | 415 | }); |
| 392 | 416 | |
| 393 | 417 | router.post('/bing', jsonParser, async (request, response) => { |
| 418 | + try { | |
| 394 | 419 | const text = request.body.text; |
| 395 | 420 | let lang = request.body.lang; |
| 396 | 421 | |
| @@ -398,17 +423,26 @@ router.post('/bing', jsonParser, async (request, response) => { | ||
| 398 | 423 | lang = 'zh-Hans'; |
| 399 | 424 | } |
| 400 | 425 | |
| 426 | + if (request.body.lang === 'zh-TW') { | |
| 427 | + lang = 'zh-Hant'; | |
| 428 | + } | |
| 429 | + | |
| 430 | + if (request.body.lang === 'pt-BR') { | |
| 431 | + lang = 'pt'; | |
| 432 | + } | |
| 433 | + | |
| 401 | 434 | if (!text || !lang) { |
| 402 | 435 | return response.sendStatus(400); |
| 403 | 436 | } |
| 404 | 437 | |
| 405 | 438 | console.log('Input text: ' + text); |
| 406 | 439 | |
| 407 | - bingTranslateApi.translate(text, null, lang).then(result => { | |
| 440 | + const result = await bingTranslate(text, null, lang); | |
| 408 | 441 | console.log('Translated text:const 'translatedText += result?.translation); |
| 409 | - return response.send(result.translation); | |
| 442 | + console.log('Translated text: ' + translatedText); | |
| 410 | - }).catch(err => { | |
| 443 | + return response.send(translatedText); | |
| 411 | - console.log('Translation error: ' + err.message); | |
| 444 | + } catch (error) { | |
| 445 | + console.log('Translation error', error); | |
| 412 | 446 | return response.sendStatus(500); |
| 413 | 447 | }); |
| 414 | 448 | }); |