From 6c17f3e9c826074c16496b69e6bfa2ef4f1b4bca Mon Sep 17 00:00:00 2001 From: binary-husky <505030475@qq.com> Date: Sat, 29 Apr 2023 00:00:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8E=86=E5=8F=B2=E5=AD=98?= =?UTF-8?q?=E6=A1=A3=E8=AF=BB=E5=8F=96=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crazy_functional.py | 18 +++++-- crazy_functions/crazy_utils.py | 43 ++++++++++++++++ crazy_functions/对话历史存档.py | 91 +++++++++++++++++++++++++++++++-- toolbox.py | 5 +- 4 files changed, 146 insertions(+), 11 deletions(-) diff --git a/crazy_functional.py b/crazy_functional.py index db0af66..4b29aef 100644 --- a/crazy_functional.py +++ b/crazy_functional.py @@ -21,16 +21,22 @@ def get_crazy_functions(): from crazy_functions.总结word文档 import 总结word文档 from crazy_functions.解析JupyterNotebook import 解析ipynb文件 from crazy_functions.对话历史存档 import 对话历史存档 + from crazy_functions.对话历史存档 import 载入对话历史存档 + from crazy_functions.对话历史存档 import 删除所有本地对话历史记录 + from crazy_functions.批量Markdown翻译 import Markdown英译中 function_plugins = { - "解析整个Python项目": { "Color": "stop", # 按钮颜色 "Function": HotReload(解析一个Python项目) }, - "保存当前的对话": { + "载入对话历史存档": { "AsButton":False, - "Function": HotReload(对话历史存档) + "Function": HotReload(载入对话历史存档) + }, + "删除所有本地对话历史记录(请谨慎操作)": { + "AsButton":False, + "Function": HotReload(删除所有本地对话历史记录) }, "[测试功能] 解析Jupyter Notebook文件": { "Color": "stop", @@ -92,7 +98,11 @@ def get_crazy_functions(): "AsButton": False, # 加入下拉菜单中 "Function": HotReload(批量生成函数注释) }, + "保存当前的对话": { + "Function": HotReload(对话历史存档) + }, "[多线程Demo] 解析此项目本身(源码自译解)": { + "AsButton": False, # 加入下拉菜单中 "Function": HotReload(解析项目本身) }, "[多线程demo] 把本项目源代码切换成全英文": { @@ -100,7 +110,7 @@ def get_crazy_functions(): "AsButton": False, # 加入下拉菜单中 "Function": HotReload(全项目切换英文) }, - "[函数插件模板Demo] 历史上的今天": { + "[插件demo] 历史上的今天": { # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效 "Function": HotReload(高阶功能模板函数) }, diff --git a/crazy_functions/crazy_utils.py b/crazy_functions/crazy_utils.py index 6af956f..e54136c 100644 --- a/crazy_functions/crazy_utils.py +++ b/crazy_functions/crazy_utils.py @@ -563,3 +563,46 @@ def read_and_clean_pdf_text(fp): # print亮绿('***************************') return meta_txt, page_one_meta + + +def get_files_from_everything(txt, type): # type='.md' + """ + 这个函数是用来获取指定目录下所有指定类型(如.md)的文件,并且对于网络上的文件,也可以获取它。 + 下面是对每个参数和返回值的说明: + 参数 + - txt: 路径或网址,表示要搜索的文件或者文件夹路径或网络上的文件。 + - type: 字符串,表示要搜索的文件类型。默认是.md。 + 返回值 + - success: 布尔值,表示函数是否成功执行。 + - file_manifest: 文件路径列表,里面包含以指定类型为后缀名的所有文件的绝对路径。 + - project_folder: 字符串,表示文件所在的文件夹路径。如果是网络上的文件,就是临时文件夹的路径。 + 该函数详细注释已添加,请确认是否满足您的需要。 + """ + import glob, os + + success = True + if txt.startswith('http'): + # 网络的远程文件 + import requests + from toolbox import get_conf + proxies, = get_conf('proxies') + r = requests.get(txt, proxies=proxies) + with open('./gpt_log/temp'+type, 'wb+') as f: f.write(r.content) + project_folder = './gpt_log/' + file_manifest = ['./gpt_log/temp'+type] + elif txt.endswith(type): + # 直接给定文件 + file_manifest = [txt] + project_folder = os.path.dirname(txt) + elif os.path.exists(txt): + # 本地路径,递归搜索 + project_folder = txt + file_manifest = [f for f in glob.glob(f'{project_folder}/**/*'+type, recursive=True)] + if len(file_manifest) == 0: + success = False + else: + project_folder = None + file_manifest = [] + success = False + + return success, file_manifest, project_folder diff --git a/crazy_functions/对话历史存档.py b/crazy_functions/对话历史存档.py index 1b232de..e78a0ca 100644 --- a/crazy_functions/对话历史存档.py +++ b/crazy_functions/对话历史存档.py @@ -1,7 +1,7 @@ from toolbox import CatchException, update_ui from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive -def write_chat_to_file(chatbot, file_name=None): +def write_chat_to_file(chatbot, history=None, file_name=None): """ 将对话记录history以Markdown格式写入文件中。如果没有指定文件名,则使用当前时间生成文件名。 """ @@ -12,19 +12,42 @@ def write_chat_to_file(chatbot, file_name=None): os.makedirs('./gpt_log/', exist_ok=True) with open(f'./gpt_log/{file_name}', 'w', encoding='utf8') as f: for i, contents in enumerate(chatbot): - for content in contents: + for j, content in enumerate(contents): try: # 这个bug没找到触发条件,暂时先这样顶一下 if type(content) != str: content = str(content) except: continue f.write(content) - f.write('\n\n') + if j == 0: + f.write('
') f.write('
\n\n') - + f.write('
\n\n raw chat context:\n') + f.write('') + for h in history: + f.write("\n>>>" + h) + f.write('') + res = '对话历史写入:' + os.path.abspath(f'./gpt_log/{file_name}') print(res) return res +def read_file_to_chat(chatbot, history, file_name): + with open(file_name, 'r', encoding='utf8') as f: + file_content = f.read() + html, history = file_content.split('
\n\n raw chat context:\n') + history = history.strip('') + history = history.strip('') + history = history.split("\n>>>") + history = list(filter(lambda x:x!="", history)) + html = html.split('
\n\n') + html = list(filter(lambda x:x!="", html)) + chatbot.clear() + for i, h in enumerate(html): + i_say, gpt_say = h.split('
') + chatbot.append([i_say, gpt_say]) + chatbot.append([f"存档文件详情?", f"[Local Message] 载入对话{len(html)}条,上下文{len(history)}条。"]) + return chatbot, history + @CatchException def 对话历史存档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port): """ @@ -37,6 +60,64 @@ def 对话历史存档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_ web_port 当前软件运行的端口号 """ - chatbot.append(("保存当前对话", f"[Local Message] {write_chat_to_file(chatbot)}")) + chatbot.append(("保存当前对话", + f"[Local Message] {write_chat_to_file(chatbot, history)},您可以调用“载入对话历史存档”还原当下的对话。\n警告!被保存的对话历史可以被使用该系统的任何人查阅。")) yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新 +def hide_cwd(str): + import os + current_path = os.getcwd() + replace_path = "." + return str.replace(current_path, replace_path) + +@CatchException +def 载入对话历史存档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port): + """ + txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径 + llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行 + plugin_kwargs 插件模型的参数,暂时没有用武之地 + chatbot 聊天显示框的句柄,用于显示给用户 + history 聊天历史,前情提要 + system_prompt 给gpt的静默提醒 + web_port 当前软件运行的端口号 + """ + from .crazy_utils import get_files_from_everything + success, file_manifest, _ = get_files_from_everything(txt, type='.html') + + if not success: + if txt == "": txt = '空空如也的输入栏' + import glob + local_history = "
".join(["`"+hide_cwd(f)+"`" for f in glob.glob(f'gpt_log/**/chatGPT对话历史*.html', recursive=True)]) + chatbot.append([f"正在查找对话历史文件(html格式): {txt}", f"找不到任何html文件: {txt}。但本地存储了以下历史文件,您可以将任意一个文件路径粘贴到输入区,然后重试:
{local_history}"]) + yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 + return + + try: + chatbot, history = read_file_to_chat(chatbot, history, file_manifest[0]) + yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 + except: + chatbot.append([f"载入对话历史文件", f"对话历史文件损坏!"]) + yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 + return + +@CatchException +def 删除所有本地对话历史记录(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port): + """ + txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径 + llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行 + plugin_kwargs 插件模型的参数,暂时没有用武之地 + chatbot 聊天显示框的句柄,用于显示给用户 + history 聊天历史,前情提要 + system_prompt 给gpt的静默提醒 + web_port 当前软件运行的端口号 + """ + + import glob, os + local_history = "
".join(["`"+hide_cwd(f)+"`" for f in glob.glob(f'gpt_log/**/chatGPT对话历史*.html', recursive=True)]) + for f in glob.glob(f'gpt_log/**/chatGPT对话历史*.html', recursive=True): + os.remove(f) + chatbot.append([f"删除所有历史对话文件", f"已删除
{local_history}"]) + yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 + return + + diff --git a/toolbox.py b/toolbox.py index 81ff91d..565a87b 100644 --- a/toolbox.py +++ b/toolbox.py @@ -90,8 +90,9 @@ def CatchException(f): from toolbox import get_conf proxies, = get_conf('proxies') tb_str = '```\n' + trimmed_format_exc() + '```' - if chatbot is None or len(chatbot) == 0: - chatbot = [["插件调度异常", "异常原因"]] + if len(chatbot) == 0: + chatbot.clear() + chatbot.append(["插件调度异常", "异常原因"]) chatbot[-1] = (chatbot[-1][0], f"[Local Message] 实验性函数调用出错: \n\n{tb_str} \n\n当前代理可用性: \n\n{check_proxy(proxies)}") yield from update_ui(chatbot=chatbot, history=history, msg=f'异常 {e}') # 刷新界面