fix(api): collapse same-origin playback sources on scene detail

A merged scene often aggregates several uploads from ONE tube (re-encodes / 4K
dups). bug-report aa79a995 "why 2 links, both porntrex?" = same scene std + 4K
(porntrex 2591377 + 2593449 "...in 4K"). In the UI these are indistinguishable
links to one hoster (same extractor). Keep one best per origin: prefer duration
matching the scene → any duration → first (origin-asc stable). Dead already filtered.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jtrzupek 2026-06-08 11:50:45 +02:00
parent 65b9df073a
commit f8b1e801ef

View file

@ -709,6 +709,27 @@ def _build_scene_out(session: Session, scene: Scene) -> SceneOut:
.scalars() .scalars()
.all() .all()
) )
# Collapse źródła dzielące ten sam origin (hoster). Zmergowana scena często agreguje
# kilka uploadów z JEDNEGO tube'a (re-enkody / wersje 4K: bug-report aa79a995 "2 linki,
# oba do porntrex" = ta sama scena std+4K) — w UI to nierozróżnialne linki do tego
# samego hostera (resolvują tym samym extractorem). Zostawiamy jeden najlepszy per
# origin: preferuj długość zgodną ze sceną (realny match) → jakąkolwiek długość →
# pierwszy (stabilnie, query jest origin-asc). Martwe już odfiltrowane (dead_at).
def _origin_pick_key(p: PlaybackSource) -> tuple[int, int]:
dur_match = (
0 if (scene.duration_sec and p.duration_sec
and abs(p.duration_sec - scene.duration_sec) <= 5) else 1
)
return (dur_match, 0 if p.duration_sec else 1)
_best_by_origin: dict[str, PlaybackSource] = {}
for p in playback_rows:
key = p.origin or ""
cur = _best_by_origin.get(key)
if cur is None or _origin_pick_key(p) < _origin_pick_key(cur):
_best_by_origin[key] = p
playback_rows = list(_best_by_origin.values())
playback_out: list[PlaybackSourceOut] = [] playback_out: list[PlaybackSourceOut] = []
for p in playback_rows: for p in playback_rows:
out = PlaybackSourceOut.model_validate(p) out = PlaybackSourceOut.model_validate(p)