import gradio as gr import os from gradio.data_classes import FileData from config import Config from chatbot import ChatBot from content_formatter import ContentFormatter from content_assistant import ContentAssistant from image_advisor import ImageAdvisor from input_parser import parse_input_text from ppt_generator import generate_presentation from template_manager import load_template, get_layout_mapping from layout_manager import LayoutManager from logger import LOG from openai_whisper import asr, transcribe # from minicpm_v_model import chat_with_image from docx_parser import generate_markdown_from_docx # os.environ["LANGCHAIN_TRACING_V2"] = "true" os.environ["LANGCHAIN_PROJECT"] = "ChatPPT" # 实例化 Config,加载配置文件 config = Config() chatbot = ChatBot(config.chatbot_prompt) content_formatter = ContentFormatter(config.content_formatter_prompt) content_assistant = ContentAssistant(config.content_assistant_prompt) image_advisor = ImageAdvisor(config.image_advisor_prompt) # 加载 PowerPoint 模板,并获取可用布局 ppt_template = load_template(config.ppt_template) # 初始化 LayoutManager,管理幻灯片布局 layout_manager = LayoutManager(get_layout_mapping(ppt_template)) # 定义生成幻灯片内容的函数 def generate_contents(message, history): try: # 初始化一个列表,用于收集用户输入的文本和音频转录 texts = [] # 获取文本输入,如果存在则添加到列表 text_input = message.get("text") if text_input: texts.append(text_input) # 获取上传的文件列表,如果存在则处理每个文件 for uploaded_file in message.get("files", []): LOG.debug(f"[上传文件]: {uploaded_file}") # 获取文件的扩展名,并转换为小写 file_ext = os.path.splitext(uploaded_file)[1].lower() if file_ext in ('.wav', '.flac', '.mp3'): # 使用 OpenAI Whisper 模型进行语音识别 audio_text = asr(uploaded_file) texts.append(audio_text) # 解释说明图像文件 # elif file_ext in ('.jpg', '.png', '.jpeg'): # if text_input: # image_desc = chat_with_image(uploaded_file, text_input) # else: # image_desc = chat_with_image(uploaded_file) # return image_desc # 使用 Docx 文件作为素材创建 PowerPoint elif file_ext in ('.docx', '.doc'): # 调用 generate_markdown_from_docx 函数,获取 markdown 内容 raw_content = generate_markdown_from_docx(uploaded_file) markdown_content = content_formatter.format(raw_content) return content_assistant.adjust_single_picture(markdown_content) else: LOG.debug(f"[格式不支持]: {uploaded_file}") # 将所有文本和转录结果合并为一个字符串,作为用户需求 user_requirement = "需求如下:\n" + "\n".join(texts) LOG.info(user_requirement) # 与聊天机器人进行对话,生成幻灯片内容 slides_content = chatbot.chat_with_history(user_requirement) return slides_content except Exception as e: LOG.error(f"[内容生成错误]: {e}") # 抛出 Gradio 错误,以便在界面上显示友好的错误信息 raise gr.Error(f"网络问题,请重试:)") def handle_image_generate(history): try: # 获取聊天记录中的最新内容 slides_content = history[-1]["content"] content_with_images, image_pair = image_advisor.generate_images(slides_content) # for k, v in image_pair.items(): # history.append( # # {"text": k, "files": FileData(path=v)} # {"role": "user", "files": FileData(path=v)} # ) new_message = {"role": "assistant", "content": content_with_images} history.append(new_message) return history except Exception as e: LOG.error(f"[配图生成错误]: {e}") # 提示用户先输入主题内容或上传文件 raise gr.Error(f"【提示】未找到合适配图,请重试!") # 定义处理生成按钮点击事件的函数 def handle_generate(history): try: # 获取聊天记录中的最新内容 slides_content = history[-1]["content"] # 解析输入文本,生成幻灯片数据和演示文稿标题 powerpoint_data, presentation_title = parse_input_text(slides_content, layout_manager) # 定义输出的 PowerPoint 文件路径 output_pptx = f"outputs/{presentation_title}.pptx" # 生成 PowerPoint 演示文稿 generate_presentation(powerpoint_data, config.ppt_template, output_pptx) return output_pptx except Exception as e: LOG.error(f"[PPT 生成错误]: {e}") # 提示用户先输入主题内容或上传文件 raise gr.Error(f"【提示】请先输入你的主题内容或上传文件") # 创建 Gradio 界面 with gr.Blocks( title="ChatPPT", css=""" body { animation: fadeIn 2s; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } """ ) as demo: # 添加标题 gr.Markdown("## ChatPPT") # 定义语音(mic)转文本的接口 # gr.Interface( # fn=transcribe, # 执行转录的函数 # inputs=[ # gr.Audio(sources="microphone", type="filepath"), # 使用麦克风录制的音频输入 # ], # outputs="text", # 输出为文本 # flagging_mode="never", # 禁用标记功能 # ) # 创建聊天机器人界面,提示用户输入 contents_chatbot = gr.Chatbot( placeholder="AI 一键生成 PPT

输入你的主题内容或上传音频文件", height=800, type="messages", ) # 定义 ChatBot 和生成内容的接口 gr.ChatInterface( fn=generate_contents, # 处理用户输入的函数 chatbot=contents_chatbot, # 绑定的聊天机器人 type="messages", multimodal=True # 支持多模态输入(文本和文件) ) image_generate_btn = gr.Button("一键为 PowerPoint 配图") image_generate_btn.click( fn=handle_image_generate, inputs=contents_chatbot, outputs=contents_chatbot, ) # 创建生成 PowerPoint 的按钮 generate_btn = gr.Button("一键生成 PowerPoint") # 监听生成按钮的点击事件 generate_btn.click( fn=handle_generate, # 点击时执行的函数 inputs=contents_chatbot, # 输入为聊天记录 outputs=gr.File() # 输出为文件下载链接 ) # 主程序入口 if __name__ == "__main__": # 启动Gradio应用,允许队列功能,并通过 HTTPS 访问 demo.queue().launch( share=False, server_name="0.0.0.0", # auth=("django", "qaz!@#$") # ⚠️注意:记住修改密码 )