diff --git a/database/music_database.py b/database/music_database.py index 530aa57c..4b4faf67 100644 --- a/database/music_database.py +++ b/database/music_database.py @@ -6514,7 +6514,7 @@ class MusicDatabase: return False def remove_artist_from_watchlist(self, artist_id: str, profile_id: int = 1) -> bool: - """Remove an artist from the watchlist (checks Spotify, iTunes, and Deezer IDs)""" + """Remove an artist from the watchlist (checks Spotify, iTunes, Deezer, and Discogs IDs)""" try: with self._get_connection() as conn: cursor = conn.cursor() @@ -6522,15 +6522,15 @@ class MusicDatabase: # Get artist name for logging (check all ID columns) cursor.execute(""" SELECT artist_name FROM watchlist_artists - WHERE (spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ?) AND profile_id = ? - """, (artist_id, artist_id, artist_id, profile_id)) + WHERE (spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? OR discogs_artist_id = ?) AND profile_id = ? + """, (artist_id, artist_id, artist_id, artist_id, profile_id)) result = cursor.fetchone() artist_name = result['artist_name'] if result else "Unknown" cursor.execute(""" DELETE FROM watchlist_artists - WHERE (spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ?) AND profile_id = ? - """, (artist_id, artist_id, artist_id, profile_id)) + WHERE (spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? OR discogs_artist_id = ?) AND profile_id = ? + """, (artist_id, artist_id, artist_id, artist_id, profile_id)) if cursor.rowcount > 0: conn.commit() @@ -6545,7 +6545,7 @@ class MusicDatabase: return False def is_artist_in_watchlist(self, artist_id: str, profile_id: int = 1, artist_name: str = None) -> bool: - """Check if an artist is currently in the watchlist (checks Spotify, iTunes, Deezer IDs and name)""" + """Check if an artist is currently in the watchlist (checks Spotify, iTunes, Deezer, Discogs IDs and name)""" try: with self._get_connection() as conn: cursor = conn.cursor() @@ -6554,15 +6554,15 @@ class MusicDatabase: if artist_name: cursor.execute(""" SELECT 1 FROM watchlist_artists - WHERE (spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? OR LOWER(artist_name) = LOWER(?)) AND profile_id = ? + WHERE (spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? OR discogs_artist_id = ? OR LOWER(artist_name) = LOWER(?)) AND profile_id = ? LIMIT 1 - """, (artist_id, artist_id, artist_id, artist_name, profile_id)) + """, (artist_id, artist_id, artist_id, artist_id, artist_name, profile_id)) else: cursor.execute(""" SELECT 1 FROM watchlist_artists - WHERE (spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ?) AND profile_id = ? + WHERE (spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? OR discogs_artist_id = ?) AND profile_id = ? LIMIT 1 - """, (artist_id, artist_id, artist_id, profile_id)) + """, (artist_id, artist_id, artist_id, artist_id, profile_id)) result = cursor.fetchone() return result is not None @@ -6833,8 +6833,8 @@ class MusicDatabase: cursor.execute(""" UPDATE watchlist_artists SET image_url = ?, updated_at = CURRENT_TIMESTAMP - WHERE spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? - """, (image_url, artist_id, artist_id, artist_id)) + WHERE spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? OR discogs_artist_id = ? + """, (image_url, artist_id, artist_id, artist_id, artist_id)) conn.commit() return cursor.rowcount > 0 diff --git a/web_server.py b/web_server.py index 54141a02..2de21fb2 100644 --- a/web_server.py +++ b/web_server.py @@ -36599,10 +36599,47 @@ def add_to_watchlist(): return jsonify({"success": False, "error": "Missing artist_id or artist_name"}), 400 database = get_database() - # Detect ID type and determine source + # Detect source from ID — check if it's a library DB ID first is_numeric_id = artist_id.isdigit() - fallback_source = _get_metadata_fallback_source() - source = fallback_source if is_numeric_id else 'spotify' + source = None + if is_numeric_id: + # Could be a library DB ID, iTunes ID, Deezer ID, or Discogs ID + # Check if this is a library DB artist and use their actual source IDs + try: + conn = database._get_connection() + cursor = conn.cursor() + cursor.execute(""" + SELECT spotify_artist_id, itunes_artist_id, deezer_id, discogs_id + FROM artists WHERE id = ? LIMIT 1 + """, (artist_id,)) + row = cursor.fetchone() + conn.close() + if row: + # Library artist — use the best available source ID + fallback = _get_metadata_fallback_source() + if fallback == 'discogs' and row['discogs_id']: + artist_id = row['discogs_id'] + source = 'discogs' + elif fallback == 'deezer' and row['deezer_id']: + artist_id = row['deezer_id'] + source = 'deezer' + elif row['spotify_artist_id']: + artist_id = row['spotify_artist_id'] + source = 'spotify' + elif row['itunes_artist_id']: + artist_id = row['itunes_artist_id'] + source = 'itunes' + elif row['deezer_id']: + artist_id = row['deezer_id'] + source = 'deezer' + elif row['discogs_id']: + artist_id = row['discogs_id'] + source = 'discogs' + except Exception: + pass + if not source: + fallback_source = _get_metadata_fallback_source() + source = fallback_source if is_numeric_id else 'spotify' success = database.add_artist_to_watchlist(artist_id, artist_name, profile_id=get_current_profile_id(), source=source) if success: @@ -36612,7 +36649,15 @@ def add_to_watchlist(): if is_numeric_id: # For numeric IDs, fetch image from the configured fallback source try: - if fallback_source == 'deezer': + if source == 'discogs': + # Discogs: fetch artist image from API + from core.discogs_client import DiscogsClient + dc = DiscogsClient() + dc_data = dc.get_artist(artist_id) + if dc_data: + image_url = dc_data.get('image_url') + print(f"🖼️ Discogs artist image: {image_url[:60] if image_url else 'None'}") + elif source == 'deezer' or fallback_source == 'deezer': # Deezer: fetch artist image directly from API dz_resp = requests.get(f'https://api.deezer.com/artist/{artist_id}', timeout=5) if dz_resp.ok: @@ -37584,9 +37629,9 @@ def watchlist_artist_config(artist_id): cur2.execute(""" SELECT banner_url, summary, style, mood, label, genres FROM artists - WHERE spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? + WHERE spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? OR discogs_artist_id = ? LIMIT 1 - """, (artist_id, artist_id, artist_id)) + """, (artist_id, artist_id, artist_id, artist_id)) lib_row = cur2.fetchone() if lib_row: artist_info['banner_url'] = lib_row[0] @@ -37679,8 +37724,8 @@ def watchlist_artist_config(artist_id): # Check if lookback_days changed — if so, clear last_scan_timestamp to force rescan cursor.execute(""" SELECT lookback_days FROM watchlist_artists - WHERE spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? - """, (artist_id, artist_id, artist_id)) + WHERE spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? OR discogs_artist_id = ? + """, (artist_id, artist_id, artist_id, artist_id)) old_row = cursor.fetchone() old_lookback = old_row[0] if old_row else None lookback_changed = old_lookback != lookback_days @@ -37692,11 +37737,11 @@ def watchlist_artist_config(artist_id): include_instrumentals = ?, lookback_days = ?, last_scan_timestamp = CASE WHEN ? THEN NULL ELSE last_scan_timestamp END, updated_at = CURRENT_TIMESTAMP - WHERE spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? + WHERE spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? OR discogs_artist_id = ? """, (int(include_albums), int(include_eps), int(include_singles), int(include_live), int(include_remixes), int(include_acoustic), int(include_compilations), int(include_instrumentals), lookback_days, lookback_changed, - artist_id, artist_id, artist_id)) + artist_id, artist_id, artist_id, artist_id)) conn.commit() if cursor.rowcount == 0: @@ -37752,8 +37797,8 @@ def watchlist_artist_link_provider(artist_id): cursor.execute(""" SELECT id, artist_name, spotify_artist_id, itunes_artist_id FROM watchlist_artists - WHERE spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? - """, (artist_id, artist_id, artist_id)) + WHERE spotify_artist_id = ? OR itunes_artist_id = ? OR deezer_artist_id = ? OR discogs_artist_id = ? + """, (artist_id, artist_id, artist_id, artist_id)) row = cursor.fetchone() if not row: diff --git a/webui/static/script.js b/webui/static/script.js index 024d4f53..5344677b 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -38782,7 +38782,7 @@ async function showWatchlistModal() { if (artist.itunes_artist_id) sourceBadges.push('iTunes'); if (artist.deezer_artist_id) sourceBadges.push('Deezer'); if (artist.discogs_artist_id) sourceBadges.push('Discogs'); - const artistPrimaryId = artist.spotify_artist_id || artist.itunes_artist_id || artist.deezer_artist_id; + const artistPrimaryId = artist.spotify_artist_id || artist.itunes_artist_id || artist.deezer_artist_id || artist.discogs_artist_id; return `