Files
cosma-qc/app/templates/_jobs_table.html
Poulpe 468f9084ec viewer on-demand — relancer viser à la demande depuis le dashboard
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)
2026-04-21 13:09:48 +00:00

83 lines
3.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% if not acquisitions %}
<p class="muted">Aucune acquisition. Ingeste un dossier via <code>scripts/ingest.py</code>.</p>
{% else %}
<div class="acq-grid">
{% for acq in acquisitions %}
<div class="acq-col">
<h3 class="acq-title">
{{ acq.name }} <span class="total">{{ acq.total_duration }}</span>
</h3>
<ul class="job-list">
{% for j in acq.jobs %}
<li class="job-item {{ j.status }}">
<span class="icon">
{% if j.status == 'done' %}<span class="check"></span>
{% elif j.status in ('running','extracting') %}<span class="spin"></span>
{% elif j.status == 'error' %}<span class="err"></span>
{% else %}<span class="sq"></span>{% endif %}
</span>
<span class="label">
{{ j.auv }}/{{ j.gopro_serial }}/{{ j.segment_label }}
{% if j.status == 'done' and j.ply_path %}
<button class="ext viewer-btn" data-view-url="jobs/{{ j.id }}/view">viser</button>
{% endif %}
</span>
<span class="dur">{{ j._duration }}</span>
{% if j.status in ('queued','extracting','running') %}
<button class="mini" hx-post="jobs/{{ j.id }}/cancel" hx-target="#jobs-table">×</button>
{% elif j.status == 'error' %}
<button class="mini" hx-post="jobs/{{ j.id }}/retry" hx-target="#jobs-table"></button>
{% else %}
<span></span>
{% endif %}
</li>
{% if j.error %}<li class="err-line">{{ j.error }}</li>{% endif %}
{% endfor %}
</ul>
<div class="stitch-section">
<div class="stitch-title">
<span class="icon"><span class="sq"></span></span>
<span>stitch</span>
</div>
{% if acq.stitches %}
<ul class="stitch-children">
{% for s in acq.stitches %}
<li class="sub {{ s.status }}">
<span class="icon stitch-icon">
{% if s.status == 'done' %}<span class="check ok"></span>
{% elif s.status == 'running' %}<span class="spin"></span>
{% elif s.status == 'error' %}<span class="err"></span>
{% else %}<span class="sq"></span>{% endif %}
</span>
<span>
{% if s.level == 'per_auv' %}pair GP1↔GP2 {{ s.auv }}
{% else %}merge final{% endif %}
{% if s._duration %}<span class="dur muted"> — {{ s._duration }}</span>{% endif %}
{% if s.status == 'done' and s.output_ply %}
<button class="ext viewer-btn" data-view-url="stitches/{{ s.id }}/view" title="{{ s.output_ply }}">viser</button>
{% endif %}
</span>
{% if s.status in ('queued','running') %}
<button class="mini" hx-post="stitches/{{ s.id }}/cancel" hx-target="#jobs-table">×</button>
{% elif s.status == 'error' %}
<button class="mini" hx-post="stitches/{{ s.id }}/retry" hx-target="#jobs-table"></button>
{% endif %}
</li>
{% if s.error %}<li class="err-line" style="padding-left:42px">{{ s.error[:120] }}</li>{% endif %}
{% endfor %}
</ul>
{% else %}
<ul class="stitch-children">
<li class="sub pending"><span class="sq"></span> pair GP1↔GP2 per AUV</li>
<li class="sub pending"><span class="sq"></span> cross-AUV merge</li>
<li class="sub pending"><span class="sq"></span> final PLY</li>
</ul>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% endif %}