From c67ca40b08bd70c1b8c737464a820bb7984b9a1c Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Thu, 2 Apr 2026 15:11:07 -0700 Subject: [PATCH] Fix spotify_public playlist refresh overwriting discovery data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - When Spotify is authenticated, spotify_public playlists now use the full API instead of the embed scraper — auto-discovers with album art, consistent with regular spotify playlists - When using scraper fallback, no longer sets extra_data on tracks — lets preservation code keep existing discovery data instead of overwriting discovered=true with discovered=false on every refresh - Consistent with Tidal/YouTube/Deezer which never set extra_data - Fixes Discover Weekly showing "not discovered" after overnight refresh --- web_server.py | 55 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/web_server.py b/web_server.py index 8084cbfa..922fc9e5 100644 --- a/web_server.py +++ b/web_server.py @@ -639,7 +639,42 @@ def _register_automation_handlers(): from core.spotify_public_scraper import parse_spotify_url, scrape_spotify_embed spotify_url = pl.get('description', '') parsed = parse_spotify_url(spotify_url) if spotify_url else None - if parsed: + + # If Spotify is authenticated, use the full API (auto-discovers with album art) + if parsed and parsed.get('type') == 'playlist' and spotify_client and spotify_client.is_spotify_authenticated(): + playlist_obj = spotify_client.get_playlist_by_id(parsed['id']) + if playlist_obj and playlist_obj.tracks: + tracks = [] + for t in playlist_obj.tracks: + artist_name = t.artists[0] if t.artists else '' + track_dict = { + 'track_name': t.name or '', + 'artist_name': str(artist_name), + 'album_name': t.album or '', + 'duration_ms': t.duration_ms or 0, + 'source_track_id': t.id or '', + } + if t.id: + _album_obj = {'name': t.album or ''} + if getattr(t, 'image_url', None): + _album_obj['images'] = [{'url': t.image_url, 'height': 600, 'width': 600}] + track_dict['extra_data'] = json.dumps({ + 'discovered': True, + 'provider': 'spotify', + 'confidence': 1.0, + 'matched_data': { + 'id': t.id, + 'name': t.name or '', + 'artists': [{'name': str(a)} for a in (t.artists or [])], + 'album': _album_obj, + 'duration_ms': t.duration_ms or 0, + 'image_url': getattr(t, 'image_url', None), + } + }) + tracks.append(track_dict) + + # Fallback: public embed scraper (no auth or album-type URL) + if tracks is None and parsed: embed_data = scrape_spotify_embed(parsed['type'], parsed['id']) if embed_data and not embed_data.get('error') and embed_data.get('tracks'): embed_album = embed_data.get('name', '') if embed_data.get('type') == 'album' else '' @@ -647,26 +682,14 @@ def _register_automation_handlers(): for t in embed_data['tracks']: artist_names = [a['name'] for a in t.get('artists', [])] artist_name = artist_names[0] if artist_names else '' - track_dict = { + tracks.append({ 'track_name': t.get('name', ''), 'artist_name': artist_name, 'album_name': embed_album, 'duration_ms': t.get('duration_ms', 0), 'source_track_id': t.get('id', ''), - } - # Store Spotify track ID as a hint for the Discover step, - # but do NOT mark as discovered — Discover needs to run a proper - # API lookup to get real album art (embed only has playlist-level images) - if t.get('id'): - track_dict['extra_data'] = json.dumps({ - 'discovered': False, - 'spotify_hint': { - 'id': t['id'], - 'name': t.get('name', ''), - 'artists': t.get('artists', []), - } - }) - tracks.append(track_dict) + }) + # No extra_data — let preservation code keep existing discovery data except Exception as e: logger.warning(f"Spotify public playlist refresh failed for {source_id}: {e}")