Spaces:
Sleeping
Sleeping
| 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"))) | |