Skip to content

Add support for private Deezer playlists using GW API#945

Open
geekinsanemx wants to merge 2 commits intonathom:devfrom
geekinsanemx:feature/private-playlists
Open

Add support for private Deezer playlists using GW API#945
geekinsanemx wants to merge 2 commits intonathom:devfrom
geekinsanemx:feature/private-playlists

Conversation

@geekinsanemx
Copy link

This adds automatic fallback to Deezer's Gateway API when accessing private/user playlists, enabling downloads of your own private playlists using your ARL token.

What was happening

Private playlists failed with PermissionException when trying to download: "An active access token must be used to query information about the current user"

This happened even with a valid ARL token because the public API doesn't support private playlists, only the Gateway (GW) API does.

Why it happened

Streamrip only used Deezer's public API (client.api.) which requires OAuth tokens for private content. The ARL token works with the Gateway API (client.gw.) but wasn't being used for playlists.

What changed

Added automatic GW API fallback in get_playlist() method:

  1. First tries public API (works for public playlists)
  2. If PermissionException occurs, automatically tries GW API
  3. Converts GW API response format to match public API format
  4. Handles private playlist quirks (CURATOR as bool vs dict)

New helper method _convert_gw_playlist_to_api_format() transforms:

  • Uppercase GW keys (DATA, SONGS) to lowercase (data, tracks)
  • Private playlist creator info from PARENT_USER fields
  • Picture URLs from hashes to full CDN URLs

Result

Users can now download their private Deezer playlists seamlessly with their ARL token. Public playlists continue to work as before. If both APIs fail, users get clear error messages explaining:

  • Possible causes (invalid ARL, restricted playlist, deleted playlist)
  • Workaround (temporarily make playlist public)

Files modified:

  • streamrip/client/deezer.py:
    • Import PermissionException from deezer.errors
    • Wrap get_playlist() with try/except for GW API fallback
    • Add _convert_gw_playlist_to_api_format() helper method
    • Add detailed error logging for troubleshooting

Tested with private playlists - successfully fetches metadata and tracks.

This adds automatic fallback to Deezer's Gateway API when accessing
private/user playlists, enabling downloads of your own private playlists
using your ARL token.

## What was happening

Private playlists failed with PermissionException when trying to download:
"An active access token must be used to query information about the current user"

This happened even with a valid ARL token because the public API doesn't
support private playlists, only the Gateway (GW) API does.

## Why it happened

Streamrip only used Deezer's public API (client.api.*) which requires
OAuth tokens for private content. The ARL token works with the Gateway
API (client.gw.*) but wasn't being used for playlists.

## What changed

Added automatic GW API fallback in get_playlist() method:
1. First tries public API (works for public playlists)
2. If PermissionException occurs, automatically tries GW API
3. Converts GW API response format to match public API format
4. Handles private playlist quirks (CURATOR as bool vs dict)

New helper method _convert_gw_playlist_to_api_format() transforms:
- Uppercase GW keys (DATA, SONGS) to lowercase (data, tracks)
- Private playlist creator info from PARENT_USER fields
- Picture URLs from hashes to full CDN URLs

## Result

Users can now download their private Deezer playlists seamlessly with
their ARL token. Public playlists continue to work as before. If both
APIs fail, users get clear error messages explaining:
- Possible causes (invalid ARL, restricted playlist, deleted playlist)
- Workaround (temporarily make playlist public)

Files modified:
- streamrip/client/deezer.py:
  - Import PermissionException from deezer.errors
  - Wrap get_playlist() with try/except for GW API fallback
  - Add _convert_gw_playlist_to_api_format() helper method
  - Add detailed error logging for troubleshooting

Tested with private playlists - successfully fetches metadata and tracks.
What was happening:
Private playlists only downloaded 10 tracks even when the playlist
had 21+ tracks.

Why it happened:
get_playlist_page() returns paginated results with only the first 10
tracks. The SONGS.data array contains only one page while SONGS.total
shows the actual total count.

What changed:
Now uses both GW API methods:
- get_playlist_page() for playlist metadata
- get_playlist_tracks() for complete track list (not paginated)

Replaces the paginated SONGS.data with the complete track list before
conversion.

Result:
Private playlists now download all tracks, matching public playlist
behavior. Verified with 21-track playlist - all tracks now fetched.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant