first commit

main
hyd998877 2023-03-24 01:45:46 +08:00
parent 45fead9667
commit 2b16997a5b
9 changed files with 1245 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
__pycache__/

10
install.py Normal file
View File

@ -0,0 +1,10 @@
import launch
import os
req_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "requirements.txt")
with open(req_file) as file:
for lib in file:
lib = lib.strip()
if not launch.is_installed(lib):
launch.run_pip(f"install {lib}", f"sd-webui-auto-language requirement: {lib}")

View File

@ -0,0 +1,727 @@
// this list no trans
var pass_keys = {
"BSRGAN":1,
"DDIM Eta":1,
"Trans Js":1,
"logSNR":1,
"DDPM":1,
"UniPCMultistep":1,
"LMSDiscrete":1,
"EulerDiscrete":1,
"Filewords":1,
"xformers":1,
"PNDM":1,
"vae":1,
"lms":1,
"pndm":1,
"ddim":1,
"dpmsolver":1,
"SGDNesterov":1,
"AdamW":1,
"DAdaptation":1,
"DPMSolverMultistep":1,
"DEISMultistep":1,
"HeunDiscrete":1,
"devilkkw":1,
"parrotzone":1,
"AdaFactor":1,
"adafactor":1,
"lowram":1,
"dpmsingle":1,
"veryslow":1,
"Perlin H":1,
"EulerAncestralDiscrete":1,
"DPMSolverSinglestep":1,
"LoRA":1
}
// is en
function containsEnWorld(text) {
if (text.length<=3)
return false
if(pass_keys[text])
return false
if (/^[a-zA-Z\s]*[a-zA-Z][.?!]?$/.test(text)) {
return true;
}
return false
}
function get_config(filePath) {
let request = new XMLHttpRequest();
request.open("GET", 'trans/config', false);//Async
request.send(null);
if (request.responseText.length == 0) return '';
try{
var json = JSON.parse(request.responseText)
return json.config;
}catch(e){
}
return {}
}
function auto_save_setting() {
var data = {
auto_language_enabled:gradioApp().querySelector('#auto_language_enabled input').checked,
show_en_enabled:gradioApp().querySelector('#show_en_enabled input').checked,
to_lan:gradioApp().querySelector('#auto_to_lang select').value,
transer:gradioApp().querySelector('#auto_langer_drop select').value
}
let request = new XMLHttpRequest();
request.open("POST", 'trans/save_config', false);//Async
request.setRequestHeader("Content-Type", "application/json");
request.send(JSON.stringify(data));
if (request.responseText.length == 0) return '';
try{
var json = JSON.parse(request.responseText)
if (json.error == 0) {
showToast('save settings successful')
}
}catch(e){
}
return
}
function local_trans_list(text_list) {
const list = Array.from(text_list);
if (list.length == 0) {
showToast('trans list is empty')
return
}
let request = new XMLHttpRequest();
request.open("POST", `trans/local_trans_list`, true);//is Async
request.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
auto_end_auto_trans()
}
};
request.send(JSON.stringify(list));
}
function local_trans(text, save=true, is_async=true, en=false) {
if (text.length == 0) {
showToast('trans text is empty')
return
}
let request = new XMLHttpRequest();
is_safe = save?1:0
request.open("GET", `trans/local_trans?text=${text}&&save=${is_safe}&&en=${en}`, is_async);//is Async
request.send(null);
if (request.responseText.length == 0) return '';
var json = JSON.parse(request.responseText)
return json.txt;
}
function local_save_trans(text, tran) {
let request = new XMLHttpRequest();
request.open("GET", `trans/local_save_trans?text=${text}&&tran=${tran}`, true);//Async
request.send(null);
}
function read_file(filePath) {
let request = new XMLHttpRequest();
request.open("GET", `file=${filePath}`, false);// no async
request.send(null);
return request.responseText;
}
function download_localization() {
try{
var json = JSON.parse(read_file('localizations/my.json?time='+Date.now()))
Object.keys(json).forEach(function(key){
localization[key] = json[key]
})
}catch(e){
}
}
function getTranslation(text){
if(! text) return undefined
if(translated_lines[text] === undefined){
original_lines[text] = 1
}
tl = localization[text]
if(tl !== undefined){
if (tl==text) return undefined
translated_lines[tl] = 1
if(typeof(trans_config)!='undefined' && trans_config.show_en_enabled)
tl = text+'/'+tl
else
tl = text
}else{
if (containsEnWorld(text)) {
// local_trans(text)
trans_config.trans_list.add(text)
}
}
return tl
}
function auto_change_lan(v){
}
function auto_change_transer(v){
}
function auto_change_language_enabled(v){
}
function auto_change_show_en_enabled(v){
}
function auto_end_auto_trans(){
gradioApp().getElementById('auto_trans_btn').innerHTML="Start Auto Translate"
showToast('finish')
}
function getActivePrompt() {
const currentTab = get_uiCurrentTabContent();
switch (currentTab.id) {
case "tab_txt2img":
return currentTab.querySelector("#txt2img_prompt textarea");
case "tab_img2img":
return currentTab.querySelector("#img2img_prompt textarea");
}
return null;
}
function getActiveNegativePrompt() {
const currentTab = get_uiCurrentTabContent();
switch (currentTab.id) {
case "tab_txt2img":
return currentTab.querySelector("#txt2img_neg_prompt textarea");
case "tab_img2img":
return currentTab.querySelector("#img2img_neg_prompt textarea");
}
return null;
}
function showProgress(progressbarContainer,atEnd,progress_call){
var dateStart = new Date()
var wasEverActive = false
var parentProgressbar = progressbarContainer.parentNode
var divProgress = document.createElement('div')
divProgress.className='progressDiv'
divProgress.style.display = ""
var divInner = document.createElement('div')
divInner.className='progress'
divProgress.appendChild(divInner)
parentProgressbar.insertBefore(divProgress, progressbarContainer)
var removeProgressBar = function(){
setTitle("")
parentProgressbar.removeChild(divProgress)
atEnd && atEnd()
}
var fun = function(id_live_preview){
request("./trans/progress", {}, function(res){
progress_call && progress_call(res)
if(res.completed){
removeProgressBar()
return
}
var rect = progressbarContainer.getBoundingClientRect()
if(rect.width){
divProgress.style.width = rect.width + "px";
}
progressText = ""
divInner.style.width = ((res.progress || 0) * 100.0) + '%'
divInner.style.background = res.progress ? "" : "transparent"
if(res.progress > 0){
progressText = ((res.progress || 0) * 100.0).toFixed(0) + '%'
}
setTitle(progressText)
if(res.textinfo && res.textinfo.indexOf("\n") == -1){
progressText = res.textinfo + " " + progressText
}
divInner.textContent = progressText
var elapsedFromStart = (new Date() - dateStart) / 1000
if(elapsedFromStart > 5 && !res.active){
removeProgressBar()
return
}
setTimeout(() => {
fun(res.id_live_preview);
}, 500)
}, function(){
removeProgressBar()
})
}
fun(0)
}
function showToast(message) {
var toast = document.getElementById('toast');
if (!toast) {
toast = document.createElement('div');
toast.id = "toast";
gradioApp().appendChild(toast);
}
toast.innerHTML = message;
toast.style.opacity = 1;
setTimeout(() => {
toast.style.opacity = 0;
}, 2000);
}
function hide_trans_dialg() {
const dialogs = document.querySelectorAll('[id^="dialog_"]');
dialogs.forEach(dialog => {
dialog.remove();
});
}
function show_trans_dialg(to_lan, top, left, title) {
if (document.getElementById('dialog_'+title)) {
return
}
// create draggable window
const windowDiv = document.createElement('div');
windowDiv.style.position = 'absolute';
windowDiv.style.top = top+'px';
windowDiv.style.left = left+'px';
windowDiv.style.width = '600px';
windowDiv.style.height = '180px';
windowDiv.style.border = 'none';
windowDiv.style.background = '#f5f5f5';
windowDiv.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.2)';
windowDiv.style.zIndex = '9999';
windowDiv.id = 'dialog_'+title
document.body.appendChild(windowDiv);
// create title bar
const titleBar = document.createElement('div');
titleBar.style.position = 'absolute';
titleBar.style.top = '0px';
titleBar.style.left = '0px';
titleBar.style.width = '580px';
titleBar.style.height = '30px';
titleBar.style.background = '#4CAF50';
titleBar.style.color = 'white';
titleBar.style.fontSize = '16px';
titleBar.style.display = 'flex';
titleBar.style.alignItems = 'center';
titleBar.style.justifyContent = 'space-between';
titleBar.style.padding = '0px 10px';
titleBar.innerHTML = title;
titleBar.draggable = true;
windowDiv.appendChild(titleBar);
// create close button
const closeButton = document.createElement('button');
closeButton.innerHTML = 'X';
closeButton.style.position = 'absolute';
closeButton.style.top = '5px';
closeButton.style.right = '5px';
closeButton.addEventListener('click', () => {
windowDiv.remove();
});
titleBar.appendChild(closeButton);
// make title bar draggable
let shiftX = 0;
let shiftY = 0;
let isDragging = false;
titleBar.addEventListener('mousedown', function(event) {
if (event.target !== closeButton && event.target !== translateButton && event.target !== backButton && event.target !== inputBox) {
isDragging = true;
shiftX = event.clientX - windowDiv.getBoundingClientRect().left;
shiftY = event.clientY - windowDiv.getBoundingClientRect().top;
}
});
document.addEventListener('mousemove', function(event) {
if (isDragging) {
windowDiv.style.left = event.pageX - shiftX + 'px';
windowDiv.style.top = event.pageY - shiftY + 'px';
}
});
document.addEventListener('mouseup', function(event) {
isDragging = false;
});
// create input text box
const inputBox = document.createElement('textarea');
inputBox.id='auto_input_strans_'+title
inputBox.style = `
position: absolute;
top: 50px;
left: 10px;
width: 570px;
height: 80px;
border-radius: 5px;
border: none;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
font-size: 16px;
padding-left: 10px;
word-wrap: break-word;
overflow-wrap: break-word;
white-space: pre-wrap;
`;
inputBox.placeholder = 'Enter text to translate';
windowDiv.appendChild(inputBox);
const charCountLabel = document.createElement('label');
charCountLabel.style = `
position: absolute;
bottom: 27px;
left: 10px;
font-size: 16px;
color: #4CAF50;
`;
charCountLabel.innerHTML = '';
inputBox.addEventListener('input', () => {
charCountLabel.innerHTML = inputBox.value.length + ' c';
});
windowDiv.appendChild(charCountLabel);
const addButton = document.createElement('button');
addButton.innerHTML = '+';
addButton.style.position = 'absolute';
addButton.style.top = '140px';
addButton.style.left = '120px';
addButton.style.width = '80px';
addButton.style.height = '30px';
addButton.style.borderRadius = '5px';
addButton.style.border = 'none';
addButton.style.background = '#4CAF50';
addButton.style.color = 'white';
addButton.style.fontSize = '16px';
addButton.addEventListener('click', () => {
const inputText = inputBox.value;
if (inputText.length==0) {return}
const translatedText = local_trans(inputText, false, false, true);
if (translatedText.length==0 || translatedText==inputText) {return}
const prompt = getActivePrompt();
if (prompt.value.length==0)
prompt.value = translatedText
else
prompt.value = prompt.value + ',' + translatedText
trans_config[title] = null
trans_config[title+'trans'] = null
});
addButton.addEventListener('mousedown', () => {
addButton.style.background = '#3e8e41';
});
addButton.addEventListener('mouseup', () => {
addButton.style.background = '#4CAF50';
});
windowDiv.appendChild(addButton);
// create translate button
const translateButton = document.createElement('button');
translateButton.innerHTML = 'Translate En';
translateButton.style.position = 'absolute';
translateButton.style.top = '140px';
translateButton.style.left = '240px';
translateButton.style.width = '140px';
translateButton.style.height = '30px';
translateButton.style.borderRadius = '5px';
translateButton.style.border = 'none';
translateButton.style.background = '#4CAF50';
translateButton.style.color = 'white';
translateButton.style.fontSize = '16px';
translateButton.addEventListener('click', () => {
const inputText = inputBox.value;
if (inputText.length==0) {return}
if (inputText == trans_config[title]) {
prompt.value = trans_config[title+'trans']
}else{
const translatedText = local_trans(inputText, false, false, true);
if (translatedText.length==0 || translatedText==inputText) {return}
const prompt = getActivePrompt();
prompt.value = translatedText
trans_config[title] = inputText
trans_config[title+'trans'] = translatedText
}
});
translateButton.addEventListener('mousedown', () => {
translateButton.style.background = '#3e8e41';
});
translateButton.addEventListener('mouseup', () => {
translateButton.style.background = '#4CAF50';
});
windowDiv.appendChild(translateButton);
// create back button
const backButton = document.createElement('button');
backButton.innerHTML = 'Translate '+to_lan;
backButton.style.position = 'absolute';
backButton.style.top = '140px';
backButton.style.left = '420px';
backButton.style.width = '140px';
backButton.style.height = '30px';
backButton.style.borderRadius = '5px';
backButton.style.border = 'none';
backButton.style.background = '#4CAF50';
backButton.style.color = 'white';
backButton.style.fontSize = '16px';
backButton.addEventListener('click', () => {
const prompt = getActivePrompt();
const inputText = prompt.value;
if (inputText.length==0) {return}
if (inputText == trans_config[title+'trans']) {
inputBox.value = trans_config[title]
}else{
const translatedText = local_trans(inputText, false, false);
if (translatedText.length==0 || translatedText==inputText) {return}
inputBox.value = translatedText
trans_config[title] = translatedText
trans_config[title+'trans'] = inputText
}
});
backButton.addEventListener('mousedown', () => {
backButton.style.background = '#3e8e41';
});
backButton.addEventListener('mouseup', () => {
backButton.style.background = '#4CAF50';
});
windowDiv.appendChild(backButton);
}
(function () {
const customCSS = `
#toast {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
padding: 10px 20px;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
border-radius: 5px;
z-index: 9999;
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
`
function add_div(){
// add btn
var txt_parent = gradioApp().getElementById('txt2img_tools')
var img_parent = gradioApp().getElementById('img2img_tools')
if(!txt_parent || !img_parent) return false;
if(!gradioApp().getElementById('txt_trans_prompt')){
var txt_html = `
<button class="gr-button gr-button-lg gr-button-tool" id="txt_trans_prompt" title="translate prompt.">en2</button>
<button class="gr-button gr-button-lg gr-button-tool" id="txt_trans_neprompt" title="translate negative prompt.">N2</button>
`
txt_parent.innerHTML+=txt_html
gradioApp().querySelector('#txt_trans_prompt').addEventListener('click', () => {
trans_config.cur_tab_index = get_tab_index('tabs')
show_trans_dialg(trans_config.to_lan, 21, 57, "txt2img Prompt")
}
);
gradioApp().querySelector('#txt_trans_neprompt').addEventListener('click', () => {
trans_config.cur_tab_index = get_tab_index('tabs')
show_trans_dialg(trans_config.to_lan, 393, 57, "txt2img Negative Prompt")
}
);
var img_html = `
<button class="gr-button gr-button-lg gr-button-tool" id="img_trans_prompt" title="translate prompt.">en2</button>
<button class="gr-button gr-button-lg gr-button-tool" id="img_trans_neprompt" title="translate negative prompt.">N2</button>
`
img_parent.innerHTML+=img_html
gradioApp().querySelector('#img_trans_prompt').addEventListener('click', () => {
trans_config.cur_tab_index = get_tab_index('tabs')
show_trans_dialg(trans_config.to_lan, 21, 57, "img2img Prompt")
}
);
gradioApp().querySelector('#img_trans_neprompt').addEventListener('click', () => {
trans_config.cur_tab_index = get_tab_index('tabs')
show_trans_dialg(trans_config.to_lan, 393, 57, "img2img Negative Prompt")
}
);
}
var node = gradioApp().getElementById('auto_language_jsdiv')
if(!node) return false;
var session = node
const modal = document.createElement('div')
modal.innerHTML = `
<div class="flex row w-full flex-wrap gap-4">
<div class="gr-form flex border-solid border bg-gray-200 dark:bg-gray-700 gap-px rounded-lg flex-wrap" style="flex-direction: inherit;">
<div class="gr-block gr-box relative w-full border-solid border border-gray-200 gr-padded">
<label class="block w-full"><span class="text-gray-500 text-[0.855rem] mb-2 block dark:text-gray-200 relative z-40">ui text</span>
<textarea id="text_local_item" data-testid="textbox" class="scroll-hide block gr-box gr-input w-full gr-text-input" placeholder="need input your want to translate" rows="3" style="overflow-y: scroll; height: 84px;"></textarea>
</label>
</div>
<div class="gr-block gr-box relative w-full border-solid border border-gray-200 gr-padded">
<label class="block w-full"><span class="text-gray-500 text-[0.855rem] mb-2 block dark:text-gray-200 relative z-40">translated text</span>
<textarea id="text_local_tran" class="scroll-hide block gr-box gr-input w-full gr-text-input" placeholder="Can be empty, indicating no translation" rows="3" style="overflow-y: scroll; height: 84px;"></textarea></label>
</div>
</div>
</div>
<div class="flex row w-full flex-wrap gap-4">
<button class="gr-button gr-button-lg gr-button-secondary" id="local_load_btn">load</button>
<button class="gr-button gr-button-lg gr-button-secondary" id="local_load_tran">translate</button>
<button class="gr-button gr-button-lg gr-button-secondary" id="local_load_save">save</button>
</div>
`
session.appendChild(modal);
gradioApp().getElementById('local_load_btn').addEventListener('click', () => {
var text_local_item = gradioApp().querySelector('#text_local_item')
var text_local_tran = gradioApp().querySelector('#text_local_tran')
if (text_local_item.value.length==0) {
return
}
var out_txt = localization[text_local_item.value]
if (out_txt) {
text_local_tran.value = out_txt
text_local_tran.placeholder = 'find but no translated:'+text_local_item.value
}else{
text_local_tran.value = ''
text_local_tran.placeholder = 'no find:'+text_local_item.value
}
}
);
gradioApp().getElementById('local_load_tran').addEventListener('click', () =>
{
var text_local_item = gradioApp().querySelector('#text_local_item')
var text_local_tran = gradioApp().querySelector('#text_local_tran')
if (text_local_item.value.length==0) {
text_local_item.placeholder = 'empty strings cannot be translated'
return
}
var out_txt = local_trans(text_local_item.value, false)// no save
if (out_txt && out_txt.length>0 && out_txt!=text_local_item.value) {
text_local_tran.value = out_txt
}else{
text_local_tran.value = ''
text_local_tran.placeholder = 'translated fail:'+text_local_item.value
}
}
);
gradioApp().getElementById('local_load_save').addEventListener('click', () =>
{
var text_local_item = gradioApp().querySelector('#text_local_item')
var text_local_tran = gradioApp().querySelector('#text_local_tran')
if (text_local_item.value.length==0) {
text_local_item.placeholder = 'empty cannot be saved'
return
}
local_save_trans(text_local_item.value, text_local_tran.value)
localization[text_local_item.value] = text_local_tran.value
showToast('save successful')
}
);
gradioApp().getElementById('save_trans_setting_btn').addEventListener('click', () =>
{
auto_save_setting()
}
);
gradioApp().getElementById('auto_trans_to_en').addEventListener('click', () =>
{
var inputText = gradioApp().querySelector('#auto_text_lan textarea').value
if (inputText.length==0) {return}
const translatedText = local_trans(inputText, false, false, true);
gradioApp().querySelector('#text_lan_translated textarea').value = translatedText
}
);
gradioApp().getElementById('auto_trans_to_lan').addEventListener('click', () =>
{
var inputText = gradioApp().querySelector('#text_lan_translated textarea').value
if (inputText.length==0) {return}
const translatedText = local_trans(inputText, false, false, false);
gradioApp().querySelector('#auto_text_lan textarea').value = translatedText
}
);
gradioApp().getElementById('auto_trans_btn').addEventListener('click', () =>
{
if (trans_config.doing_list || trans_config.trans_list.size == 0) {
return;
}
gradioApp().getElementById('auto_trans_btn').innerHTML="doing"
trans_config.doing_list = true
showProgress(gradioApp().getElementById('auto_textbox_info'), auto_end_auto_trans, (res)=>{
if (res.trans_succ) {
gradioApp().querySelector('#auto_textbox_info textarea').value=`Auto Translate Num:${res.trans_succ}`
}
})
}
);
trans_config.is_init = true
return true
}
function init() {
trans_config = get_config()
trans_config.trans_list = new Set()
download_localization()
// Add style to dom
let $styleEL = document.createElement('style');
if ($styleEL.styleSheet) {
$styleEL.styleSheet.cssText = customCSS;
} else {
$styleEL.appendChild(document.createTextNode(customCSS));
}
gradioApp().appendChild($styleEL);
trans_config.is_init = false
const observer = new MutationObserver(mutations => {
if (!trans_config.is_init) add_div()
if (!trans_config.is_init) return;
var cur_index = get_tab_index('tabs')
if (cur_index!=trans_config.cur_tab_index) {
hide_trans_dialg()
}
if (trans_config.doing_list) {
local_trans_list(trans_config.trans_list)
trans_config.trans_list = new Set()
trans_config.doing_list = false
}
})
observer.observe(gradioApp(), {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['title', 'style']
})
}
// Init after page loaded
document.addEventListener('DOMContentLoaded', init)
})();

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
pygoogletranslation
googletrans==4.0.0-rc1
lru-dict
translators

