From a9eccfe1c50abdd782fcf9187b519f003759250b Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Thu, 2 Apr 2026 17:48:57 -0700 Subject: [PATCH] Fix Discogs source display, album types, and track search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix source name mapping so sidebar/dashboard shows 'Discogs' instead of falling through to 'iTunes' - Fix album type detection: parse format string from artist releases endpoint (e.g. "File, FLAC, Single, 320") to correctly identify singles, EPs, albums, compilations — was defaulting everything to 'single' because track count was 0 - Remove fake track search that returned albums as tracks — Discogs has no track-level search API, so tracks section is empty (honest) - Track data available via album tracklists instead --- core/discogs_client.py | 55 ++++++++++++------------------------------ webui/static/script.js | 4 +-- 2 files changed, 18 insertions(+), 41 deletions(-) diff --git a/core/discogs_client.py b/core/discogs_client.py index a549fc13..1af00b1f 100644 --- a/core/discogs_client.py +++ b/core/discogs_client.py @@ -240,20 +240,25 @@ class Album: tracklist = release_data.get('tracklist', []) total_tracks = len(tracklist) if tracklist else (release_data.get('format_quantity', 0) or 0) - # Album type from formats + # Album type from formats array (full release detail) or format string (search/artist releases) formats = release_data.get('formats', []) format_name = formats[0].get('name', '').lower() if formats else '' descriptions = [d.lower() for d in formats[0].get('descriptions', [])] if formats else [] - if 'single' in descriptions or 'single' in format_name: + # Also check the comma-separated 'format' string from search/artist release endpoints + format_str = (release_data.get('format') or '').lower() + + if 'single' in descriptions or 'single' in format_name or 'single' in format_str: album_type = 'single' - elif 'ep' in descriptions: + elif 'ep' in descriptions or ', ep' in format_str or format_str.endswith('ep'): album_type = 'ep' - elif 'compilation' in descriptions or 'compilation' in (release_data.get('type', '') or '').lower(): + elif 'compilation' in descriptions or 'compilation' in format_str or 'compilation' in (release_data.get('type', '') or '').lower(): album_type = 'compilation' - elif total_tracks <= 3: + elif 'lp' in descriptions or 'lp' in format_str or 'album' in descriptions or 'album' in format_str: + album_type = 'album' + elif total_tracks <= 3 and total_tracks > 0: album_type = 'single' - elif total_tracks <= 6: + elif total_tracks <= 6 and total_tracks > 0: album_type = 'ep' else: album_type = 'album' @@ -393,39 +398,11 @@ class DiscogsClient: def search_tracks(self, query: str, limit: int = 10) -> List[Track]: """Search for tracks on Discogs. - Discogs doesn't have a track-level search, so we search releases - and extract matching tracks from the tracklists.""" - data = self._api_get('/database/search', { - 'q': query, 'type': 'release', 'per_page': min(limit, 20), - }) - if not data or not data.get('results'): - return [] - - tracks = [] - query_lower = query.lower() - for item in data['results'][:20]: - try: - # Fetch full release for tracklist - release_url = item.get('resource_url') - if not release_url: - continue - release = self._api_get(release_url) - if not release or not release.get('tracklist'): - continue - - for t in release['tracklist']: - if t.get('type_', '') == 'track' or not t.get('type_'): - # Check if track title matches query - title = t.get('title', '').lower() - if query_lower in title or title in query_lower or any(w in title for w in query_lower.split()): - track = Track.from_discogs_track(t, release) - tracks.append(track) - if len(tracks) >= limit: - return tracks - except Exception as e: - logger.debug(f"Error extracting Discogs tracks: {e}") - - return tracks + Discogs doesn't have a track-level search API — returns empty list. + Track data is available via get_album() tracklists instead.""" + # Discogs has no track search endpoint. Artists and albums are the + # searchable entities. Individual tracks come from release tracklists. + return [] # --- Lookup Methods --- diff --git a/webui/static/script.js b/webui/static/script.js index 312ff433..b52a19bb 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -37524,7 +37524,7 @@ function updateServiceStatus(service, statusData) { if (service === 'spotify' && statusData.source) { const musicSourceTitleElement = document.getElementById('music-source-title'); if (musicSourceTitleElement) { - const sourceName = statusData.source === 'spotify' ? 'Spotify' : statusData.source === 'deezer' ? 'Deezer' : 'iTunes'; + const sourceName = statusData.source === 'spotify' ? 'Spotify' : statusData.source === 'deezer' ? 'Deezer' : statusData.source === 'discogs' ? 'Discogs' : 'iTunes'; musicSourceTitleElement.textContent = sourceName; currentMusicSourceName = sourceName; } @@ -37579,7 +37579,7 @@ function updateSidebarServiceStatus(service, statusData) { if (service === 'spotify' && statusData.source) { const musicSourceNameElement = document.getElementById('music-source-name'); if (musicSourceNameElement) { - const sourceName = statusData.source === 'spotify' ? 'Spotify' : statusData.source === 'deezer' ? 'Deezer' : 'iTunes'; + const sourceName = statusData.source === 'spotify' ? 'Spotify' : statusData.source === 'deezer' ? 'Deezer' : statusData.source === 'discogs' ? 'Discogs' : 'iTunes'; musicSourceNameElement.textContent = sourceName; } }