Fix slow Tidal playlist loading — metadata only, no track fetching

get_user_playlists_metadata_only() was fetching full track lists for
every playlist sequentially (1+ API calls per playlist with 1s sleep
between pagination pages). For 20+ playlists this took 30-60 seconds.

Now returns only metadata (name, ID, track count, image) from a
single V2 API call. Track count comes from the numberOfTracks
attribute. Tracks are fetched on-demand when the user selects a
specific playlist to sync/mirror via the existing get_playlist()
endpoint.
This commit is contained in:
Broque Thomas 2026-03-31 09:27:15 -07:00
parent 03298afac1
commit 3154d16cf3
2 changed files with 25 additions and 17 deletions

View file

@ -619,33 +619,41 @@ class TidalClient:
playlists = []
# Step 3: Process the playlists from the main 'data' array.
# Only extract metadata — tracks are fetched on-demand when the user
# selects a playlist to sync/mirror, not during the listing step.
for playlist_data in data.get('data', []):
attributes = playlist_data.get('attributes', {})
playlist_id = playlist_data.get('id')
# Create playlist with basic metadata first
# Extract image URL from relationships if available
image_url = None
try:
relationships = playlist_data.get('relationships', {})
image_rel = relationships.get('image', {}).get('data', {})
if image_rel:
# Image URL may be in included resources or constructed from ID
image_id = image_rel.get('id', '')
if image_id:
image_url = f"https://resources.tidal.com/images/{image_id.replace('-', '/')}/640x640.jpg"
except Exception:
pass
new_playlist = Playlist(
id=str(playlist_id),
name=attributes.get('name', 'Unknown Playlist'),
description=attributes.get('description', ''),
external_urls={'tidal': f"https://listen.tidal.com/playlist/{playlist_id}"},
public=attributes.get('accessType') == 'PUBLIC'
public=attributes.get('accessType') == 'PUBLIC',
tracks=[], # Empty — fetched on-demand via get_playlist()
)
# Step 4: Fetch ALL tracks for this playlist using the paginated get_playlist() method
# This ensures we get all tracks, not just the first ~20
logger.info(f"Fetching full track list for playlist: {new_playlist.name} ({playlist_id})")
full_playlist = self.get_playlist(playlist_id)
if full_playlist and full_playlist.tracks:
new_playlist.tracks = full_playlist.tracks
logger.info(f"Added {len(full_playlist.tracks)} tracks to playlist {new_playlist.name}")
else:
logger.warning(f"Could not fetch tracks for playlist {playlist_id}, it will have 0 tracks")
# Store track count from metadata (no API call needed)
new_playlist.track_count = attributes.get('numberOfTracks', 0)
if image_url:
new_playlist.image_url = image_url
playlists.append(new_playlist)
logger.info(f"Successfully retrieved {len(playlists)} playlists with the V2 filter method.")
logger.info(f"Successfully retrieved {len(playlists)} playlists (metadata only) with the V2 filter method.")
return playlists
except Exception as e:

View file

@ -28485,8 +28485,8 @@ def get_tidal_playlists():
playlist_data = []
for p in playlists:
# Get track count from actual tracks if available
track_count = len(p.tracks) if hasattr(p, 'tracks') and p.tracks else 0
# Get track count from metadata (set during listing) or actual tracks
track_count = getattr(p, 'track_count', 0) or (len(p.tracks) if hasattr(p, 'tracks') and p.tracks else 0)
playlist_dict = {
"id": p.id,