import os import io import time import gradio as gr from modules.text_processing import process_text from modules.pptx_builder import build_presentation from modules.utils import safe_hex_to_rgb, ensure_tmpdir APP_NAME = "Auto-PPT Generator" def generate_pptx(long_text: str, title: str, theme_hex: str, logo_file, add_summary: bool, add_tables: bool, add_charts: bool, use_inference_api: bool, summarizer_model: str, generator_model: str, max_summary_words: int): if not long_text or not long_text.strip(): raise gr.Error("入力テキストが空です。長文を貼り付けてください。") theme_rgb = safe_hex_to_rgb(theme_hex or "#3B82F6") # Read logo (optional) logo_bytes = None if logo_file is not None: try: if hasattr(logo_file, "read"): logo_bytes = logo_file.read() elif hasattr(logo_file, "name") and logo_file.name: with open(logo_file.name, "rb") as f: logo_bytes = f.read() except Exception: logo_bytes = None # Step 1–3: NLP pipeline (summary, sections, bullets, tables, chart data) result = process_text( text=long_text, use_inference_api=use_inference_api, summarizer_model=summarizer_model, generator_model=generator_model, want_summary=add_summary, want_tables=add_tables, want_charts=add_charts, max_summary_words=max_summary_words, ) # Step 4: Build PPTX ensure_tmpdir() timestamp = time.strftime('%Y%m%d-%H%M%S') out_path = f"/tmp/auto_ppt_{timestamp}.pptx" build_presentation( output_path=out_path, title=(title or "Auto-PPT"), theme_rgb=theme_rgb, logo_bytes=logo_bytes, executive_summary=result.get("summary"), sections=result.get("sections", []), bullets_by_section=result.get("bullets", {}), tables=result.get("tables", []), charts=result.get("charts", []), ) # Return file path for download return out_path def ui(): with gr.Blocks(title=APP_NAME) as demo: gr.Markdown(f"# {APP_NAME}\n長文→要約→セクション分割→箇条書き/表/図→**PPTX出力** まで自動化") with gr.Row(): with gr.Column(scale=2): long_text = gr.Textbox(label="長文テキスト (貼り付け)", lines=20, placeholder="ここに文章を貼り付け…") title = gr.Textbox(label="タイトル", value="自動生成スライド") theme_hex = gr.Textbox(label="ブランドカラー HEX", value="#3465A4") logo = gr.File(label="ロゴ (任意, PNG/JPG)") with gr.Row(): add_summary = gr.Checkbox(value=True, label="要約スライドを追加") add_tables = gr.Checkbox(value=True, label="表を抽出して追加") add_charts = gr.Checkbox(value=True, label="チャートを生成して追加") with gr.Column(scale=1): gr.Markdown("### モデル設定") use_inference_api = gr.Checkbox(value=False, label="Hugging Face Inference API を使用") summarizer_model = gr.Textbox(label="要約モデル (local or API)", value="sshleifer/distilbart-cnn-12-6") generator_model = gr.Textbox(label="生成モデル (API推奨, 任意)", value="") max_summary_words = gr.Slider(50, 600, value=200, step=10, label="要約の最大語数(目安)") generate = gr.Button("PPTXを生成", variant="primary") output_file = gr.File(label="ダウンロード") generate.click( fn=generate_pptx, inputs=[long_text, title, theme_hex, logo, add_summary, add_tables, add_charts, use_inference_api, summarizer_model, generator_model, max_summary_words], outputs=[output_file], ) gr.Markdown(""" **Tips** - 日本語要約には `sonoisa/t5-base-japanese` を推奨(`text2text-generation`)。 - Inference API を使う場合は、Space の Secrets に `HF_TOKEN` を設定してください。 - チャートは `Label: 123` 形式の行を自動検出して棒グラフを作成します。 """) return demo if __name__ == "__main__": demo = ui() # Spaces は自動でバインドされますが、ローカル互換のため指定可能 demo.queue().launch(server_name="0.0.0.0", server_port=int(os.getenv("PORT", "7860")))