11package xyz .gianlu .librespot .api ;
22
33import com .google .gson .JsonElement ;
4+ import com .google .gson .JsonObject ;
45import com .google .protobuf .AbstractMessageLite ;
56import org .jetbrains .annotations .NotNull ;
7+ import org .jetbrains .annotations .Nullable ;
68import xyz .gianlu .librespot .api .server .AbsApiHandler ;
79import xyz .gianlu .librespot .api .server .ApiServer ;
810import xyz .gianlu .librespot .core .Session ;
911import xyz .gianlu .librespot .mercury .MercuryClient ;
1012import xyz .gianlu .librespot .mercury .MercuryRequests ;
1113import xyz .gianlu .librespot .mercury .ProtoJsonMercuryRequest ;
12- import xyz .gianlu .librespot .mercury .model .PlaylistId ;
13- import xyz .gianlu .librespot .mercury .model .TrackId ;
14+ import xyz .gianlu .librespot .mercury .model .*;
1415
1516import java .io .IOException ;
1617
@@ -27,15 +28,40 @@ public MetadataHandler(@NotNull Session session) {
2728 this .client = session .mercury ();
2829 }
2930
31+ @ NotNull
32+ private static <I extends SpotifyId > I extractId (@ NotNull Class <I > clazz , @ NotNull ApiServer .Request request , @ Nullable JsonElement params ) throws ApiServer .PredefinedJsonRpcException {
33+ if (params == null || !params .isJsonObject ())
34+ throw ApiServer .PredefinedJsonRpcException .from (request , ApiServer .PredefinedJsonRpcError .INVALID_PARAMS );
35+
36+ try {
37+ JsonObject obj = params .getAsJsonObject ();
38+ if (obj .has ("gid" )) {
39+ return SpotifyId .fromHex (clazz , obj .get ("gid" ).getAsString ());
40+ } else if (obj .has ("uri" )) {
41+ return SpotifyId .fromUri (clazz , obj .get ("uri" ).getAsString ());
42+ } else if (obj .has ("base62" )) {
43+ return SpotifyId .fromBase62 (clazz , obj .get ("gid" ).getAsString ());
44+ } else {
45+ throw ApiServer .PredefinedJsonRpcException .from (request , ApiServer .PredefinedJsonRpcError .INVALID_REQUEST );
46+ }
47+ } catch (SpotifyId .SpotifyIdParsingException ex ) {
48+ throw ApiServer .PredefinedJsonRpcException .from (request , ApiServer .PredefinedJsonRpcError .INVALID_REQUEST );
49+ }
50+ }
51+
3052 @ Override
3153 protected @ NotNull JsonElement handleRequest (ApiServer .@ NotNull Request request ) throws ApiServer .PredefinedJsonRpcException , HandlingException {
3254 switch (request .getSuffix ()) {
3355 case "rootlists" :
3456 return handle (MercuryRequests .getRootPlaylists (session .apWelcome ().getCanonicalUsername ()));
3557 case "playlist" :
36- return handle (MercuryRequests .getPlaylist (PlaylistId .fromUri ( request .params . getAsString () )));
58+ return handle (MercuryRequests .getPlaylist (extractId ( PlaylistId .class , request , request .params )));
3759 case "track" :
38- return handle (MercuryRequests .getTrack (TrackId .fromUri (request .params .getAsString ())));
60+ return handle (MercuryRequests .getTrack (extractId (TrackId .class , request , request .params )));
61+ case "artist" :
62+ return handle (MercuryRequests .getArtist (extractId (ArtistId .class , request , request .params )));
63+ case "album" :
64+ return handle (MercuryRequests .getAlbum (extractId (AlbumId .class , request , request .params )));
3965 default :
4066 throw ApiServer .PredefinedJsonRpcException .from (request , ApiServer .PredefinedJsonRpcError .METHOD_NOT_FOUND );
4167 }
@@ -45,13 +71,14 @@ public MetadataHandler(@NotNull Session session) {
4571 private <P extends AbstractMessageLite > JsonElement handle (@ NotNull ProtoJsonMercuryRequest <P > req ) throws HandlingException {
4672 try {
4773 return client .sendSync (req ).json ();
48- } catch (IOException | MercuryClient .MercuryException ex ) {
49- throw new HandlingException (ex , 100 ); // FIXME: Create error codes table
74+ } catch (MercuryClient .MercuryException ex ) {
75+ throw new HandlingException (ex , ErrorCode .MERCURY_EXCEPTION );
76+ } catch (IOException ex ) {
77+ throw new HandlingException (ex , ErrorCode .IO_EXCEPTION );
5078 }
5179 }
5280
5381 @ Override
5482 protected void handleNotification (ApiServer .@ NotNull Request request ) {
55-
5683 }
5784}
0 commit comments