Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import os | |
| import subprocess | |
| import re | |
| from tinydb import TinyDB, Query | |
| import datetime | |
| from bs4 import BeautifulSoup | |
| import warnings | |
| from article_generator import generate_article # clear_state と continue_generate_article を削除 | |
| from tavily_search import create_tavily_search_ui, tavily_search_interface # 追加 | |
| import time # 追加 | |
| def is_valid_html(html): | |
| with warnings.catch_warnings(record=True) as w: | |
| warnings.simplefilter('always') | |
| BeautifulSoup(html, 'html.parser') | |
| return len(w) == 0 | |
| # データベースの初期化 | |
| db = TinyDB("db.json") | |
| current_time = datetime.datetime.now() | |
| one_day_ago = current_time - datetime.timedelta(days=1) | |
| db.remove(Query().timestamp.test(lambda x: datetime.datetime.fromisoformat(x) <= one_day_ago)) | |
| def process_article(new_keyword, other_keywords, action, edited_article_structure): | |
| keyword_id = re.sub(r"\W+", "", new_keyword) if new_keyword else None | |
| response_text = "" | |
| final_article_content = "" | |
| if action == "構成作成": | |
| all_keywords = new_keyword | |
| if other_keywords: | |
| all_keywords += " " + other_keywords | |
| print(f"Running keywords_processor.py with arguments: {new_keyword}, {other_keywords}") | |
| result = subprocess.run(["python3", "keywords_processor.py", new_keyword, other_keywords], capture_output=True, text=True) | |
| print(f"Return code: {result.returncode}") | |
| if result.returncode != 0: | |
| response_text = "Keywords Processor Error: " + result.stderr | |
| print("Keywords Processor Error:", result.stderr) | |
| else: | |
| response_text = result.stdout | |
| print("Keywords Processor Output:", result.stdout) | |
| # headline_generator.py を実行 | |
| print("Running headline_generator.py") | |
| headline_result = subprocess.run(["python3", "headline_generator.py", new_keyword], capture_output=True, text=True) | |
| print(f"Headline Generator Return code: {headline_result.returncode}") | |
| if headline_result.returncode != 0: | |
| print("Headline Generator Error:", headline_result.stderr) | |
| else: | |
| response_text += headline_result.stdout | |
| print("Headline Generator Output:", headline_result.stdout) | |
| return response_text, None # 編集可能な記事構成にのみ出力 | |
| elif action == "本文作成": | |
| response_text = edited_article_structure | |
| try: | |
| final_article_content = generate_article(edited_article_structure) | |
| # output3.txt ファイルが作成されるのを待つ | |
| while not os.path.exists("output3.txt"): | |
| time.sleep(0.1) | |
| with open("output3.txt", "r", encoding="utf-8") as f: | |
| final_article_content = f.read() | |
| except Exception as e: | |
| final_article_content = f"予期せぬエラーが発生しました:{str(e)}" | |
| print(f"予期せぬエラーが発生しました:{str(e)}") | |
| return response_text, final_article_content | |
| # Gradioアプリの設定 | |
| with gr.Blocks(css=".column { float: left; width: 50%; } .clear { clear: both; } .right-align { margin-top: 24px; }") as app: | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.Markdown("### BabyWriterPRO") | |
| new_keyword = gr.Textbox(label="キーワード") | |
| other_keywords = gr.Textbox(label="その他のキーワード", lines=4) | |
| create_structure_button = gr.Button("構成作成") | |
| editable_output2 = gr.Textbox(label="編集可能な記事構成", lines=10, placeholder="記事構成がここに表示されます") | |
| create_article_button = gr.Button("本文作成") | |
| final_article = gr.Textbox(label="最終的な記事本文", lines=10) | |
| create_structure_button.click( | |
| fn=process_article, | |
| inputs=[new_keyword, other_keywords, gr.State("構成作成"), gr.State("")], | |
| outputs=[editable_output2, final_article] | |
| ) | |
| create_article_button.click( | |
| fn=process_article, | |
| inputs=[new_keyword, other_keywords, gr.State("本文作成"), editable_output2], | |
| outputs=[editable_output2, final_article] | |
| ) | |
| with gr.Column(): | |
| gr.Markdown(" ", elem_id="spacer") # 空白を作るための見えないMarkdown | |
| selected_text = gr.Textbox(label="検索キーワード", lines=3, elem_classes="right-align", placeholder="検索したいキーワードを入力(文章でも可)") | |
| domain_filter = gr.Radio(label="検索フィルタ(all:全検索、official:公式、企業、政府系)", choices=["all", "official"], value="all", elem_classes="right-align") | |
| search_button = gr.Button("検索", elem_classes="right-align") | |
| display_format = gr.Radio(label="表示形式(検索結果表示後の切り替え可能)", choices=["Markdown", "HTML"], value="Markdown", elem_classes="right-align") | |
| search_results_md = gr.Markdown(elem_classes="right-align") | |
| search_results_html = gr.HTML(elem_classes="right-align", visible=False) | |
| def switch_display_format(format): | |
| if format == "Markdown": | |
| return gr.update(visible=True), gr.update(visible=False) | |
| else: | |
| return gr.update(visible(False)), gr.update(visible=True) | |
| search_button.click(tavily_search_interface, inputs=[selected_text, domain_filter], outputs=[search_results_md, search_results_html]) | |
| display_format.change(switch_display_format, inputs=display_format, outputs=[search_results_md, search_results_html]) | |
| app.launch() | |