Fix wishlisted tracks showing 'Unknown Album' with no cover art

Multiple code paths built wishlist album data as a bare string instead
of a dict with images/album_type/total_tracks, causing wishlist entries
to lose album name and artwork. Fixed in: Beatport fallback conversion,
sync normalization, _ensure_spotify_track_format, and wishlist service
track reconstruction. Now uses track name as album fallback and always
includes required album dict keys.
This commit is contained in:
Broque Thomas 2026-03-18 14:23:53 -07:00
parent 4a7f297b2c
commit 2c2c006f83
2 changed files with 37 additions and 12 deletions

View file

@ -290,14 +290,14 @@ class WishlistService:
# Look for Spotify metadata in the result # Look for Spotify metadata in the result
if hasattr(slskd_result, 'artist') and hasattr(slskd_result, 'title'): if hasattr(slskd_result, 'artist') and hasattr(slskd_result, 'title'):
# Reconstruct basic Spotify track structure album_name = getattr(slskd_result, 'album', '') or getattr(slskd_result, 'title', 'Unknown Album')
return { return {
'id': f"reconstructed_{hash(f'{slskd_result.artist}_{slskd_result.title}')}", 'id': f"reconstructed_{hash(f'{slskd_result.artist}_{slskd_result.title}')}",
'name': getattr(slskd_result, 'title', 'Unknown Track'), 'name': getattr(slskd_result, 'title', 'Unknown Track'),
'artists': [{'name': getattr(slskd_result, 'artist', 'Unknown Artist')}], 'artists': [{'name': getattr(slskd_result, 'artist', 'Unknown Artist')}],
'album': {'name': getattr(slskd_result, 'album', 'Unknown Album')}, 'album': {'name': album_name, 'images': [], 'album_type': 'single', 'total_tracks': 1},
'duration_ms': 0, # Unknown 'duration_ms': 0,
'reconstructed': True # Mark as reconstructed data 'reconstructed': True
} }
# If no Spotify data found, try to reconstruct from available info # If no Spotify data found, try to reconstruct from available info
@ -321,16 +321,17 @@ class WishlistService:
if hasattr(spotify_track, 'title') and hasattr(spotify_track, 'artist') and not hasattr(spotify_track, 'id'): if hasattr(spotify_track, 'title') and hasattr(spotify_track, 'artist') and not hasattr(spotify_track, 'id'):
logger.info("DEBUG: Detected TrackResult object, converting...") logger.info("DEBUG: Detected TrackResult object, converting...")
# Handle TrackResult objects - these don't have Spotify IDs # Handle TrackResult objects - these don't have Spotify IDs
album_name = getattr(spotify_track, 'album', '') or getattr(spotify_track, 'title', 'Unknown Album')
result = { result = {
'id': f"trackresult_{hash(f'{spotify_track.artist}_{spotify_track.title}')}", 'id': f"trackresult_{hash(f'{spotify_track.artist}_{spotify_track.title}')}",
'name': getattr(spotify_track, 'title', 'Unknown Track'), 'name': getattr(spotify_track, 'title', 'Unknown Track'),
'artists': [{'name': getattr(spotify_track, 'artist', 'Unknown Artist')}], 'artists': [{'name': getattr(spotify_track, 'artist', 'Unknown Artist')}],
'album': {'name': getattr(spotify_track, 'album', 'Unknown Album')}, 'album': {'name': album_name, 'images': [], 'album_type': 'single', 'total_tracks': 1},
'duration_ms': 0, # TrackResult doesn't have duration 'duration_ms': 0,
'preview_url': None, 'preview_url': None,
'external_urls': {}, 'external_urls': {},
'popularity': 0, 'popularity': 0,
'source': 'trackresult' # Mark as reconstructed from TrackResult 'source': 'trackresult'
} }
logger.info(f"DEBUG: TrackResult converted successfully: {result['name']} by {result['artists'][0]['name']}") logger.info(f"DEBUG: TrackResult converted successfully: {result['name']} by {result['artists'][0]['name']}")
return result return result

View file

@ -20758,8 +20758,14 @@ def _ensure_spotify_track_format(track_info):
album.setdefault('name', 'Unknown Album') album.setdefault('name', 'Unknown Album')
else: else:
album = { album = {
'name': str(album_data) if album_data else 'Unknown Album' 'name': str(album_data) if album_data else track_info.get('name', 'Unknown Album'),
'album_type': 'single',
'total_tracks': 1,
'release_date': '',
} }
album.setdefault('images', [])
album.setdefault('album_type', 'album')
album.setdefault('total_tracks', 0)
# Build proper Spotify track structure # Build proper Spotify track structure
spotify_track = { spotify_track = {
@ -29494,12 +29500,22 @@ def _run_sync_task(playlist_id, playlist_name, tracks_json, automation_id=None):
track_id = t.get('id', '') track_id = t.get('id', '')
if track_id: if track_id:
normalized = dict(t) normalized = dict(t)
# Normalize album to dict format # Normalize album to dict format, preserving images and metadata
raw_album = normalized.get('album', '') raw_album = normalized.get('album', '')
if isinstance(raw_album, str): if isinstance(raw_album, str):
normalized['album'] = {'name': raw_album} if raw_album else {'name': 'Unknown Album'} normalized['album'] = {
'name': raw_album or normalized.get('name', 'Unknown Album'),
'images': [], 'album_type': 'single', 'total_tracks': 1, 'release_date': ''
}
elif not isinstance(raw_album, dict): elif not isinstance(raw_album, dict):
normalized['album'] = {'name': str(raw_album) if raw_album else 'Unknown Album'} normalized['album'] = {
'name': str(raw_album) if raw_album else normalized.get('name', 'Unknown Album'),
'images': [], 'album_type': 'single', 'total_tracks': 1, 'release_date': ''
}
else:
# Dict — ensure required keys exist
raw_album.setdefault('name', 'Unknown Album')
raw_album.setdefault('images', [])
# Normalize artists to list of dicts # Normalize artists to list of dicts
raw_artists = normalized.get('artists', []) raw_artists = normalized.get('artists', [])
if raw_artists and isinstance(raw_artists[0], str): if raw_artists and isinstance(raw_artists[0], str):
@ -38064,11 +38080,19 @@ def convert_beatport_results_to_spotify_tracks(discovery_results):
}) })
elif result.get('spotify_track') and result.get('status_class') == 'found': elif result.get('spotify_track') and result.get('status_class') == 'found':
# Build from individual fields (automatic discovery format) # Build from individual fields (automatic discovery format)
album_val = result.get('spotify_album', '')
album_dict = album_val if isinstance(album_val, dict) else {
'name': album_val or result.get('spotify_track', 'Unknown Album'),
'album_type': 'single',
'images': [],
'release_date': '',
'total_tracks': 1,
}
spotify_tracks.append({ spotify_tracks.append({
'id': result.get('spotify_id', 'unknown'), 'id': result.get('spotify_id', 'unknown'),
'name': result.get('spotify_track', 'Unknown Track'), 'name': result.get('spotify_track', 'Unknown Track'),
'artists': [result.get('spotify_artist', 'Unknown Artist')] if result.get('spotify_artist') else ['Unknown Artist'], 'artists': [result.get('spotify_artist', 'Unknown Artist')] if result.get('spotify_artist') else ['Unknown Artist'],
'album': result.get('spotify_album', 'Unknown Album'), 'album': album_dict,
'source': 'beatport' 'source': 'beatport'
}) })