goon/app/templates/candidate_detail.html
goon-foss ad0284585b Initial commit
Goon — self-hosted aggregator for adult-content scene metadata.

Indexes scenes from TPDB, StashDB, and 30+ public adult tube sites.
Cross-source deduplication via perceptual hash + Levenshtein distance.
FastAPI backend + APScheduler worker + React Native (Expo) mobile client.

FOSS, ad-free, donation-funded. See README for details.
2026-05-20 10:10:22 +02:00

83 lines
2.7 KiB
HTML

{% extends "base.html" %}
{% block title %}Candidate · goon{% endblock %}
{% block content %}
<div class="toolbar">
<a href="/ui/">← back</a>
<span class="muted">{{ cand.kind }} · {{ cand.status }}</span>
<span class="score {{ score_class(cand.score) }}">{{ '%.2f' % cand.score }}</span>
</div>
{% if cand.status == "pending" %}
<div class="card" id="actions">
<form
method="post"
hx-post="/ui/candidate/{{ cand.id }}/resolve"
hx-target="#actions"
hx-swap="outerHTML"
style="display:flex;gap:8px;flex-wrap:wrap;align-items:center;"
>
<button name="action" value="merge_keep_left" class="primary">Merge → keep LEFT</button>
<button name="action" value="merge_keep_right" class="primary">Merge → keep RIGHT</button>
<button name="action" value="reject" class="danger">Reject (keep both)</button>
</form>
</div>
{% else %}
<div class="card muted">Resolved.</div>
{% endif %}
<div class="row">
<div class="col card">
<h2>LEFT</h2>
{% if cand.left %}
{{ scene_block(cand.left) }}
{% else %}
<div class="muted">scene missing (id={{ cand.left_id }})</div>
{% endif %}
</div>
<div class="col card">
<h2>RIGHT</h2>
{% if cand.right %}
{{ scene_block(cand.right) }}
{% else %}
<div class="muted">scene missing (id={{ cand.right_id }})</div>
{% endif %}
</div>
</div>
<div class="card">
<h2>Reasons</h2>
<pre>{{ cand.reasons | tojson(indent=2) }}</pre>
</div>
{% macro scene_block(s) %}
<div class="stack">
<div><strong>{{ s.title }}</strong></div>
<div class="muted">
{{ s.release_date or '?' }}
{% if s.studio %} · {{ s.studio.name }}{% endif %}
{% if s.duration_sec %} · {{ '%dm%02ds' % (s.duration_sec // 60, s.duration_sec % 60) }}{% endif %}
</div>
{% if s.code %}<div class="muted">code: {{ s.code }}</div>{% endif %}
<div>
{% for p in s.performers %}
<span class="pill">
{{ p.canonical_name }}{% if p.as_alias %} <span class="muted">as {{ p.as_alias }}</span>{% endif %}
</span>
{% endfor %}
</div>
<div>
{% for t in s.tags %}<span class="pill">{{ t.name }}</span>{% endfor %}
</div>
<div class="muted">
sources:
{% for r in s.external_refs %}
<span class="pill">{{ r.source }}{% if r.external_id %} · {{ r.external_id[:8] }}{% endif %}</span>
{% endfor %}
</div>
{% if s.description %}
<div class="muted" style="margin-top:8px;">{{ s.description[:280] }}{% if s.description|length > 280 %}…{% endif %}</div>
{% endif %}
</div>
{% endmacro %}
{% endblock %}