Siyuan Hu commited on
Commit
aab81af
·
1 Parent(s): f3dfa83

feat(runtime): download tectonic on-the-fly into runs/_bin when not found; use for both poster and debug compiles

Browse files
Files changed (1) hide show
  1. app.py +50 -26
app.py CHANGED
@@ -354,6 +354,54 @@ def render_overleaf_button(overleaf_b64):
354
  """
355
  return html
356
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
  def _compile_poster_pdf(OUTPUT_DIR: Path, logs):
358
  """
359
  Compile output/poster_latex_proj/poster_output.tex into a PDF using an
@@ -380,20 +428,8 @@ def _compile_poster_pdf(OUTPUT_DIR: Path, logs):
380
 
381
  def _has(bin_name):
382
  return _sh.which(bin_name) is not None
383
- def _candidate_tectonic():
384
- import os
385
- cands = [
386
- "tectonic",
387
- str(Path("/usr/local/bin/tectonic")),
388
- str(Path("/usr/bin/tectonic")),
389
- os.path.expanduser("~/.local/bin/tectonic"),
390
- ]
391
- for c in cands:
392
- if _sh.which(c) or Path(c).exists():
393
- return c
394
- return None
395
 
396
- tbin = _candidate_tectonic()
397
  if tbin:
398
  cmd = [tbin, tex_path.name]
399
  logs.append("▶ Compiling with tectonic …")
@@ -457,19 +493,7 @@ def _compile_tex_to_pdf(tex_path: Path, logs):
457
  import shutil as _sh, subprocess as _sp
458
  def _has(bin_name):
459
  return _sh.which(bin_name) is not None
460
- def _candidate_tectonic():
461
- import os
462
- cands = [
463
- "tectonic",
464
- str(Path("/usr/local/bin/tectonic")),
465
- str(Path("/usr/bin/tectonic")),
466
- os.path.expanduser("~/.local/bin/tectonic"),
467
- ]
468
- for c in cands:
469
- if _sh.which(c) or Path(c).exists():
470
- return c
471
- return None
472
- tbin = _candidate_tectonic()
473
  if tbin:
474
  cmd = [tbin, tex_path.name]
475
  logs.append("▶ Compiling with tectonic …")
 
354
  """
355
  return html
356
 
357
+ def _get_tectonic_bin(logs):
358
+ """Return a usable path to the tectonic binary. Try PATH/common paths; if not found, download to runs/_bin."""
359
+ import shutil as _sh, tarfile, urllib.request, os
360
+ # 1) existing in PATH or common dirs
361
+ cands = [
362
+ "tectonic",
363
+ str(Path("/usr/local/bin/tectonic")),
364
+ str(Path("/usr/bin/tectonic")),
365
+ os.path.expanduser("~/.local/bin/tectonic"),
366
+ str((RUNS_DIR / "_bin" / "tectonic").resolve()),
367
+ ]
368
+ for c in cands:
369
+ if _sh.which(c) or Path(c).exists():
370
+ return c
371
+ # 2) download to runs/_bin
372
+ try:
373
+ url = "https://github.com/tectonic-typesetting/tectonic/releases/download/tectonic%400.15.0/tectonic-0.15.0-x86_64-unknown-linux-gnu.tar.gz"
374
+ bin_dir = RUNS_DIR / "_bin"
375
+ bin_dir.mkdir(parents=True, exist_ok=True)
376
+ tgz = bin_dir / "tectonic.tar.gz"
377
+ logs.append("⬇️ Downloading tectonic binary …")
378
+ with urllib.request.urlopen(url, timeout=60) as resp, open(tgz, "wb") as out:
379
+ out.write(resp.read())
380
+ with tarfile.open(tgz, "r:gz") as tf:
381
+ tf.extractall(path=bin_dir)
382
+ # find binary
383
+ tbin = None
384
+ for p in bin_dir.rglob("tectonic"):
385
+ if p.is_file() and os.access(p, os.X_OK):
386
+ tbin = p
387
+ break
388
+ if not tbin:
389
+ # make executable if needed
390
+ for p in bin_dir.rglob("tectonic"):
391
+ try:
392
+ p.chmod(0o755)
393
+ tbin = p
394
+ break
395
+ except Exception:
396
+ continue
397
+ if tbin:
398
+ logs.append(f"✅ Tectonic ready at {tbin}")
399
+ return str(tbin)
400
+ logs.append("⚠️ Tectonic binary not found after download.")
401
+ except Exception as e:
402
+ logs.append(f"⚠️ Tectonic download failed: {e}")
403
+ return None
404
+
405
  def _compile_poster_pdf(OUTPUT_DIR: Path, logs):
406
  """
407
  Compile output/poster_latex_proj/poster_output.tex into a PDF using an
 
428
 
429
  def _has(bin_name):
430
  return _sh.which(bin_name) is not None
 
 
 
 
 
 
 
 
 
 
 
 
431
 
432
+ tbin = _get_tectonic_bin(logs)
433
  if tbin:
434
  cmd = [tbin, tex_path.name]
435
  logs.append("▶ Compiling with tectonic …")
 
493
  import shutil as _sh, subprocess as _sp
494
  def _has(bin_name):
495
  return _sh.which(bin_name) is not None
496
+ tbin = _get_tectonic_bin(logs)
 
 
 
 
 
 
 
 
 
 
 
 
497
  if tbin:
498
  cmd = [tbin, tex_path.name]
499
  logs.append("▶ Compiling with tectonic …")