From fa996f62d6f01f9c3a947ee735640a571dc0579b Mon Sep 17 00:00:00 2001 From: Flag Date: Wed, 22 Apr 2026 19:48:43 +0000 Subject: [PATCH] =?UTF-8?q?dashboard=20=C2=97=20bouton=20live=20(viser=20n?= =?UTF-8?q?atif=20demo.py)=20+=20PLY=20(fallback=20viser=5Fply)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit live button: - POST /jobs/{id}/live - Probe le port natif (worker viser_port_base + job_id) via nc - 200 + viser_url si demo.py encore alive (necessite le patch keep-alive) - 410 + fallback message si ferme PLY button: - POST /jobs/{id}/view (existant) - Lance viser_ply.py standalone sur port VIEWER_PORT_BASE+id Permet de choisir entre viser natif (PointCloudViewer de lingbot-map avec camera frustums, filtre confiance interactif, animation) et viewer basic XYZ+RGB uniquement. --- app/main.py | 25 +++++++++++++++++++++++++ app/templates/_jobs_table.html | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/app/main.py b/app/main.py index cb7d236..4ce65a9 100644 --- a/app/main.py +++ b/app/main.py @@ -375,6 +375,31 @@ async def view_job(job_id: int): return {"url": f"http://{worker['host']}:{port}"} +@app.post("/jobs/{job_id}/live") +async def live_job(job_id: int): + """Return the URL of demo.py's native viser (PointCloudViewer with camera frustums, + confidence filtering, animation) if it's still listening. Otherwise 404 so the UI falls + back to /view (viser_ply.py standalone).""" + with closing(db()) as conn: + row = conn.execute( + "SELECT viser_url, worker_host FROM jobs WHERE id=? AND status='done'", + (job_id,), + ).fetchone() + if not row or not row["viser_url"]: + raise HTTPException(404, "viser natif jamais démarré") + worker = _worker_by_host(row["worker_host"]) or WORKERS[0] + native_port = worker["viser_port_base"] + job_id + proc = await asyncio.create_subprocess_exec( + "ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=3", worker["ssh_alias"], + f"nc -z -w2 127.0.0.1 {native_port}", + stdout=asyncio.subprocess.DEVNULL, stderr=asyncio.subprocess.DEVNULL, + ) + await proc.wait() + if proc.returncode != 0: + raise HTTPException(410, "viser natif fermé — utilise le bouton PLY") + return {"url": row["viser_url"]} + + @app.post("/stitches/{stitch_id}/view") async def view_stitch(stitch_id: int): with closing(db()) as conn: diff --git a/app/templates/_jobs_table.html b/app/templates/_jobs_table.html index 1c748ce..be9911a 100644 --- a/app/templates/_jobs_table.html +++ b/app/templates/_jobs_table.html @@ -23,7 +23,8 @@ {{ j.progress }}% {% endif %} {% if j.status == 'done' and j.ply_path %} - + + {% endif %} {{ j._duration }}