diff --git a/backend/spotify_resolve.py b/backend/spotify_resolve.py index 75e57e4..681a9da 100644 --- a/backend/spotify_resolve.py +++ b/backend/spotify_resolve.py @@ -64,10 +64,26 @@ def resolve(sp_type, sp_id): url = f'https://open.spotify.com/{sp_type}/{sp_id}' if sp_type == 'track': - # Song requires a client instance as first arg; Public() is the unauthenticated client - public = sp_mod.Public() - song = sp_mod.Song(public, url) - raw = song.get_song_info() + # Song(url) stores url as the client object, then get_song_info() or init + # tries to call url.login which fails. Try: Song(url) + get_song_info(url), + # then Song(url) + get_song_info(), log methods as last resort. + song = sp_mod.Song(url) + song_methods = [m for m in dir(song) if not m.startswith('_')] + eprint(f'[spotapi] Song methods: {song_methods}') + raw = None + for attempt in [ + lambda: song.get_song_info(url), + lambda: song.get_song_info(), + ]: + try: + raw = attempt() + break + except Exception as e: + eprint(f'[spotapi] track attempt failed: {type(e).__name__}: {e}') + if raw is None: + pub = sp_mod.Public() + eprint(f'[spotapi] Public methods: {[m for m in dir(pub) if not m.startswith("_")]}') + raise Exception('Song resolution: all attempts failed') eprint(f'[spotapi] track raw type={type(raw).__name__} keys={list(raw.keys()) if isinstance(raw, dict) else "?"}') if isinstance(raw, dict): for k, v in raw.items(): @@ -113,10 +129,11 @@ def resolve(sp_type, sp_id): art = cover_items[0].get('url', '') if cover_items else '' # tracks raw_tracks = (au.get('tracks') or {}).get('items') or [] - # album track items look like {uid, track: {data: {trackUnion: {...}}}} + # album track items: {uid, track: {__typename, data: {trackUnion: {...}}}} + # wrap as {itemV2: track_obj} so _parse_track can navigate itemV2.data.trackUnion def _alb_track(item): - inner = item.get('track') or item - return _parse_track(inner, + track_obj = item.get('track') or item + return _parse_track({'itemV2': track_obj}, default_album=name, default_art=art, default_artist=artist) tracks = [t for t in (_alb_track(i) for i in raw_tracks) if t]