From 0de8841b14a28b3da95f21fa1bb8d2db7cb4fa81 Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Thu, 19 Mar 2026 08:53:14 -0700 Subject: [PATCH] Fix bulk Fix All ignoring Single/Album Dedup findings and expand version keywords - Add single_album_redundant to fixable_types in bulk_fix_findings so Fix All actually includes these findings (Fix Selected worked, Fix All silently returned 0) - Expand version keyword regex from 9 to 25 terms (remastered, deluxe, unplugged, etc.) to reduce false positives in Single/Album Dedup - Add word boundary anchors to prevent substring matches (e.g. "live" inside "Alive", "edit" inside "Meditate") - Cast similarity thresholds to float for config type safety --- core/repair_jobs/duplicate_detector.py | 4 ++-- core/repair_jobs/single_album_dedup.py | 9 ++++++--- core/repair_worker.py | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/core/repair_jobs/duplicate_detector.py b/core/repair_jobs/duplicate_detector.py index ee0b9af4..5588c642 100644 --- a/core/repair_jobs/duplicate_detector.py +++ b/core/repair_jobs/duplicate_detector.py @@ -42,8 +42,8 @@ class DuplicateDetectorJob(RepairJob): result = JobResult() settings = self._get_settings(context) - title_threshold = settings.get('title_similarity', 0.85) - artist_threshold = settings.get('artist_similarity', 0.80) + title_threshold = float(settings.get('title_similarity', 0.85)) + artist_threshold = float(settings.get('artist_similarity', 0.80)) ignore_cross_album = settings.get('ignore_cross_album', True) # Fetch all tracks with artist/album names via JOIN diff --git a/core/repair_jobs/single_album_dedup.py b/core/repair_jobs/single_album_dedup.py index eb95b42d..cbcad948 100644 --- a/core/repair_jobs/single_album_dedup.py +++ b/core/repair_jobs/single_album_dedup.py @@ -42,8 +42,8 @@ class SingleAlbumDedupJob(RepairJob): result = JobResult() settings = self._get_settings(context) - title_threshold = settings.get('title_similarity', 0.85) - artist_threshold = settings.get('artist_similarity', 0.80) + title_threshold = float(settings.get('title_similarity', 0.85)) + artist_threshold = float(settings.get('artist_similarity', 0.80)) # Fetch all tracks with album type info conn = None @@ -257,7 +257,10 @@ class SingleAlbumDedupJob(RepairJob): _VERSION_KEYWORDS = re.compile( - r'(live|acoustic|remix|demo|instrumental|radio edit|extended|karaoke|a\s?cappella)', + r'\b(live|acoustic|remix|remixed|demo|instrumental|radio edit|extended|karaoke|' + r'a\s?cappella|remaster(?:ed)?|deluxe|bonus|stripped|unplugged|orchestral|' + r'sped up|slowed|reverb|clean|explicit|mono|stereo|alternate|alt\.?\s*(?:version|mix)|' + r'club mix|dub mix|vip mix|edit)\b', re.IGNORECASE, ) diff --git a/core/repair_worker.py b/core/repair_worker.py index 044bc635..1e60c85c 100644 --- a/core/repair_worker.py +++ b/core/repair_worker.py @@ -1709,7 +1709,8 @@ class RepairWorker: # Build query for pending fixable findings fixable_types = ('dead_file', 'orphan_file', 'track_number_mismatch', - 'missing_cover_art', 'metadata_gap', 'duplicate_tracks', 'mbid_mismatch', + 'missing_cover_art', 'metadata_gap', 'duplicate_tracks', + 'single_album_redundant', 'mbid_mismatch', 'incomplete_album') placeholders = ','.join(['?'] * len(fixable_types)) where_parts = [f"finding_type IN ({placeholders})", "status = 'pending'"]