diff --git a/src/spotify_webapi.c b/src/spotify_webapi.c index 2be2cfe1..56b7c2b3 100644 --- a/src/spotify_webapi.c +++ b/src/spotify_webapi.c @@ -120,14 +120,15 @@ static const char *spotify_client_id = "0e684a5422384114a8ae7ac020f01789"; static const char *spotify_client_secret = "232af95f39014c9ba218285a5c11a239"; static const char *spotify_auth_uri = "https://accounts.spotify.com/authorize"; static const char *spotify_token_uri = "https://accounts.spotify.com/api/token"; -static const char *spotify_playlist_uri = "https://api.spotify.com/v1/users/%s/playlists/%s"; +static const char *spotify_playlist_uri = "https://api.spotify.com/v1/playlists/%s"; static const char *spotify_track_uri = "https://api.spotify.com/v1/tracks/%s"; static const char *spotify_me_uri = "https://api.spotify.com/v1/me"; static const char *spotify_albums_uri = "https://api.spotify.com/v1/me/albums?limit=50"; static const char *spotify_album_uri = "https://api.spotify.com/v1/albums/%s"; static const char *spotify_album_tracks_uri = "https://api.spotify.com/v1/albums/%s/tracks"; static const char *spotify_playlists_uri = "https://api.spotify.com/v1/me/playlists?limit=50"; -static const char *spotify_playlist_tracks_uri = "https://api.spotify.com/v1/users/%s/playlists/%s/tracks"; +static const char *spotify_playlist_tracks_uri = "https://api.spotify.com/v1/playlists/%s/tracks"; +static const char *spotify_artist_albums_uri = "https://api.spotify.com/v1/artists/%s/albums?include_groups=album,single"; @@ -736,51 +737,6 @@ parse_metadata_playlist(json_object *jsonplaylist, struct spotify_playlist *play } } -/* - * Extracts the owner and the id from a spotify playlist uri - * - * Playlist-uri has the following format: spotify:user:[owner]:playlist:[id] - * Owner and plid must be freed by the caller. - */ -static int -get_owner_plid_from_uri(const char *uri, char **owner, char **plid) -{ - char *ptr1; - char *ptr2; - char *tmp; - size_t len; - - ptr1 = strchr(uri, ':'); - if (!ptr1) - return -1; - ptr1++; - ptr1 = strchr(ptr1, ':'); - if (!ptr1) - return -1; - ptr1++; - ptr2 = strchr(ptr1, ':'); - - len = ptr2 - ptr1; - - tmp = malloc(sizeof(char) * (len + 1)); - strncpy(tmp, ptr1, len); - tmp[len] = '\0'; - *owner = tmp; - - ptr2++; - ptr1 = strchr(ptr2, ':'); - if (!ptr1) - { - free(tmp); - *owner = NULL; - return -1; - } - ptr1++; - *plid = strdup(ptr1); - - return 0; -} - /* * Creates a new string for the playlist API endpoint for the given playist-uri. * The returned string needs to be freed by the caller. @@ -808,21 +764,19 @@ static char * get_playlist_endpoint_uri(const char *uri) { char *endpoint_uri = NULL; - char *owner = NULL; char *id = NULL; int ret; - ret = get_owner_plid_from_uri(uri, &owner, &id); + ret = get_id_from_uri(uri, &id); if (ret < 0) { DPRINTF(E_LOG, L_SPOTIFY, "Error extracting owner and id from playlist uri '%s'\n", uri); goto out; } - endpoint_uri = safe_asprintf(spotify_playlist_uri, owner, id); + endpoint_uri = safe_asprintf(spotify_playlist_uri, id); out: - free(owner); free(id); return endpoint_uri; } @@ -831,21 +785,19 @@ static char * get_playlist_tracks_endpoint_uri(const char *uri) { char *endpoint_uri = NULL; - char *owner = NULL; char *id = NULL; int ret; - ret = get_owner_plid_from_uri(uri, &owner, &id); + ret = get_id_from_uri(uri, &id); if (ret < 0) { DPRINTF(E_LOG, L_SPOTIFY, "Error extracting owner and id from playlist uri '%s'\n", uri); goto out; } - endpoint_uri = safe_asprintf(spotify_playlist_tracks_uri, owner, id); + endpoint_uri = safe_asprintf(spotify_playlist_tracks_uri, id); out: - free(owner); free(id); return endpoint_uri; } @@ -913,6 +865,27 @@ get_track_endpoint_uri(const char *uri) return endpoint_uri; } +static char * +get_artist_albums_endpoint_uri(const char *uri) +{ + char *endpoint_uri = NULL; + char *id = NULL; + int ret; + + ret = get_id_from_uri(uri, &id); + if (ret < 0) + { + DPRINTF(E_LOG, L_SPOTIFY, "Error extracting id from uri '%s'\n", uri); + goto out; + } + + endpoint_uri = safe_asprintf(spotify_artist_albums_uri, id); + + out: + free(id); + return endpoint_uri; +} + static json_object * request_track(const char *path) { @@ -1154,6 +1127,51 @@ queue_add_album(const char *uri, int position, char reshuffle, uint32_t item_id, return ret; } +static int +queue_add_albums(json_object *item, int index, int total, void *arg) +{ + struct db_queue_add_info *param; + struct queue_add_album_param param_add_album; + char *endpoint_uri = NULL; + int ret; + + param = arg; + param_add_album.queue_add_info = *param; + + parse_metadata_album(item, ¶m_add_album.album, ART_DEFAULT_WIDTH); + + endpoint_uri = get_album_tracks_endpoint_uri(param_add_album.album.uri); + ret = request_pagingobject_endpoint(endpoint_uri, queue_add_album_tracks, NULL, NULL, true, ¶m_add_album); + + *param = param_add_album.queue_add_info; + + free(endpoint_uri); + return ret; + +} + +static int +queue_add_artist(const char *uri, int position, char reshuffle, uint32_t item_id, int *count, int *new_item_id) +{ + struct db_queue_add_info queue_add_info; + char *endpoint_uri = NULL; + int ret; + + ret = db_queue_add_start(&queue_add_info, position); + if (ret < 0) + return -1; + + endpoint_uri = get_artist_albums_endpoint_uri(uri); + ret = request_pagingobject_endpoint(endpoint_uri, queue_add_albums, NULL, NULL, true, &queue_add_info); + + ret = db_queue_add_end(&queue_add_info, reshuffle, item_id, ret); + if (ret == 0 && count) + *count = queue_add_info.count; + + free(endpoint_uri); + return ret; +} + static int queue_add_playlist_tracks(json_object *item, int index, int total, void *arg) { @@ -1222,6 +1240,11 @@ queue_add(const char *uri, int position, char reshuffle, uint32_t item_id, int * queue_add_track(uri, position, reshuffle, item_id, count, new_item_id); return LIBRARY_OK; } + else if (strncasecmp(uri, "spotify:artist:", strlen("spotify:artist:")) == 0) + { + queue_add_artist(uri, position, reshuffle, item_id, count, new_item_id); + return LIBRARY_OK; + } else if (strncasecmp(uri, "spotify:album:", strlen("spotify:album:")) == 0) { queue_add_album(uri, position, reshuffle, item_id, count, new_item_id);