Kazdy tube zapisuje tytul po swojemu ("[Milfy] Koda Monroe (...)", "Milfy 26 09 16 ...",
"... 4K"), a miniatury sa z innych klatek, wiec ani phash, ani title_duration_dedup
(identyczny tytul) ich nie lapaly. Jedna scena Milfy wisiala w katalogu 8 razy.
Nowy job porownuje rdzen tytulu w obrebie studia: bez nazwy studia, dat, znacznikow
jakosci i nazwisk obsady. Numery czesci zostaja ("Part 1" to nie "Part 2"). Straznicy:
dlugosc, data premiery, wspolna obsada, dluzszy rdzen gdy brak dlugosci. Kopie bez studia
dolaczaja tylko przy zgodnej co do 3 s dlugosci. Kategorie wpisane przez tube jako obsada
nie skracaja rdzenia. Cyklicznie co 12 h z oknem 30 dni.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
93 lines
4.7 KiB
Python
93 lines
4.7 KiB
Python
from datetime import date, datetime
|
||
|
||
from app.scheduler.studio_title_dedup import Cand, plan_merges, same_scene, studio_tokens
|
||
|
||
_T0 = datetime(2026, 9, 16, 23, 0)
|
||
_MILFY = studio_tokens("Milfy", "milfy")
|
||
|
||
|
||
def _c(cid, title, dur=None, rel=None, perfs=(), canon=False, live=1, studio="milfy"):
|
||
return Cand(
|
||
id=cid, title=title, studio_id=studio, studio_name="Milfy", studio_slug="milfy",
|
||
duration_sec=dur, release_date=rel, created_at=_T0, perfs=tuple(perfs), canon=canon, live=live,
|
||
)
|
||
|
||
|
||
# Zgloszenie bb1a357d: ta sama scena z osmiu tubow, kazdy z innym formatem tytulu.
|
||
_MILFY_COPIES = [
|
||
_c("canon", "Voluptuous Therapist Fucks Prisoner", 2218, date(2026, 9, 16),
|
||
("Troy Francisco", "Koda Monroe"), canon=True),
|
||
_c("a", "MILFY – Koda Monroe – Voluptuous Therapist Fucks Prisoner", 2218, date(2026, 9, 16),
|
||
("Troy Francisco", "Koda Monroe"), live=4),
|
||
_c("b", "[Milfy] Koda Monroe (Voluptuous Therapist Fucks Prisoner)", None, date(2026, 9, 16)),
|
||
_c("c", "[MILFY] Koda Monroe – Voluptuous Therapist Fucks Prisoner", perfs=("Koda Monroe",)),
|
||
_c("d", "Koda Monroe - Voluptuous Therapist Fucks Prisoner (17/9/26)", 2218),
|
||
_c("e", "Koda Monroe Voluptuous Therapist Fucks Prisoner 4K", 2218),
|
||
_c("f", "Milfy 26 09 16 Koda Monroe Voluptuous Therapist Fucks Prisoner", None, date(2026, 9, 16)),
|
||
]
|
||
|
||
|
||
def test_milfy_copies_collapse_into_canonical_scene():
|
||
plan = plan_merges(_MILFY_COPIES)
|
||
assert len(plan) == 1
|
||
keep, drops = plan[0]
|
||
assert keep.id == "canon"
|
||
assert {d.id for d in drops} == {"a", "b", "c", "d", "e", "f"}
|
||
|
||
|
||
def test_part_numbers_are_not_dates():
|
||
one = _c("1", "Ariel Swings Her Whip", 600, date(2026, 9, 16))
|
||
two = _c("2", "Ariel Swings Her Whip 2", 600, date(2026, 9, 16))
|
||
assert not same_scene(one, two, _MILFY)
|
||
p1 = _c("p1", "Jewell - Punishment Stool - Part 1", 232, date(2003, 11, 13))
|
||
p2 = _c("p2", "Jewell - Punishment Stool - Part 2", 231, date(2003, 11, 13))
|
||
assert not same_scene(p1, p2, _MILFY)
|
||
|
||
|
||
def test_guards():
|
||
base = _c("x", "Voluptuous Therapist Fucks Prisoner", 2218, date(2026, 9, 16), ("Koda Monroe",))
|
||
longer = _c("y", "Voluptuous Therapist Fucks Prisoner", 2600, date(2026, 9, 16), ("Koda Monroe",))
|
||
assert not same_scene(base, longer, _MILFY)
|
||
later = _c("z", "Voluptuous Therapist Fucks Prisoner", 2218, date(2026, 10, 1), ("Koda Monroe",))
|
||
assert not same_scene(base, later, _MILFY)
|
||
year_only = _c("j", "Voluptuous Therapist Fucks Prisoner", 2218, date(2026, 1, 1), ("Koda Monroe",))
|
||
assert same_scene(base, year_only, _MILFY)
|
||
other_cast = _c("o", "Voluptuous Therapist Fucks Prisoner", 2218, date(2026, 9, 16), ("Someone Else",))
|
||
assert not same_scene(base, other_cast, _MILFY)
|
||
other_studio = _c("s", "Voluptuous Therapist Fucks Prisoner", 2218, date(2026, 9, 16), studio="blacked")
|
||
assert not same_scene(base, other_studio, _MILFY)
|
||
# Bez dlugosci po obu stronach trzy slowa to za malo.
|
||
short_a = _c("sa", "[Milfy] Hot Stepmom Fun")
|
||
short_b = _c("sb", "Milfy 26 09 16 Hot Stepmom Fun")
|
||
assert not same_scene(short_a, short_b, _MILFY)
|
||
|
||
|
||
def test_chain_does_not_pull_in_incompatible_scene():
|
||
keep = _c("k", "Hotel Vixen Season 3 Episode 4 Soft Launch Hard Times", 2608, canon=True)
|
||
bridge = _c("m", "[Milfy] Hotel Vixen Season 3 Episode 4 Soft Launch Hard Times")
|
||
other = _c("l", "Milfy Hotel Vixen Season 3 Episode 4 Soft Launch Hard Times", 2896)
|
||
plan = plan_merges([keep, bridge, other])
|
||
assert [(k.id, [d.id for d in ds]) for k, ds in plan] == [("k", ["m"])]
|
||
|
||
|
||
def test_category_named_as_performer_does_not_shorten_core():
|
||
# Tube wpisal kategorie jako obsade. Bez listy smieci "big", "ass" i "tits" wypadlyby
|
||
# z obu tytulow i dwie rozne sceny mialyby ten sam rdzen "blonde fucks jason luv".
|
||
a = _c("a", "Big Ass Blonde Fucks Jason Luv", perfs=("Big Ass", "Big Tits"))
|
||
b = _c("b", "Big Tits Blonde Fucks Jason Luv")
|
||
assert not same_scene(a, b, _MILFY, junk_names=frozenset({"big ass", "big tits"}))
|
||
|
||
|
||
def test_copies_without_studio_join_only_with_matching_duration():
|
||
orphan = _c("o1", "Koda Monroe - Voluptuous Therapist Fucks Prisoner (17/9/26)", 2218, studio="")
|
||
orphan_4k = _c("o2", "Koda Monroe Voluptuous Therapist Fucks Prisoner 4K", 2217, studio="")
|
||
other_cut = _c("o3", "Koda Monroe Voluptuous Therapist Fucks Prisoner", 2600, studio="")
|
||
no_duration = _c("o4", "Koda Monroe Voluptuous Therapist Fucks Prisoner", None, studio="")
|
||
plan = plan_merges(_MILFY_COPIES + [orphan, orphan_4k, other_cut, no_duration])
|
||
keep, drops = plan[0]
|
||
assert keep.id == "canon"
|
||
ids = {d.id for d in drops}
|
||
assert {"o1", "o2"} <= ids
|
||
assert not ids & {"o3", "o4"}
|
||
# Dwie sceny bez studia nie maja kotwicy.
|
||
assert not same_scene(orphan, orphan_4k, _MILFY)
|