110
scripts/lan.py Normal file
View File

@ -0,0 +1,110 @@
lans = [
"zh-CN",
"af",
"sq",
"am",
"ar",
"hy",
"az",
"eu",
"be",
"bn",
"bs",
"bg",
"ca",
"ceb",
"ny",
"co",
"hr",
"cs",
"da",
"nl",
"en",
"eo",
"et",
"tl",
"fi",
"fr",
"fy",
"gl",
"ka",
"de",
"el",
"gu",
"ht",
"ha",
"haw",
"iw",
"hi",
"hmn",
"hu",
"is",
"ig",
"id",
"ga",
"it",
"ja",
"jw",
"kn",
"kk",
"km",
"rw",
"ko",
"ku",
"ky",
"lo",
"la",
"lv",
"lt",
"lb",
"mk",
"mg",
"ms",
"ml",
"mt",
"mi",
"mr",
"mn",
"my",
"ne",
"no",
"or",
"ps",
"fa",
"pl",
"pt",
"pa",
"ro",
"ru",
"sm",
"gd",
"sr",
"st",
"sn",
"sd",
"si",
"sk",
"sl",
"so",
"es",
"su",
"sw",
"sv",
"tg",
"ta",
"tt",
"te",
"th",
"tr",
"tk",
"uk",
"ur",
"ug",
"uz",
"vi",
"cy",
"xh",
"yi",
"yo",
"zu",
]

