mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add DeepLX translation provider #1111
This commit is contained in:
@ -135,8 +135,8 @@ const languageCodes = {
|
|||||||
'Zulu': 'zu',
|
'Zulu': 'zu',
|
||||||
};
|
};
|
||||||
|
|
||||||
const KEY_REQUIRED = ['deepl','libre'];
|
const KEY_REQUIRED = ['deepl', 'libre'];
|
||||||
const LOCAL_URL = ['libre', 'oneringtranslator'];
|
const LOCAL_URL = ['libre', 'oneringtranslator', 'deeplx'];
|
||||||
|
|
||||||
function showKeysButton() {
|
function showKeysButton() {
|
||||||
const providerRequiresKey = KEY_REQUIRED.includes(extension_settings.translate.provider);
|
const providerRequiresKey = KEY_REQUIRED.includes(extension_settings.translate.provider);
|
||||||
@ -271,6 +271,27 @@ async function translateProviderDeepl(text, lang) {
|
|||||||
throw new Error(response.statusText);
|
throw new Error(response.statusText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates text using the DeepLX API
|
||||||
|
* @param {string} text Text to translate
|
||||||
|
* @param {string} lang Target language code
|
||||||
|
* @returns {Promise<string>} Translated text
|
||||||
|
*/
|
||||||
|
async function translateProviderDeepLX(text, lang) {
|
||||||
|
const response = await fetch('/api/translate/deeplx', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: getRequestHeaders(),
|
||||||
|
body: JSON.stringify({ text: text, lang: lang }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const result = await response.text();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(response.statusText);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translates text using the selected translation provider
|
* Translates text using the selected translation provider
|
||||||
* @param {string} text Text to translate
|
* @param {string} text Text to translate
|
||||||
@ -290,6 +311,8 @@ async function translate(text, lang) {
|
|||||||
return await translateProviderGoogle(text, lang);
|
return await translateProviderGoogle(text, lang);
|
||||||
case 'deepl':
|
case 'deepl':
|
||||||
return await translateProviderDeepl(text, lang);
|
return await translateProviderDeepl(text, lang);
|
||||||
|
case 'deeplx':
|
||||||
|
return await translateProviderDeepLX(text, lang);
|
||||||
case 'oneringtranslator':
|
case 'oneringtranslator':
|
||||||
return await translateProviderOneRing(text, lang);
|
return await translateProviderOneRing(text, lang);
|
||||||
default:
|
default:
|
||||||
@ -437,6 +460,7 @@ jQuery(() => {
|
|||||||
<option value="libre">Libre</option>
|
<option value="libre">Libre</option>
|
||||||
<option value="google">Google</option>
|
<option value="google">Google</option>
|
||||||
<option value="deepl">DeepL</option>
|
<option value="deepl">DeepL</option>
|
||||||
|
<option value="deeplx">DeepLX</option>
|
||||||
<option value="oneringtranslator">OneRingTranslator</option>
|
<option value="oneringtranslator">OneRingTranslator</option>
|
||||||
<select>
|
<select>
|
||||||
<div id="translate_key_button" class="menu_button fa-solid fa-key margin0"></div>
|
<div id="translate_key_button" class="menu_button fa-solid fa-key margin0"></div>
|
||||||
@ -490,13 +514,17 @@ jQuery(() => {
|
|||||||
|
|
||||||
await writeSecret(extension_settings.translate.provider, key);
|
await writeSecret(extension_settings.translate.provider, key);
|
||||||
toastr.success('API Key saved');
|
toastr.success('API Key saved');
|
||||||
|
$("#translate_key_button").addClass('success');
|
||||||
});
|
});
|
||||||
$('#translate_url_button').on('click', async () => {
|
$('#translate_url_button').on('click', async () => {
|
||||||
const optionText = $('#translation_provider option:selected').text();
|
const optionText = $('#translation_provider option:selected').text();
|
||||||
const exampleURLs = {};
|
const exampleURLs = {
|
||||||
exampleURLs['libre'] = 'http://127.0.0.1:5000/translate';
|
'libre': 'http://127.0.0.1:5000/translate',
|
||||||
exampleURLs['oneringtranslator'] = 'http://127.0.0.1:4990/translate';
|
'oneringtranslator': 'http://127.0.0.1:4990/translate',
|
||||||
const url = await callPopup(`<h3>${optionText} API URL</h3><i>Example: <tt>` + exampleURLs[extension_settings.translate.provider] + `</tt></i>`, 'input');
|
'deeplx': 'http://127.0.0.1:1188/translate',
|
||||||
|
};
|
||||||
|
const popupText = `<h3>${optionText} API URL</h3><i>Example: <tt>${String(exampleURLs[extension_settings.translate.provider])}</tt></i>`;
|
||||||
|
const url = await callPopup(popupText, 'input');
|
||||||
|
|
||||||
if (url == false) {
|
if (url == false) {
|
||||||
return;
|
return;
|
||||||
@ -504,6 +532,7 @@ jQuery(() => {
|
|||||||
|
|
||||||
await writeSecret(extension_settings.translate.provider + "_url", url);
|
await writeSecret(extension_settings.translate.provider + "_url", url);
|
||||||
toastr.success('API URL saved');
|
toastr.success('API URL saved');
|
||||||
|
$("#translate_url_button").addClass('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
@ -17,6 +17,7 @@ const SECRET_KEYS = {
|
|||||||
AI21: 'api_key_ai21',
|
AI21: 'api_key_ai21',
|
||||||
SCALE_COOKIE: 'scale_cookie',
|
SCALE_COOKIE: 'scale_cookie',
|
||||||
ONERING_URL: 'oneringtranslator_url',
|
ONERING_URL: 'oneringtranslator_url',
|
||||||
|
DEEPLX_URL: 'deeplx_url',
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,6 +3,9 @@ const https = require('https');
|
|||||||
const { readSecret, SECRET_KEYS } = require('./secrets');
|
const { readSecret, SECRET_KEYS } = require('./secrets');
|
||||||
const { generateRequestUrl, normaliseResponse } = require('google-translate-api-browser');
|
const { generateRequestUrl, normaliseResponse } = require('google-translate-api-browser');
|
||||||
|
|
||||||
|
const DEEPLX_URL_DEFAULT = 'http://127.0.0.1:1188/translate';
|
||||||
|
const ONERING_URL_DEFAULT = 'http://127.0.0.1:4990/translate';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("express").Express} app
|
* @param {import("express").Express} app
|
||||||
* @param {any} jsonParser
|
* @param {any} jsonParser
|
||||||
@ -134,13 +137,18 @@ function registerEndpoints(app, jsonParser) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.post('/api/translate/onering', jsonParser, async (request, response) => {
|
app.post('/api/translate/onering', jsonParser, async (request, response) => {
|
||||||
const url = readSecret(SECRET_KEYS.ONERING_URL);
|
const secretUrl = readSecret(SECRET_KEYS.ONERING_URL);
|
||||||
|
const url = secretUrl || ONERING_URL_DEFAULT;
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
console.log('OneRing URL is not configured.');
|
console.log('OneRing URL is not configured.');
|
||||||
return response.sendStatus(401);
|
return response.sendStatus(401);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!secretUrl && url === ONERING_URL_DEFAULT) {
|
||||||
|
console.log('OneRing URL is using default value.', ONERING_URL_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
const text = request.body.text;
|
const text = request.body.text;
|
||||||
const from_lang = request.body.from_lang;
|
const from_lang = request.body.from_lang;
|
||||||
const to_lang = request.body.to_lang;
|
const to_lang = request.body.to_lang;
|
||||||
@ -180,6 +188,59 @@ function registerEndpoints(app, jsonParser) {
|
|||||||
return response.sendStatus(500);
|
return response.sendStatus(500);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.post('/api/translate/deeplx', jsonParser, async (request, response) => {
|
||||||
|
const secretUrl = readSecret(SECRET_KEYS.DEEPLX_URL);
|
||||||
|
const url = secretUrl || DEEPLX_URL_DEFAULT;
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
console.log('DeepLX URL is not configured.');
|
||||||
|
return response.sendStatus(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!secretUrl && url === DEEPLX_URL_DEFAULT) {
|
||||||
|
console.log('DeepLX URL is using default value.', DEEPLX_URL_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
const text = request.body.text;
|
||||||
|
const lang = request.body.lang;
|
||||||
|
|
||||||
|
if (!text || !lang) {
|
||||||
|
return response.sendStatus(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Input text: ' + text);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
text: text,
|
||||||
|
source_lang: 'auto',
|
||||||
|
target_lang: lang,
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
timeout: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.ok) {
|
||||||
|
const error = await result.text();
|
||||||
|
console.log('DeepLX error: ', result.statusText, error);
|
||||||
|
return response.sendStatus(result.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
const json = await result.json();
|
||||||
|
console.log('Translated text: ' + json.data);
|
||||||
|
|
||||||
|
return response.send(json.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("DeepLX translation error: " + error.message);
|
||||||
|
return response.sendStatus(500);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
Reference in New Issue
Block a user