fix(scenes): filter junk 'performers' from similar-scene matching
Some checks are pending
Backend tests / test (push) Waiting to run

Kategorie/studia podszywające się pod performera (over-attribution z luźnego
tube-searcha: 'Big Tits', 'Brazzers', 'Ball Licking') zaśmiecały ranking similar
— klastrował po nich zamiast po treści. Odsiew: slug performera pokrywa się z
tagiem I brak kanonicznego refa (tpdb/stashdb). Prawdziwi performerzy z tym samym
tagiem mają kanoniczny ref → zostają (Jax Slayher/Angela White OK). Scena z samymi
śmieciowymi performerami spada na tag-matching (i pusto gdy ma tylko mega-tag).
This commit is contained in:
goon-foss 2026-07-21 15:50:49 +02:00
parent 45459b414b
commit f97369a764

View file

@ -26,7 +26,7 @@ from app.api.schemas import (
from app.db import get_session
from app.api.device import LEGACY_DEVICE, get_device_id
from app.models.favorite_scene import FavoriteScene
from app.models.performer import Performer
from app.models.performer import Performer, PerformerExternalRef
from app.models.play_progress import ScenePlayProgress
from app.models.playback_source import PlaybackSource
from app.models.scene import Scene, SceneExternalRef, ScenePerformer, SceneTag
@ -526,6 +526,31 @@ def similar_scenes(
perf_ids = session.execute(
select(ScenePerformer.performer_id).where(ScenePerformer.scene_id == scene_id)
).scalars().all()
# Odsiej ŚMIECIOWYCH performerów: kategorie/studia podszywające się pod performera
# (over-attribution z luźnego tube-searcha — np. "Big Tits", "Brazzers", "Ball Licking").
# Sygnał: slug pokrywa się z tagiem I performer NIE ma kanonicznego refa (tpdb/stashdb).
# Prawdziwi performerzy z tym samym tagiem (tuby tagują sceny nazwiskiem) mają kanoniczny
# ref → zostają. Bez tego similar klastrował się po "Ball Licking" zamiast po treści.
if perf_ids:
junk = set(
session.execute(
select(Performer.id).where(
Performer.id.in_(perf_ids),
exists(select(1).select_from(Tag).where(Tag.slug == Performer.slug)),
~exists(
select(1)
.select_from(PerformerExternalRef)
.join(Source, Source.id == PerformerExternalRef.source_id)
.where(
PerformerExternalRef.performer_id == Performer.id,
Source.kind.in_([SourceKind.tpdb, SourceKind.stashdb]),
)
),
)
).scalars().all()
)
if junk:
perf_ids = [p for p in perf_ids if p not in junk]
tag_ids = session.execute(
select(SceneTag.tag_id).where(SceneTag.scene_id == scene_id)
).scalars().all()