283
scripts/main.py Normal file
View File

@ -0,0 +1,283 @@
import gradio as gr
from pathlib import Path
from modules import script_callbacks, shared
import json
import os
from typing import List
from lru import LRU
from typing import Optional
# import asyncio
import concurrent.futures
from fastapi import FastAPI, Response, Body
from scripts.lan import lans
from scripts.trans_google import GoogleTranslate
from scripts.trans_youdao import YoudaoTranslate
from scripts.trans_tp import TpTranslate,init_transers
transers = ['free_google', 'free_youdao_zh']
init_transers(transers)
transer = None
# Webui root path
ROOT_DIR = Path().absolute()
trans_file = os.path.join(ROOT_DIR, "localizations/my.json")
current_path = os.path.dirname(os.path.abspath(__file__))
config_file = os.path.join(current_path, "config.json")
trans_succ = 0
trans_config = None
textbox_info = None
end_trans_btn = None
m_temp_trans_list = None
m_temp_transed_num = 0
m_trans_dict = LRU(1000)
def read_or_create_json_file(filename):
if not os.path.exists(filename):
with open(filename, 'w', encoding='utf-8') as f:
json.dump({}, f)
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
return data
def update_json_key(filename, data, key, value):
data[key] = value
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4)
# print(f'{filename} update: {key}={value}')
def update_json_file(filename,data):
if not data:
print('data is None')
return
# 保存 JSON 文件
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4)
# print(f'{filename} update all')
def check_transer():
global transer
cur_transer = trans_config['transer']
if cur_transer == 'free_google':
transer = GoogleTranslate()
elif cur_transer == 'free_youdao_zh':
transer = YoudaoTranslate()
else:
if cur_transer.startswith("tp_"):
tp_transer = cur_transer[3:]
transer = TpTranslate(tp_transer)
def init():
global trans_config
global trans_data
global trans_succ
trans_data = read_or_create_json_file(trans_file)
trans_succ = len(list(trans_data))
trans_config = read_or_create_json_file(config_file)
if 'show_en_enabled' not in trans_config:
# trans_config['auto_language_enabled'] = False
trans_config['show_en_enabled'] = True
trans_config['to_lan'] = 'zh-CN'
trans_config['transer'] = transers[0]
trans_config['trans_succ'] = trans_succ
check_transer()
init()
#--------------------------------ui---------------------------------------
def update_info():
textbox_info.update(f'Auto Translate Num:{trans_succ}')
def auto_remove_trans():
global trans_data
global trans_succ
if trans_succ==0:
return
trans_succ = 0
trans_data = []
update_json_file(trans_file,trans_data)
textbox_info.update(f'Auto Translate Num:{trans_succ}')
def on_ui_tabs():
global textbox_info
global end_trans_btn
with gr.Blocks(analytics_enabled=False) as translate_interface:
gr.HTML("<p style=\"margin-bottom:0.75em\">The untranslated characters will be translated automatically and will not affect the old translations. Use the function in the lower right corner to easily check and quickly modify the current translation.1,Save the setting;2,Click start button;3,Reload your browser.</p>")
with gr.Row():
with gr.Column(scale=80):
textbox_info = gr.Textbox(label='Translated Status', value=f'Auto Translate Num:{trans_succ}',readonly=True, elem_id="auto_textbox_info")
auto_trans_btn = gr.Button(value="Start Auto Translate", variant='primary', elem_id="auto_trans_btn")
with gr.Row():
with gr.Column(scale=45):
text_lan = gr.Textbox(label="Text", lines=3, value="", elem_id="auto_text_lan", placeholder="your select language")
with gr.Column():
with gr.Row():
auto_trans_to_en = gr.Button(value=f'-->', elem_id="auto_trans_to_en")
with gr.Row():
auto_trans_to_lan = gr.Button(value=f'<--', elem_id="auto_trans_to_lan")
with gr.Column(scale=45):
text_lan_translated = gr.Textbox(label="Translated Text", lines=3, value="", elem_id="text_lan_translated", placeholder="english")
gr.HTML("<hr />")
with gr.Row():
with gr.Column(scale=5):
with gr.Row():
tar_lang_drop = gr.Dropdown(label="To Language", choices=lans, value=trans_config['to_lan'], elem_id="auto_to_lang")
auto_langer_drop = gr.Dropdown(label="Select Translater", choices=transers, value=trans_config['transer'], elem_id="auto_langer_drop")
with gr.Row():
# auto_language_enabled = gr.Checkbox(label='enable auto trans ui language.(Need reload browser)', elem_id='auto_language_enabled', value=trans_config['auto_language_enabled'])
show_en_enabled = gr.Checkbox(label='display both english and target language', elem_id='show_en_enabled', value=trans_config['show_en_enabled'])
with gr.Row():
save_trans_setting_btn = gr.Button(value="Save Setting", elem_id='save_trans_setting_btn')
remove_trans_btn = gr.Button(value="Remove Auto Trans", elem_id='remove_trans_btn')
with gr.Column(scale=5, elem_id='auto_language_jsdiv'):
pass
end_trans_btn = gr.Button(value="Remove Auto Trans", elem_id='end_trans_btn', visible=False)
end_trans_btn.click(None,_js="auto_end_auto_trans", show_progress=False, inputs=[],outputs=[])
remove_trans_btn.click(fn=auto_remove_trans,show_progress=False, inputs=[],outputs=[])
tar_lang_drop.change(None,_js="auto_change_lan", inputs=[tar_lang_drop])
auto_langer_drop.change(None,_js="auto_change_transer", inputs=[auto_langer_drop])
# auto_language_enabled.change(None,_js="auto_change_language_enabled", inputs=[auto_language_enabled])
show_en_enabled.change(None,_js="auto_change_show_en_enabled", inputs=[show_en_enabled])
return [(translate_interface, "Auto Translate", "auto_translate")]
script_callbacks.on_ui_tabs(on_ui_tabs)
#--------------------------------api--------------------------------------
def transAPI(demo: gr.Blocks, app: FastAPI):
@app.get("/trans/config")
async def config():
res_data = {"error": 0}
res_data['config'] = trans_config
return res_data
@app.post("/trans/save_config")
async def auto_save_setting(data: dict = Body(...)):
res_data = {"error": 0}
# trans_config['auto_language_enabled'] = data['auto_language_enabled']
trans_config['show_en_enabled'] = data['show_en_enabled']
if trans_config['to_lan'] != data['to_lan']:
auto_remove_trans()
trans_config['to_lan'] = data['to_lan']
if trans_config['transer'] != data['transer']:
trans_config['transer'] = data['transer']
check_transer()
if 'appid' in data:
trans_config['appid'] = data['appid']
update_json_file(config_file, trans_config)
return res_data
@app.get("/trans/local_trans")
async def local_trans(text, save: Optional[bool] = True, en: Optional[bool] = False):
res_data = {"error": 0}
res_text = ''
global trans_succ
global m_trans_dict
if len(text) > 0:
print('text', text, save, en)
if text in trans_data:
res_text = trans_data[text]
elif text in m_trans_dict:
res_text = m_trans_dict[text]
else:
if en:
res_text = transer.translate(text, trans_config['to_lan'], 'en')
else:
res_text = transer.translate(text, 'en', trans_config['to_lan'])
print('local_trans', text, res_text)
if res_text != text and len(res_text)>0:
trans_succ = trans_succ + 1
m_trans_dict[text] = res_text
update_info()
if save:
update_json_key(trans_file, trans_data, text, res_text)
else:
res_data['error']=-1
res_data['txt'] = res_text
return res_data
def heavy_computation():
global trans_succ
global m_trans_dict
global m_temp_trans_list
global m_temp_transed_num
for text in m_temp_trans_list:
m_temp_transed_num = m_temp_transed_num + 1
if text in trans_data or text in m_trans_dict:
continue
res_text = transer.translate(text, 'en', trans_config['to_lan'])
print('local_trans', text, res_text)
if res_text != text and len(res_text)>0:
trans_succ = trans_succ + 1
m_trans_dict[text] = res_text
update_info()
update_json_key(trans_file, trans_data, text, res_text)
@app.post("/trans/local_trans_list")
async def local_trans_list(json_str: str = Body(...)):
res_data = {"error": 0}
items=json.loads(json_str)
global m_temp_trans_list
m_temp_trans_list = items
# print('local_trans_list items', items)
# asyncio.create_task(heavy_computation())
executor = concurrent.futures.ThreadPoolExecutor()
future = executor.submit(heavy_computation)
return res_data
@app.get("/trans/progress")
async def progress_get():
res_data = {"error": 0, "completed": False, "progress":0, "textinfo":"", "active":False, "trans_succ":trans_succ}
global m_temp_trans_list
if m_temp_trans_list:
res_data['active'] = True
res_data['progress'] = m_temp_transed_num/len(m_temp_trans_list)
if m_temp_transed_num>0:
key = m_temp_trans_list[m_temp_transed_num-1]
if key in m_trans_dict:
res_data['textinfo'] = key+'->'+m_trans_dict[key]
if res_data['progress']==int(1):
res_data['completed'] = True
m_temp_trans_list = None
m_temp_transed_num = 0
return res_data
@app.post("/trans/progress")
async def progress():
return await progress_get()
@app.get("/trans/local_save_trans")
async def local_save_trans(text, tran):
res_data = {"error": 0}
if len(text) > 0:
update_json_key(trans_file,trans_data, text, tran)
else:
res_data = {"error": -1}
return res_data
script_callbacks.on_app_started(transAPI)

