Skip to content

Commit

Permalink
new: spotify liked tracks, local artists
Browse files Browse the repository at this point in the history
  • Loading branch information
dxstiny committed Jan 31, 2024
1 parent 6b102a1 commit 981c4a1
Show file tree
Hide file tree
Showing 145 changed files with 378 additions and 193 deletions.
30 changes: 28 additions & 2 deletions src/server/handler/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ async def putArtist(
return web.Response()
return web.HTTPBadRequest(text="invalid spotify id")

async def getArtists(self, _: web.Request) -> web.Response:
"""get(/api/artists)"""
artists = await self._dbManager.artists.all()
return web.json_response(data = [ artist.toDict() for artist in artists ])

@withObjectPayload(Object({"name": String().min(1)}), inPath=True)
async def getArtist(
self, payload: Dict[str, Any]
Expand Down Expand Up @@ -178,7 +183,7 @@ def _implement() -> SpotifyResult[List[SpotifyPlaylist]]:

@withObjectPayload(Object({"id": String().min(22).max(22)}), inPath=True)
async def spotifyPlaylist(self, payload: Dict[str, Any]) -> web.Response:
"""post(/api/spotify/playlists/{id})"""
"""get(/api/spotify/playlists/{id})"""
id_: str = payload["id"]

def _implement() -> SpotifyResult[List[Dict[str, Any]]]:
Expand All @@ -188,7 +193,7 @@ def _implement() -> SpotifyResult[List[Dict[str, Any]]]:

tracks = result.unwrap()
metadatas = [Metadata(self._spotify, track.url) for track in tracks]
# TODO add metadata in UI for playlists, albums

return result.transform([(metadata.toDict()) for metadata in metadatas])

data = await asyncRunInThreadWithReturn(_implement)
Expand Down Expand Up @@ -222,6 +227,27 @@ def _implement() -> SpotifyResult[List[Dict[str, Any]]]:

return web.json_response(data=data.unwrap())

@useCache(900) # type: ignore
async def spotifyLiked(self, _: web.Request) -> web.Response:
"""get(/api/spotify/tracks)"""

def _implement() -> SpotifyResult[List[Dict[str, Any]]]:
result = self._spotify.likedTracks()
if not result:
return result.transform([])

tracks = result.unwrap()
metadatas = [Metadata(self._spotify, track.url) for track in tracks]

return result.transform([(metadata.toDict()) for metadata in metadatas])

data = await asyncRunInThreadWithReturn(_implement)

if not data:
return data.httpResponse()

return web.json_response(data=data.unwrap())

@withObjectPayload(Object({"id": String().min(22).max(22)}), inPath=True)
async def spotifyArtist(self, payload: Dict[str, Any]) -> web.Response:
"""post(/api/spotify/artists/{id})"""
Expand Down
12 changes: 11 additions & 1 deletion src/server/meta/spotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def wrapper(self: Spotify, *args: Any, **kwargs: Any) -> Any:

return SpotifyResult.errorResult(SpotifyState.InternalError)
except Exception as exc: # pylint: disable=broad-except
logger.error("Exception: %s", exc)
logger.exception("Exception: %s", exc)
# if KeyError 'expires_at'
if isinstance(exc, KeyError):
self.auth.addExpiresAt()
Expand Down Expand Up @@ -491,3 +491,13 @@ def audioFeatures(self, trackId: str) -> SpotifyResult[SpotifyAudioFeatures]:
if not features:
return SpotifyResult.errorResult(SpotifyState.NotFound)
return SpotifyResult.successResult(SpotifyAudioFeatures(JDict(features[0])))

@_connectionRequired
@_mayFail
def likedTracks(self) -> SpotifyResult[List[SpotifyTrack]]:
"""returns a user's saved tracks"""
self._logger.debug("Getting user's saved tracks")
assert self._spotify is not None
tracks = self._spotify.current_user_saved_tracks()
tracks = JDict(tracks).ensureCast("items", JList).iterator().ensure(dict)
return SpotifyResult.successResult([SpotifyTrack(track["track"]) for track in tracks])
2 changes: 2 additions & 0 deletions src/server/router/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def applyRoutes( # pylint: disable=too-many-statements, too-many-arguments
app.router.add_post("/api/sports", sportsHandler.getMatches)

# /api/spotify/
app.router.add_get("/api/spotify/tracks", metaHandler.spotifyLiked)
app.router.add_get("/api/spotify/albums/{id}", metaHandler.spotifyAlbum)
app.router.add_get("/api/spotify/artists/{id}", metaHandler.spotifyArtist)
app.router.add_get("/api/spotify/artists", metaHandler.spotifyArtists)
Expand Down Expand Up @@ -128,6 +129,7 @@ def applyRoutes( # pylint: disable=too-many-statements, too-many-arguments
app.router.add_get("/api/tracks/{id}/download", downloadHandler.downloadTrack)

# /api/artists
app.router.add_get("/api/artists", metaHandler.getArtists)
app.router.add_get("/api/artists/{name}", metaHandler.getArtist)
app.router.add_put("/api/artists/{name}", metaHandler.putArtist)

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file removed src/ui/dist/assets/Artist-4312b911.js.gz
Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added src/ui/dist/assets/Artist-784f729e.js.gz
Binary file not shown.
1 change: 1 addition & 0 deletions src/ui/dist/assets/Artists-3dd104fe.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added src/ui/dist/assets/Artists-3dd104fe.js.gz
Binary file not shown.
Loading

0 comments on commit 981c4a1

Please sign in to comment.