Files
ani-cli-web/title_matching.py

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