27
scripts/trans_google.py Normal file
View File

@ -0,0 +1,27 @@
# 使用的谷歌翻译接口
from pygoogletranslation import Translator
class GoogleTranslate():
def __init__(self):
print('init GoogleTranslate')
# proxy = {
# 'http': "127.0.0.1:1080"
# }
# self.translator = Translator(proxies=proxy)
self.translator = Translator()
def translate(self, input_string, input_lang=None, output_lang=None, retry=False):
res_txt = ''
if input_lang == None:
input_lang = ''
try:
res_txt = self.translator.translate(input_string, dest=output_lang).text
except Exception as e:
print(e)
return res_txt
if __name__ == "__main__":
tran = GoogleTranslate()
print('res', tran.translate("test", output_lang='zh-CN'))

27
scripts/trans_tp.py Normal file
View File

@ -0,0 +1,27 @@
import translators as ts
# ts.preaccelerate()
def init_transers(transers):
for x in range(len(ts.server.__all__)):
if x>2:
transers.append('tp_'+ts.server.__all__[x])
class TpTranslate():
def __init__(self, translator):
print('init TpTranslate')
self.translator = translator
def translate(self, input_string, input_lang=None, output_lang=None, retry=False):
res_txt = ''
if input_lang == None:
input_lang = 'auto'
try:
res_txt = ts.translate_text(input_string, from_language=input_lang, to_language=output_lang)
except Exception as e:
print(e)
return res_txt
if __name__ == "__main__":
tran = TpTranslate()
print('res', tran.translate("test", output_lang='zh-CN'))

