This commit is contained in:
Francesco Durighetto 2026-06-29 13:40:43 +03:00 committed by GitHub
commit 0de1641b90
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 96 additions and 5 deletions

View file

@ -8513,6 +8513,22 @@ class MusicDatabase:
cleaned = re.sub(r'\s*\(with\s+[^)]*\)', '', cleaned, flags=re.IGNORECASE)
cleaned = re.sub(r'\s*\[with\s+[^\]]*\]', '', cleaned, flags=re.IGNORECASE)
# Featuring in parentheses/brackets — must run BEFORE bracket flattening.
# Otherwise ``feat.`` removal after flattening is greedy and strips
# version suffixes ("Extended Mix", "Radio Edit", …) from the same title.
cleaned = re.sub(
r'\s*\([^)]*(?:feat\.?|ft\.?|featuring)[^)]*\)',
'',
cleaned,
flags=re.IGNORECASE,
)
cleaned = re.sub(
r'\s*\[[^\]]*(?:feat\.?|ft\.?|featuring)[^\]]*\]',
'',
cleaned,
flags=re.IGNORECASE,
)
# STEP 1: Normalize bracket/dash styles for consistent matching
# Convert all bracket styles to spaces for better matching
cleaned = re.sub(r'\s*[\[\(]\s*', ' ', cleaned) # Convert opening brackets/parens to space
@ -8528,11 +8544,6 @@ class MusicDatabase:
r'\s*explicit\s*', # Remove explicit markers
r'\s*clean\s*', # Remove clean markers
# Featuring/collaboration (metadata, not different version)
r'\s*feat\..*', # Remove featuring
r'\s*featuring.*', # Remove featuring
r'\s*ft\..*', # Remove ft.
# Remasters (same recording, different mastering)
r'\s*\d{4}\s*remaster.*', # Remove "2015 remaster"
r'\s*remaster.*', # Remove "remaster/remastered"
@ -8569,6 +8580,19 @@ class MusicDatabase:
for pattern in patterns_to_remove:
cleaned = re.sub(pattern, '', cleaned, flags=re.IGNORECASE).strip()
# Unparenthesized featuring (e.g. after bracket flatten) — bounded so
# "feat. Vika - Extended Mix" keeps the version tail.
_version_boundary = (
r'(?:extended|radio|club|dub|instrumental|acoustic|live|remix|'
r'original|edit|mix|version)\b'
)
cleaned = re.sub(
rf'\s+(?:feat\.?|ft\.?|featuring)\s+.+?(?=\s+-\s+{_version_boundary}|\s+{_version_boundary}|$)',
'',
cleaned,
flags=re.IGNORECASE,
).strip()
# STEP 3: Clean up extra spaces
cleaned = re.sub(r'\s+', ' ', cleaned).strip()

View file

@ -0,0 +1,67 @@
"""Regression: normal vs Extended Mix must not collapse to the same cleaned title."""
import tempfile
from pathlib import Path
import pytest
from database.music_database import DatabaseTrack, MusicDatabase
@pytest.fixture
def db(tmp_path: Path):
return MusicDatabase(database_path=str(tmp_path / "test.db"))
def test_clean_title_preserves_extended_mix_after_feat(db):
normal = db._clean_track_title_for_comparison("Latinamerica (feat. Vika)")
extended = db._clean_track_title_for_comparison(
"Latinamerica (feat. Vika) - Extended Mix"
)
assert normal == "latinamerica"
assert extended == "latinamerica extended mix"
assert normal != extended
def test_normal_does_not_match_extended_in_library(db):
extended_track = DatabaseTrack(
id="t1",
album_id="a1",
artist_id="ar1",
title="Latinamerica (feat. Vika) - Extended Mix",
track_number=1,
duration=300000,
file_path="/music/ext.flac",
bitrate=320,
)
extended_track.artist_name = "Raffa FL"
extended_track.album_title = "Latinamerica (feat. Vika)"
confidence = db._calculate_track_confidence(
"Latinamerica (feat. Vika)",
"Raffa FL",
extended_track,
)
assert confidence < 0.7
def test_extended_matches_extended_in_library(db):
extended_track = DatabaseTrack(
id="t1",
album_id="a1",
artist_id="ar1",
title="Latinamerica (feat. Vika) - Extended Mix",
track_number=1,
duration=300000,
file_path="/music/ext.flac",
bitrate=320,
)
extended_track.artist_name = "Raffa FL"
extended_track.album_title = "Latinamerica (feat. Vika)"
confidence = db._calculate_track_confidence(
"Latinamerica (feat. Vika) - Extended Mix",
"Raffa FL",
extended_track,
)
assert confidence >= 0.7