fix: tolerate spotify version suffixes and surface rerank failures

This commit is contained in:
Justin Visser 2026-08-10 14:02:54 +02:00
parent ce652d3114
commit 0ccc9a5d4e
6 changed files with 92 additions and 29 deletions

View file

@ -8,6 +8,7 @@ from difflib import SequenceMatcher
from app.domain.models import Track, TrackCandidate
_SUFFIX_PATTERN = re.compile(r"(?:\s*(?:\([^)]*\)|\[[^]]*\]))+\s*$")
_DASH_SUFFIX_PATTERN = re.compile(r"\s+-\s+[^-]+$")
@dataclass(frozen=True)
@ -35,12 +36,19 @@ def normalize_text(value: str) -> str:
def title_similarity(candidate_title: str, track_title: str) -> float:
"""Return normalized sequence similarity for two track titles."""
return SequenceMatcher(
None,
normalize_text(candidate_title),
normalize_text(track_title),
).ratio()
"""Return normalized title similarity, tolerating version dash suffixes."""
normalized_candidate = normalize_text(candidate_title)
full_similarity = _ratio(normalized_candidate, normalize_text(track_title))
# Spotify appends version info as "Title - Remaster 2023"; some tracks
# only exist in suffixed releases. The tiny penalty keeps an exact
# original title ahead of a suffixed release at equal similarity.
stripped_title = _DASH_SUFFIX_PATTERN.sub("", track_title)
stripped_similarity = _ratio(normalized_candidate, normalize_text(stripped_title)) - 0.001
return max(full_similarity, stripped_similarity)
def _ratio(left: str, right: str) -> float:
return SequenceMatcher(None, left, right).ratio()
def artist_matches(candidate_artist: str, track_artists: tuple[str, ...]) -> bool: