fix: parse spotapi playlist response structure (data.playlistV2.content.items)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
575ca385fd
commit
7b5928f809
1 file changed
+26
-15
+26
-15
@@ -105,20 +105,32 @@ def resolve(sp_type, sp_id):
|
|||||||
if not cls_name:
|
if not cls_name:
|
||||||
raise Exception(f'spotapi has no playlist class (available: {available})')
|
raise Exception(f'spotapi has no playlist class (available: {available})')
|
||||||
pl = getattr(sp_mod, cls_name)(url)
|
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__}')
|
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
|
tracks, skipped, offset = [], 0, 0
|
||||||
|
first_page = None
|
||||||
while True:
|
while True:
|
||||||
page = pl.get_playlist_info(limit=100, offset=offset)
|
page = pl.get_playlist_info(limit=100, offset=offset)
|
||||||
if offset == 0:
|
if first_page is None: first_page = page
|
||||||
eprint(f'[spotapi] page0 type={type(page).__name__} keys={list(page.keys()) if isinstance(page, dict) else "list"}')
|
items = _pl_items(page)
|
||||||
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 not items: break
|
if not items: break
|
||||||
for item in items:
|
for item in items:
|
||||||
typename = (item.get('itemV2') or {}).get('data', {}).get('__typename', '')
|
typename = (item.get('itemV2') or {}).get('data', {}).get('__typename', '')
|
||||||
@@ -130,11 +142,10 @@ def resolve(sp_type, sp_id):
|
|||||||
offset += len(items)
|
offset += len(items)
|
||||||
time.sleep(0.3)
|
time.sleep(0.3)
|
||||||
|
|
||||||
name = owner = art = ''
|
attrs, owner_data, imgs = _pl_meta(first_page or {})
|
||||||
if isinstance(pl_meta, dict):
|
name = attrs.get('name', '') or attrs.get('title', '')
|
||||||
name = pl_meta.get('name', '')
|
owner = owner_data.get('name', '') or owner_data.get('displayName', '')
|
||||||
owner = pl_meta.get('owner', '') or pl_meta.get('owner_name', '')
|
art = imgs[0].get('url', '') if imgs else ''
|
||||||
art = pl_meta.get('image', '') or pl_meta.get('cover', '')
|
|
||||||
|
|
||||||
eprint(f'[spotapi] playlist ok — {len(tracks)} tracks')
|
eprint(f'[spotapi] playlist ok — {len(tracks)} tracks')
|
||||||
return {'type': 'playlist', 'name': name, 'artist': owner,
|
return {'type': 'playlist', 'name': name, 'artist': owner,
|
||||||
|
|||||||
Reference in new issue
Block a user