diff --git a/database/music_database.py b/database/music_database.py index 5601e5a8..c434cd8a 100644 --- a/database/music_database.py +++ b/database/music_database.py @@ -5424,6 +5424,8 @@ class MusicDatabase: r'\s+special\s*edition?$': ['special', 'special edition'], r'\s*-\s*deluxe': ['deluxe'], r'\s*-\s*platinum\s*edition?': ['platinum', 'platinum edition'], + r'\s+collector\'?s?\s*edition?$': ['collectors', 'collectors edition'], + r'\s*\(collector\'?s?\s*edition?\)': ['collectors', 'collectors edition'], # Generic catch-alls for any edition in parens/brackets (e.g. Silver Edition, MMXI Special Edition) r'\s*\([^)]*\bedition\b[^)]*\)': ['edition'], r'\s*\[[^\]]*\bedition\b[^\]]*\]': ['edition'], diff --git a/web_server.py b/web_server.py index d6dba799..329ffff5 100644 --- a/web_server.py +++ b/web_server.py @@ -10250,6 +10250,18 @@ def _check_album_completion(db, album_data: dict, artist_name: str, test_mode: b album_name = album_data.get('name', '') total_tracks = album_data.get('total_tracks', 0) album_id = album_data.get('id', '') + + # If total_tracks is 0 (Discogs masters don't include track counts), + # try to fetch the real count from the source + if total_tracks == 0 and album_id: + try: + fallback = _get_metadata_fallback_client() + album_detail = fallback.get_album_tracks(str(album_id)) + if album_detail and album_detail.get('items'): + total_tracks = len(album_detail['items']) + logger.debug(f"Fetched track count for '{album_name}': {total_tracks}") + except Exception: + pass print(f"🔍 Checking album: '{album_name}' ({total_tracks} tracks)") diff --git a/webui/static/script.js b/webui/static/script.js index b52a19bb..844bfb87 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -34371,6 +34371,23 @@ function updateAlbumCompletionOverlay(completionData, containerType) { return; } + // Reclassify album type if we now know the track count (Discogs lazy fetch) + const currentType = albumCard.dataset.albumType; + const expectedTracks = completionData.expected_tracks || 0; + if (currentType === 'album' && expectedTracks > 0 && expectedTracks <= 3) { + albumCard.dataset.albumType = 'single'; + const typeEl = albumCard.querySelector('.album-card-type'); + if (typeEl) typeEl.textContent = 'Single'; + } else if (currentType === 'album' && expectedTracks > 3 && expectedTracks <= 6) { + albumCard.dataset.albumType = 'ep'; + const typeEl = albumCard.querySelector('.album-card-type'); + if (typeEl) typeEl.textContent = 'EP'; + } + // Update stored total tracks + if (expectedTracks > 0) { + albumCard.dataset.totalTracks = expectedTracks; + } + const overlay = albumCard.querySelector('.completion-overlay'); if (!overlay) { console.warn(`Completion overlay not found for album: ${completionData.name}`); @@ -34385,12 +34402,13 @@ function updateAlbumCompletionOverlay(completionData, containerType) { // Update overlay text and content const statusText = getCompletionStatusText(completionData); - const progressText = `${completionData.owned_tracks}/${completionData.expected_tracks}`; + const progressText = completionData.expected_tracks > 0 + ? `${completionData.owned_tracks}/${completionData.expected_tracks}` + : ''; - overlay.innerHTML = ` - ${statusText} - ${progressText} - `; + overlay.innerHTML = progressText + ? `${statusText}${progressText}` + : `${statusText}`; // Add tooltip with more details overlay.title = `${completionData.name}\n${statusText} (${completionData.completion_percentage}%)\nTracks: ${completionData.owned_tracks}/${completionData.expected_tracks}\nConfidence: ${completionData.confidence}`; @@ -42227,7 +42245,8 @@ function createReleaseCard(release) { } } } else { - completionText.textContent = "Missing"; + const totalTr = release.total_tracks || release.track_completion?.total_tracks || 0; + completionText.textContent = totalTr > 0 ? `Missing (${totalTr} tracks)` : "Not in library"; completionText.className = "completion-text missing"; completionFill.className += " missing"; completionFill.style.width = "0%";