Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -4,6 +4,8 @@ import yaml
|
|
| 4 |
import shutil
|
| 5 |
import subprocess
|
| 6 |
import sys
|
|
|
|
|
|
|
| 7 |
from datetime import datetime
|
| 8 |
from concurrent.futures import ThreadPoolExecutor, as_completed
|
| 9 |
from typing import Iterable
|
|
@@ -277,51 +279,87 @@ def run_mineru_parsing_and_dag_gen():
|
|
| 277 |
error_log = full_log + f"\n[Global Exception] Exception occurred:\n{str(e)}"
|
| 278 |
yield "❌ Execution Exception", get_debug_info(), error_log
|
| 279 |
|
|
|
|
| 280 |
def run_final_generation(task_type="all"):
|
|
|
|
|
|
|
|
|
|
| 281 |
if not os.path.exists(OUTPUT_DIR):
|
| 282 |
-
|
|
|
|
| 283 |
|
| 284 |
scripts_to_run = []
|
| 285 |
if task_type == "ppt": scripts_to_run = ["gen_ppt.py"]
|
| 286 |
elif task_type == "poster": scripts_to_run = ["gen_poster.py"]
|
| 287 |
elif task_type == "pr": scripts_to_run = ["gen_pr.py"]
|
| 288 |
elif task_type == "all": scripts_to_run = ["gen_ppt.py", "gen_poster.py", "gen_pr.py"]
|
| 289 |
-
else:
|
|
|
|
|
|
|
| 290 |
|
| 291 |
full_log = f"🚀 Preparing to start {len(scripts_to_run)} tasks...\n"
|
| 292 |
-
|
| 293 |
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 297 |
|
| 298 |
try:
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 318 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
zip_base_name = ZIP_OUTPUT_PATH.replace(".zip", "")
|
| 320 |
shutil.make_archive(zip_base_name, 'zip', OUTPUT_DIR)
|
| 321 |
-
|
|
|
|
|
|
|
|
|
|
| 322 |
except Exception as e:
|
| 323 |
error_log = full_log + f"\n[Global Exception] Exception occurred:\n{str(e)}"
|
| 324 |
-
|
|
|
|
| 325 |
|
| 326 |
# ==========================================
|
| 327 |
# --- 🚀 UI Configuration & Advanced CSS ---
|
|
@@ -566,17 +604,18 @@ with gr.Blocks(theme=purple_theme, css=custom_css) as demo:
|
|
| 566 |
|
| 567 |
parse_btn.click(fn=run_mineru_parsing_and_dag_gen, outputs=[parse_status, debug_view, cmd_logs])
|
| 568 |
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
|
|
|
| 573 |
|
| 574 |
-
gen_ppt_btn.click(fn=
|
| 575 |
-
gen_poster_btn.click(fn=
|
| 576 |
-
gen_pr_btn.click(fn=
|
| 577 |
-
gen_all_btn.click(fn=
|
| 578 |
|
| 579 |
refresh_btn.click(fn=get_debug_info, outputs=debug_view)
|
| 580 |
|
| 581 |
if __name__ == "__main__":
|
| 582 |
-
demo.launch(
|
|
|
|
| 4 |
import shutil
|
| 5 |
import subprocess
|
| 6 |
import sys
|
| 7 |
+
import queue
|
| 8 |
+
import threading
|
| 9 |
from datetime import datetime
|
| 10 |
from concurrent.futures import ThreadPoolExecutor, as_completed
|
| 11 |
from typing import Iterable
|
|
|
|
| 279 |
error_log = full_log + f"\n[Global Exception] Exception occurred:\n{str(e)}"
|
| 280 |
yield "❌ Execution Exception", get_debug_info(), error_log
|
| 281 |
|
| 282 |
+
|
| 283 |
def run_final_generation(task_type="all"):
|
| 284 |
+
"""
|
| 285 |
+
使用队列和多线程实时获取子进程的流式输出,并通过 yield 推送到前端界面。
|
| 286 |
+
"""
|
| 287 |
if not os.path.exists(OUTPUT_DIR):
|
| 288 |
+
yield "❌ Please run the parsing step first", get_debug_info(), "No output folder found.", gr.update(visible=False)
|
| 289 |
+
return
|
| 290 |
|
| 291 |
scripts_to_run = []
|
| 292 |
if task_type == "ppt": scripts_to_run = ["gen_ppt.py"]
|
| 293 |
elif task_type == "poster": scripts_to_run = ["gen_poster.py"]
|
| 294 |
elif task_type == "pr": scripts_to_run = ["gen_pr.py"]
|
| 295 |
elif task_type == "all": scripts_to_run = ["gen_ppt.py", "gen_poster.py", "gen_pr.py"]
|
| 296 |
+
else:
|
| 297 |
+
yield "❌ Unknown task type", get_debug_info(), "Invalid task_type.", gr.update(visible=False)
|
| 298 |
+
return
|
| 299 |
|
| 300 |
full_log = f"🚀 Preparing to start {len(scripts_to_run)} tasks...\n"
|
| 301 |
+
yield f"⏳ Starting {task_type.upper()} generation...", get_debug_info(), full_log, gr.update(visible=False)
|
| 302 |
|
| 303 |
+
q = queue.Queue()
|
| 304 |
+
processes = []
|
| 305 |
+
|
| 306 |
+
# 将标准输出推送到队列的工作线程
|
| 307 |
+
def enqueue_output(out, script_name):
|
| 308 |
+
for line in iter(out.readline, ''):
|
| 309 |
+
q.put((script_name, line))
|
| 310 |
+
out.close()
|
| 311 |
|
| 312 |
try:
|
| 313 |
+
# 并发启动所有脚本
|
| 314 |
+
for script in scripts_to_run:
|
| 315 |
+
p = subprocess.Popen(
|
| 316 |
+
[sys.executable, script],
|
| 317 |
+
stdout=subprocess.PIPE,
|
| 318 |
+
stderr=subprocess.STDOUT,
|
| 319 |
+
text=True,
|
| 320 |
+
bufsize=1
|
| 321 |
+
)
|
| 322 |
+
processes.append((script, p))
|
| 323 |
+
t = threading.Thread(target=enqueue_output, args=(p.stdout, script))
|
| 324 |
+
t.daemon = True
|
| 325 |
+
t.start()
|
| 326 |
+
|
| 327 |
+
# 从队列中实时读取日志并更新 UI
|
| 328 |
+
active_processes = len(processes)
|
| 329 |
+
while active_processes > 0 or not q.empty():
|
| 330 |
+
try:
|
| 331 |
+
# 设定 timeout,这样即便没有日志产生也能循环检查进程是否结束
|
| 332 |
+
script_name, line = q.get(timeout=0.1)
|
| 333 |
+
full_log += f"[{script_name}] {line}"
|
| 334 |
+
yield f"⏳ Generating {task_type.upper()}...", get_debug_info(), full_log, gr.update(visible=False)
|
| 335 |
+
except queue.Empty:
|
| 336 |
+
active_processes = sum(1 for _, p in processes if p.poll() is None)
|
| 337 |
+
|
| 338 |
+
# 检查最终执行结果
|
| 339 |
+
success = True
|
| 340 |
+
for script, p in processes:
|
| 341 |
+
if p.returncode != 0:
|
| 342 |
+
success = False
|
| 343 |
+
full_log += f"\n❌ [Error] {script} returned non-zero exit code (Exit Code: {p.returncode})\n"
|
| 344 |
+
|
| 345 |
+
if not success:
|
| 346 |
+
yield f"❌ {task_type.upper()} contains failed tasks, please check logs", get_debug_info(), full_log, gr.update(visible=False)
|
| 347 |
+
return
|
| 348 |
|
| 349 |
+
# 全部成功后进行压缩
|
| 350 |
+
full_log += "\n📦 Zipping output directory...\n"
|
| 351 |
+
yield f"��� Zipping outputs...", get_debug_info(), full_log, gr.update(visible=False)
|
| 352 |
+
|
| 353 |
zip_base_name = ZIP_OUTPUT_PATH.replace(".zip", "")
|
| 354 |
shutil.make_archive(zip_base_name, 'zip', OUTPUT_DIR)
|
| 355 |
+
|
| 356 |
+
full_log += "✅ All tasks and zipping completed successfully.\n"
|
| 357 |
+
yield f"✅ {task_type.upper()} generated and zipped successfully", get_debug_info(), full_log, gr.update(value=ZIP_OUTPUT_PATH, visible=True)
|
| 358 |
+
|
| 359 |
except Exception as e:
|
| 360 |
error_log = full_log + f"\n[Global Exception] Exception occurred:\n{str(e)}"
|
| 361 |
+
yield "❌ Global exception during final generation", get_debug_info(), error_log, gr.update(visible=False)
|
| 362 |
+
|
| 363 |
|
| 364 |
# ==========================================
|
| 365 |
# --- 🚀 UI Configuration & Advanced CSS ---
|
|
|
|
| 604 |
|
| 605 |
parse_btn.click(fn=run_mineru_parsing_and_dag_gen, outputs=[parse_status, debug_view, cmd_logs])
|
| 606 |
|
| 607 |
+
# 为了确保 Gradio 生成器模式正确工作,拆分为显式的封装函数
|
| 608 |
+
def trigger_gen_ppt(): yield from run_final_generation("ppt")
|
| 609 |
+
def trigger_gen_poster(): yield from run_final_generation("poster")
|
| 610 |
+
def trigger_gen_pr(): yield from run_final_generation("pr")
|
| 611 |
+
def trigger_gen_all(): yield from run_final_generation("all")
|
| 612 |
|
| 613 |
+
gen_ppt_btn.click(fn=trigger_gen_ppt, outputs=[gen_status, debug_view, cmd_logs, download_file])
|
| 614 |
+
gen_poster_btn.click(fn=trigger_gen_poster, outputs=[gen_status, debug_view, cmd_logs, download_file])
|
| 615 |
+
gen_pr_btn.click(fn=trigger_gen_pr, outputs=[gen_status, debug_view, cmd_logs, download_file])
|
| 616 |
+
gen_all_btn.click(fn=trigger_gen_all, outputs=[gen_status, debug_view, cmd_logs, download_file])
|
| 617 |
|
| 618 |
refresh_btn.click(fn=get_debug_info, outputs=debug_view)
|
| 619 |
|
| 620 |
if __name__ == "__main__":
|
| 621 |
+
demo.launch()
|