* Bump deezer-python to 5.12.0
* Add fd to ffmpeg whitelisted protocols
* Add documentation
* Refactor, throttler limit, artist toptracks limit, no eval
* provider name based on username
* Revert "Bump deezer-python to 5.12.0"
This reverts commit
a95449d3885daf91f71d49650250a953125a20b3.
---------
Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
"warning" if LOGGER.isEnabledFor(logging.DEBUG) else "quiet",
"-ignore_unknown",
"-protocol_whitelist",
- "file,http,https,tcp,tls,crypto,pipe", # support nested protocols (e.g. within playlist)
+ "file,http,https,tcp,tls,crypto,pipe,fd", # support nested protocols (e.g. within playlist)
]
# collect input args
input_args = []
)
-class DeezerProvider(MusicProvider):
+class DeezerProvider(MusicProvider): # pylint: disable=W0223
"""Deezer provider support."""
client: DeezerClient
creds: Credential
_throttler: Throttler
+ @property
+ def name(self) -> str:
+ """Return (custom) friendly name for this provider instance."""
+ if client := getattr(self, "client", None):
+ return f"Deezer - {client.user.name}"
+ return super().name
+
async def handle_setup(self) -> None:
"""Set up the Deezer provider."""
- self._throttler = Throttler(rate_limit=4, period=1)
+ self._throttler = Throttler(rate_limit=50, period=5)
self.creds = Credential(
app_id=DEEZER_APP_ID,
app_secret=DEEZER_APP_SECRET,
async def get_artist_toptracks(self, prov_artist_id: str) -> list[Track]:
"""Get top 25 tracks of an artist."""
artist = await self.client.get_artist(artist_id=int(prov_artist_id))
- top_tracks = (await self.client.get_artist_top(artist=artist))[:25]
+ top_tracks = await self.client.get_artist_top(artist=artist, limit=25)
return [
self.parse_track(track=track, user_country=self.gw_client.user_country)
for track in top_tracks
async def add_playlist_tracks(self, prov_playlist_id: str, prov_track_ids: list[str]):
"""Add tra ck(s) to playlist."""
await self.client.add_playlist_tracks(
- playlist_id=prov_playlist_id, tracks=[eval(i) for i in prov_track_ids]
+ playlist_id=prov_playlist_id, tracks=[int(i) for i in prov_track_ids]
)
async def remove_playlist_tracks(
class DeezerGWError(BaseException):
"""Exception type for GWClient related exceptions."""
- pass
-
class GWClient:
"""The GWClient class can be used to perform actions not being of the official API."""
csrf_token = self._gw_csrf_token if use_csrf_token else "null"
if params is None:
params = {}
- p = {"api_version": "1.0", "api_token": csrf_token, "input": "3", "method": method}
- p.update(params)
+ parameters = {"api_version": "1.0", "api_token": csrf_token, "input": "3", "method": method}
+ parameters |= params
result = await self.session.request(
http_method,
GW_LIGHT_URL,
- params=p,
+ params=parameters,
timeout=30,
json=args,
headers={"User-Agent": USER_AGENT_HEADER},
return await asyncio.to_thread(_get_albums_by_artist)
- async def get_artist_top(self, artist: deezer.Artist) -> deezer.PaginatedList:
+ async def get_artist_top(self, artist: deezer.Artist, limit: int = 25) -> deezer.PaginatedList:
"""Get top tracks by an artist."""
def _get_artist_top():
- return artist.get_top()
+ return artist.get_top()[:limit]
return await asyncio.to_thread(_get_artist_top)
"name": "Deezer",
"description": "Support for the Deezer streaming provider in Music Assistant.",
"codeowners": ["@Un10ck3d", "@micha91"],
+ "documentation": "https://github.com/orgs/music-assistant/discussions/1245",
"requirements": ["deezer-python==5.12.0", "pycryptodome==3.18.0"],
"multi_instance": true
}