Spaces:
Sleeping
Sleeping
Push Bot
commited on
Commit
·
3bbe849
1
Parent(s):
86979b5
Preview: remove duplicate base64; add 'Download Poster (PDF)' file output; wire yields to 5 outputs
Browse files
app.py
CHANGED
|
@@ -494,7 +494,6 @@ def _pdf_to_iframe_html(pdf_path: Path, width="100%", height="900px") -> str:
|
|
| 494 |
return (
|
| 495 |
f"<div style='border:1px solid #ddd;border-radius:8px;overflow:hidden'>"
|
| 496 |
f"<embed type='application/pdf' width='{width}' height='{height}' src='data:application/pdf;base64,{b64}'></embed>"
|
| 497 |
-
f"<div style='padding:8px'><a download='poster.pdf' href='data:application/pdf;base64,{b64}'>⬇️ Download PDF</a></div>"
|
| 498 |
f"</div>"
|
| 499 |
)
|
| 500 |
except Exception:
|
|
@@ -977,7 +976,7 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 977 |
POSTER_LATEX_DIR = WORK_DIR / "posterbuilder" / "latex_proj"
|
| 978 |
|
| 979 |
_write_logs(LOG_PATH, logs)
|
| 980 |
-
yield "\n".join(logs), "", None, ""
|
| 981 |
|
| 982 |
# ====== Validation: must upload LOGO ======
|
| 983 |
if logo_files is None:
|
|
@@ -1004,7 +1003,7 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 1004 |
saved_logo_paths.append(p)
|
| 1005 |
logs.append(f"🏷️ Saved {len(saved_logo_paths)} logo file(s) → {LOGO_DIR.relative_to(WORK_DIR)}")
|
| 1006 |
_write_logs(LOG_PATH, logs)
|
| 1007 |
-
yield "\n".join(logs), "", None, ""
|
| 1008 |
|
| 1009 |
# ====== Handle uploaded PDF (optional) ======
|
| 1010 |
pdf_path = None
|
|
@@ -1019,14 +1018,14 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 1019 |
canonical_pdf = INPUT_DIR / "paper.pdf"
|
| 1020 |
shutil.copy(pdf_file.name, canonical_pdf)
|
| 1021 |
_write_logs(LOG_PATH, logs)
|
| 1022 |
-
yield "\n".join(logs), "", None, ""
|
| 1023 |
|
| 1024 |
# ====== Validate input source ======
|
| 1025 |
if not arxiv_url and not pdf_file:
|
| 1026 |
msg = "❌ Please provide either an arXiv link or upload a PDF file (choose one)."
|
| 1027 |
logs.append(msg)
|
| 1028 |
_write_logs(LOG_PATH, logs)
|
| 1029 |
-
yield "\n".join(logs), "", None, ""
|
| 1030 |
return
|
| 1031 |
|
| 1032 |
# ====== Build command (run INSIDE workspace) ======
|
|
@@ -1047,7 +1046,7 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 1047 |
logs.append("\n======= REAL-TIME LOG =======")
|
| 1048 |
logs.append(f"cwd = runs/{WORK_DIR.name}")
|
| 1049 |
_write_logs(LOG_PATH, logs)
|
| 1050 |
-
yield "\n".join(logs), "", None, ""
|
| 1051 |
|
| 1052 |
# ====== Run with REAL-TIME streaming, inside workspace ======
|
| 1053 |
try:
|
|
@@ -1064,7 +1063,7 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 1064 |
msg = f"❌ Pipeline failed to start: {e}"
|
| 1065 |
logs.append(msg)
|
| 1066 |
_write_logs(LOG_PATH, logs)
|
| 1067 |
-
yield "\n".join(logs), "", None, ""
|
| 1068 |
return
|
| 1069 |
|
| 1070 |
last_yield = time.time()
|
|
@@ -1078,7 +1077,7 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 1078 |
except Exception:
|
| 1079 |
pass
|
| 1080 |
_write_logs(LOG_PATH, logs)
|
| 1081 |
-
yield "\n".join(logs), "", None, ""
|
| 1082 |
return
|
| 1083 |
|
| 1084 |
line = process.stdout.readline()
|
|
@@ -1089,7 +1088,7 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 1089 |
now = time.time()
|
| 1090 |
if now - last_yield >= 0.3:
|
| 1091 |
last_yield = now
|
| 1092 |
-
yield "\n".join(logs), "", None, ""
|
| 1093 |
elif process.poll() is not None:
|
| 1094 |
break
|
| 1095 |
else:
|
|
@@ -1098,18 +1097,18 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 1098 |
return_code = process.wait()
|
| 1099 |
logs.append(f"\nProcess finished with code {return_code}")
|
| 1100 |
_write_logs(LOG_PATH, logs)
|
| 1101 |
-
yield "\n".join(logs), "", None, ""
|
| 1102 |
|
| 1103 |
if return_code != 0:
|
| 1104 |
logs.append("❌ Process exited with non-zero status. See logs above.")
|
| 1105 |
_write_logs(LOG_PATH, logs)
|
| 1106 |
-
yield "\n".join(logs), "", None, ""
|
| 1107 |
return
|
| 1108 |
|
| 1109 |
except Exception as e:
|
| 1110 |
logs.append(f"❌ Error during streaming: {e}")
|
| 1111 |
_write_logs(LOG_PATH, logs)
|
| 1112 |
-
yield "\n".join(logs), "", None, ""
|
| 1113 |
return
|
| 1114 |
finally:
|
| 1115 |
try:
|
|
@@ -1132,7 +1131,7 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 1132 |
msg = "❌ No output generated. Please check logs above."
|
| 1133 |
logs.append(msg)
|
| 1134 |
_write_logs(LOG_PATH, logs)
|
| 1135 |
-
yield "\n".join(logs), "", None, ""
|
| 1136 |
return
|
| 1137 |
|
| 1138 |
# ====== NEW: Post-processing (optional features) ======
|
|
@@ -1150,25 +1149,20 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 1150 |
_ensure_left_logo_or_disable(OUTPUT_DIR, logs)
|
| 1151 |
|
| 1152 |
_write_logs(LOG_PATH, logs)
|
| 1153 |
-
yield "\n".join(logs), "", None, ""
|
| 1154 |
|
| 1155 |
|
| 1156 |
_write_logs(LOG_PATH, logs)
|
| 1157 |
-
yield "\n".join(logs), "", None, ""
|
| 1158 |
|
| 1159 |
# ====== Compile PDF (for inline preview) ======
|
| 1160 |
pdf_html = ""
|
|
|
|
| 1161 |
try:
|
| 1162 |
pdf_path = _compile_poster_pdf(OUTPUT_DIR, logs)
|
| 1163 |
if pdf_path and pdf_path.exists():
|
| 1164 |
-
|
| 1165 |
-
|
| 1166 |
-
open_tab = f"<a target='_blank' rel='noopener' href='data:application/pdf;base64,{b64}'>Open PDF in new tab</a>"
|
| 1167 |
-
pdf_html = (
|
| 1168 |
-
f"<div style='margin-bottom:8px'>{open_tab}</div>" + _pdf_to_iframe_html(pdf_path)
|
| 1169 |
-
)
|
| 1170 |
-
except Exception:
|
| 1171 |
-
pdf_html = _pdf_to_iframe_html(pdf_path)
|
| 1172 |
logs.append("🖨️ PDF ready for preview in UI.")
|
| 1173 |
except Exception as e:
|
| 1174 |
logs.append(f"⚠️ PDF compile/preview skipped: {e}")
|
|
@@ -1209,6 +1203,8 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 1209 |
_write_logs(LOG_PATH, logs)
|
| 1210 |
yield "\n".join(logs), (
|
| 1211 |
pdf_html
|
|
|
|
|
|
|
| 1212 |
), (
|
| 1213 |
str(ZIP_PATH) if ZIP_PATH.exists() else None
|
| 1214 |
), render_overleaf_button(overleaf_zip_b64)
|
|
@@ -1277,7 +1273,7 @@ The framework builds upon [CAMEL-ai](https://github.com/camel-ai/camel).
|
|
| 1277 |
run_btn.click(
|
| 1278 |
fn=run_pipeline,
|
| 1279 |
inputs=[arxiv_in, pdf_in, key_in, inst_logo_in, conf_logo_in, theme_in],
|
| 1280 |
-
outputs=[logs_out, pdf_out, zip_out, overleaf_out],
|
| 1281 |
)
|
| 1282 |
debug_zip_btn.click(fn=debug_compile_output_zip, inputs=[], outputs=[debug_zip_out])
|
| 1283 |
debug_last_btn.click(fn=debug_compile_last_pipeline_zip, inputs=[], outputs=[debug_last_out])
|
|
|
|
| 494 |
return (
|
| 495 |
f"<div style='border:1px solid #ddd;border-radius:8px;overflow:hidden'>"
|
| 496 |
f"<embed type='application/pdf' width='{width}' height='{height}' src='data:application/pdf;base64,{b64}'></embed>"
|
|
|
|
| 497 |
f"</div>"
|
| 498 |
)
|
| 499 |
except Exception:
|
|
|
|
| 976 |
POSTER_LATEX_DIR = WORK_DIR / "posterbuilder" / "latex_proj"
|
| 977 |
|
| 978 |
_write_logs(LOG_PATH, logs)
|
| 979 |
+
yield "\n".join(logs), "", None, None, ""
|
| 980 |
|
| 981 |
# ====== Validation: must upload LOGO ======
|
| 982 |
if logo_files is None:
|
|
|
|
| 1003 |
saved_logo_paths.append(p)
|
| 1004 |
logs.append(f"🏷️ Saved {len(saved_logo_paths)} logo file(s) → {LOGO_DIR.relative_to(WORK_DIR)}")
|
| 1005 |
_write_logs(LOG_PATH, logs)
|
| 1006 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1007 |
|
| 1008 |
# ====== Handle uploaded PDF (optional) ======
|
| 1009 |
pdf_path = None
|
|
|
|
| 1018 |
canonical_pdf = INPUT_DIR / "paper.pdf"
|
| 1019 |
shutil.copy(pdf_file.name, canonical_pdf)
|
| 1020 |
_write_logs(LOG_PATH, logs)
|
| 1021 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1022 |
|
| 1023 |
# ====== Validate input source ======
|
| 1024 |
if not arxiv_url and not pdf_file:
|
| 1025 |
msg = "❌ Please provide either an arXiv link or upload a PDF file (choose one)."
|
| 1026 |
logs.append(msg)
|
| 1027 |
_write_logs(LOG_PATH, logs)
|
| 1028 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1029 |
return
|
| 1030 |
|
| 1031 |
# ====== Build command (run INSIDE workspace) ======
|
|
|
|
| 1046 |
logs.append("\n======= REAL-TIME LOG =======")
|
| 1047 |
logs.append(f"cwd = runs/{WORK_DIR.name}")
|
| 1048 |
_write_logs(LOG_PATH, logs)
|
| 1049 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1050 |
|
| 1051 |
# ====== Run with REAL-TIME streaming, inside workspace ======
|
| 1052 |
try:
|
|
|
|
| 1063 |
msg = f"❌ Pipeline failed to start: {e}"
|
| 1064 |
logs.append(msg)
|
| 1065 |
_write_logs(LOG_PATH, logs)
|
| 1066 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1067 |
return
|
| 1068 |
|
| 1069 |
last_yield = time.time()
|
|
|
|
| 1077 |
except Exception:
|
| 1078 |
pass
|
| 1079 |
_write_logs(LOG_PATH, logs)
|
| 1080 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1081 |
return
|
| 1082 |
|
| 1083 |
line = process.stdout.readline()
|
|
|
|
| 1088 |
now = time.time()
|
| 1089 |
if now - last_yield >= 0.3:
|
| 1090 |
last_yield = now
|
| 1091 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1092 |
elif process.poll() is not None:
|
| 1093 |
break
|
| 1094 |
else:
|
|
|
|
| 1097 |
return_code = process.wait()
|
| 1098 |
logs.append(f"\nProcess finished with code {return_code}")
|
| 1099 |
_write_logs(LOG_PATH, logs)
|
| 1100 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1101 |
|
| 1102 |
if return_code != 0:
|
| 1103 |
logs.append("❌ Process exited with non-zero status. See logs above.")
|
| 1104 |
_write_logs(LOG_PATH, logs)
|
| 1105 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1106 |
return
|
| 1107 |
|
| 1108 |
except Exception as e:
|
| 1109 |
logs.append(f"❌ Error during streaming: {e}")
|
| 1110 |
_write_logs(LOG_PATH, logs)
|
| 1111 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1112 |
return
|
| 1113 |
finally:
|
| 1114 |
try:
|
|
|
|
| 1131 |
msg = "❌ No output generated. Please check logs above."
|
| 1132 |
logs.append(msg)
|
| 1133 |
_write_logs(LOG_PATH, logs)
|
| 1134 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1135 |
return
|
| 1136 |
|
| 1137 |
# ====== NEW: Post-processing (optional features) ======
|
|
|
|
| 1149 |
_ensure_left_logo_or_disable(OUTPUT_DIR, logs)
|
| 1150 |
|
| 1151 |
_write_logs(LOG_PATH, logs)
|
| 1152 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1153 |
|
| 1154 |
|
| 1155 |
_write_logs(LOG_PATH, logs)
|
| 1156 |
+
yield "\n".join(logs), "", None, None, ""
|
| 1157 |
|
| 1158 |
# ====== Compile PDF (for inline preview) ======
|
| 1159 |
pdf_html = ""
|
| 1160 |
+
compiled_pdf_file = None
|
| 1161 |
try:
|
| 1162 |
pdf_path = _compile_poster_pdf(OUTPUT_DIR, logs)
|
| 1163 |
if pdf_path and pdf_path.exists():
|
| 1164 |
+
pdf_html = _pdf_to_iframe_html(pdf_path)
|
| 1165 |
+
compiled_pdf_file = str(pdf_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1166 |
logs.append("🖨️ PDF ready for preview in UI.")
|
| 1167 |
except Exception as e:
|
| 1168 |
logs.append(f"⚠️ PDF compile/preview skipped: {e}")
|
|
|
|
| 1203 |
_write_logs(LOG_PATH, logs)
|
| 1204 |
yield "\n".join(logs), (
|
| 1205 |
pdf_html
|
| 1206 |
+
), (
|
| 1207 |
+
compiled_pdf_file
|
| 1208 |
), (
|
| 1209 |
str(ZIP_PATH) if ZIP_PATH.exists() else None
|
| 1210 |
), render_overleaf_button(overleaf_zip_b64)
|
|
|
|
| 1273 |
run_btn.click(
|
| 1274 |
fn=run_pipeline,
|
| 1275 |
inputs=[arxiv_in, pdf_in, key_in, inst_logo_in, conf_logo_in, theme_in],
|
| 1276 |
+
outputs=[logs_out, pdf_out, pdf_file_out, zip_out, overleaf_out],
|
| 1277 |
)
|
| 1278 |
debug_zip_btn.click(fn=debug_compile_output_zip, inputs=[], outputs=[debug_zip_out])
|
| 1279 |
debug_last_btn.click(fn=debug_compile_last_pipeline_zip, inputs=[], outputs=[debug_last_out])
|