diff --git a/backend/spotify_resolve.py b/backend/spotify_resolve.py index d5e9e73..3b682d6 100644 --- a/backend/spotify_resolve.py +++ b/backend/spotify_resolve.py @@ -104,21 +104,33 @@ def resolve(sp_type, sp_id): cls_name = next((n for n in ('PublicPlaylist', 'Playlist') if n in available), None) if not cls_name: raise Exception(f'spotapi has no playlist class (available: {available})') - pl = getattr(sp_mod, cls_name)(url) - pl_meta = pl.get_playlist_info(limit=1) - eprint(f'[spotapi] playlist first-page type={type(pl_meta).__name__}') + pl = getattr(sp_mod, cls_name)(url) + + def _pl_items(page): + """Extract items list from partner API response: data.playlistV2.content.items""" + if isinstance(page, list): return page + d = page.get('data') or {} + pl2 = d.get('playlistV2') or {} + content = pl2.get('content') or {} + return content.get('items') or page.get('items') or page.get('tracks') or [] + + def _pl_meta(page): + """Extract playlist metadata from partner API response""" + if not isinstance(page, dict): return {}, {}, [] + d = page.get('data') or {} + pl2 = d.get('playlistV2') or {} + attrs = pl2.get('attributes') or pl2 + owner_obj = pl2.get('ownerV2') or pl2.get('owner') or {} + owner_data = owner_obj.get('data') or owner_obj + imgs = (pl2.get('images') or {}).get('items') or [] + return attrs, owner_data, imgs tracks, skipped, offset = [], 0, 0 + first_page = None while True: page = pl.get_playlist_info(limit=100, offset=offset) - if offset == 0: - eprint(f'[spotapi] page0 type={type(page).__name__} keys={list(page.keys()) if isinstance(page, dict) else "list"}') - if isinstance(page, dict): - for k, v in page.items(): - eprint(f'[spotapi] page0[{k!r}] = {type(v).__name__} {repr(v)[:120]}') - elif isinstance(page, list) and page: - eprint(f'[spotapi] page0[0] = {repr(page[0])[:200]}') - items = page if isinstance(page, list) else (page.get('items') or page.get('tracks') or []) + if first_page is None: first_page = page + items = _pl_items(page) if not items: break for item in items: typename = (item.get('itemV2') or {}).get('data', {}).get('__typename', '') @@ -130,11 +142,10 @@ def resolve(sp_type, sp_id): offset += len(items) time.sleep(0.3) - name = owner = art = '' - if isinstance(pl_meta, dict): - name = pl_meta.get('name', '') - owner = pl_meta.get('owner', '') or pl_meta.get('owner_name', '') - art = pl_meta.get('image', '') or pl_meta.get('cover', '') + attrs, owner_data, imgs = _pl_meta(first_page or {}) + name = attrs.get('name', '') or attrs.get('title', '') + owner = owner_data.get('name', '') or owner_data.get('displayName', '') + art = imgs[0].get('url', '') if imgs else '' eprint(f'[spotapi] playlist ok — {len(tracks)} tracks') return {'type': 'playlist', 'name': name, 'artist': owner,