From 965f93ab317f31ea2d7a5729103d135ad685fd06 Mon Sep 17 00:00:00 2001 From: Broque Thomas Date: Mon, 9 Feb 2026 21:01:40 -0800 Subject: [PATCH] Fix: Validate iTunes explicit albums have tracks before deduplication Fixed issue where broken iTunes explicit album IDs were preferred over working clean versions during deduplication. Some iTunes explicit albums (e.g., "Mr. Morale & The Big Steppers" ID 1623854804) report track counts in metadata but return 0 tracks when queried. Added validation in itunes_client.py get_artist_albums() to verify explicit albums actually have tracks before keeping them. If an explicit version has 0 tracks, it's skipped and the clean version is used instead. This fixes: - "No tracks found" error when clicking affected albums - Incorrect track count mismatches (19/18) caused by broken API data The validation only runs for explicit albums during deduplication, minimal performance impact. --- core/itunes_client.py | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/core/itunes_client.py b/core/itunes_client.py index 9858578..cbd570f 100644 --- a/core/itunes_client.py +++ b/core/itunes_client.py @@ -722,16 +722,50 @@ class iTunesClient: # Deduplicate by normalized name, prefer explicit versions normalized_name = normalize_album_name(album.name) + + logger.debug(f"Processing album: {album.name} (ID: {album.id}, explicit: {is_explicit}, normalized: {normalized_name})") if normalized_name in seen_albums: + logger.debug(f" Found duplicate for: {normalized_name}") # Only replace if current one is explicit and previous was clean + # BUT verify the explicit version actually has tracks (some iTunes albums are broken) if is_explicit and not seen_albums[normalized_name]['is_explicit']: - logger.debug(f"Replacing clean version with explicit: {album.name}") - seen_albums[normalized_name] = {'album': album, 'is_explicit': is_explicit} + logger.info(f" Attempting to replace clean with explicit for: {album.name}") + # Quick validation: check if this explicit album actually has tracks + try: + test_tracks = self._lookup(id=album.id, entity='song') + track_count = len([t for t in test_tracks if t.get('wrapperType') == 'track']) + + if track_count > 0: + logger.debug(f"Replacing clean version with explicit: {album.name} (verified {track_count} tracks)") + seen_albums[normalized_name] = {'album': album, 'is_explicit': is_explicit} + else: + logger.warning(f"⚠️ Skipping broken explicit album {album.name} (ID {album.id}): reports tracks but has 0") + except Exception as e: + logger.warning(f"Failed to validate explicit album {album.name}: {e}, keeping clean version") else: logger.debug(f"Skipping duplicate album: {album.name} (normalized: {normalized_name})") else: - seen_albums[normalized_name] = {'album': album, 'is_explicit': is_explicit} + logger.debug(f" First occurrence of: {normalized_name}") + + # If this is an explicit album, validate it has tracks before keeping it + # (Some iTunes explicit albums are broken and return 0 tracks) + if is_explicit: + try: + test_tracks = self._lookup(id=album.id, entity='song') + track_count = len([t for t in test_tracks if t.get('wrapperType') == 'track']) + + if track_count > 0: + logger.debug(f" Verified explicit album has {track_count} tracks") + seen_albums[normalized_name] = {'album': album, 'is_explicit': is_explicit} + else: + logger.warning(f"⚠️ Skipping broken explicit album {album.name} (ID {album.id}): reports tracks but has 0") + # Don't add to seen_albums so a clean version can be added later + except Exception as e: + logger.warning(f"Failed to validate explicit album {album.name}: {e}, skipping") + else: + # Clean versions - just add them + seen_albums[normalized_name] = {'album': album, 'is_explicit': is_explicit} # Extract albums from dict albums = [item['album'] for item in seen_albums.values()]