fix(performers): zbedne przypisania jednotokenowe obok osoby pelnoimiennej
Ranking z poprzedniego commita ujawnil klase, ktorej zaden wczesniejszy sygnal nie widzial: wpisy bedace SAMYM NAZWISKIEM albo samym imieniem, powstale z rozbicia peleno nazwy przez tube-search. "Devine" obok "Shalina Devine", "Kitana" obok "Kitana A", "Rayne" obok "Tiffany Rayne". Taki wpis lapie potem kazda scene z tym slowem, nalezaca do zupelnie innej osoby. Regula jest DOWODLIWIE BEZSTRATNA: kasujemy przypisanie jednotokenowe tylko wtedy, gdy ta sama scena ma juz przypisana osobe pelnoimienna zawierajaca to slowo. Informacja o obsadzie zostaje, znika tylko niejednoznaczny duplikat. Kontrola potwierdzila, ze zadna scena nie zostala przez to bez obsady (0). Prowenancja z migracji 0026 dala zabezpieczenie: z 62 783 zbednych przypisan 62 120 to scraper (skasowane), 73 kanon (chronione), 590 nieznane (zostawione). Bez niej nie dalo by sie tego rozdzielic. Wynik: 62 120 przypisan zdjetych, 2156 wpisow odchudzonych (Devine 170 na 60), 1740 pustych rekordow usunietych. Regula dopieta do joba junk_performers, drugi przebieg daje zera. Zostaje residuum: sceny, na ktorych osoba pelnoimienna NIE byla przypisana, wiec regula nie miala sie o co oprzec (James, Blue, Moon, Crystal, Cruz, Starr, Knight po 60-160 przypisan). Tam trzeba by DOPISAC wlasciwa osobe, a nie kasowac - to osobne, bardziej ryzykowne zadanie. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
ef8c255e1f
commit
9af5fd4eb4
1 changed files with 43 additions and 2 deletions
|
|
@ -129,6 +129,32 @@ def find_junk_performers(
|
|||
return list(ids)
|
||||
|
||||
|
||||
# Jednotokenowy performer jest ZBĘDNY na scenie, która ma już osobę pełnoimienną
|
||||
# zawierającą to samo słowo: „Devine" obok „Shalina Devine", „Kitana" obok „Kitana A".
|
||||
# To rozbite zapisy tej samej osoby, powstałe z parsowania tytułów przez tube-search —
|
||||
# jeden wpis nazwiskiem łapie potem wszystkie sceny z tym nazwiskiem, należące do
|
||||
# zupełnie innych ludzi (audyt 2026-07-27: 62 tys. takich przypisań, 2156 wpisów).
|
||||
#
|
||||
# Kasowanie jest DOWODLIWIE BEZSTRATNE: warunek wymaga, żeby konkretna osoba już była
|
||||
# przypisana do tej sceny, więc informacja o obsadzie zostaje. Żadna scena nie może
|
||||
# przez to zostać bez obsady (sprawdzone: 0).
|
||||
#
|
||||
# Ograniczone do `kind='scraper'` — przypisania z kanonu zostają nietknięte (73 takie).
|
||||
_PRUNE_SURNAME_SQL = """
|
||||
DELETE FROM scene_performers sp
|
||||
USING sources s, performers p
|
||||
WHERE p.id = sp.performer_id
|
||||
AND p.canonical_name !~ ' '
|
||||
AND length(p.canonical_name) >= 4
|
||||
AND s.id = sp.source_id
|
||||
AND s.kind = 'scraper'
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM scene_performers sp2 JOIN performers q ON q.id = sp2.performer_id
|
||||
WHERE sp2.scene_id = sp.scene_id AND q.id <> p.id AND q.canonical_name ~ ' '
|
||||
AND q.canonical_name ~* ('\\m' || p.canonical_name || '\\M')
|
||||
)
|
||||
"""
|
||||
|
||||
_PRUNE_ARTIFACT_SQL = """
|
||||
DELETE FROM scene_performers sp
|
||||
USING sources s, performers p
|
||||
|
|
@ -148,8 +174,9 @@ WHERE length(trim(p.canonical_name)) <= :max_len
|
|||
def prune_artifact_name_attributions(
|
||||
session: Session, *, max_len: int = MAX_ARTIFACT_NAME_LEN
|
||||
) -> tuple[int, int]:
|
||||
"""Zdejmij scraperowe przypisania z nazw 1-2 znakowych i usuń tych, którym nic nie
|
||||
zostało. Kanoniczne przypisania zostają nietknięte — patrz MAX_ARTIFACT_NAME_LEN.
|
||||
"""Zdejmij scraperowe przypisania w dwóch przypadkach i usuń tych, którym nic nie
|
||||
zostało: (1) nazwy 1-2 znakowe, (2) jednotokenowy performer na scenie, która ma już
|
||||
osobę pełnoimienną zawierającą to słowo. Kanoniczne przypisania zostają nietknięte.
|
||||
|
||||
Wymaga wypełnionego `scene_performers.source_id` (migracja 0026): bez provenance nie
|
||||
dałoby się odróżnić „Cj" z obsady TPDB od „Cj" wyłuskanego z tytułu przez tube-search.
|
||||
|
|
@ -157,9 +184,23 @@ def prune_artifact_name_attributions(
|
|||
pruned = int(
|
||||
session.execute(text(_PRUNE_ARTIFACT_SQL), {"max_len": max_len}).rowcount or 0
|
||||
)
|
||||
pruned += int(session.execute(text(_PRUNE_SURNAME_SQL)).rowcount or 0)
|
||||
dropped = int(
|
||||
session.execute(text(_DROP_EMPTY_ARTIFACT_SQL), {"max_len": max_len}).rowcount or 0
|
||||
)
|
||||
dropped += int(
|
||||
session.execute(
|
||||
text(
|
||||
"DELETE FROM performers p WHERE p.canonical_name !~ ' ' "
|
||||
"AND length(p.canonical_name) >= 4 "
|
||||
"AND NOT EXISTS (SELECT 1 FROM scene_performers sp "
|
||||
"WHERE sp.performer_id = p.id) "
|
||||
"AND NOT EXISTS (SELECT 1 FROM performer_external_refs r "
|
||||
"JOIN sources s ON s.id = r.source_id WHERE r.performer_id = p.id "
|
||||
"AND s.kind IN ('tpdb','stashdb'))"
|
||||
)
|
||||
).rowcount or 0
|
||||
)
|
||||
return pruned, dropped
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue