import os import json import subprocess from pathlib import Path from fastapi import HTTPException from config import EPT_DIR from services.manifest import save_manifest from utils.disk import get_entwine_path ENTWINE_PATH = get_entwine_path() ENTWINE_AVAILABLE = ENTWINE_PATH is not None def run_entwine(input_path: Path, out_dir: Path) -> dict: if not ENTWINE_AVAILABLE: raise HTTPException(status_code=500, detail="entwine n'est pas installé ou introuvable dans le PATH") out_dir.mkdir(parents=True, exist_ok=True) # entwine build -i -o cmd = [ ENTWINE_PATH, "build", "-i", str(input_path.absolute()), "-o", str(out_dir.absolute()), ] print(f"Exécution: {' '.join(cmd)}") print(f"CMD: {cmd}") proc = subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, timeout=7200, env=os.environ.copy() ) if proc.returncode != 0: raise HTTPException(status_code=500, detail=f"entwine failed (code {proc.returncode}):\n{proc.stdout}") result = _analyze_ept_output(out_dir, proc.stdout) save_manifest(out_dir, result) return result def _analyze_ept_output(out_dir: Path, entwine_output: str) -> dict: """ Entwine produit un dossier EPT dont la structure est : out_dir/ ept.json ← fichier d'entrée principal ept-data/ ← tuiles binaires ept-hierarchy/ ← hiérarchie des noeuds """ ept_json = out_dir / "ept.json" result = { "format": "ept", "entry_file": None, "entry_type": None, "stdout": entwine_output[-2000:], } if ept_json.exists(): result["entry_file"] = ept_json.relative_to(EPT_DIR).as_posix() result["entry_type"] = "ept.json" # Le dossier EPT = le dossier contenant ept.json result["ept_dir"] = str(ept_json.parent.relative_to(EPT_DIR)) else: raise HTTPException(status_code=500, detail=f"entwine a terminé mais ept.json introuvable dans {out_dir}") return result