Skip to content

Commit eb04e58

Browse files
authored
Add method to check if a single URI is added to the library (#543)
1 parent 77fb65f commit eb04e58

2 files changed

Lines changed: 119 additions & 0 deletions

File tree

src/spotifyaio/spotify.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ async def are_albums_saved(self, album_ids: list[str]) -> dict[str, bool]:
253253
body: list[bool] = orjson.loads(response) # pylint: disable=no-member
254254
return dict(zip(identifiers, body))
255255

256+
async def is_album_saved(self, album_id: str) -> bool:
257+
"""Check if album is saved."""
258+
identifier = get_identifier(album_id)
259+
return (await self.are_albums_saved([identifier]))[identifier]
260+
256261
async def get_new_releases(self) -> list[SimplifiedAlbum]:
257262
"""Get new releases."""
258263
params: dict[str, Any] = {"limit": 48}
@@ -450,6 +455,24 @@ async def are_episodes_saved(self, episode_ids: list[str]) -> dict[str, bool]:
450455
body: list[bool] = orjson.loads(response) # pylint: disable=no-member
451456
return dict(zip(identifiers, body))
452457

458+
async def is_episode_saved(self, episode_id: str) -> bool:
459+
"""Check if episode is saved."""
460+
identifier = get_identifier(episode_id)
461+
return (await self.are_episodes_saved([identifier]))[identifier]
462+
463+
async def is_added_to_library(self, uri: str) -> bool:
464+
"""Check if item is added to library."""
465+
if uri.startswith("spotify:track:"):
466+
return await self.is_track_saved(uri)
467+
if uri.startswith("spotify:episode:"):
468+
return await self.is_episode_saved(uri)
469+
if uri.startswith("spotify:show:"):
470+
return await self.is_show_saved(uri)
471+
if uri.startswith("spotify:album:"):
472+
return await self.is_album_saved(uri)
473+
msg = "Invalid URI format"
474+
raise ValueError(msg)
475+
453476
async def get_playback(self) -> PlaybackState | None:
454477
"""Get playback state."""
455478
response = await self._get(
@@ -784,6 +807,11 @@ async def are_shows_saved(self, show_ids: list[str]) -> dict[str, bool]:
784807
body: list[bool] = orjson.loads(response) # pylint: disable=no-member
785808
return dict(zip(identifiers, body))
786809

810+
async def is_show_saved(self, show_id: str) -> bool:
811+
"""Check if show is saved."""
812+
identifier = get_identifier(show_id)
813+
return (await self.are_shows_saved([identifier]))[identifier]
814+
787815
# Get a track
788816

789817
# Get several tracks
@@ -831,6 +859,11 @@ async def are_tracks_saved(self, track_ids: list[str]) -> dict[str, bool]:
831859
body: list[bool] = orjson.loads(response) # pylint: disable=no-member
832860
return dict(zip(identifiers, body))
833861

862+
async def is_track_saved(self, track_id: str) -> bool:
863+
"""Check if track is saved."""
864+
identifier = get_identifier(track_id)
865+
return (await self.are_tracks_saved([identifier]))[identifier]
866+
834867
async def get_audio_features(self, track_id: str) -> AudioFeatures:
835868
"""Get audio features."""
836869
identifier = get_identifier(track_id)

tests/test_spotify.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,26 @@ async def test_check_saved_episodes(
18731873
)
18741874

18751875

1876+
async def test_check_saved_episode(
1877+
responses: aioresponses,
1878+
authenticated_client: SpotifyClient,
1879+
) -> None:
1880+
"""Test checking saved episode."""
1881+
responses.get(
1882+
f"{SPOTIFY_URL}/v1/me/episodes/contains?ids=18yVqkdbdRvS24c0Ilj2ci",
1883+
status=200,
1884+
body=load_fixture("tracks_saved.json"),
1885+
)
1886+
assert await authenticated_client.is_episode_saved("18yVqkdbdRvS24c0Ilj2ci") is True
1887+
responses.assert_called_once_with(
1888+
f"{SPOTIFY_URL}/v1/me/episodes/contains",
1889+
METH_GET,
1890+
headers=HEADERS,
1891+
params={"ids": "18yVqkdbdRvS24c0Ilj2ci"},
1892+
json=None,
1893+
)
1894+
1895+
18761896
async def test_check_no_saved_episodes(
18771897
responses: aioresponses,
18781898
authenticated_client: SpotifyClient,
@@ -2470,6 +2490,72 @@ async def test_check_saved_tracks(
24702490
)
24712491

24722492

2493+
async def test_check_saved_track(
2494+
responses: aioresponses,
2495+
authenticated_client: SpotifyClient,
2496+
) -> None:
2497+
"""Test checking saved track."""
2498+
responses.get(
2499+
f"{SPOTIFY_URL}/v1/me/tracks/contains?ids=18yVqkdbdRvS24c0Ilj2ci",
2500+
status=200,
2501+
body=load_fixture("tracks_saved.json"),
2502+
)
2503+
assert await authenticated_client.is_track_saved("18yVqkdbdRvS24c0Ilj2ci") is True
2504+
responses.assert_called_once_with(
2505+
f"{SPOTIFY_URL}/v1/me/tracks/contains",
2506+
METH_GET,
2507+
headers=HEADERS,
2508+
params={"ids": "18yVqkdbdRvS24c0Ilj2ci"},
2509+
json=None,
2510+
)
2511+
2512+
2513+
@pytest.mark.parametrize(
2514+
("prefix", "url_part"),
2515+
[
2516+
("spotify:track:", "tracks"),
2517+
("spotify:episode:", "episodes"),
2518+
("spotify:show:", "shows"),
2519+
("spotify:album:", "albums"),
2520+
],
2521+
)
2522+
async def test_check_saved_item(
2523+
responses: aioresponses,
2524+
authenticated_client: SpotifyClient,
2525+
prefix: str,
2526+
url_part: str,
2527+
) -> None:
2528+
"""Test checking saved track."""
2529+
responses.get(
2530+
f"{SPOTIFY_URL}/v1/me/{url_part}/contains?ids=18yVqkdbdRvS24c0Ilj2ci",
2531+
status=200,
2532+
body=load_fixture("tracks_saved.json"),
2533+
)
2534+
assert (
2535+
await authenticated_client.is_added_to_library(
2536+
f"{prefix}18yVqkdbdRvS24c0Ilj2ci"
2537+
)
2538+
is True
2539+
)
2540+
responses.assert_called_once_with(
2541+
f"{SPOTIFY_URL}/v1/me/{url_part}/contains",
2542+
METH_GET,
2543+
headers=HEADERS,
2544+
params={"ids": "18yVqkdbdRvS24c0Ilj2ci"},
2545+
json=None,
2546+
)
2547+
2548+
2549+
async def test_checking_invalid_uri(
2550+
authenticated_client: SpotifyClient,
2551+
) -> None:
2552+
"""Test checking saved track."""
2553+
with pytest.raises(ValueError, match="Invalid URI format"):
2554+
await authenticated_client.is_added_to_library(
2555+
"spotify:new:18yVqkdbdRvS24c0Ilj2ci"
2556+
)
2557+
2558+
24732559
async def test_check_no_saved_tracks(
24742560
responses: aioresponses,
24752561
authenticated_client: SpotifyClient,

0 commit comments

Comments
 (0)