diff --git a/CHANGELOG.md b/CHANGELOG.md index f5fd7b2..3b12bb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Enabled using both short and long IDs for playlist_change_details - Added a cache handler to `SpotifyClientCredentials` +- Added the following endpoints + * `Spotify.current_user_saved_episodes` + * `Spotify.current_user_saved_episodes_add` + * `Spotify.current_user_saved_episodes_delete` + * `Spotify.current_user_saved_episodes_contains` + * `Spotify.available_markets` ### Changed diff --git a/spotipy/client.py b/spotipy/client.py index 95e2aa7..8c1fc8a 100644 --- a/spotipy/client.py +++ b/spotipy/client.py @@ -1171,16 +1171,184 @@ class Spotify(object): """ return self._get("me/player/currently-playing") - def current_user_saved_tracks(self, limit=20, offset=0): + def current_user_saved_albums(self, limit=20, offset=0, market=None): + """ Gets a list of the albums saved in the current authorized user's + "Your Music" library + + Parameters: + - limit - the number of albums to return + - offset - the index of the first album to return + - market - an ISO 3166-1 alpha-2 country code. + + """ + return self._get("me/albums", limit=limit, offset=offset, market=market) + + def current_user_saved_albums_add(self, albums=[]): + """ Add one or more albums to the current user's + "Your Music" library. + Parameters: + - albums - a list of album URIs, URLs or IDs + """ + + alist = [self._get_id("album", a) for a in albums] + return self._put("me/albums?ids=" + ",".join(alist)) + + def current_user_saved_albums_delete(self, albums=[]): + """ Remove one or more albums from the current user's + "Your Music" library. + + Parameters: + - albums - a list of album URIs, URLs or IDs + """ + alist = [self._get_id("album", a) for a in albums] + return self._delete("me/albums/?ids=" + ",".join(alist)) + + def current_user_saved_albums_contains(self, albums=[]): + """ Check if one or more albums is already saved in + the current Spotify user’s “Your Music” library. + + Parameters: + - albums - a list of album URIs, URLs or IDs + """ + alist = [self._get_id("album", a) for a in albums] + return self._get("me/albums/contains?ids=" + ",".join(alist)) + + def current_user_saved_tracks(self, limit=20, offset=0, market=None): """ Gets a list of the tracks saved in the current authorized user's "Your Music" library Parameters: - limit - the number of tracks to return - offset - the index of the first track to return + - market - an ISO 3166-1 alpha-2 country code """ - return self._get("me/tracks", limit=limit, offset=offset) + return self._get("me/tracks", limit=limit, offset=offset, market=market) + + def current_user_saved_tracks_add(self, tracks=None): + """ Add one or more tracks to the current user's + "Your Music" library. + + Parameters: + - tracks - a list of track URIs, URLs or IDs + """ + tlist = [] + if tracks is not None: + tlist = [self._get_id("track", t) for t in tracks] + return self._put("me/tracks/?ids=" + ",".join(tlist)) + + def current_user_saved_tracks_delete(self, tracks=None): + """ Remove one or more tracks from the current user's + "Your Music" library. + + Parameters: + - tracks - a list of track URIs, URLs or IDs + """ + tlist = [] + if tracks is not None: + tlist = [self._get_id("track", t) for t in tracks] + return self._delete("me/tracks/?ids=" + ",".join(tlist)) + + def current_user_saved_tracks_contains(self, tracks=None): + """ Check if one or more tracks is already saved in + the current Spotify user’s “Your Music” library. + + Parameters: + - tracks - a list of track URIs, URLs or IDs + """ + tlist = [] + if tracks is not None: + tlist = [self._get_id("track", t) for t in tracks] + return self._get("me/tracks/contains?ids=" + ",".join(tlist)) + + def current_user_saved_episodes(self, limit=20, offset=0, market=None): + """ Gets a list of the episodes saved in the current authorized user's + "Your Music" library + + Parameters: + - limit - the number of episodes to return + - offset - the index of the first episode to return + - market - an ISO 3166-1 alpha-2 country code + + """ + return self._get("me/episodes", limit=limit, offset=offset, market=market) + + def current_user_saved_episodes_add(self, episodes=None): + """ Add one or more episodes to the current user's + "Your Music" library. + + Parameters: + - episodes - a list of episode URIs, URLs or IDs + """ + elist = [] + if episodes is not None: + elist = [self._get_id("episode", e) for e in episodes] + return self._put("me/episodes/?ids=" + ",".join(elist)) + + def current_user_saved_episodes_delete(self, episodes=None): + """ Remove one or more episodes from the current user's + "Your Music" library. + + Parameters: + - episodes - a list of episode URIs, URLs or IDs + """ + elist = [] + if episodes is not None: + elist = [self._get_id("episode", e) for e in episodes] + return self._delete("me/episodes/?ids=" + ",".join(elist)) + + def current_user_saved_episodes_contains(self, episodes=None): + """ Check if one or more episodes is already saved in + the current Spotify user’s “Your Music” library. + + Parameters: + - episodes - a list of episode URIs, URLs or IDs + """ + elist = [] + if episodes is not None: + elist = [self._get_id("episode", e) for e in episodes] + return self._get("me/episodes/contains?ids=" + ",".join(elist)) + + def current_user_saved_shows(self, limit=20, offset=0, market=None): + """ Gets a list of the shows saved in the current authorized user's + "Your Music" library + + Parameters: + - limit - the number of shows to return + - offset - the index of the first show to return + - market - an ISO 3166-1 alpha-2 country code + + """ + return self._get("me/shows", limit=limit, offset=offset, market=market) + + def current_user_saved_shows_add(self, shows=[]): + """ Add one or more albums to the current user's + "Your Music" library. + Parameters: + - shows - a list of show URIs, URLs or IDs + """ + slist = [self._get_id("show", s) for s in shows] + return self._put("me/shows?ids=" + ",".join(slist)) + + def current_user_saved_shows_delete(self, shows=[]): + """ Remove one or more shows from the current user's + "Your Music" library. + + Parameters: + - shows - a list of show URIs, URLs or IDs + """ + slist = [self._get_id("show", s) for s in shows] + return self._delete("me/shows/?ids=" + ",".join(slist)) + + def current_user_saved_shows_contains(self, shows=[]): + """ Check if one or more shows is already saved in + the current Spotify user’s “Your Music” library. + + Parameters: + - shows - a list of show URIs, URLs or IDs + """ + slist = [self._get_id("show", s) for s in shows] + return self._get("me/shows/contains?ids=" + ",".join(slist)) def current_user_followed_artists(self, limit=20, after=None): """ Gets a list of the artists followed by the current authorized user @@ -1225,42 +1393,6 @@ class Spotify(object): "me/following/contains", ids=",".join(idlist), type="user" ) - def current_user_saved_tracks_delete(self, tracks=None): - """ Remove one or more tracks from the current user's - "Your Music" library. - - Parameters: - - tracks - a list of track URIs, URLs or IDs - """ - tlist = [] - if tracks is not None: - tlist = [self._get_id("track", t) for t in tracks] - return self._delete("me/tracks/?ids=" + ",".join(tlist)) - - def current_user_saved_tracks_contains(self, tracks=None): - """ Check if one or more tracks is already saved in - the current Spotify user’s “Your Music” library. - - Parameters: - - tracks - a list of track URIs, URLs or IDs - """ - tlist = [] - if tracks is not None: - tlist = [self._get_id("track", t) for t in tracks] - return self._get("me/tracks/contains?ids=" + ",".join(tlist)) - - def current_user_saved_tracks_add(self, tracks=None): - """ Add one or more tracks to the current user's - "Your Music" library. - - Parameters: - - tracks - a list of track URIs, URLs or IDs - """ - tlist = [] - if tracks is not None: - tlist = [self._get_id("track", t) for t in tracks] - return self._put("me/tracks/?ids=" + ",".join(tlist)) - def current_user_top_artists( self, limit=20, offset=0, time_range="medium_term" ): @@ -1310,86 +1442,6 @@ class Spotify(object): before=before, ) - def current_user_saved_albums(self, limit=20, offset=0): - """ Gets a list of the albums saved in the current authorized user's - "Your Music" library - - Parameters: - - limit - the number of albums to return - - offset - the index of the first album to return - - """ - return self._get("me/albums", limit=limit, offset=offset) - - def current_user_saved_albums_contains(self, albums=[]): - """ Check if one or more albums is already saved in - the current Spotify user’s “Your Music” library. - - Parameters: - - albums - a list of album URIs, URLs or IDs - """ - alist = [self._get_id("album", a) for a in albums] - return self._get("me/albums/contains?ids=" + ",".join(alist)) - - def current_user_saved_albums_add(self, albums=[]): - """ Add one or more albums to the current user's - "Your Music" library. - Parameters: - - albums - a list of album URIs, URLs or IDs - """ - alist = [self._get_id("album", a) for a in albums] - return self._put("me/albums?ids=" + ",".join(alist)) - - def current_user_saved_albums_delete(self, albums=[]): - """ Remove one or more albums from the current user's - "Your Music" library. - - Parameters: - - albums - a list of album URIs, URLs or IDs - """ - alist = [self._get_id("album", a) for a in albums] - return self._delete("me/albums/?ids=" + ",".join(alist)) - - def current_user_saved_shows(self, limit=50, offset=0): - """ Gets a list of the shows saved in the current authorized user's - "Your Music" library - - Parameters: - - limit - the number of shows to return - - offset - the index of the first show to return - - """ - return self._get("me/shows", limit=limit, offset=offset) - - def current_user_saved_shows_contains(self, shows=[]): - """ Check if one or more shows is already saved in - the current Spotify user’s “Your Music” library. - - Parameters: - - shows - a list of show URIs, URLs or IDs - """ - slist = [self._get_id("show", s) for s in shows] - return self._get("me/shows/contains?ids=" + ",".join(slist)) - - def current_user_saved_shows_add(self, shows=[]): - """ Add one or more albums to the current user's - "Your Music" library. - Parameters: - - shows - a list of show URIs, URLs or IDs - """ - slist = [self._get_id("show", s) for s in shows] - return self._put("me/shows?ids=" + ",".join(slist)) - - def current_user_saved_shows_delete(self, shows=[]): - """ Remove one or more shows from the current user's - "Your Music" library. - - Parameters: - - shows - a list of show URIs, URLs or IDs - """ - slist = [self._get_id("show", s) for s in shows] - return self._delete("me/shows/?ids=" + ",".join(slist)) - def user_follow_artists(self, ids=[]): """ Follow one or more artists Parameters: @@ -1829,6 +1881,13 @@ class Spotify(object): return self._post(endpoint) + def available_markets(self): + """ Get the list of markets where Spotify is available. + Returns a list of the countries in which Spotify is available, identified by their + ISO 3166-1 alpha-2 country code with additional country codes for special territories. + """ + return self._get("markets") + def _append_device_id(self, path, device_id): """ Append device ID to API path. diff --git a/tests/integration/test_non_user_endpoints.py b/tests/integration/test_non_user_endpoints.py index abfafc3..dc17ab3 100644 --- a/tests/integration/test_non_user_endpoints.py +++ b/tests/integration/test_non_user_endpoints.py @@ -364,3 +364,9 @@ class AuthTestSpotipy(unittest.TestCase): self.assertNotIsInstance(with_no_session._session, requests.Session) user = with_no_session.user(user="akx") self.assertEqual(user["uri"], "spotify:user:akx") + + def test_available_markets(self): + markets = self.spotify.available_markets()["markets"] + self.assertTrue(isinstance(markets, list)) + self.assertIn("US", markets) + self.assertIn("GB", markets) diff --git a/tests/integration/test_user_endpoints.py b/tests/integration/test_user_endpoints.py index a6c8921..206b419 100644 --- a/tests/integration/test_user_endpoints.py +++ b/tests/integration/test_user_endpoints.py @@ -209,6 +209,10 @@ class SpotipyLibraryApiTests(unittest.TestCase): "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf"] cls.album_ids = ["spotify:album:6kL09DaURb7rAoqqaA51KU", "spotify:album:6RTzC0rDbvagTSJLlY7AKl"] + cls.episode_ids = [ + "spotify:episode:3OEdPEYB69pfXoBrhvQYeC", + "spotify:episode:5LEFdZ9pYh99wSz7Go2D0g" + ] cls.username = os.getenv(CCEV['client_username']) scope = ( @@ -267,6 +271,21 @@ class SpotipyLibraryApiTests(unittest.TestCase): resp = self.spotify.current_user_saved_albums_contains(self.album_ids) self.assertEqual(resp, [False, False]) + def test_current_user_saved_episodes(self): + # Add + self.spotify.current_user_saved_episodes_add(self.episode_ids) + episodes = self.spotify.current_user_saved_episodes(market="US") + self.assertGreaterEqual(len(episodes['items']), 2) + + # Contains + resp = self.spotify.current_user_saved_episodes_contains(self.episode_ids) + self.assertEqual(resp, [True, True]) + + # Remove + self.spotify.current_user_saved_episodes_delete(self.episode_ids) + resp = self.spotify.current_user_saved_episodes_contains(self.episode_ids) + self.assertEqual(resp, [False, False]) + class SpotipyUserApiTests(unittest.TestCase): @classmethod