Fix all watchlist Discogs gaps
- Add discogs_artist_id to ALL watchlist WHERE clauses + bind params - Fix artistPrimaryId to include discogs_artist_id - Fix View Discography — add Discogs source branch - Fix openWatchlistArtistDetailView — destructure discogs_artist_id from response (was causing ReferenceError) - Discogs source/provider badges + CSS + image fetch + ID resolution
This commit is contained in:
parent
f51a8a9ee9
commit
55f7e174d8
3 changed files with 75 additions and 28 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -38782,7 +38782,7 @@ async function showWatchlistModal() {
|
|||
if (artist.itunes_artist_id) sourceBadges.push('<span class="watchlist-source-badge watchlist-source-itunes">iTunes</span>');
|
||||
if (artist.deezer_artist_id) sourceBadges.push('<span class="watchlist-source-badge watchlist-source-deezer">Deezer</span>');
|
||||
if (artist.discogs_artist_id) sourceBadges.push('<span class="watchlist-source-badge watchlist-source-discogs">Discogs</span>');
|
||||
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 `
|
||||
<div class="watchlist-artist-card"
|
||||
data-artist-name="${artist.artist_name.toLowerCase().replace(/"/g, '"')}"
|
||||
|
|
@ -39278,7 +39278,7 @@ async function openWatchlistArtistDetailView(artistId, artistName) {
|
|||
return;
|
||||
}
|
||||
|
||||
const { config, artist, recent_releases, spotify_artist_id, itunes_artist_id, deezer_artist_id } = data;
|
||||
const { config, artist, recent_releases, spotify_artist_id, itunes_artist_id, deezer_artist_id, discogs_artist_id } = data;
|
||||
|
||||
// Remove existing overlay if any
|
||||
const existing = document.querySelector('.watchlist-artist-detail-overlay');
|
||||
|
|
@ -39407,13 +39407,15 @@ async function openWatchlistArtistDetailView(artistId, artistName) {
|
|||
const activeSrc = (currentMusicSourceName || '').toLowerCase();
|
||||
if (activeSrc.includes('spotify') && spotify_artist_id) {
|
||||
discogId = spotify_artist_id; source = 'spotify';
|
||||
} else if (activeSrc.includes('discogs') && discogs_artist_id) {
|
||||
discogId = discogs_artist_id; source = 'discogs';
|
||||
} else if (activeSrc.includes('deezer') && deezer_artist_id) {
|
||||
discogId = deezer_artist_id; source = 'deezer';
|
||||
} else if (itunes_artist_id) {
|
||||
discogId = itunes_artist_id; source = 'itunes';
|
||||
} else {
|
||||
discogId = spotify_artist_id || deezer_artist_id || itunes_artist_id;
|
||||
source = spotify_artist_id ? 'spotify' : deezer_artist_id ? 'deezer' : 'itunes';
|
||||
discogId = spotify_artist_id || discogs_artist_id || deezer_artist_id || itunes_artist_id;
|
||||
source = spotify_artist_id ? 'spotify' : discogs_artist_id ? 'discogs' : deezer_artist_id ? 'deezer' : 'itunes';
|
||||
}
|
||||
if (discogId) {
|
||||
// Close watchlist modal + detail overlay
|
||||
|
|
|
|||
Loading…
Reference in a new issue