Spaces:
Sleeping
Sleeping
v1.1.0
Browse files- app.py +141 -89
- config.json +42 -29
- requirements.txt +2 -1
- themes.py +3 -4
app.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
import gradio as gr
|
|
|
|
| 2 |
from os import path as osp
|
| 3 |
import json
|
| 4 |
from utils import *
|
|
@@ -9,6 +10,12 @@ from themes import *
|
|
| 9 |
# idx指代顺序排列的序号,0,1,2,...
|
| 10 |
config_path = osp.join(osp.dirname(osp.abspath(__file__)),"./config.json")
|
| 11 |
args = load_config(config_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
if_save_id_immediately = True if int(args["if_save_id_immediately"]) else False
|
| 13 |
moyu_mode = True if int(args["moyu_mode"]) else False
|
| 14 |
path = args["file_path"]
|
|
@@ -16,7 +23,7 @@ abs_path = smart_path(path)
|
|
| 16 |
replace_dict_path = smart_path(args["replace_dict_path"])
|
| 17 |
name_dict_path = smart_path(args["name_dict_path"])
|
| 18 |
altered_text_finals= set()
|
| 19 |
-
|
| 20 |
|
| 21 |
if osp.exists(abs_path):
|
| 22 |
with open(abs_path, "r", encoding ="utf8") as json_file:
|
|
@@ -51,10 +58,25 @@ if osp.exists(name_dict_path):
|
|
| 51 |
name_dic[item[0]]=item[1]
|
| 52 |
|
| 53 |
# Translate
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
def gpt_translate(text,text_id):
|
| 55 |
text = text.replace("\n"," ")
|
| 56 |
prompt = args["openai_api_settings"]["prompt_prefix"]+text+args["openai_api_settings"]["prompt_postfix"]
|
| 57 |
-
translation, if_succ = get_gpt_completion(prompt,
|
| 58 |
if dic[text_id]["text"].replace("\n"," ") == text and if_succ:
|
| 59 |
dic[text_id]["gpt3"] = translation
|
| 60 |
return translation
|
|
@@ -70,7 +92,7 @@ def baidu_translate(text,text_id):
|
|
| 70 |
dic[text_id]["baidu"] = translation
|
| 71 |
return translation
|
| 72 |
|
| 73 |
-
def batch_translate(
|
| 74 |
progress(0, desc="Starting...")
|
| 75 |
if text_start_id not in id_lis or text_end_id not in id_lis or idx_dic[text_start_id] > idx_dic[text_end_id]:
|
| 76 |
gr.Warning("找不到指定序号, 或id前后顺序错误")
|
|
@@ -78,14 +100,9 @@ def batch_translate(radio, check, text_start_id,text_end_id,progress=gr.Progress
|
|
| 78 |
start = idx_dic[text_start_id]
|
| 79 |
end = idx_dic[text_end_id] + 1
|
| 80 |
lis = id_lis[start:end]
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
time.sleep(0.1)
|
| 85 |
-
if radio == 'Baidu':
|
| 86 |
-
for key in progress.tqdm(lis):
|
| 87 |
-
baidu_translate(dic[key]['text'],key)
|
| 88 |
-
time.sleep(0.1)
|
| 89 |
if check:
|
| 90 |
save_json(show_info=False)
|
| 91 |
gr.Info(f"批量机翻成功, 共完成{end-start}句翻译")
|
|
@@ -104,7 +121,7 @@ def next_text():
|
|
| 104 |
id_idx += 1
|
| 105 |
return id_lis[id_idx]
|
| 106 |
|
| 107 |
-
def replace(
|
| 108 |
if not text_id:
|
| 109 |
text_id = id_lis[id_idx]
|
| 110 |
if check_file:
|
|
@@ -116,33 +133,53 @@ def replace(text_gpt,text_baidu,text_final,text_id, check_file = True):
|
|
| 116 |
replace_dic[item[0]]=item[1]
|
| 117 |
f.close()
|
| 118 |
for key,value in replace_dic.items():
|
| 119 |
-
|
| 120 |
-
|
| 121 |
text_final = text_final.replace(key, value)
|
| 122 |
-
dic[text_id][
|
| 123 |
-
dic[text_id][
|
| 124 |
dic[text_id]["text_CN"] = text_final
|
| 125 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
|
| 127 |
-
def change_id(text_id):
|
| 128 |
if not text_id or text_id not in idx_dic: return args["file_path"],"","","","","",""
|
| 129 |
global id_idx
|
| 130 |
id_idx = idx_dic[text_id]
|
| 131 |
-
if
|
| 132 |
-
dic[text_id][
|
| 133 |
-
if
|
| 134 |
-
dic[text_id][
|
| 135 |
if "text_CN" not in dic[text_id]:
|
| 136 |
dic[text_id]["text_CN"] = ""
|
| 137 |
if dic[text_id]["name"] not in name_dic:
|
| 138 |
name_dic[dic[text_id]["name"]] = dic[text_id]["name"]
|
| 139 |
dic[text_id]["name_CN"] = name_dic[dic[text_id]["name"]]
|
| 140 |
-
replace(dic[text_id][
|
|
|
|
| 141 |
if if_save_id_immediately:
|
| 142 |
args["last_edited_id"] = text_id
|
| 143 |
save_config(args,config_path)
|
| 144 |
return args["file_path"],dic[text_id]["text"],dic[text_id]["name"],name_dic[dic[text_id]["name"]],\
|
| 145 |
-
dic[text_id][
|
| 146 |
|
| 147 |
def change_final(text,text_id):
|
| 148 |
if not text_id or not text_id in idx_dic: return
|
|
@@ -157,6 +194,9 @@ def change_name(name,name_cn,text_id):
|
|
| 157 |
dic[text_id]["name_CN"] = name_cn
|
| 158 |
return
|
| 159 |
|
|
|
|
|
|
|
|
|
|
| 160 |
def save_json(show_info = True):
|
| 161 |
global altered_text_finals
|
| 162 |
with open(abs_path, "w", encoding ="utf8") as json_file:
|
|
@@ -191,7 +231,7 @@ def load_last_position(text_path):
|
|
| 191 |
save_config(args,config_path)
|
| 192 |
return args["last_edited_id"]
|
| 193 |
|
| 194 |
-
def submit_api(baidu_api_id, baidu_api_key, from_lang, to_lang,
|
| 195 |
global args
|
| 196 |
if baidu_api_id != "":
|
| 197 |
args["baidu_api_settings"]["api_id"] = baidu_api_id
|
|
@@ -201,8 +241,8 @@ def submit_api(baidu_api_id, baidu_api_key, from_lang, to_lang, openai_api_key,p
|
|
| 201 |
args["baidu_api_settings"]["from_lang"] = from_lang
|
| 202 |
if to_lang != "":
|
| 203 |
args["baidu_api_settings"]["to_lang"] = to_lang
|
| 204 |
-
if
|
| 205 |
-
args["
|
| 206 |
args["openai_api_settings"]["prompt_prefix"] = prefix
|
| 207 |
args["openai_api_settings"]["prompt_postfix"] = postfix
|
| 208 |
args["target_id"] = target_id
|
|
@@ -368,23 +408,23 @@ shortcut_js = """
|
|
| 368 |
<script>
|
| 369 |
function shortcuts(e) {
|
| 370 |
|
| 371 |
-
if (e.key.toLowerCase() == "s" && e.
|
| 372 |
document.getElementById("button_save").click();
|
| 373 |
}
|
| 374 |
-
if (e.key.toLowerCase() == "w" && e.
|
| 375 |
document.getElementById("button_up").click();
|
| 376 |
}
|
| 377 |
-
if (e.key.toLowerCase() == "x" && e.
|
| 378 |
document.getElementById("button_down").click();
|
| 379 |
}
|
| 380 |
-
if (e.key.toLowerCase() == "r" && e.
|
| 381 |
document.getElementById("button_replace").click();
|
| 382 |
}
|
| 383 |
-
if (e.key.toLowerCase() == "
|
| 384 |
-
document.getElementById("
|
| 385 |
}
|
| 386 |
-
if (e.key.toLowerCase() == "
|
| 387 |
-
document.getElementById("
|
| 388 |
}
|
| 389 |
|
| 390 |
}
|
|
@@ -393,13 +433,13 @@ document.addEventListener('keyup', shortcuts, false);
|
|
| 393 |
"""
|
| 394 |
|
| 395 |
with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo:
|
| 396 |
-
gr.Markdown("# <center>EasyTranslator v1.0
|
| 397 |
# 文本编辑页
|
| 398 |
with gr.Tab("文本编辑"):
|
| 399 |
gr.Markdown("## 文本编辑及保存区")
|
| 400 |
with gr.Row():
|
| 401 |
-
text_file_path = gr.Textbox(label = "File Path", value = args["file_path"])
|
| 402 |
-
text_id = gr.Textbox(label = "Text id",show_copy_button=True)
|
| 403 |
button_load_pos = gr.Button("LOAD last edited position")
|
| 404 |
if not if_save_id_immediately:
|
| 405 |
button_save_pos = gr.Button("SAVE last edited position")
|
|
@@ -407,18 +447,21 @@ with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo:
|
|
| 407 |
if not moyu_mode:
|
| 408 |
# 全屏mode
|
| 409 |
with gr.Column():
|
| 410 |
-
text_name = gr.Textbox(label = "Name")
|
| 411 |
-
text_text = gr.Textbox(label = "Text", lines=10,show_copy_button=True)
|
| 412 |
-
button_save = gr.Button("SAVE FILE",scale= 2,elem_id = "button_save")
|
|
|
|
|
|
|
|
|
|
| 413 |
with gr.Column():
|
| 414 |
-
text_name_cn = gr.Textbox(label = "Name_CN")
|
| 415 |
with gr.Row():
|
| 416 |
-
|
| 417 |
-
|
| 418 |
with gr.Row():
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
text_final = gr.Textbox(label = "Text_CN", lines=3,show_copy_button=True,interactive = True)
|
| 422 |
with gr.Row():
|
| 423 |
button_up = gr.Button("↑",elem_id = "button_up")
|
| 424 |
button_down = gr.Button("↓",elem_id = "button_down")
|
|
@@ -426,32 +469,35 @@ with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo:
|
|
| 426 |
else:
|
| 427 |
# 摸鱼mode
|
| 428 |
with gr.Column():
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
|
|
|
| 432 |
with gr.Column():
|
| 433 |
with gr.Row():
|
| 434 |
-
|
| 435 |
-
|
| 436 |
with gr.Row():
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
text_text = gr.Textbox(label = "Text", lines=3,show_copy_button=True)
|
| 440 |
-
text_final = gr.Textbox(label = "Text_CN", lines=3,show_copy_button=True,interactive = True)
|
| 441 |
with gr.Row():
|
| 442 |
-
button_up = gr.Button("↑")
|
| 443 |
-
button_down = gr.Button("↓")
|
| 444 |
-
button_replace = gr.Button("Replace")
|
|
|
|
|
|
|
| 445 |
label_remaining_text = gr.Label(label="进度",value = "目标剩余???条")
|
| 446 |
gr.Markdown("## 批量机翻区")
|
| 447 |
with gr.Row():
|
| 448 |
text_translate_start_id = gr.Textbox(label = "起始句id")
|
| 449 |
text_translate_end_id = gr.Textbox(label = "结束句id")
|
| 450 |
with gr.Row():
|
| 451 |
-
|
| 452 |
label_progress = gr.Label(label = "进度条",value="")
|
| 453 |
-
checkbox_if_save_translation = gr.Checkbox(value= False, label = "
|
| 454 |
-
button_batch_translate = gr.Button("
|
| 455 |
|
| 456 |
tab_context = gr.Tab("文本预览及导出")
|
| 457 |
with tab_context:
|
|
@@ -459,14 +505,14 @@ with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo:
|
|
| 459 |
with gr.Row():
|
| 460 |
with gr.Column():
|
| 461 |
with gr.Row():
|
| 462 |
-
text_refresh_id = gr.Textbox(label = "
|
| 463 |
text_context_length = gr.Textbox(label = "上下文长度", value = args["context_half_length"])
|
| 464 |
radio_context_type = gr.Radio(choices = ["上下文","上文", "下文"], label = "预览模式",value="下文")
|
| 465 |
with gr.Column():
|
| 466 |
with gr.Row():
|
| 467 |
button_refresh = gr.Button("Refresh")
|
| 468 |
button_save_context = gr.Button("Save Changes")
|
| 469 |
-
checkbox_if_save_context = gr.Checkbox(value= False, label = "
|
| 470 |
dataframe_context = gr.DataFrame(headers=['id','name','name_CN','text','text_CN'],
|
| 471 |
interactive=True)
|
| 472 |
gr.Markdown("## 文档导出区")
|
|
@@ -498,9 +544,10 @@ with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo:
|
|
| 498 |
gr.Markdown("## JSON to CSV(支持批量上传)")
|
| 499 |
with gr.Row():
|
| 500 |
with gr.Column():
|
| 501 |
-
file_target_json = gr.File(file_types=["json"],file_count = "multiple",label="Input JSON")
|
| 502 |
button_convert2csv = gr.Button("Convert")
|
| 503 |
-
file_result_csv = gr.File(file_types=["
|
|
|
|
| 504 |
# 文件合并页
|
| 505 |
with gr.Tab("文件合并"):
|
| 506 |
gr.Markdown("## 合并JSON文件")
|
|
@@ -509,8 +556,8 @@ with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo:
|
|
| 509 |
若起止id顺序颠倒或不存在,按钮不会作用。请仔细检查并做好备份!!")
|
| 510 |
with gr.Column():
|
| 511 |
|
| 512 |
-
text_merged_path = gr.Textbox(label = "File Path", value = args["file_path"])
|
| 513 |
-
file_merging_json = gr.File(file_types=["json"],file_count = "single", label="File to be merged")
|
| 514 |
with gr.Row():
|
| 515 |
text_merge_start_id = gr.Textbox(label="起始句id",value = "")
|
| 516 |
text_merge_end_id = gr.Textbox(label="结束句id",value = "")
|
|
@@ -531,28 +578,33 @@ with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo:
|
|
| 531 |
|
| 532 |
# API设置页
|
| 533 |
with gr.Tab("API Settings"):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 534 |
gr.Markdown("## 百度 API")
|
| 535 |
-
|
| 536 |
-
|
| 537 |
with gr.Row():
|
| 538 |
text_from_lang = gr.Textbox(label="From Lang",value = args["baidu_api_settings"]["from_lang"])
|
| 539 |
text_to_lang = gr.Textbox(label="To Lang",value = args["baidu_api_settings"]["to_lang"])
|
| 540 |
-
gr.Markdown("## OPENAI API")
|
| 541 |
-
text_openai_api = gr.Textbox(label="OPENAI API Key",value = args["openai_api_settings"]["openai_api_key"])
|
| 542 |
-
with gr.Row():
|
| 543 |
-
text_prefix = gr.Textbox(label="Prompt Prefix",value = args["openai_api_settings"]["prompt_prefix"])
|
| 544 |
-
text_postfix = gr.Textbox(label="Prompt Postfix",value = args["openai_api_settings"]["prompt_postfix"])
|
| 545 |
-
gr.Markdown("## 目标id")
|
| 546 |
-
text_target_id = gr.Textbox(label="Target Id",value = args["target_id"])
|
| 547 |
button_api_submit = gr.Button("Submit")
|
| 548 |
|
| 549 |
-
|
| 550 |
# 标签页行为
|
| 551 |
tab_context.select(refresh_context, inputs=[text_id,text_context_length,radio_context_type],outputs=[dataframe_context,text_refresh_id])
|
| 552 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 553 |
# 文本框行为
|
| 554 |
-
text_id.change(change_id, inputs = [text_id],
|
| 555 |
-
outputs = [text_file_path,text_text,text_name,text_name_cn,
|
| 556 |
text_id.change(get_remaining_text_num,inputs = None, outputs= [label_remaining_text])
|
| 557 |
text_final.change(change_final,inputs = [text_final,text_id])
|
| 558 |
text_name_cn.change(change_name,inputs = [text_name,text_name_cn,text_id])
|
|
@@ -564,16 +616,16 @@ with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo:
|
|
| 564 |
button_save_pos.click(save_last_position, inputs = [text_id])
|
| 565 |
button_up.click(last_text, outputs = text_id)
|
| 566 |
button_down.click(next_text, outputs = text_id)
|
| 567 |
-
|
| 568 |
-
inputs=[text_text,text_id], outputs=
|
| 569 |
-
|
| 570 |
-
inputs=[text_text,text_id], outputs=
|
| 571 |
button_replace.click(replace,
|
| 572 |
-
inputs = [
|
| 573 |
-
outputs=[
|
| 574 |
button_save.click(save_json)
|
| 575 |
|
| 576 |
-
button_batch_translate.click(batch_translate, inputs = [
|
| 577 |
outputs = [label_progress])
|
| 578 |
|
| 579 |
# -预览及导出页
|
|
@@ -598,8 +650,8 @@ with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo:
|
|
| 598 |
|
| 599 |
# -API管理页
|
| 600 |
button_api_submit.click(submit_api,
|
| 601 |
-
inputs = [
|
| 602 |
-
|
| 603 |
|
| 604 |
demo.queue()
|
| 605 |
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
+
import os
|
| 3 |
from os import path as osp
|
| 4 |
import json
|
| 5 |
from utils import *
|
|
|
|
| 10 |
# idx指代顺序排列的序号,0,1,2,...
|
| 11 |
config_path = osp.join(osp.dirname(osp.abspath(__file__)),"./config.json")
|
| 12 |
args = load_config(config_path)
|
| 13 |
+
|
| 14 |
+
model_list = list(MODEL_NAME_DICT.keys()) + ["gpt3","baidu"]
|
| 15 |
+
for key, value in args["API_KEYS"].items():
|
| 16 |
+
if "API_KEY" in key and "YOUR" not in value:
|
| 17 |
+
os.environ[key] = value
|
| 18 |
+
|
| 19 |
if_save_id_immediately = True if int(args["if_save_id_immediately"]) else False
|
| 20 |
moyu_mode = True if int(args["moyu_mode"]) else False
|
| 21 |
path = args["file_path"]
|
|
|
|
| 23 |
replace_dict_path = smart_path(args["replace_dict_path"])
|
| 24 |
name_dict_path = smart_path(args["name_dict_path"])
|
| 25 |
altered_text_finals= set()
|
| 26 |
+
time_limit = int(args["time_limit"]) if "time_limit" in args and isinstance(args["time_limit"],int) else 10
|
| 27 |
|
| 28 |
if osp.exists(abs_path):
|
| 29 |
with open(abs_path, "r", encoding ="utf8") as json_file:
|
|
|
|
| 58 |
name_dic[item[0]]=item[1]
|
| 59 |
|
| 60 |
# Translate
|
| 61 |
+
def llm_translate(text, text_id, model_name):
|
| 62 |
+
if model_name not in model_list:
|
| 63 |
+
return ""
|
| 64 |
+
if model_name == "baidu":
|
| 65 |
+
return baidu_translate(text,text_id)
|
| 66 |
+
elif model_name == "gpt3":
|
| 67 |
+
return gpt_translate(text,text_id)
|
| 68 |
+
text = text.replace("\n"," ")
|
| 69 |
+
prompt = args["openai_api_settings"]["prompt_prefix"]+text+args["openai_api_settings"]["prompt_postfix"]
|
| 70 |
+
translation, if_succ = get_llm_completion(prompt, time_limit=int(time_limit), model_name=model_name)
|
| 71 |
+
if dic[text_id]["text"].replace("\n"," ") == text and if_succ:
|
| 72 |
+
dic[text_id][model_name] = translation
|
| 73 |
+
save_config(args,config_path)
|
| 74 |
+
return translation
|
| 75 |
+
|
| 76 |
def gpt_translate(text,text_id):
|
| 77 |
text = text.replace("\n"," ")
|
| 78 |
prompt = args["openai_api_settings"]["prompt_prefix"]+text+args["openai_api_settings"]["prompt_postfix"]
|
| 79 |
+
translation, if_succ = get_gpt_completion(prompt, time_limit=int(time_limit))
|
| 80 |
if dic[text_id]["text"].replace("\n"," ") == text and if_succ:
|
| 81 |
dic[text_id]["gpt3"] = translation
|
| 82 |
return translation
|
|
|
|
| 92 |
dic[text_id]["baidu"] = translation
|
| 93 |
return translation
|
| 94 |
|
| 95 |
+
def batch_translate(dropdown_batch_model, check, text_start_id,text_end_id,progress=gr.Progress()):
|
| 96 |
progress(0, desc="Starting...")
|
| 97 |
if text_start_id not in id_lis or text_end_id not in id_lis or idx_dic[text_start_id] > idx_dic[text_end_id]:
|
| 98 |
gr.Warning("找不到指定序号, 或id前后顺序错误")
|
|
|
|
| 100 |
start = idx_dic[text_start_id]
|
| 101 |
end = idx_dic[text_end_id] + 1
|
| 102 |
lis = id_lis[start:end]
|
| 103 |
+
for key in progress.tqdm(lis):
|
| 104 |
+
llm_translate(dic[key]['text'],key,dropdown_batch_model)
|
| 105 |
+
time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
if check:
|
| 107 |
save_json(show_info=False)
|
| 108 |
gr.Info(f"批量机翻成功, 共完成{end-start}句翻译")
|
|
|
|
| 121 |
id_idx += 1
|
| 122 |
return id_lis[id_idx]
|
| 123 |
|
| 124 |
+
def replace(dropbox_model1,dropbox_model2,text_model1,text_model2,text_final,text_id, check_file = True):
|
| 125 |
if not text_id:
|
| 126 |
text_id = id_lis[id_idx]
|
| 127 |
if check_file:
|
|
|
|
| 133 |
replace_dic[item[0]]=item[1]
|
| 134 |
f.close()
|
| 135 |
for key,value in replace_dic.items():
|
| 136 |
+
text_model1 = text_model1.replace(key, value)
|
| 137 |
+
text_model2 = text_model2.replace(key, value)
|
| 138 |
text_final = text_final.replace(key, value)
|
| 139 |
+
dic[text_id][dropbox_model1] = text_model1
|
| 140 |
+
dic[text_id][dropbox_model2] = text_model2
|
| 141 |
dic[text_id]["text_CN"] = text_final
|
| 142 |
+
return text_model1,text_model2,text_final
|
| 143 |
+
|
| 144 |
+
def change_model_name0(text_id, model_name):
|
| 145 |
+
# 改变机翻文本框
|
| 146 |
+
if not text_id or not text_id in idx_dic: return ""
|
| 147 |
+
if model_name not in model_list: return ""
|
| 148 |
+
args["selected_model"][0] = model_name
|
| 149 |
+
if model_name in dic[text_id]:
|
| 150 |
+
return dic[text_id][model_name]
|
| 151 |
+
else:
|
| 152 |
+
return ""
|
| 153 |
+
def change_model_name1(text_id, model_name):
|
| 154 |
+
# 改变机翻文本框
|
| 155 |
+
if not text_id or not text_id in idx_dic: return ""
|
| 156 |
+
if model_name not in model_list: return ""
|
| 157 |
+
args["selected_model"][1] = model_name
|
| 158 |
+
if model_name in dic[text_id]:
|
| 159 |
+
return dic[text_id][model_name]
|
| 160 |
+
else:
|
| 161 |
+
return ""
|
| 162 |
|
| 163 |
+
def change_id(text_id, dropbox_model1, dropbox_model2):
|
| 164 |
if not text_id or text_id not in idx_dic: return args["file_path"],"","","","","",""
|
| 165 |
global id_idx
|
| 166 |
id_idx = idx_dic[text_id]
|
| 167 |
+
if dropbox_model1 not in dic[text_id]:
|
| 168 |
+
dic[text_id][dropbox_model1] = ""
|
| 169 |
+
if dropbox_model2 not in dic[text_id]:
|
| 170 |
+
dic[text_id][dropbox_model2] = ""
|
| 171 |
if "text_CN" not in dic[text_id]:
|
| 172 |
dic[text_id]["text_CN"] = ""
|
| 173 |
if dic[text_id]["name"] not in name_dic:
|
| 174 |
name_dic[dic[text_id]["name"]] = dic[text_id]["name"]
|
| 175 |
dic[text_id]["name_CN"] = name_dic[dic[text_id]["name"]]
|
| 176 |
+
replace(dropbox_model1, dropbox_model2, dic[text_id][dropbox_model1],dic[text_id][dropbox_model2],dic[text_id]["text_CN"],text_id,False)
|
| 177 |
+
args["selected_model"] = [dropbox_model1, dropbox_model2]
|
| 178 |
if if_save_id_immediately:
|
| 179 |
args["last_edited_id"] = text_id
|
| 180 |
save_config(args,config_path)
|
| 181 |
return args["file_path"],dic[text_id]["text"],dic[text_id]["name"],name_dic[dic[text_id]["name"]],\
|
| 182 |
+
dic[text_id][dropbox_model1],dic[text_id][dropbox_model2],dic[text_id]["text_CN"]
|
| 183 |
|
| 184 |
def change_final(text,text_id):
|
| 185 |
if not text_id or not text_id in idx_dic: return
|
|
|
|
| 194 |
dic[text_id]["name_CN"] = name_cn
|
| 195 |
return
|
| 196 |
|
| 197 |
+
def change_apikey(dropdown_apikey):
|
| 198 |
+
return args["API_KEYS"][dropdown_apikey] if dropdown_apikey in args["API_KEYS"] else ""
|
| 199 |
+
|
| 200 |
def save_json(show_info = True):
|
| 201 |
global altered_text_finals
|
| 202 |
with open(abs_path, "w", encoding ="utf8") as json_file:
|
|
|
|
| 231 |
save_config(args,config_path)
|
| 232 |
return args["last_edited_id"]
|
| 233 |
|
| 234 |
+
def submit_api(baidu_api_id, baidu_api_key, from_lang, to_lang, dropdown_apikey,text_apikey,prefix,postfix,target_id):
|
| 235 |
global args
|
| 236 |
if baidu_api_id != "":
|
| 237 |
args["baidu_api_settings"]["api_id"] = baidu_api_id
|
|
|
|
| 241 |
args["baidu_api_settings"]["from_lang"] = from_lang
|
| 242 |
if to_lang != "":
|
| 243 |
args["baidu_api_settings"]["to_lang"] = to_lang
|
| 244 |
+
if text_apikey != "":
|
| 245 |
+
args["API_KEYS"][dropdown_apikey] = text_apikey
|
| 246 |
args["openai_api_settings"]["prompt_prefix"] = prefix
|
| 247 |
args["openai_api_settings"]["prompt_postfix"] = postfix
|
| 248 |
args["target_id"] = target_id
|
|
|
|
| 408 |
<script>
|
| 409 |
function shortcuts(e) {
|
| 410 |
|
| 411 |
+
if (e.key.toLowerCase() == "s" && e.altKey) {
|
| 412 |
document.getElementById("button_save").click();
|
| 413 |
}
|
| 414 |
+
if (e.key.toLowerCase() == "w" && e.altKey) {
|
| 415 |
document.getElementById("button_up").click();
|
| 416 |
}
|
| 417 |
+
if (e.key.toLowerCase() == "x" && e.altKey) {
|
| 418 |
document.getElementById("button_down").click();
|
| 419 |
}
|
| 420 |
+
if (e.key.toLowerCase() == "r" && e.altKey) {
|
| 421 |
document.getElementById("button_replace").click();
|
| 422 |
}
|
| 423 |
+
if (e.key.toLowerCase() == "q" && e.altKey) {
|
| 424 |
+
document.getElementById("button_translate_model1").click();
|
| 425 |
}
|
| 426 |
+
if (e.key.toLowerCase() == "e" && e.altKey) {
|
| 427 |
+
document.getElementById("button_translate_model2").click();
|
| 428 |
}
|
| 429 |
|
| 430 |
}
|
|
|
|
| 433 |
"""
|
| 434 |
|
| 435 |
with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo:
|
| 436 |
+
gr.Markdown("# <center>EasyTranslator v1.1.0</center> ",visible=True)
|
| 437 |
# 文本编辑页
|
| 438 |
with gr.Tab("文本编辑"):
|
| 439 |
gr.Markdown("## 文本编辑及保存区")
|
| 440 |
with gr.Row():
|
| 441 |
+
text_file_path = gr.Textbox(label = "File Path - 数据文件JSON路径", value = args["file_path"])
|
| 442 |
+
text_id = gr.Textbox(label = "Text id - 当前文本id",show_copy_button=True)
|
| 443 |
button_load_pos = gr.Button("LOAD last edited position")
|
| 444 |
if not if_save_id_immediately:
|
| 445 |
button_save_pos = gr.Button("SAVE last edited position")
|
|
|
|
| 447 |
if not moyu_mode:
|
| 448 |
# 全屏mode
|
| 449 |
with gr.Column():
|
| 450 |
+
text_name = gr.Textbox(label = "Name - 原文人名")
|
| 451 |
+
text_text = gr.Textbox(label = "Text - 原文文本", lines=10,show_copy_button=True)
|
| 452 |
+
button_save = gr.Button("SAVE JSON FILE",scale= 2,elem_id = "button_save")
|
| 453 |
+
dropdown_model1 = gr.Dropdown(choices=model_list,value=args["selected_model"][0], label = "Choose Model1 - 选择模型1",interactive=True)
|
| 454 |
+
dropdown_model2 = gr.Dropdown(choices=model_list,value=args["selected_model"][1], label = "Choose Model2 - 选择模型2",interactive=True)
|
| 455 |
+
|
| 456 |
with gr.Column():
|
| 457 |
+
text_name_cn = gr.Textbox(label = "Name_CN - 译文人名")
|
| 458 |
with gr.Row():
|
| 459 |
+
text_model1 = gr.Textbox(label="Model1 - 模型1译文",lines=3,show_copy_button=True,interactive = True)
|
| 460 |
+
button_translate_model1 = gr.Button("Translate(Model1)",elem_id = "button_translate_model1")
|
| 461 |
with gr.Row():
|
| 462 |
+
text_model2 = gr.Textbox(label="Model2 - 模型2译文",lines=3,show_copy_button=True,interactive = True)
|
| 463 |
+
button_translate_model2 = gr.Button("Translate(Model2)",elem_id = "button_translate_model2")
|
| 464 |
+
text_final = gr.Textbox(label = "Text_CN - 人工译文", lines=3,show_copy_button=True,interactive = True)
|
| 465 |
with gr.Row():
|
| 466 |
button_up = gr.Button("↑",elem_id = "button_up")
|
| 467 |
button_down = gr.Button("↓",elem_id = "button_down")
|
|
|
|
| 469 |
else:
|
| 470 |
# 摸鱼mode
|
| 471 |
with gr.Column():
|
| 472 |
+
dropdown_model1 = gr.Dropdown(choices=model_list,value=args["selected_model"][0], label = "Choose Model1 - 选择模型1",interactive=True)
|
| 473 |
+
dropdown_model2 = gr.Dropdown(choices=model_list,value=args["selected_model"][1], label = "Choose Model2 - 选择模型2",interactive=True)
|
| 474 |
+
text_name = gr.Textbox(label = "Name - 原文人名")
|
| 475 |
+
text_name_cn = gr.Textbox(label = "Name_CN - 译文人名")
|
| 476 |
with gr.Column():
|
| 477 |
with gr.Row():
|
| 478 |
+
text_model1 = gr.Textbox(label="Model1 - 模型1译文",lines=3,show_copy_button=True,interactive = True)
|
| 479 |
+
button_translate_model1 = gr.Button("Translate(Model1)",elem_id = "button_translate_model1")
|
| 480 |
with gr.Row():
|
| 481 |
+
text_model2 = gr.Textbox(label="Model2 - 模型2译文",lines=3,show_copy_button=True,interactive = True)
|
| 482 |
+
button_translate_model2 = gr.Button("Translate(Model2)",elem_id = "button_translate_model2")
|
| 483 |
+
text_text = gr.Textbox(label = "Text - 原文文本", lines=3,show_copy_button=True)
|
| 484 |
+
text_final = gr.Textbox(label = "Text_CN - 人工译文", lines=3,show_copy_button=True,interactive = True)
|
| 485 |
with gr.Row():
|
| 486 |
+
button_up = gr.Button("↑",elem_id = "button_up")
|
| 487 |
+
button_down = gr.Button("↓",elem_id = "button_down")
|
| 488 |
+
button_replace = gr.Button("Replace",elem_id = "button_replace")
|
| 489 |
+
button_save = gr.Button("SAVE JSON FILE",scale= 2,elem_id = "button_save")
|
| 490 |
+
|
| 491 |
label_remaining_text = gr.Label(label="进度",value = "目标剩余???条")
|
| 492 |
gr.Markdown("## 批量机翻区")
|
| 493 |
with gr.Row():
|
| 494 |
text_translate_start_id = gr.Textbox(label = "起始句id")
|
| 495 |
text_translate_end_id = gr.Textbox(label = "结束句id")
|
| 496 |
with gr.Row():
|
| 497 |
+
dropdown_model_batch = gr.Dropdown(choices=model_list,value=args["selected_model"][0], label = "批量翻译模型选择",interactive=True)
|
| 498 |
label_progress = gr.Label(label = "进度条",value="")
|
| 499 |
+
checkbox_if_save_translation = gr.Checkbox(value= False, label = "翻译完成后直接保存文件")
|
| 500 |
+
button_batch_translate = gr.Button("开始批量翻译")
|
| 501 |
|
| 502 |
tab_context = gr.Tab("文本预览及导出")
|
| 503 |
with tab_context:
|
|
|
|
| 505 |
with gr.Row():
|
| 506 |
with gr.Column():
|
| 507 |
with gr.Row():
|
| 508 |
+
text_refresh_id = gr.Textbox(label = "Text id - 当前文本id", value = args["last_edited_id"])
|
| 509 |
text_context_length = gr.Textbox(label = "上下文长度", value = args["context_half_length"])
|
| 510 |
radio_context_type = gr.Radio(choices = ["上下文","上文", "下文"], label = "预览模式",value="下文")
|
| 511 |
with gr.Column():
|
| 512 |
with gr.Row():
|
| 513 |
button_refresh = gr.Button("Refresh")
|
| 514 |
button_save_context = gr.Button("Save Changes")
|
| 515 |
+
checkbox_if_save_context = gr.Checkbox(value= False, label = "修改直接存入json文件")
|
| 516 |
dataframe_context = gr.DataFrame(headers=['id','name','name_CN','text','text_CN'],
|
| 517 |
interactive=True)
|
| 518 |
gr.Markdown("## 文档导出区")
|
|
|
|
| 544 |
gr.Markdown("## JSON to CSV(支持批量上传)")
|
| 545 |
with gr.Row():
|
| 546 |
with gr.Column():
|
| 547 |
+
file_target_json = gr.File(file_types=[".json"],file_count = "multiple",label="Input JSON")
|
| 548 |
button_convert2csv = gr.Button("Convert")
|
| 549 |
+
file_result_csv = gr.File(file_types=[".csv"],label="Output CSV",interactive=False)
|
| 550 |
+
|
| 551 |
# 文件合并页
|
| 552 |
with gr.Tab("文件合并"):
|
| 553 |
gr.Markdown("## 合并JSON文件")
|
|
|
|
| 556 |
若起止id顺序颠倒或不存在,按钮不会作用。请仔细检查并做好备份!!")
|
| 557 |
with gr.Column():
|
| 558 |
|
| 559 |
+
text_merged_path = gr.Textbox(label = "File Path - 被覆盖的文件地址", value = args["file_path"])
|
| 560 |
+
file_merging_json = gr.File(file_types=["json"],file_count = "single", label="File to be merged - 用于覆盖的文件")
|
| 561 |
with gr.Row():
|
| 562 |
text_merge_start_id = gr.Textbox(label="起始句id",value = "")
|
| 563 |
text_merge_end_id = gr.Textbox(label="结束句id",value = "")
|
|
|
|
| 578 |
|
| 579 |
# API设置页
|
| 580 |
with gr.Tab("API Settings"):
|
| 581 |
+
gr.Markdown("## 目标id")
|
| 582 |
+
text_target_id = gr.Textbox(label="Target Id",value = args["target_id"])
|
| 583 |
+
gr.Markdown("## API KEY")
|
| 584 |
+
dropdown_apikey = gr.Dropdown(list(args["API_KEYS"].keys()), value="OPENAI_API_KEY",label = "填写API KEY",interactive=True)
|
| 585 |
+
text_apikey = gr.Textbox(label="API KEY",value = args["API_KEYS"]["OPENAI_API_KEY"])
|
| 586 |
+
with gr.Row():
|
| 587 |
+
text_prefix = gr.Textbox(label="Prompt Prefix",value = args["openai_api_settings"]["prompt_prefix"])
|
| 588 |
+
text_postfix = gr.Textbox(label="Prompt Postfix",value = args["openai_api_settings"]["prompt_postfix"])
|
| 589 |
gr.Markdown("## 百度 API")
|
| 590 |
+
text_model2_api_id = gr.Textbox(label="Baidu API Id",value = args["baidu_api_settings"]["api_id"])
|
| 591 |
+
text_model2_api_key = gr.Textbox(label="Baidu API Key", value = args["baidu_api_settings"]["api_key"])
|
| 592 |
with gr.Row():
|
| 593 |
text_from_lang = gr.Textbox(label="From Lang",value = args["baidu_api_settings"]["from_lang"])
|
| 594 |
text_to_lang = gr.Textbox(label="To Lang",value = args["baidu_api_settings"]["to_lang"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 595 |
button_api_submit = gr.Button("Submit")
|
| 596 |
|
|
|
|
| 597 |
# 标签页行为
|
| 598 |
tab_context.select(refresh_context, inputs=[text_id,text_context_length,radio_context_type],outputs=[dataframe_context,text_refresh_id])
|
| 599 |
|
| 600 |
+
# 下拉选框行为
|
| 601 |
+
dropdown_model1.change(change_model_name0, inputs = [text_id,dropdown_model1], outputs=[text_model1])
|
| 602 |
+
dropdown_model2.change(change_model_name1, inputs = [text_id,dropdown_model2], outputs=[text_model2])
|
| 603 |
+
dropdown_apikey.change(change_apikey, inputs=[dropdown_apikey], outputs=[text_apikey])
|
| 604 |
+
|
| 605 |
# 文本框行为
|
| 606 |
+
text_id.change(change_id, inputs = [text_id,dropdown_model1,dropdown_model2],
|
| 607 |
+
outputs = [text_file_path,text_text,text_name,text_name_cn,text_model1,text_model2,text_final])
|
| 608 |
text_id.change(get_remaining_text_num,inputs = None, outputs= [label_remaining_text])
|
| 609 |
text_final.change(change_final,inputs = [text_final,text_id])
|
| 610 |
text_name_cn.change(change_name,inputs = [text_name,text_name_cn,text_id])
|
|
|
|
| 616 |
button_save_pos.click(save_last_position, inputs = [text_id])
|
| 617 |
button_up.click(last_text, outputs = text_id)
|
| 618 |
button_down.click(next_text, outputs = text_id)
|
| 619 |
+
button_translate_model1.click(llm_translate,
|
| 620 |
+
inputs=[text_text, text_id, dropdown_model1], outputs=text_model1)
|
| 621 |
+
button_translate_model2.click(llm_translate,
|
| 622 |
+
inputs=[text_text, text_id, dropdown_model2], outputs=text_model2)
|
| 623 |
button_replace.click(replace,
|
| 624 |
+
inputs = [dropdown_model1,dropdown_model2,text_model1,text_model2,text_final,text_id],
|
| 625 |
+
outputs=[text_model1,text_model2,text_final])
|
| 626 |
button_save.click(save_json)
|
| 627 |
|
| 628 |
+
button_batch_translate.click(batch_translate, inputs = [dropdown_model_batch,checkbox_if_save_translation,text_translate_start_id,text_translate_end_id],
|
| 629 |
outputs = [label_progress])
|
| 630 |
|
| 631 |
# -预览及导出页
|
|
|
|
| 650 |
|
| 651 |
# -API管理页
|
| 652 |
button_api_submit.click(submit_api,
|
| 653 |
+
inputs = [text_model2_api_id,text_model2_api_key,text_from_lang,text_to_lang,
|
| 654 |
+
dropdown_apikey,text_apikey,text_prefix,text_postfix,text_target_id])
|
| 655 |
|
| 656 |
demo.queue()
|
| 657 |
|
config.json
CHANGED
|
@@ -1,30 +1,43 @@
|
|
| 1 |
{
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
{
|
| 2 |
+
"moyu_mode": "1",
|
| 3 |
+
"if_save_id_immediately": "1",
|
| 4 |
+
"last_edited_id": "100001002",
|
| 5 |
+
"target_id": "100001005",
|
| 6 |
+
"file_path": "./example_text.json",
|
| 7 |
+
"context_half_length": "10",
|
| 8 |
+
"name_dict_path": "./example_name_dict.json",
|
| 9 |
+
"replace_dict_path": "./example_replace_dict.json",
|
| 10 |
+
"output_txt_path": "./output.txt",
|
| 11 |
+
"seperator_long": "===============================",
|
| 12 |
+
"seperator_short": "---------------------",
|
| 13 |
+
"csv_column_name": {
|
| 14 |
+
"id": "",
|
| 15 |
+
"text": "text",
|
| 16 |
+
"name": "name"
|
| 17 |
+
},
|
| 18 |
+
"selected_model": [
|
| 19 |
+
"baidu",
|
| 20 |
+
"gpt3"
|
| 21 |
+
],
|
| 22 |
+
"baidu_api_settings": {
|
| 23 |
+
"api_id": "YOUR BAIDU API ID",
|
| 24 |
+
"api_key": "YOUR BAIDU API KEY",
|
| 25 |
+
"from_lang": "jp",
|
| 26 |
+
"to_lang": "zh"
|
| 27 |
+
},
|
| 28 |
+
"openai_api_settings": {
|
| 29 |
+
"openai_api_key": "YOUR OPENAI API KEY",
|
| 30 |
+
"prompt_prefix": "将以下文字翻译为中文:",
|
| 31 |
+
"prompt_postfix": "",
|
| 32 |
+
"time_limit": 15
|
| 33 |
+
},
|
| 34 |
+
"API_KEYS": {
|
| 35 |
+
"OPENAI_API_KEY": "YOUR OPENAI API KEY (https://platform.openai.com/docs/overview)",
|
| 36 |
+
"GEMINI_API_KEY": "YOUR GEMINI API KEY (https://ai.google.dev/gemini-api/)",
|
| 37 |
+
"DASHSCOPE_API_KEY": "YOUR QWEN API KEY (https://help.aliyun.com/zh/model-studio/)",
|
| 38 |
+
"DEEPSEEK_API_KEY": "YOUR DEEPSEEK API KEY (https://api-docs.deepseek.com/)",
|
| 39 |
+
"ANTHROPIC_API_KEY": "YOUR CLAUDE API KEY (https://www.anthropic.com/api)",
|
| 40 |
+
"ARK_API_KEY": "YOUR DOUBAO API KEY (https://www.volcengine.com/product/doubao)",
|
| 41 |
+
"OPENROUTER_API_KEY": "YOUR OPENROUTER API KEY (https://openrouter.ai/)"
|
| 42 |
+
}
|
| 43 |
+
}
|
requirements.txt
CHANGED
|
@@ -1 +1,2 @@
|
|
| 1 |
-
|
|
|
|
|
|
| 1 |
+
gradio>=5.16.0
|
| 2 |
+
openai>=1.63.0
|
themes.py
CHANGED
|
@@ -46,9 +46,8 @@ class Theme1(Base):
|
|
| 46 |
super().set(
|
| 47 |
input_background_fill="*neutral_100",
|
| 48 |
block_title_text_weight="600",
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
# button_secondary_background_fill_hover="*neutral_300",
|
| 53 |
)
|
| 54 |
|
|
|
|
| 46 |
super().set(
|
| 47 |
input_background_fill="*neutral_100",
|
| 48 |
block_title_text_weight="600",
|
| 49 |
+
block_border_width="3px",
|
| 50 |
+
button_large_padding="32px",
|
| 51 |
+
button_secondary_background_fill_hover="*neutral_300",
|
|
|
|
| 52 |
)
|
| 53 |
|