56
scripts/trans_youdao.py Normal file
View File

@ -0,0 +1,56 @@
import requests
import json
lan_map = {
'zh-CN2en':'ZH_CN2EN',
'zh-CN2ja':'ZH_CN2JA',
'zh-CN2kr':'ZH_CN2KR',
'zh-CN2fr':'ZH_CN2FR',
'zh-CN2ru':'ZH_CN2RU',
'zh-CN2sp':'ZH_CN2SP',
'en2zh-CN':'EN2ZH_CN',
'ja2zh-CN':'JA2ZH_CN',
'kr2zh-CN':'KR2ZH_CN',
'fr2zh-CN':'FR2ZH_CN',
'ru2zh-CN':'RU2ZH_CN',
'sp2zh-CN':'SP2ZH_CN'
}
class YoudaoTranslate():
def __init__(self):
print('init YoudaoTranslate')
def translate(self, input_string, input_lang='', output_lang='', retry=False):
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
res_txt = ''
key = input_lang+'2'+output_lang
if key in lan_map:
ty = lan_map[key]
print('ty', ty)
url = f'http://fanyi.youdao.com/translate?&doctype=json&type={ty}&i={input_string}'
else:
url = f'http://fanyi.youdao.com/translate?&doctype=json&type=AUTO&i={input_string}'
if url==None:
return res_txt
response = requests.get(url, headers = headers)
if response.status_code == 200:
try:
j_data = json.loads(response.text)
if j_data['errorCode'] == 0:
res_txt = j_data['translateResult'][0][0]['tgt']
else:
print('youdao', response.text)
except Exception as e:
print(e)
finally:
pass
else:
print('youdao status_code', response.status_code)
return res_txt
if __name__ == "__main__":
tran = YoudaoTranslate()
print('res', tran.translate("test", output_lang='zh-CN'))