Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crash for unknown resource, add Podcast & Episode resources #134

Merged
merged 7 commits into from
Aug 20, 2020
Merged
49 changes: 37 additions & 12 deletions deezer/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
Artist,
Chart,
Comment,
Episode,
Genre,
Playlist,
Podcast,
Radio,
Resource,
Track,
User,
)
Expand Down Expand Up @@ -61,16 +64,18 @@ class Client:
objects_types = {
"album": Album,
"artist": Artist,
"chart": Chart,
"comment": Comment,
"editorial": None,
"episode": Episode,
# 'folder': None, # need identification
"genre": Genre,
"playlist": Playlist,
"podcast": Podcast,
"radio": Radio,
"search": None,
"track": Track,
"user": User,
"chart": Chart,
}

def __init__(
Expand Down Expand Up @@ -123,7 +128,11 @@ def _process_json(self, item, parent=None):
result[parent.type] = parent

if "type" in result:
object_class = self.objects_types[result["type"]]
if result["type"] in self.objects_types:
object_class = self.objects_types[result["type"]]
else:
# in case any new types are introduced by the API
object_class = Resource
else:
object_class = self.objects_types[parent]
return object_class(self, result)
Expand Down Expand Up @@ -187,16 +196,6 @@ def get_object(
)
return self._process_json(json, parent)

def get_chart(self, relation=None, index=0, limit=10, **kwargs):
"""
Get chart

:returns: a list of :class:`~deezer.resources.Resource` objects.
"""
return self.get_object(
"chart", object_id="0", relation=relation, parent="chart", **kwargs
)

def get_album(self, object_id, relation=None, **kwargs):
"""
Get the album with the provided id
Expand All @@ -213,6 +212,16 @@ def get_artist(self, object_id, relation=None, **kwargs):
"""
return self.get_object("artist", object_id, relation=relation, **kwargs)

def get_chart(self, relation=None, index=0, limit=10, **kwargs):
"""
Get chart

:returns: a list of :class:`~deezer.resources.Resource` objects.
"""
return self.get_object(
"chart", object_id="0", relation=relation, parent="chart", **kwargs
)

def get_comment(self, object_id):
"""
Get the comment with the provided id
Expand All @@ -221,6 +230,14 @@ def get_comment(self, object_id):
"""
return self.get_object("comment", object_id)

def get_episode(self, object_id):
"""
Get the episode with the provided id

:returns: a :class:`~deezer.resources.Episode` object
"""
return self.get_object("episode", object_id)

def get_genre(self, object_id):
"""
Get the genre with the provided id
Expand All @@ -243,6 +260,14 @@ def get_playlist(self, object_id):
"""
return self.get_object("playlist", object_id)

def get_podcast(self, object_id):
"""
Get the podcast with the provided id

:returns: a :class:`~deezer.resources.Podcast` object
"""
return self.get_object("podcast", object_id)

def get_radio(self, object_id=None):
"""
Get the radio with the provided id.
Expand Down
32 changes: 32 additions & 0 deletions deezer/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,3 +430,35 @@ def iter_playlists(self, **kwargs):
:returns: list of :mod:`Playlist <deezer.resources.Playlist>` instances
"""
return self.iter_relation("playlists", **kwargs)


class Podcast(Resource):
"""
To access an :deezer-api:`podcast object <podcast>`.

All the fields documented on Deezer are accessible by as class attributes.
"""

def get_episodes(self, **kwargs):
"""
Get episodes from a podcast

:returns: list of :mod:`Episode <deezer.resources.Episode>` instances
"""
return self.get_relation("episodes", **kwargs)

def iter_episodes(self, **kwargs):
"""
Iterate over episodes of a podcast

:returns: list of :mod:`Episode <deezer.resources.Episode>` instances
"""
return self.iter_relation("episodes", **kwargs)


class Episode(Resource):
"""
To access an :deezer-api:`episode object <episode>`.

All the fields documented on Deezer are accessible by as class attributes.
"""
288 changes: 194 additions & 94 deletions tests/cassettes/TestChart.test_chart_albums.yaml

Large diffs are not rendered by default.

271 changes: 185 additions & 86 deletions tests/cassettes/TestChart.test_chart_artists.yaml

Large diffs are not rendered by default.

297 changes: 197 additions & 100 deletions tests/cassettes/TestChart.test_chart_playlists.yaml

Large diffs are not rendered by default.

307 changes: 206 additions & 101 deletions tests/cassettes/TestChart.test_chart_tracks.yaml

Large diffs are not rendered by default.

209 changes: 143 additions & 66 deletions tests/cassettes/TestClient.test_chart.yaml

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions tests/cassettes/TestClient.test_get_episode.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- identity
Connection:
- keep-alive
User-Agent:
- python-requests/2.24.0
method: GET
uri: https://api.deezer.com/episode/238455362
response:
body:
string: '{"id":238455362,"title":"Episode 9: Follow the money","description":"The
search for Dr Ruja is back on. A lot has happened since Episode 8. Original
music and sound design: Phil Channell Original Music and vocals: Dessislava
Stefanova and the London Bulgarian Choir This audio was updated on 12\/08\/2020
to reflect additional correspondence with Chelgate.","available":true,"release_date":"2020-08-06
09:00:00","duration":2755,"link":"https:\/\/www.deezer.com\/episode\/238455362","share":"https:\/\/www.deezer.com\/episode\/238455362?utm_source=deezer&utm_content=episode-238455362&utm_term=0_1597915623&utm_medium=web","picture":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/180x180-000000-80-0-0.jpg","picture_small":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/56x56-000000-80-0-0.jpg","picture_medium":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/250x250-000000-80-0-0.jpg","picture_big":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/500x500-000000-80-0-0.jpg","picture_xl":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/1000x1000-000000-80-0-0.jpg","podcast":{"id":699612,"title":"The
Missing Cryptoqueen","link":"https:\/\/www.deezer.com\/show\/699612","picture":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/180x180-000000-80-0-0.jpg","picture_small":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/56x56-000000-80-0-0.jpg","picture_medium":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/250x250-000000-80-0-0.jpg","picture_big":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/500x500-000000-80-0-0.jpg","picture_xl":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/1000x1000-000000-80-0-0.jpg","type":"podcast"},"type":"episode"}'
headers:
Content-Length:
- '1994'
Content-Type:
- application/json; charset=utf-8
Date:
- Thu, 20 Aug 2020 09:27:03 GMT
P3P:
- policyref="/w3c/p3p.xml" CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"
Server:
- Apache
Set-Cookie:
- dzr_uniq_id=dzr_uniq_id_frf4ec25bbbe333607bc2293723d55ce03f709c4; expires=Tue,
16-Feb-2021 09:27:03 GMT; Max-Age=15552000; path=/;SameSite=None; domain=.deezer.com;
secure; HttpOnly
Vary:
- Accept-Encoding
X-Content-Type-Options:
- nosniff
X-Host:
- blm-web-143
status:
code: 200
message: OK
version: 1
44 changes: 44 additions & 0 deletions tests/cassettes/TestClient.test_get_podcast.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- identity
Connection:
- keep-alive
User-Agent:
- python-requests/2.24.0
method: GET
uri: https://api.deezer.com/podcast/699612
response:
body:
string: '{"id":699612,"title":"The Missing Cryptoqueen","description":"Dr Ruja
Ignatova persuaded millions to join her financial revolution. Then she disappeared.
Why? Jamie Bartlett presents a story of greed, deceit and herd madness.","available":true,"rating":0,"fans":159,"link":"https:\/\/www.deezer.com\/show\/699612","share":"https:\/\/www.deezer.com\/show\/699612?utm_source=deezer&utm_content=show-699612&utm_term=0_1597915624&utm_medium=web","picture":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/180x180-000000-80-0-0.jpg","picture_small":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/56x56-000000-80-0-0.jpg","picture_medium":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/250x250-000000-80-0-0.jpg","picture_big":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/500x500-000000-80-0-0.jpg","picture_xl":"https:\/\/cdns-images.dzcdn.net\/images\/talk\/34df19abb7d60668cf967d1d866943b3\/1000x1000-000000-80-0-0.jpg","type":"podcast"}'
headers:
Content-Length:
- '1074'
Content-Type:
- application/json; charset=utf-8
Date:
- Thu, 20 Aug 2020 09:27:04 GMT
P3P:
- policyref="/w3c/p3p.xml" CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"
Server:
- Apache
Set-Cookie:
- dzr_uniq_id=dzr_uniq_id_fr4352bb520686d0df8a87224e972c04b235cade; expires=Tue,
16-Feb-2021 09:27:04 GMT; Max-Age=15552000; path=/;SameSite=None; domain=.deezer.com;
secure; HttpOnly
Vary:
- Accept-Encoding
X-Content-Type-Options:
- nosniff
X-Host:
- blm-web-148
status:
code: 200
message: OK
version: 1
40 changes: 40 additions & 0 deletions tests/cassettes/TestClient.test_no_episode_raise.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- identity
Connection:
- keep-alive
User-Agent:
- python-requests/2.24.0
method: GET
uri: https://api.deezer.com/episode/-1
response:
body:
string: '{"error":{"type":"Exception","message":"An error has occured"}}'
headers:
Content-Length:
- '63'
Content-Type:
- application/json; charset=utf-8
Date:
- Thu, 20 Aug 2020 09:27:03 GMT
P3P:
- policyref="/w3c/p3p.xml" CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"
Server:
- Apache
Set-Cookie:
- dzr_uniq_id=dzr_uniq_id_frb4df369d3350c71e2d28a0bd170b497aee3126; expires=Tue,
16-Feb-2021 09:27:03 GMT; Max-Age=15552000; path=/;SameSite=None; domain=.deezer.com;
secure; HttpOnly
X-Content-Type-Options:
- nosniff
X-Host:
- blm-web-86
status:
code: 200
message: OK
version: 1
40 changes: 40 additions & 0 deletions tests/cassettes/TestClient.test_no_podcast_raise.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- identity
Connection:
- keep-alive
User-Agent:
- python-requests/2.24.0
method: GET
uri: https://api.deezer.com/podcast/-1
response:
body:
string: '{"error":{"type":"Exception","message":"An error has occured"}}'
headers:
Content-Length:
- '63'
Content-Type:
- application/json; charset=utf-8
Date:
- Thu, 20 Aug 2020 09:27:04 GMT
P3P:
- policyref="/w3c/p3p.xml" CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"
Server:
- Apache
Set-Cookie:
- dzr_uniq_id=dzr_uniq_id_fr6d1ba4e79fef242c32077dfb30454763c64dd0; expires=Tue,
16-Feb-2021 09:27:04 GMT; Max-Age=15552000; path=/;SameSite=None; domain=.deezer.com;
secure; HttpOnly
X-Content-Type-Options:
- nosniff
X-Host:
- blm-web-139
status:
code: 200
message: OK
version: 1
Loading