import gradio as gr import os from os import path as osp import json from utils import * from themes import * # Initialization # id指代台词的编号,为一个字符串 # idx指代顺序排列的序号,0,1,2,... config_path = osp.join(osp.dirname(osp.abspath(__file__)),"./config.json") args = load_config(config_path) model_list = list(MODEL_NAME_DICT.keys()) + ["gpt3","baidu"] for key, value in args["API_KEYS"].items(): if "API_KEY" in key and "YOUR" not in value: os.environ[key] = value if_save_id_immediately = True if int(args["if_save_id_immediately"]) else False moyu_mode = True if int(args["moyu_mode"]) else False path = args["file_path"] abs_path = smart_path(path) replace_dict_path = smart_path(args["replace_dict_path"]) name_dict_path = smart_path(args["name_dict_path"]) altered_text_finals= set() time_limit = int(args["time_limit"]) if "time_limit" in args and isinstance(args["time_limit"],int) else 10 if osp.exists(abs_path): with open(abs_path, "r", encoding ="utf8") as json_file: dic = json.load(json_file) id_lis = list(dic.keys()) idx_dic = dict() for idx,id_ in enumerate(id_lis): idx_dic[id_] = idx id_idx = 0 if args["last_edited_id"] in id_lis: id_idx = idx_dic[args["last_edited_id"]] # Dict for replacement replace_dic = {} if osp.exists(replace_dict_path): with open(replace_dict_path, "r", encoding="utf-8") as f: for line in f: if not line:continue item = line.split(" ") item[1] = item[1].replace("\n","") replace_dic[item[0]]=item[1] f.close() # Dict for name name_dic = {} if osp.exists(name_dict_path): with open(name_dict_path, "r", encoding="utf-8") as f: for line in f: if not line:continue item = line.split(" ") item[1] = item[1].replace("\n","") name_dic[item[0]]=item[1] # Translate def llm_translate(text, text_id, model_name): if model_name not in model_list: return "" if model_name == "baidu": return baidu_translate(text,text_id) elif model_name == "gpt3": return gpt_translate(text,text_id) text = text.replace("\n"," ") prompt = args["openai_api_settings"]["prompt_prefix"]+text+args["openai_api_settings"]["prompt_postfix"] translation, if_succ = get_llm_completion(prompt, time_limit=int(time_limit), model_name=model_name) if dic[text_id]["text"].replace("\n"," ") == text and if_succ: dic[text_id][model_name] = translation save_config(args,config_path) return translation def gpt_translate(text,text_id): text = text.replace("\n"," ") prompt = args["openai_api_settings"]["prompt_prefix"]+text+args["openai_api_settings"]["prompt_postfix"] translation, if_succ = get_gpt_completion(prompt, time_limit=int(time_limit)) if dic[text_id]["text"].replace("\n"," ") == text and if_succ: dic[text_id]["gpt3"] = translation return translation def baidu_translate(text,text_id): text = text.replace("\n"," ") translation = get_baidu_completion(text, api_id = args["baidu_api_settings"]["api_id"], api_key = args["baidu_api_settings"]["api_key"], from_lang=args["baidu_api_settings"]["from_lang"], to_lang=args["baidu_api_settings"]["to_lang"],) if dic[text_id]["text"].replace("\n"," ") == text: dic[text_id]["baidu"] = translation return translation def batch_translate(dropdown_batch_model, check, text_start_id,text_end_id,progress=gr.Progress()): progress(0, desc="Starting...") 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]: gr.Warning("找不到指定序号, 或id前后顺序错误") return start = idx_dic[text_start_id] end = idx_dic[text_end_id] + 1 lis = id_lis[start:end] for key in progress.tqdm(lis): llm_translate(dic[key]['text'],key,dropdown_batch_model) time.sleep(0.05) if check: save_json(show_info=False) gr.Info(f"批量机翻成功, 共完成{end-start}句翻译") return f"已完成{end-start}句翻译" # Other actions def last_text(): global id_idx if id_idx > 0: id_idx -= 1 return id_lis[id_idx] def next_text(): global id_idx if id_idx < len(id_lis)-1: id_idx += 1 return id_lis[id_idx] def replace(dropbox_model1,dropbox_model2,text_model1,text_model2,text_final,text_id, check_file = True): if not text_id: text_id = id_lis[id_idx] if check_file: if osp.exists(replace_dict_path): with open(replace_dict_path, "r", encoding="utf-8") as f: for line in f: item = line.split(" ") item[1] = item[1].replace("\n","") replace_dic[item[0]]=item[1] f.close() for key,value in replace_dic.items(): text_model1 = text_model1.replace(key, value) text_model2 = text_model2.replace(key, value) text_final = text_final.replace(key, value) dic[text_id][dropbox_model1] = text_model1 dic[text_id][dropbox_model2] = text_model2 dic[text_id]["text_CN"] = text_final return text_model1,text_model2,text_final def change_model_name0(text_id, model_name): # 改变机翻文本框 if not text_id or not text_id in idx_dic: return "" if model_name not in model_list: return "" args["selected_model"][0] = model_name if model_name in dic[text_id]: return dic[text_id][model_name] else: return "" def change_model_name1(text_id, model_name): # 改变机翻文本框 if not text_id or not text_id in idx_dic: return "" if model_name not in model_list: return "" args["selected_model"][1] = model_name if model_name in dic[text_id]: return dic[text_id][model_name] else: return "" def change_id(text_id, dropbox_model1, dropbox_model2): if not text_id or text_id not in idx_dic: return args["file_path"],"","","","","","" global id_idx id_idx = idx_dic[text_id] if dropbox_model1 not in dic[text_id]: dic[text_id][dropbox_model1] = "" if dropbox_model2 not in dic[text_id]: dic[text_id][dropbox_model2] = "" if "text_CN" not in dic[text_id]: dic[text_id]["text_CN"] = "" if dic[text_id]["name"] not in name_dic: name_dic[dic[text_id]["name"]] = dic[text_id]["name"] dic[text_id]["name_CN"] = name_dic[dic[text_id]["name"]] replace(dropbox_model1, dropbox_model2, dic[text_id][dropbox_model1],dic[text_id][dropbox_model2],dic[text_id]["text_CN"],text_id,False) args["selected_model"] = [dropbox_model1, dropbox_model2] if if_save_id_immediately: args["last_edited_id"] = text_id save_config(args,config_path) return args["file_path"],dic[text_id]["text"],dic[text_id]["name"],name_dic[dic[text_id]["name"]],\ dic[text_id][dropbox_model1],dic[text_id][dropbox_model2],dic[text_id]["text_CN"] def change_final(text,text_id): if not text_id or not text_id in idx_dic: return if text != dic[text_id]["text_CN"]: dic[text_id]["text_CN"] = text altered_text_finals.add(text_id) return def change_name(name,name_cn,text_id): if not text_id or not text_id in idx_dic: return name_dic[name] = name_cn dic[text_id]["name_CN"] = name_cn return def change_apikey(dropdown_apikey): return args["API_KEYS"][dropdown_apikey] if dropdown_apikey in args["API_KEYS"] else "" def save_json(show_info = True): global altered_text_finals with open(abs_path, "w", encoding ="utf8") as json_file: json.dump(dic,json_file,indent = 1,ensure_ascii = False) if osp.exists(name_dict_path): with open(name_dict_path,"w",encoding = "utf-8") as f: for key,value in name_dic.items(): f.write(f"{key} {value}\n") if show_info: gr.Info(f"JSON保存成功, 共更新{len(altered_text_finals)}句译文") altered_text_finals = set() def save_last_position(text_id): args["last_edited_id"] = text_id save_config(args,config_path) return def load_last_position(text_path): global id_idx,id_lis,idx_dic,path,dic if not osp.exists(smart_path(text_path)): raise gr.Error("文件不存在") if path != text_path: path = text_path with open(smart_path(text_path), "r", encoding ="utf8") as json_file: dic = json.load(json_file) id_lis = list(dic.keys()) idx_dic = dict() for idx,id_ in enumerate(id_lis): idx_dic[id_] = idx id_idx = 0 args["file_path"] = path save_config(args,config_path) return args["last_edited_id"] def submit_api(baidu_api_id, baidu_api_key, from_lang, to_lang, dropdown_apikey,text_apikey,prefix,postfix,target_id): global args if baidu_api_id != "": args["baidu_api_settings"]["api_id"] = baidu_api_id if baidu_api_key != "": args["baidu_api_settings"]["api_key"] = baidu_api_key if from_lang != "": args["baidu_api_settings"]["from_lang"] = from_lang if to_lang != "": args["baidu_api_settings"]["to_lang"] = to_lang if text_apikey != "": args["API_KEYS"][dropdown_apikey] = text_apikey args["openai_api_settings"]["prompt_prefix"] = prefix args["openai_api_settings"]["prompt_postfix"] = postfix args["target_id"] = target_id save_config(args,config_path) return def refresh_context(refresh_id,length,context_type): if not refresh_id or not refresh_id in idx_dic: return [],id_lis[id_idx] length = int(length) idx = idx_dic[refresh_id] if context_type == "上下文": ids = id_lis[max(idx-length, 0):idx+length+1] elif context_type == "上文": ids = id_lis[max(idx-length, 0):idx+1] elif context_type == "下文": ids = id_lis[idx:idx+length+1] data = [] for i in ids: if dic[i]["name"] not in name_dic: name_dic[dic[i]["name"]] = dic[i]["name"] dic[i]["name_CN"] = name_dic[dic[i]["name"]] if 'text_CN' not in dic[i]: dic[i]['text_CN'] = "" row = [i, dic[i]['name'],dic[i]['name_CN'], dic[i]['text'],dic[i]['text_CN']] if i == id_lis[idx]: row[0] = f"**{i}**" if i in altered_text_finals: row[4] = f"*{row[4]}" data.append(row) return data,id_lis[id_idx] def save_context(data, refresh_id, if_save = False): altered = 0 for i in range(len(data)): text_id = data['id'][i] text_cn = data['text_CN'][i] text_id = text_id.replace("*","") if text_id in altered_text_finals and text_cn and text_cn[0] == "*": text_cn = text_cn[1:] if dic[text_id]['text_CN'] != text_cn: altered += 1 altered_text_finals.add(text_id) dic[text_id]['text_CN'] = text_cn gr.Info(f"已修改{altered}条译文") if if_save: save_json() return # Derive text def derive_text(radio_type, text_start_id, text_end_id,text_seperator_long,text_seperator_short, output_txt_path): output_txt_path = smart_path(output_txt_path) if output_txt_path[-4:] != ".txt": gr.Warning("输出路径错误") return 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]: gr.Warning("找不到指定序号, 或id前后顺序错误") return start = idx_dic[text_start_id] end = idx_dic[text_end_id] + 1 lis = id_lis[start:end] if radio_type == "双语|人名文本": with open(output_txt_path,"w",encoding="utf-8") as f: for key in lis: # if key[-3:] == "001": # f.write("【"+key[-4]+"】\n") f.write(text_seperator_long+"\n") f.write(dic[key]["name"]+"\n") f.write("\n") f.write(dic[key]["text"]+"\n") f.write("\n") f.write(text_seperator_short+"\n") f.write(dic[key]["name_CN"]+"\n\n") f.write(dic[key]["text_CN"]+"\n") f.write("\n") return if radio_type == "中文|人名文本": with open(output_txt_path,"w",encoding="utf-8") as f: for key in lis: # if key[-3:] == "001": # f.write("【"+key[-4]+"】\n") f.write(text_seperator_long+"\n") f.write(dic[key]["name_CN"]+"\n\n") f.write(dic[key]["text_CN"]+"\n") f.write("\n") return if radio_type == "中文|单次人名文本": with open(output_txt_path,"w",encoding="utf-8") as f: name_lis = [] for key in lis: name = dic[key]["name_CN"] if name not in name_lis: name_lis.append(name) f.write(name + ": "+ dic[key]["text_CN"]+"\n") else: f.write(dic[key]["text_CN"]+"\n") f.write("\n") if radio_type == "中文|纯文本": with open(output_txt_path,"w",encoding="utf-8") as f: for key in lis: f.write(dic[key]["text_CN"]+"\n") f.write("\n") gr.Info(f"Txt导出成功, 共导出{len(lis)}条记录") def get_remaining_text_num(): if args["target_id"] in id_lis: target_idx= idx_dic[args["target_id"]] rem = target_idx - id_idx label = f"目标剩余{rem}条" else: label = "目标剩余???条" return label def merge_json(merged_path,file_merging_json,text_start_id,text_end_id,type): merged_path = smart_path(merged_path) if not osp.exists(merged_path): gr.Warning("路径不存在") return with open(merged_path, "r", encoding ="utf8") as json_file: dic_merge = json.load(json_file) id_lis_merge = list(dic_merge.keys()) idx_dic_merge = dict() for idx,id_ in enumerate(id_lis_merge): idx_dic_merge[id_] = idx if text_start_id not in id_lis_merge or text_end_id not in id_lis_merge or idx_dic_merge[text_start_id] > idx_dic_merge[text_end_id]: gr.Warning("找不到指定序号, 或id前后顺序错误") return path = file_merging_json.name with open(path, "r", encoding ="utf8") as json_file: dic_new = json.load(json_file) for idx in range(idx_dic_merge[text_start_id],idx_dic_merge[text_end_id] + 1): if type == "仅人工翻译": dic_merge[id_lis_merge[idx]]['text_CN'] = dic_new[id_lis_merge[idx]]['text_CN'] else: dic_merge[id_lis_merge[idx]] = dic_new[id_lis_merge[idx]] with open(merged_path, "w", encoding ="utf8") as json_file: json.dump(dic_merge,json_file,indent = 1,ensure_ascii = False) gr.Info(f"合并成功,共更新{idx_dic_merge[text_end_id] - idx_dic_merge[text_start_id] + 1}条译文") return def output_json(merged_path,text_start_id,text_end_id): merged_path = smart_path(merged_path) if not osp.exists(merged_path): gr.Warning("路径不存在") return with open(merged_path, "r", encoding ="utf8") as json_file: dic_merge = json.load(json_file) id_lis_merge = list(dic_merge.keys()) idx_dic_merge = dict() for idx,id_ in enumerate(id_lis_merge): idx_dic_merge[id_] = idx if text_start_id not in id_lis_merge or text_end_id not in id_lis_merge or idx_dic_merge[text_start_id] > idx_dic_merge[text_end_id]: gr.Warning("找不到指定序号, 或id前后顺序错误") return dic_new = {} for idx in range(idx_dic_merge[text_start_id],idx_dic_merge[text_end_id] + 1): dic_new[id_lis_merge[idx]] = dic_merge[id_lis_merge[idx]] name = "small_" + osp.basename(path) new_path = osp.join(osp.dirname(merged_path), name) with open(new_path, "w", encoding ="utf8") as json_file: json.dump(dic_new,json_file,indent = 1,ensure_ascii = False) return new_path shortcut_js = """ """ with gr.Blocks(theme=Theme1(),head=shortcut_js) as demo: gr.Markdown("#