Skip to content

Commit

Permalink
Bring back removing playlist item occurrences API
Browse files Browse the repository at this point in the history
  • Loading branch information
Ch00k committed Apr 6, 2024
1 parent 40ba9eb commit 78da661
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 6 deletions.
4 changes: 4 additions & 0 deletions docs/src/reference/client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,8 @@ Playlist API
Spotify.playlist_add
Spotify.playlist_clear
Spotify.playlist_remove
Spotify.playlist_remove_indices
Spotify.playlist_remove_occurrences
Spotify.playlist_reorder
Spotify.playlist_replace

Expand All @@ -386,6 +388,8 @@ for additional information.
.. automethod:: Spotify.playlist_add
.. automethod:: Spotify.playlist_clear
.. automethod:: Spotify.playlist_remove
.. automethod:: Spotify.playlist_remove_indices
.. automethod:: Spotify.playlist_remove_occurrences
.. automethod:: Spotify.playlist_reorder
.. automethod:: Spotify.playlist_replace

Expand Down
10 changes: 9 additions & 1 deletion docs/src/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@

Release notes
=============
Unreleased
------------------
Added
*****
- re-add :class:`SpotifyPlaylistItems` methods ``playlist_remove_indices`` and
``playlist_remove_occurrences``, removed in :issue:`315`, marking them as
undocumented (:issue:`321`)

5.4.0 (2024-02-27)
------------------
Fixed
Expand Down Expand Up @@ -43,7 +51,7 @@ Fixed

Added
*****
- Add ``restrictions`` to :class:`FullEpisode <model.FullEpisode>`
- Add ``restrictions`` to :class:`FullEpisode <model.FullEpisode>`
(:issue:`310`)
- Support HTTPX ``0.26`` (:issue:`311`)
- Improve ``UnknownModelAttributeWarning`` to include model name (:issue:`313`)
Expand Down
68 changes: 68 additions & 0 deletions src/tekore/_client/api/playlist/items.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List, Optional, Tuple

from tekore._auth import scope

from ...base import SpotifyBase
Expand Down Expand Up @@ -139,3 +141,69 @@ def playlist_remove(
return self._generic_playlist_remove(
playlist_id, {"tracks": items}, snapshot_id
)

@scopes([scope.playlist_modify_public], [scope.playlist_modify_private])
@send_and_process(top_item("snapshot_id"))
def playlist_remove_occurrences(
self,
playlist_id: str,
refs: List[Tuple[str, int]],
snapshot_id: Optional[str] = None,
) -> str:
"""
Remove items by URI and position.
.. warning::
This feature is undocumented and may stop working at any time.
Parameters
----------
playlist_id
playlist ID
refs
a list of tuples containing the URI and index of items to remove
snapshot_id
snapshot ID for the playlist
Returns
-------
str
snapshot ID for the playlist
"""
gathered = {}
for uri, ix in refs:
gathered.setdefault(uri, []).append(ix)

items = [
{"uri": uri, "positions": ix_list} for uri, ix_list in gathered.items()
]
return self._generic_playlist_remove(
playlist_id, {"tracks": items}, snapshot_id
)

@scopes([scope.playlist_modify_public], [scope.playlist_modify_private])
@send_and_process(top_item("snapshot_id"))
def playlist_remove_indices(
self, playlist_id: str, indices: list, snapshot_id: str
) -> str:
"""
Remove items by position.
.. warning::
This feature is undocumented and may stop working at any time.
Parameters
----------
playlist_id
playlist ID
indices
a list of indices of tracks to remove
snapshot_id
snapshot ID for the playlist
Returns
-------
str
snapshot ID for the playlist
"""
return self._generic_playlist_remove(
playlist_id, {"positions": indices}, snapshot_id
)
21 changes: 16 additions & 5 deletions tests/client/playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,24 @@ def test_playlist_modifications(self, user_client, current_user_id):
items = user_client.playlist_items(playlist.id)
assert items.total == 0

# Add tracks back with duplicates
# Add tracks back with duplicates and test removing occurrences
new_tracks = track_uris + track_uris[::-1]
user_client.playlist_replace(playlist.id, new_tracks)
user_client.playlist_remove(playlist.id, track_uris)
# All items removed
items = user_client.playlist_items(playlist.id)
assert items.total == 0
user_client.playlist_remove_occurrences(
playlist.id, [(uri, ix) for ix, uri in enumerate(track_uris)]
)
# Occurrences removed
assert_items_equal(user_client, playlist.id, track_uris[::-1])

# Add tracks back with duplicates and test removing indices
new_tracks = track_uris + track_uris[::-1]
user_client.playlist_replace(playlist.id, new_tracks)
playlist = user_client.playlist(playlist.id)
user_client.playlist_remove_indices(
playlist.id, list(range(len(track_uris))), playlist.snapshot_id
)
# Indices removed
assert_items_equal(user_client, playlist.id, track_uris[::-1])

# Tracks cleared
user_client.playlist_clear(playlist.id)
Expand Down

0 comments on commit 78da661

Please sign in to comment.