Fix hero slider + recommended modal returning 0 artists
get_top_similar_artists now accepts require_source parameter to filter by source ID in SQL. Previously fetched 200 artists then post-filtered, but cycling logic (last_featured ASC) rotated artists without IDs to the front, causing all 200 to be filtered out. Both /api/discover/hero and /api/discover/similar-artists now pass require_source=active_source so only artists with valid IDs are returned.
This commit is contained in:
parent
36e83e64ee
commit
c336604b71
2 changed files with 20 additions and 22 deletions
|
|
@ -7260,13 +7260,23 @@ class MusicDatabase:
|
|||
logger.error(f"Error checking similar artists freshness: {e}")
|
||||
return False # Default to re-fetching on error
|
||||
|
||||
def get_top_similar_artists(self, limit: int = 50, profile_id: int = 1) -> List[SimilarArtist]:
|
||||
"""Get top similar artists excluding watchlist artists, with cycling support"""
|
||||
def get_top_similar_artists(self, limit: int = 50, profile_id: int = 1, require_source: str = None) -> List[SimilarArtist]:
|
||||
"""Get top similar artists excluding watchlist artists, with cycling support.
|
||||
require_source: if set ('spotify','itunes','deezer'), only returns artists with that source ID."""
|
||||
try:
|
||||
with self._get_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("""
|
||||
# Build source filter
|
||||
source_filter = ''
|
||||
if require_source == 'spotify':
|
||||
source_filter = "AND sa.similar_artist_spotify_id IS NOT NULL AND sa.similar_artist_spotify_id != ''"
|
||||
elif require_source == 'itunes':
|
||||
source_filter = "AND sa.similar_artist_itunes_id IS NOT NULL AND sa.similar_artist_itunes_id != ''"
|
||||
elif require_source == 'deezer':
|
||||
source_filter = "AND sa.similar_artist_deezer_id IS NOT NULL AND sa.similar_artist_deezer_id != ''"
|
||||
|
||||
cursor.execute(f"""
|
||||
SELECT
|
||||
MAX(sa.id) as id,
|
||||
MAX(sa.source_artist_id) as source_artist_id,
|
||||
|
|
@ -7287,7 +7297,7 @@ class MusicDatabase:
|
|||
OR (sa.similar_artist_deezer_id IS NOT NULL AND sa.similar_artist_deezer_id = wa.deezer_artist_id)
|
||||
OR LOWER(sa.similar_artist_name) = LOWER(wa.artist_name)
|
||||
) AND wa.profile_id = ?
|
||||
WHERE wa.id IS NULL AND sa.profile_id = ?
|
||||
WHERE wa.id IS NULL AND sa.profile_id = ? {source_filter}
|
||||
GROUP BY sa.similar_artist_name
|
||||
ORDER BY
|
||||
CASE WHEN MAX(sa.last_featured) IS NULL THEN 0 ELSE 1 END,
|
||||
|
|
|
|||
|
|
@ -39021,7 +39021,8 @@ def get_discover_hero():
|
|||
# Get top similar artists (excluding watchlist, cycled by last_featured)
|
||||
# Fetch more than needed since strict source filtering may drop many
|
||||
pid = get_current_profile_id()
|
||||
similar_artists = database.get_top_similar_artists(limit=200, profile_id=pid)
|
||||
print(f"[Discover Hero] Profile ID: {pid}, Active source: {active_source}")
|
||||
similar_artists = database.get_top_similar_artists(limit=200, profile_id=pid, require_source=active_source)
|
||||
|
||||
# FALLBACK: If no similar artists exist, use watchlist artists for Hero section
|
||||
if not similar_artists:
|
||||
|
|
@ -39067,15 +39068,8 @@ def get_discover_hero():
|
|||
print(f"[Discover Hero] Returning {len(hero_artists)} watchlist artists as fallback")
|
||||
return jsonify({"success": True, "artists": hero_artists, "source": active_source, "fallback": "watchlist"})
|
||||
|
||||
# Filter to artists that have the appropriate ID for the active source
|
||||
valid_artists = []
|
||||
for artist in similar_artists:
|
||||
if active_source == 'spotify' and artist.similar_artist_spotify_id:
|
||||
valid_artists.append(artist)
|
||||
elif active_source == 'deezer' and getattr(artist, 'similar_artist_deezer_id', None):
|
||||
valid_artists.append(artist)
|
||||
elif active_source == 'itunes' and artist.similar_artist_itunes_id:
|
||||
valid_artists.append(artist)
|
||||
# Artists are already filtered by source in SQL — no post-filter needed
|
||||
valid_artists = list(similar_artists)
|
||||
|
||||
# FALLBACK: If no valid artists for fallback source, try to resolve IDs on-the-fly
|
||||
if active_source in ('itunes', 'deezer') and not valid_artists:
|
||||
|
|
@ -39198,20 +39192,14 @@ def get_discover_similar_artists():
|
|||
database = get_database()
|
||||
active_source = _get_active_discovery_source()
|
||||
|
||||
similar_artists = database.get_top_similar_artists(limit=200, profile_id=get_current_profile_id())
|
||||
similar_artists = database.get_top_similar_artists(limit=200, profile_id=get_current_profile_id(), require_source=active_source)
|
||||
|
||||
if not similar_artists:
|
||||
return jsonify({"success": True, "artists": [], "source": active_source, "count": 0})
|
||||
|
||||
# Filter to artists with valid ID for active source (strict — no cross-source)
|
||||
# Artists already filtered by source in SQL
|
||||
result_artists = []
|
||||
for artist in similar_artists:
|
||||
if active_source == 'spotify' and not artist.similar_artist_spotify_id:
|
||||
continue
|
||||
if active_source == 'deezer' and not getattr(artist, 'similar_artist_deezer_id', None) and not artist.similar_artist_itunes_id:
|
||||
continue
|
||||
if active_source == 'itunes' and not artist.similar_artist_itunes_id:
|
||||
continue
|
||||
|
||||
if active_source == 'spotify':
|
||||
artist_id = artist.similar_artist_spotify_id
|
||||
|
|
|
|||
Loading…
Reference in a new issue