diff --git a/CHANGELOG.md b/CHANGELOG.md index 26f9ed5c..5e16ab30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Pin Github Actions Runner to Ubuntu 20 for Py27 - Fixed potential error where `found` variable in `test_artist_related_artists` is undefined if for loop never evaluates to true - Fixed false positive test `test_new_releases` which looks up the wrong property of the JSON response object and always evaluates to true +- Fixed playlist_add_items() to accept only URIs and URLs and not IDs, since 'track' and 'episode' cannot be inferred from ID only ## [2.21.0] - 2022-09-26 diff --git a/examples/add_tracks_to_playlist.py b/examples/add_tracks_to_playlist.py index 28e6cf49..eaaa6637 100644 --- a/examples/add_tracks_to_playlist.py +++ b/examples/add_tracks_to_playlist.py @@ -11,7 +11,7 @@ def get_args(): parser = argparse.ArgumentParser(description='Adds track to user playlist') - parser.add_argument('-t', '--tids', action='append', + parser.add_argument('-u', '--uris', action='append', required=True, help='Track ids') parser.add_argument('-p', '--playlist', required=True, help='Playlist to add track to') @@ -22,7 +22,7 @@ def main(): args = get_args() sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope)) - sp.playlist_add_items(args.playlist, args.tids) + sp.playlist_add_items(args.playlist, args.uris) if __name__ == '__main__': diff --git a/spotipy/client.py b/spotipy/client.py index a0222328..65432954 100644 --- a/spotipy/client.py +++ b/spotipy/client.py @@ -846,8 +846,27 @@ def user_playlist_add_tracks( - tracks - a list of track URIs, URLs or IDs - position - the position to add the tracks """ + tracks = [self._get_uri("track", tid) for tid in tracks] return self.playlist_add_items(playlist_id, tracks, position) + def user_playlist_add_episodes( + self, user, playlist_id, episodes, position=None + ): + warnings.warn( + "You should use `playlist_add_items(playlist_id, episodes)` instead", + DeprecationWarning, + ) + """ Adds episodes to a playlist + + Parameters: + - user - the id of the user + - playlist_id - the id of the playlist + - episodes - a list of track URIs, URLs or IDs + - position - the position to add the episodes + """ + episodes = [self._get_uri("episode", tid) for tid in episodes] + return self.playlist_add_items(playlist_id, episodes, position) + def user_playlist_replace_tracks(self, user, playlist_id, tracks): """ Replace all tracks in a playlist for a user @@ -1032,14 +1051,17 @@ def playlist_add_items( Parameters: - playlist_id - the id of the playlist - - items - a list of track/episode URIs, URLs or IDs + - items - a list of track/episode URIs or URLs - position - the position to add the tracks """ + for item in items: + if not self._is_uri(item) and not self._is_url(item): + raise RuntimeError("playlist_add_items() only accepts URIs and URLs.") plid = self._get_id("playlist", playlist_id) - ftracks = [self._get_uri("track", tid) for tid in items] + items = [self._url_to_uri(item) if self._is_url(item) else item for item in items] return self._post( "playlists/%s/tracks" % (plid), - payload=ftracks, + payload=items, position=position, ) @@ -1945,6 +1967,13 @@ def _get_uri(self, type, id): def _is_uri(self, uri): return uri.startswith("spotify:") and len(uri.split(':')) == 3 + def _is_url(self, url): + return url.startswith("http") + + def _url_to_uri(self, url): + splitted = url.split("/") + return "spotify:" + splitted[-2] + ":" + splitted[-1] + def _search_multiple_markets(self, q, limit, offset, type, markets, total): if total and limit > total: limit = total diff --git a/tests/integration/user_endpoints/test.py b/tests/integration/user_endpoints/test.py index d2568499..ec035771 100644 --- a/tests/integration/user_endpoints/test.py +++ b/tests/integration/user_endpoints/test.py @@ -35,6 +35,14 @@ def setUpClass(cls): "spotify:episode:7cRcsGYYRUFo1OF3RgRzdx", ] + cls.tracks_and_episodes = [ + "spotify:track:3F5CgOj3wFlRv51JsHbxhe", + "http://open.spotify.com/track/5mCPDVBb16L4XQwDdbRUpz", + + "spotify:episode:7AY0yaj2k0W3obOSCfm6m4", + "https://open.spotify.com/episode/5AJB2BTp7RExSGpbQlIsXI" + ] + scope = ( 'playlist-modify-public ' 'user-library-read ' @@ -101,7 +109,7 @@ def test_current_user_follow_playlist(self): def test_playlist_replace_items(self): # add tracks to playlist self.spotify.playlist_add_items( - self.new_playlist['id'], self.four_tracks) + self.new_playlist['id'], self.tracks_and_episodes) playlist = self.spotify.playlist(self.new_playlist['id']) self.assertEqual(playlist['tracks']['total'], 4) self.assertEqual(len(playlist['tracks']['items']), 4)