Respect configured primary source in seasonal, playlists, and explorer
Seasonal discovery, personalized playlists, and playlist explorer all defaulted to Spotify when authenticated, ignoring the user's configured primary source. Now they read from config first. Spotify's related_artists API (no Deezer/iTunes equivalent) is preserved as a fallback for all users in personalized playlists. Artist discography endpoint intentionally unchanged — ID-based lookups need the source that owns the ID.
This commit is contained in:
parent
7d21385ce9
commit
57fc18f994
3 changed files with 21 additions and 21 deletions
|
|
@ -102,17 +102,16 @@ class PersonalizedPlaylistsService:
|
||||||
|
|
||||||
def _get_active_source(self) -> str:
|
def _get_active_source(self) -> str:
|
||||||
"""
|
"""
|
||||||
Determine which music source is active for discovery.
|
Determine which music source is active — respects user's configured primary source.
|
||||||
Returns 'spotify' if Spotify is authenticated, otherwise the configured fallback ('itunes' or 'deezer').
|
|
||||||
"""
|
"""
|
||||||
if self.spotify_client and hasattr(self.spotify_client, 'is_spotify_authenticated'):
|
|
||||||
if self.spotify_client.is_spotify_authenticated():
|
|
||||||
return 'spotify'
|
|
||||||
try:
|
try:
|
||||||
from config.settings import config_manager
|
from config.settings import config_manager
|
||||||
return config_manager.get('metadata.fallback_source', 'itunes') or 'itunes'
|
source = config_manager.get('metadata.fallback_source', 'deezer') or 'deezer'
|
||||||
|
if source == 'spotify' and not (self.spotify_client and hasattr(self.spotify_client, 'is_spotify_authenticated') and self.spotify_client.is_spotify_authenticated()):
|
||||||
|
return 'deezer'
|
||||||
|
return source
|
||||||
except Exception:
|
except Exception:
|
||||||
return 'itunes'
|
return 'deezer'
|
||||||
|
|
||||||
def _build_track_dict(self, row, source: str) -> Dict:
|
def _build_track_dict(self, row, source: str) -> Dict:
|
||||||
"""Build a standardized track dictionary from a database row."""
|
"""Build a standardized track dictionary from a database row."""
|
||||||
|
|
@ -882,8 +881,8 @@ class PersonalizedPlaylistsService:
|
||||||
logger.error(f"Invalid seed artists count: {len(seed_artist_ids)}")
|
logger.error(f"Invalid seed artists count: {len(seed_artist_ids)}")
|
||||||
return {'tracks': [], 'error': 'Must provide 1-5 seed artists'}
|
return {'tracks': [], 'error': 'Must provide 1-5 seed artists'}
|
||||||
|
|
||||||
use_spotify = self.spotify_client and self.spotify_client.sp
|
active_source = self._get_active_source()
|
||||||
active_source = 'spotify' if use_spotify else self._get_active_source()
|
use_spotify = (active_source == 'spotify') and self.spotify_client and self.spotify_client.sp
|
||||||
logger.info(f"Building custom playlist from {len(seed_artist_ids)} seed artists (source: {active_source})")
|
logger.info(f"Building custom playlist from {len(seed_artist_ids)} seed artists (source: {active_source})")
|
||||||
|
|
||||||
# Step 1: Get similar artists for each seed
|
# Step 1: Get similar artists for each seed
|
||||||
|
|
@ -914,8 +913,8 @@ class PersonalizedPlaylistsService:
|
||||||
seen_artist_ids.add(artist_id)
|
seen_artist_ids.add(artist_id)
|
||||||
if len(all_similar_artists) >= 25:
|
if len(all_similar_artists) >= 25:
|
||||||
break
|
break
|
||||||
elif use_spotify:
|
elif self.spotify_client and self.spotify_client.sp:
|
||||||
# Fallback: fetch related artists from Spotify API
|
# Fallback: fetch related artists from Spotify API (no Deezer/iTunes equivalent)
|
||||||
logger.info(f"No cached similar artists for {seed_artist_id}, trying Spotify related artists API")
|
logger.info(f"No cached similar artists for {seed_artist_id}, trying Spotify related artists API")
|
||||||
try:
|
try:
|
||||||
related = self.spotify_client.sp.artist_related_artists(seed_artist_id)
|
related = self.spotify_client.sp.artist_related_artists(seed_artist_id)
|
||||||
|
|
|
||||||
|
|
@ -96,14 +96,16 @@ class SeasonalDiscoveryService:
|
||||||
self._ensure_database_schema()
|
self._ensure_database_schema()
|
||||||
|
|
||||||
def _get_source(self):
|
def _get_source(self):
|
||||||
"""Determine active music source (matches _get_active_discovery_source in web_server)"""
|
"""Determine active music source — respects user's configured primary source"""
|
||||||
if self.spotify_client and self.spotify_client.is_spotify_authenticated():
|
|
||||||
return 'spotify'
|
|
||||||
try:
|
try:
|
||||||
from core.metadata_service import _get_configured_fallback_source
|
from config.settings import config_manager
|
||||||
return _get_configured_fallback_source()
|
source = config_manager.get('metadata.fallback_source', 'deezer') or 'deezer'
|
||||||
|
# If user selected spotify, verify it's actually authenticated
|
||||||
|
if source == 'spotify' and not (self.spotify_client and self.spotify_client.is_spotify_authenticated()):
|
||||||
|
return 'deezer'
|
||||||
|
return source
|
||||||
except Exception:
|
except Exception:
|
||||||
return 'itunes'
|
return 'deezer'
|
||||||
|
|
||||||
def _ensure_database_schema(self):
|
def _ensure_database_schema(self):
|
||||||
"""Create seasonal content tables if they don't exist"""
|
"""Create seasonal content tables if they don't exist"""
|
||||||
|
|
|
||||||
|
|
@ -47377,11 +47377,10 @@ def playlist_explorer_build_tree():
|
||||||
if not tracks:
|
if not tracks:
|
||||||
return jsonify({"success": False, "error": "Playlist has no tracks"}), 400
|
return jsonify({"success": False, "error": "Playlist has no tracks"}), 400
|
||||||
|
|
||||||
# Determine active metadata source
|
# Determine active metadata source — respect user's configured primary
|
||||||
spotify_available = spotify_client and spotify_client.is_spotify_authenticated()
|
source_name = _get_active_discovery_source()
|
||||||
if spotify_available:
|
if source_name == 'spotify' and spotify_client and spotify_client.is_spotify_authenticated():
|
||||||
active_client = spotify_client
|
active_client = spotify_client
|
||||||
source_name = 'spotify'
|
|
||||||
else:
|
else:
|
||||||
active_client = _get_metadata_fallback_client()
|
active_client = _get_metadata_fallback_client()
|
||||||
source_name = _get_metadata_fallback_source()
|
source_name = _get_metadata_fallback_source()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue