Laramie2 commited on
Commit
4395c8b
·
verified ·
1 Parent(s): 3edd387

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -36
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
- return "❌ Please run the parsing step first", get_debug_info(), "No output folder found.", None
 
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: return "❌ Unknown task type", get_debug_info(), "Invalid task_type.", None
 
 
290
 
291
  full_log = f"🚀 Preparing to start {len(scripts_to_run)} tasks...\n"
292
- success = True
293
 
294
- def execute_script(script):
295
- command = [sys.executable, script]
296
- return script, subprocess.run(command, capture_output=True, text=True, timeout=600)
 
 
 
 
 
297
 
298
  try:
299
- with ThreadPoolExecutor(max_workers=len(scripts_to_run)) as executor:
300
- future_to_script = {executor.submit(execute_script, s): s for s in scripts_to_run}
301
- for future in as_completed(future_to_script):
302
- script_name = future_to_script[future]
303
- try:
304
- _, result = future.result()
305
- full_log += f"\n================ ✅ Execution Complete: {script_name} ================\n"
306
- full_log += f"--- STDOUT ---\n{result.stdout}\n\n--- STDERR ---\n{result.stderr}\n"
307
- if result.returncode != 0:
308
- success = False
309
- full_log += f"❌ [Error] {script_name} returned non-zero exit code (Exit Code: {result.returncode})\n"
310
- except subprocess.TimeoutExpired as e:
311
- success = False
312
- full_log += f"\n================ ❌ Task Timeout: {script_name} ================\n{str(e)}\n"
313
- except Exception as e:
314
- success = False
315
- full_log += f"\n================ Task Exception: {script_name} ================\n{str(e)}\n"
316
-
317
- if not success: return f"❌ {task_type.upper()} contains failed tasks, please check logs", get_debug_info(), full_log, None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
 
 
 
 
 
319
  zip_base_name = ZIP_OUTPUT_PATH.replace(".zip", "")
320
  shutil.make_archive(zip_base_name, 'zip', OUTPUT_DIR)
321
- return f"✅ {task_type.upper()} generated and zipped successfully", get_debug_info(), full_log, ZIP_OUTPUT_PATH
 
 
 
322
  except Exception as e:
323
  error_log = full_log + f"\n[Global Exception] Exception occurred:\n{str(e)}"
324
- return "❌ Global exception during final generation", get_debug_info(), error_log, None
 
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
- def trigger_gen(task):
570
- status, debug, logs, file_path = run_final_generation(task)
571
- file_update = gr.update(value=file_path, visible=True) if file_path else gr.update(visible=False)
572
- return status, debug, logs, file_update
 
573
 
574
- gen_ppt_btn.click(fn=lambda: trigger_gen("ppt"), outputs=[gen_status, debug_view, cmd_logs, download_file])
575
- gen_poster_btn.click(fn=lambda: trigger_gen("poster"), outputs=[gen_status, debug_view, cmd_logs, download_file])
576
- gen_pr_btn.click(fn=lambda: trigger_gen("pr"), outputs=[gen_status, debug_view, cmd_logs, download_file])
577
- gen_all_btn.click(fn=lambda: trigger_gen("all"), outputs=[gen_status, debug_view, cmd_logs, download_file])
578
 
579
  refresh_btn.click(fn=get_debug_info, outputs=debug_view)
580
 
581
  if __name__ == "__main__":
582
- demo.launch(debug=True)
 
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()