Skip to content

Commit

Permalink
[soundcloud] improved track iteration (#922)
Browse files Browse the repository at this point in the history
  • Loading branch information
domanchi authored Nov 12, 2023
1 parent 7b08dcf commit 91ff687
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
12 changes: 6 additions & 6 deletions music_assistant/server/providers/soundcloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,7 @@ async def get_library_playlists(self) -> AsyncGenerator[Playlist, None]:
async def get_library_tracks(self) -> AsyncGenerator[Track, None]:
"""Retrieve library tracks from Soundcloud."""
time_start = time.time()
tracks = await self._soundcloud.get_tracks_liked()
self.logger.debug(
"Processing Soundcloud library tracks took %s seconds",
round(time.time() - time_start, 2),
)
for item in tracks["collection"]:
async for item in self._soundcloud.get_tracks_liked():
track = await self._soundcloud.get_track_details(item)
try:
yield await self._parse_track(track[0])
Expand All @@ -207,6 +202,11 @@ async def get_library_tracks(self) -> AsyncGenerator[Track, None]:
self.logger.debug("Parse track failed: %s", track, exc_info=error)
continue

self.logger.debug(
"Processing Soundcloud library tracks took %s seconds",
round(time.time() - time_start, 2),
)

async def get_artist(self, prov_artist_id) -> Artist:
"""Get full artist details by id."""
artist_obj = await self._soundcloud.get_user_details(user_id=prov_artist_id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""
from __future__ import annotations

from collections.abc import AsyncGenerator
from typing import TYPE_CHECKING

BASE_URL = "https://api-v2.soundcloud.com"
Expand Down Expand Up @@ -118,13 +119,42 @@ async def get_track_details(self, track_id):
headers=self.headers,
)

async def get_tracks_liked(self, limit=50):
""":param limit: number of tracks to get"""
return await self.get(
async def get_tracks_liked(self, limit: int = 0) -> AsyncGenerator[int, None]:
"""Obtain the authenticated user's liked tracks.
:param limit: number of tracks to get. if 0, will fetch all tracks.
:returns: list of track ids liked by the current user
"""
query_limit = limit
if query_limit == 0:
# NOTE(2023-11-11): At the time of writing, soundcloud does not look like it caps
# the limit. However, we still implement pagination for future proofing.
query_limit = 100

url = (
f"{BASE_URL}/me/track_likes/ids?client_id={self.client_id}&"
f"limit={limit}&app_version={self.app_version}",
headers=self.headers,
f"limit={query_limit}&app_version={self.app_version}"
)
num_items = 0
while True:
response = await self.get(url, headers=self.headers)

# Sanity check.
if "collection" not in response:
raise RuntimeError("Unexpected Soundcloud API response")

for item in response["collection"]:
num_items += 1
if limit > 0 and num_items >= limit:
return

yield item

# Handle case when results requested exceeds number of actual results.
if len(response["collection"]) < query_limit:
return

url = response["next_href"]

async def get_track_by_genre_recent(self, genre, limit=10):
"""Get track by genre recent.
Expand Down

0 comments on commit 91ff687

Please sign in to comment.