fix seasonal discovery showing "Various Artists" and using wrong download mode

This commit is contained in:
Broque Thomas 2026-02-15 19:29:20 -08:00
parent 33f4c90015
commit 5f12634f61
3 changed files with 52 additions and 19 deletions

View file

@ -475,7 +475,7 @@ class SeasonalDiscoveryService:
seasonal_albums.append({
'spotify_album_id': album.id,
'album_name': album.name,
'artist_name': album.artist if hasattr(album, 'artist') else 'Various Artists',
'artist_name': ', '.join(album.artists) if album.artists else 'Various Artists',
'album_cover_url': album.image_url if hasattr(album, 'image_url') else None,
'release_date': album.release_date if hasattr(album, 'release_date') else None,
'popularity': getattr(album, 'popularity', 50)

View file

@ -20631,11 +20631,18 @@ def refresh_seasonal_content():
database = get_database()
seasonal_service = get_seasonal_discovery_service(spotify_client, database)
# Populate all seasons in background thread
# Force populate current season in background thread (bypass 7-day threshold)
import threading
def populate_all():
try:
seasonal_service.populate_all_seasons()
current_season = seasonal_service.get_current_season()
if current_season:
print(f"🔄 Force-refreshing seasonal content for: {current_season}")
seasonal_service.populate_seasonal_content(current_season)
seasonal_service.curate_seasonal_playlist(current_season)
print(f"✅ Seasonal content refreshed for: {current_season}")
else:
print(" No active season to refresh")
except Exception as e:
print(f"Error in background seasonal population: {e}")

View file

@ -5924,7 +5924,7 @@ async function openDownloadMissingModalForYouTube(virtualPlaylistId, playlistNam
}
// CRITICAL FIX: Use album context for discover_album playlists
const isDiscoverAlbum = virtualPlaylistId.startsWith('discover_album_');
const isDiscoverAlbum = virtualPlaylistId.startsWith('discover_album_') || virtualPlaylistId.startsWith('seasonal_album_');
const heroContext = isDiscoverAlbum && album && artist ? {
type: 'album', // ✅ Show as album, not playlist
album: {
@ -7503,8 +7503,8 @@ async function startMissingTracksProcess(playlistId) {
};
// If this is an artist album download, use album name and include full context
// Match 'artist_album_', 'enhanced_search_album_', and 'discover_album_' prefixes
if (playlistId.startsWith('artist_album_') || playlistId.startsWith('enhanced_search_album_') || playlistId.startsWith('discover_album_')) {
// Match 'artist_album_', 'enhanced_search_album_', 'discover_album_', and 'seasonal_album_' prefixes
if (playlistId.startsWith('artist_album_') || playlistId.startsWith('enhanced_search_album_') || playlistId.startsWith('discover_album_') || playlistId.startsWith('seasonal_album_')) {
requestBody.playlist_name = process.album?.name || process.playlist.name;
requestBody.is_album_download = true;
requestBody.album_context = process.album; // Full Spotify album object
@ -33149,12 +33149,20 @@ async function openDownloadModalForSeasonalAlbum(albumIndex) {
return;
}
console.log(`📥 Opening Download Missing Tracks modal for album: ${album.album_name}`);
console.log(`📥 Opening Download Missing Tracks modal for seasonal album: ${album.album_name}`);
showLoadingOverlay(`Loading tracks for ${album.album_name}...`);
try {
// Fetch album tracks from Spotify API via backend
const response = await fetch(`/api/spotify/album/${album.spotify_album_id}`);
// Determine source and album ID - use source-agnostic endpoint (matches Recent Releases)
const source = album.source || (album.spotify_album_id && !album.spotify_album_id.match(/^\d+$/) ? 'spotify' : 'itunes');
const albumId = album.spotify_album_id;
if (!albumId) {
throw new Error('No album ID available');
}
// Fetch album tracks from appropriate source via backend
const response = await fetch(`/api/discover/album/${source}/${albumId}`);
if (!response.ok) {
throw new Error('Failed to fetch album tracks');
}
@ -33164,10 +33172,9 @@ async function openDownloadModalForSeasonalAlbum(albumIndex) {
throw new Error('No tracks found in album');
}
// Convert to expected format
// Convert to expected format with full album context (matches Recent Releases)
const spotifyTracks = albumData.tracks.map(track => {
// Normalize artists to array of strings
let artists = track.artists || [{ name: album.artist_name }];
let artists = track.artists || albumData.artists || [{ name: album.artist_name }];
if (Array.isArray(artists)) {
artists = artists.map(a => a.name || a);
}
@ -33177,19 +33184,38 @@ async function openDownloadModalForSeasonalAlbum(albumIndex) {
name: track.name,
artists: artists,
album: {
name: album.album_name,
images: album.album_cover_url ? [{ url: album.album_cover_url }] : []
id: albumData.id,
name: albumData.name,
album_type: albumData.album_type || 'album',
total_tracks: albumData.total_tracks || 0,
release_date: albumData.release_date || '',
images: albumData.images || []
},
duration_ms: track.duration_ms || 0
duration_ms: track.duration_ms || 0,
track_number: track.track_number || 0
};
});
// Create virtual playlist ID
const virtualPlaylistId = `seasonal_album_${album.spotify_album_id}`;
const playlistName = `${album.album_name} - ${album.artist_name}`;
const virtualPlaylistId = `seasonal_album_${albumId}`;
// Open download modal (same as Recent Releases)
await openDownloadMissingModalForYouTube(virtualPlaylistId, playlistName, spotifyTracks);
// Pass proper artist/album context for album download (1 worker + source reuse)
const artistContext = {
name: album.artist_name,
source: source
};
const albumContext = {
id: albumData.id,
name: albumData.name,
album_type: albumData.album_type || 'album',
total_tracks: albumData.total_tracks || 0,
release_date: albumData.release_date || '',
images: albumData.images || []
};
// Open download modal with album context (same as Recent Releases)
await openDownloadMissingModalForYouTube(virtualPlaylistId, albumData.name, spotifyTracks, artistContext, albumContext);
hideLoadingOverlay();