Le viser de demo.py était tué dès que le PLY était écrit (pour libérer la VRAM),
donc les liens dans le dashboard menaient vers ERR_CONNECTION_REFUSED.
Ajout d'un viewer standalone indépendant :
- scripts/viser_ply.py : charge un PLY via open3d + sert via viser (sans GPU),
subsample random à 2M pts max pour rester fluide
- app/main.py : routes POST /jobs/{id}/view et /stitches/{id}/view qui scp
le script sur le worker et lancent un viser détaché (nohup+setsid+disown via
wrapper shell déposé sur le worker)
- templates : remplace <a href> par <button class=viewer-btn> qui POST puis
window.open de l'URL retournée
- Dockerfile : copie scripts/ dans l'image (nécessaire pour scp-er viser_ply.py)
48 lines
1.3 KiB
HTML
48 lines
1.3 KiB
HTML
<!doctype html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>cosma-qc — dashboard</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<base href="/cosma-qc/">
|
|
<script src="static/htmx.min.js"></script>
|
|
<link rel="stylesheet" href="static/style.css">
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<h1>cosma-qc</h1>
|
|
<span class="sub">post-acquisition QC · lingbot-map pipeline</span>
|
|
</header>
|
|
|
|
<section id="monitor" hx-get="partials/monitor" hx-trigger="load, every 5s" hx-swap="innerHTML">
|
|
<p class="muted">Chargement des workers…</p>
|
|
</section>
|
|
|
|
<section id="jobs">
|
|
<h2>Jobs</h2>
|
|
<div id="jobs-table" hx-get="partials/jobs" hx-trigger="load, every 3s" hx-swap="innerHTML">
|
|
<p class="muted">Chargement…</p>
|
|
</div>
|
|
</section>
|
|
|
|
<script>
|
|
document.addEventListener('click', async (e) => {
|
|
const btn = e.target.closest('.viewer-btn');
|
|
if (!btn) return;
|
|
e.preventDefault();
|
|
const url = btn.dataset.viewUrl;
|
|
btn.textContent = '…';
|
|
btn.disabled = true;
|
|
try {
|
|
const res = await fetch(url, { method: 'POST' });
|
|
const data = await res.json();
|
|
if (res.ok && data.url) window.open(data.url, '_blank');
|
|
else alert(data.detail || 'Erreur lancement viewer');
|
|
} catch (err) { alert('Erreur réseau: ' + err); }
|
|
btn.textContent = 'viser';
|
|
btn.disabled = false;
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|