From cf9741b3192f571cce40bd72b6bce36865bbbc44 Mon Sep 17 00:00:00 2001 From: goon-foss Date: Tue, 15 Sep 2026 15:51:08 +0200 Subject: [PATCH] fix(normalize): separator feat/ft w person_named_in naprawde dziala W _PERSON_SEPARATOR_RE zamiast \b staly doslowne znaki 0x08 (heredoc przy commicie b7a8911), wiec tytul nigdy nie byl ciety na feat/ft. Regex uzywa teraz prawdziwych granic slowa, lapie tez "featuring", a myslniki podaje jako escape zamiast doslownych znakow. Skutek w danych sprawdzony na prodzie: 255 701 przypisan na scenach z sxyprn, 6530 tytulow z feat/ft, stara i nowa regula roznia sie w 0 przypadkach, bo sam czlon feat/ft i tak przerywal sasiedztwo nazwiska. Poprawka zamyka przypadki brzegowe (smieciowy performer "Feat"). Co-Authored-By: Claude Opus 5 --- app/normalize/text.py | 6 +++++- tests/test_normalize.py | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/normalize/text.py b/app/normalize/text.py index 91c5f4f..2e6bd05 100644 --- a/app/normalize/text.py +++ b/app/normalize/text.py @@ -153,7 +153,11 @@ _GLUED_NAME_MIN = 5 # rozdzielone przecinkiem albo myślnikiem, a na końcu doklejone tagi. Bez tego cięcia # śmieciowy performer „Rope Bondage" dopasowywał się do ogona „- rope - bondage", # bo po normalizacji separator znika i człony stają się sąsiednie. -_PERSON_SEPARATOR_RE = re.compile(r"\s[-–—]\s|[,|&/;:()\[\]]|feat\.?|ft\.?", re.IGNORECASE) +# `\b` wokol feat/ft byl kiedys zapisany jako znak 0x08, wiec ten separator nigdy nie +# dzialal (naprawione 2026-09-15). Myslniki podajemy jako `\u2013`/`\u2014`, nie doslownie. +_PERSON_SEPARATOR_RE = re.compile( + r"\s[-\u2013\u2014]\s|[,|&/;:()\[\]]|\b(?:feat(?:uring)?|ft)\b\.?", re.IGNORECASE +) def _person_token_match(name_tok: str, text_tok: str, *, exact: bool = False) -> bool: diff --git a/tests/test_normalize.py b/tests/test_normalize.py index 2d20000..e84b1b5 100644 --- a/tests/test_normalize.py +++ b/tests/test_normalize.py @@ -79,6 +79,14 @@ def test_strip_accents_idempotent() -> None: # Przedrostek z limitem dlugosci: wariant zapisu tak, doklejone slowo nie. ("Alexis Crystal Returns", "Alexis Crystalline", False), ("Sasha Grey Returns", "Sash Grey", True), + # feat/ft/featuring rozdziela osoby, nazwisko nie moze przez nie przejsc. + ("Anna Bell ft. Bella Rose", "Bell Ft", False), + ("Anna Bell feat Bella Rose", "Feat", False), + ("Anna Bell FEAT. Bella Rose", "Bella Rose", True), + ("Lily Lou featuring Bella Rose", "Lily Lou", True), + ("Sasha Paige ft.Martin Spell", "Martin Spell", True), + # ft wewnatrz slowa to nie separator. + ("Craft Beer Night", "Craft Beer", True), ], ) def test_person_named_in(title: str, person: str, expected: bool) -> None: