84 lines
2.4 KiB
Python
84 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""Shared anime title normalization and matching helpers."""
|
|
|
|
import re
|
|
import unicodedata
|
|
|
|
|
|
def normalize_title_key(value):
|
|
text = unicodedata.normalize("NFKD", str(value or ""))
|
|
text = "".join(char for char in text if not unicodedata.combining(char))
|
|
text = text.lower()
|
|
text = re.sub(r"\((19|20)\d{2}\)", " ", text)
|
|
text = re.sub(r"[^a-z0-9]+", " ", text)
|
|
return re.sub(r"\s+", " ", text).strip()
|
|
|
|
|
|
def normalize_identity_title_key(value):
|
|
text = normalize_title_key(value)
|
|
if not text:
|
|
return ""
|
|
text = re.sub(r"\b(\d+)(st|nd|rd|th)\s+season\b", r"season \1", text)
|
|
return re.sub(r"\s+", " ", text).strip()
|
|
|
|
|
|
def base_title_variants(value):
|
|
text = str(value or "").strip()
|
|
variants = []
|
|
if text:
|
|
variants.append(text)
|
|
patterns = [
|
|
r"\s+\((19|20)\d{2}\)\s*$",
|
|
r"\s+season\s+\d+\s*$",
|
|
r"\s+part\s+\d+\s*$",
|
|
r"\s+cour\s+\d+\s*$",
|
|
r"\s+\d+(st|nd|rd|th)\s+season\s*$",
|
|
]
|
|
changed = True
|
|
current = text
|
|
while current and changed:
|
|
changed = False
|
|
for pattern in patterns:
|
|
trimmed = re.sub(pattern, "", current, flags=re.IGNORECASE).strip(" -:")
|
|
if trimmed and trimmed != current:
|
|
current = trimmed
|
|
if current not in variants:
|
|
variants.append(current)
|
|
changed = True
|
|
return variants
|
|
|
|
|
|
def title_match_variants(value):
|
|
variants = set()
|
|
for raw_value in base_title_variants(value):
|
|
normalized = normalize_title_key(raw_value)
|
|
if normalized:
|
|
variants.add(normalized)
|
|
stripped = re.sub(r"\b(19|20)\d{2}\b", " ", normalized)
|
|
stripped = re.sub(r"\s+", " ", stripped).strip()
|
|
if stripped:
|
|
variants.add(stripped)
|
|
return variants
|
|
|
|
|
|
def identity_title_variants(value):
|
|
variants = set()
|
|
normalized = normalize_identity_title_key(value)
|
|
if normalized:
|
|
variants.add(normalized)
|
|
stripped = re.sub(r"\b(19|20)\d{2}\b", " ", normalized)
|
|
stripped = re.sub(r"\s+", " ", stripped).strip()
|
|
if stripped:
|
|
variants.add(stripped)
|
|
return variants
|
|
|
|
|
|
def title_lookup_queries(value):
|
|
queries = []
|
|
for raw_value in base_title_variants(value):
|
|
text = str(raw_value or "").strip()
|
|
if text and text not in queries:
|
|
queries.append(text)
|
|
return queries
|