Add Deezer ARL favorite artists support
Add get_user_favorite_artists(limit=200) to DeezerDownloadClient to fetch a user's favorite artists via the public API using an ARL-authenticated session (paginated, error-handled, returns deezer_id, name, image_url). Update web_server to treat Deezer as connected if either OAuth or ARL is authenticated, and to fetch favorite artists from OAuth client when available or from soulseek_client.deezer_dl (ARL) otherwise. Fetched artists are upserted into the database and appropriate log/console messages and counters are updated.
This commit is contained in:
parent
8fc4484846
commit
453eb90f19
2 changed files with 61 additions and 11 deletions
|
|
@ -282,6 +282,47 @@ class DeezerDownloadClient:
|
|||
logger.info(f"Fetched {len(playlists)} user playlists from Deezer")
|
||||
return playlists
|
||||
|
||||
def get_user_favorite_artists(self, limit: int = 200) -> list:
|
||||
"""Fetch the authenticated user's favorite artists via public API with ARL cookies."""
|
||||
if not self._authenticated or not self._user_data:
|
||||
return []
|
||||
user_id = self._user_data.get('USER_ID')
|
||||
if not user_id:
|
||||
return []
|
||||
|
||||
artists = []
|
||||
index = 0
|
||||
while len(artists) < limit:
|
||||
try:
|
||||
resp = self._session.get(
|
||||
f'https://api.deezer.com/user/{user_id}/artists',
|
||||
params={'index': index, 'limit': min(100, limit - len(artists))},
|
||||
timeout=15
|
||||
)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
if 'error' in data:
|
||||
logger.warning(f"Deezer artists error: {data['error']}")
|
||||
break
|
||||
items = data.get('data', [])
|
||||
if not items:
|
||||
break
|
||||
for a in items:
|
||||
artists.append({
|
||||
'deezer_id': str(a.get('id', '')),
|
||||
'name': a.get('name', ''),
|
||||
'image_url': a.get('picture_xl') or a.get('picture_big') or a.get('picture_medium', ''),
|
||||
})
|
||||
if not data.get('next'):
|
||||
break
|
||||
index += len(items)
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching favorite artists at index {index}: {e}")
|
||||
break
|
||||
|
||||
logger.info(f"Fetched {len(artists)} favorite artists from Deezer (ARL)")
|
||||
return artists
|
||||
|
||||
def get_playlist_tracks(self, playlist_id: str) -> Optional[dict]:
|
||||
"""Fetch full playlist details with tracks via public API (ARL cookies grant private access)."""
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -42405,10 +42405,13 @@ def get_your_artists_sources():
|
|||
# Last.fm
|
||||
if config_manager.get('lastfm.api_key', '') and config_manager.get('lastfm.session_key', ''):
|
||||
connected.append('lastfm')
|
||||
# Deezer
|
||||
# Deezer — OAuth token OR ARL token both count as connected
|
||||
try:
|
||||
deezer_cl = _get_deezer_client()
|
||||
if deezer_cl and hasattr(deezer_cl, 'is_user_authenticated') and deezer_cl.is_user_authenticated():
|
||||
deezer_oauth = deezer_cl and hasattr(deezer_cl, 'is_user_authenticated') and deezer_cl.is_user_authenticated()
|
||||
deezer_arl = (hasattr(soulseek_client, 'deezer_dl') and soulseek_client.deezer_dl
|
||||
and soulseek_client.deezer_dl.is_authenticated())
|
||||
if deezer_oauth or deezer_arl:
|
||||
connected.append('deezer')
|
||||
except Exception:
|
||||
pass
|
||||
|
|
@ -42518,22 +42521,28 @@ def _fetch_and_match_liked_artists(profile_id: int):
|
|||
except Exception as e:
|
||||
logger.error(f"[Your Artists] Last.fm fetch error: {e}")
|
||||
|
||||
# 4. Fetch from Deezer (favorite artists — requires OAuth)
|
||||
# 4. Fetch from Deezer (favorite artists — OAuth or ARL)
|
||||
try:
|
||||
if 'deezer' not in enabled_sources:
|
||||
print("[Your Artists] Deezer skipped (disabled in sources config)")
|
||||
else:
|
||||
deezer_cl = _get_deezer_client()
|
||||
artists = []
|
||||
if deezer_cl and hasattr(deezer_cl, 'is_user_authenticated') and deezer_cl.is_user_authenticated():
|
||||
print("[Your Artists] Fetching favorite artists from Deezer...")
|
||||
print("[Your Artists] Fetching favorite artists from Deezer (OAuth)...")
|
||||
artists = deezer_cl.get_user_favorite_artists(limit=200)
|
||||
for a in artists:
|
||||
database.upsert_liked_artist(
|
||||
artist_name=a['name'], source_service='deezer',
|
||||
source_id=a.get('deezer_id'), source_id_type='deezer',
|
||||
image_url=a.get('image_url'), profile_id=profile_id
|
||||
)
|
||||
fetched += len(artists)
|
||||
elif (hasattr(soulseek_client, 'deezer_dl') and soulseek_client.deezer_dl
|
||||
and soulseek_client.deezer_dl.is_authenticated()):
|
||||
print("[Your Artists] Fetching favorite artists from Deezer (ARL)...")
|
||||
artists = soulseek_client.deezer_dl.get_user_favorite_artists(limit=200)
|
||||
for a in artists:
|
||||
database.upsert_liked_artist(
|
||||
artist_name=a['name'], source_service='deezer',
|
||||
source_id=a.get('deezer_id'), source_id_type='deezer',
|
||||
image_url=a.get('image_url'), profile_id=profile_id
|
||||
)
|
||||
fetched += len(artists)
|
||||
if artists:
|
||||
print(f"[Your Artists] Fetched {len(artists)} from Deezer")
|
||||
except Exception as e:
|
||||
logger.error(f"[Your Artists] Deezer fetch error: {e}")
|
||||
|
|
|
|||
Loading…
Reference in a new issue