diff --git a/crazy_functional.py b/crazy_functional.py index 92bc2842..c7c37854 100644 --- a/crazy_functional.py +++ b/crazy_functional.py @@ -21,7 +21,7 @@ def get_crazy_functions(): from crazy_functions.询问多个大语言模型 import 同时问询 from crazy_functions.SourceCode_Analyse import 解析一个Lua项目 from crazy_functions.SourceCode_Analyse import 解析一个CSharp项目 - from crazy_functions.总结word文档 import 总结word文档 + from crazy_functions.总结文档 import 总结文件 from crazy_functions.解析JupyterNotebook import 解析ipynb文件 from crazy_functions.Conversation_To_File import 载入对话历史存档 from crazy_functions.Conversation_To_File import 对话历史存档 @@ -110,12 +110,13 @@ def get_crazy_functions(): "Function": HotReload(Latex翻译中文并重新编译PDF), # 当注册Class后,Function旧接口仅会在“虚空终端”中起作用 "Class": Arxiv_Localize, # 新一代插件需要注册Class }, - "批量总结Word文档": { + "批量总结文档": { "Group": "学术", "Color": "stop", "AsButton": False, + "AdvancedArgs": True, "Info": "批量总结word文档 | 输入参数为路径", - "Function": HotReload(总结word文档), + "Function": HotReload(总结文件), }, "解析整个Matlab项目": { "Group": "编程", diff --git a/crazy_functions/rag_fns/rag_file_support.py b/crazy_functions/rag_fns/rag_file_support.py new file mode 100644 index 00000000..f826fab1 --- /dev/null +++ b/crazy_functions/rag_fns/rag_file_support.py @@ -0,0 +1,45 @@ +import os +from llama_index.core import SimpleDirectoryReader + +supports_format = ['.csv', '.docx','.doc', '.epub', '.ipynb', '.mbox', '.md', '.pdf', '.txt', '.ppt', + '.pptm', '.pptx','.py', '.xls', '.xlsx', '.html', '.json', '.xml', '.yaml', '.yml' ,'.m'] + +def read_docx_doc(file_path): + if file_path.split(".")[-1] == "docx": + from docx import Document + doc = Document(file_path) + file_content = "\n".join([para.text for para in doc.paragraphs]) + else: + try: + import win32com.client + word = win32com.client.Dispatch("Word.Application") + word.visible = False + # 打开文件 + doc = word.Documents.Open(os.getcwd() + '/' + file_path) + # file_content = doc.Content.Text + doc = word.ActiveDocument + file_content = doc.Range().Text + doc.Close() + word.Quit() + except: + raise RuntimeError('请先将.doc文档转换为.docx文档。') + return file_content + +# 修改后的 extract_text 函数,结合 SimpleDirectoryReader 和自定义解析逻辑 +import os + +def extract_text(file_path): + _, ext = os.path.splitext(file_path.lower()) + + # 使用 SimpleDirectoryReader 处理它支持的文件格式 + if ext in ['.docx', '.doc']: + return read_docx_doc(file_path) + try: + reader = SimpleDirectoryReader(input_files=[file_path]) + documents = reader.load_data() + if len(documents) > 0: + return documents[0].text + except Exception as e: + pass + + return None diff --git a/crazy_functions/总结word文档.py b/crazy_functions/总结文档.py similarity index 56% rename from crazy_functions/总结word文档.py rename to crazy_functions/总结文档.py index 99f0919b..271c123d 100644 --- a/crazy_functions/总结word文档.py +++ b/crazy_functions/总结文档.py @@ -2,34 +2,22 @@ from toolbox import update_ui from toolbox import CatchException, report_exception from toolbox import write_history_to_file, promote_file_to_downloadzone from crazy_functions.crazy_utils import request_gpt_model_in_new_thread_with_ui_alive + fast_debug = False -def 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt): +def 文档总结(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt): import time, os + from crazy_functions.rag_fns.rag_file_support import extract_text, supports_format # pip install python-docx 用于docx格式,跨平台 # pip install pywin32 用于doc格式,仅支持Win平台 for index, fp in enumerate(file_manifest): - if fp.split(".")[-1] == "docx": - from docx import Document - doc = Document(fp) - file_content = "\n".join([para.text for para in doc.paragraphs]) - else: - try: - import win32com.client - word = win32com.client.Dispatch("Word.Application") - word.visible = False - # 打开文件 - doc = word.Documents.Open(os.getcwd() + '/' + fp) - # file_content = doc.Content.Text - doc = word.ActiveDocument - file_content = doc.Range().Text - doc.Close() - word.Quit() - except: - raise RuntimeError('请先将.doc文档转换为.docx文档。') - + file_content = extract_text(fp) # private_upload里面的文件名在解压zip后容易出现乱码(rar和7z格式正常),故可以只分析文章内容,不输入文件名 + if file_content==None: + chatbot.append( + [f"上传文件: {os.path.basename(fp)}", f"此文件解析失败,无法提取文本内容。失败原因可能为:1.文档格式过于复杂;2. 不支持的文件格式,支持的文件格式后缀有:" + ", ".join(supports_format)+ "等其他文本格式类型文件。"]) + continue from crazy_functions.pdf_fns.breakdown_txt import breakdown_text_to_satisfy_token_limit from request_llms.bridge_all import model_info max_token = model_info[llm_kwargs['llm_model']]['max_token'] @@ -37,8 +25,8 @@ def 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot paper_fragments = breakdown_text_to_satisfy_token_limit(txt=file_content, limit=TOKEN_LIMIT_PER_FRAGMENT, llm_model=llm_kwargs['llm_model']) this_paper_history = [] for i, paper_frag in enumerate(paper_fragments): - i_say = f'请对下面的文章片段用中文做概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{paper_frag}```' - i_say_show_user = f'请对下面的文章片段做概述: {os.path.abspath(fp)}的第{i+1}/{len(paper_fragments)}个片段。' + i_say = f'请对下面的内容用中文做概述,文件名是{os.path.relpath(fp, project_folder)},做概述时请优先满足以下要求:{plugin_kwargs['advanced_arg']}:内容是 ```{paper_frag}```' + i_say_show_user = f'请对下面的内容片段做概述,做概述时请优先满足以下要求:{plugin_kwargs['advanced_arg']}: {os.path.abspath(fp)}的第{i+1}/{len(paper_fragments)}个片段。' gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive( inputs=i_say, inputs_show_user=i_say_show_user, @@ -54,14 +42,14 @@ def 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot # 已经对该文章的所有片段总结完毕,如果文章被切分了, if len(paper_fragments) > 1: - i_say = f"根据以上的对话,总结文章{os.path.abspath(fp)}的主要内容。" + i_say = f"根据以上的对话,总结时请注意以下要求:{plugin_kwargs['advanced_arg']},总结文件{os.path.abspath(fp)}的主要内容。" gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive( inputs=i_say, inputs_show_user=i_say, llm_kwargs=llm_kwargs, chatbot=chatbot, history=this_paper_history, - sys_prompt="总结文章。" + sys_prompt="总结文件内容。" ) history.extend([i_say,gpt_say]) @@ -69,35 +57,24 @@ def 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot res = write_history_to_file(history) promote_file_to_downloadzone(res, chatbot=chatbot) - chatbot.append(("完成了吗?", res)) + chatbot.append((f"路径{fp}文件解读完成了吗?", "解读完成,存储路径为"+res)) yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 res = write_history_to_file(history) promote_file_to_downloadzone(res, chatbot=chatbot) - chatbot.append(("所有文件都总结完成了吗?", res)) - yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 @CatchException -def 总结word文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, user_request): +def 总结文件(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, user_request): import glob, os # 基本信息:功能、贡献者 chatbot.append([ "函数插件功能?", - "批量总结Word文档。函数插件贡献者: JasonGuo1。注意, 如果是.doc文件, 请先转化为.docx格式。"]) + f"批量总结各类文件。函数插件贡献者: JasonGuo1 and BoyinLiu。支持的文件类型包括:{', '.join(supports_format)}。" + ]) yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 - # 尝试导入依赖,如果缺少依赖,则给出安装建议 - try: - from docx import Document - except: - report_exception(chatbot, history, - a=f"解析项目: {txt}", - b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade python-docx pywin32```。") - yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 - return - # 清空历史,以免输入溢出 history = [] @@ -111,17 +88,14 @@ def 总结word文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_pr return # 搜索需要处理的文件清单 - if txt.endswith('.docx') or txt.endswith('.doc'): - file_manifest = [txt] - else: - file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.docx', recursive=True)] + \ - [f for f in glob.glob(f'{project_folder}/**/*.doc', recursive=True)] + + file_manifest = [f for f in glob.glob(f'{project_folder}/**', recursive=True) if os.path.isfile(f)] # 如果没找到任何文件 if len(file_manifest) == 0: - report_exception(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何.docx或doc文件: {txt}") + report_exception(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何支持的文件类型: {txt}") yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 return # 开始正式执行任务 - yield from 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt) + yield from 文档总结(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt) \ No newline at end of file