Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding getPlaylist feature (based on searchForSong) #75

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions src/SpotifyArduino.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,89 @@ int SpotifyArduino::searchForSong(String query, int limit, processSearch searchC
return statusCode;
}

int SpotifyArduino::getPlaylist(String query, int limit, String market, processPlaylist playlistCallback, PlaylistResult results[])
{

#ifdef SPOTIFY_DEBUG
Serial.println(SPOTIFY_PLAYLIST_ENDPOINT);
printStack();
#endif

// Get from https://arduinojson.org/v6/assistant/
const size_t bufferSize = playlistDetailsBufferSize;
if (autoTokenRefresh)
{
checkAndRefreshAccessToken();
}

int statusCode = makeGetRequest((SPOTIFY_PLAYLIST_ENDPOINT + query + "?market=" + market + "&fields=tracks.items%28track%28name%2Curi%2Calbum%28name%2Curi%29%2Cartists%28name%2Curi%29%29").c_str(), _bearerToken);
#ifdef SPOTIFY_DEBUG
Serial.print("Status Code: ");
Serial.println(statusCode);
#endif
if (statusCode > 0)
{
skipHeaders();
}

if (statusCode == 200)
{

// Allocate DynamicJsonDocument
DynamicJsonDocument doc(bufferSize);

// Parse JSON object
#ifndef SPOTIFY_PRINT_JSON_PARSE
DeserializationError error = deserializeJson(doc, *client);
#else
ReadLoggingStream loggingStream(*client, Serial);
DeserializationError error = deserializeJson(doc, loggingStream);
#endif
//serializeJsonPretty(doc, Serial);
if (!error)
{

uint8_t totalResults = doc["tracks"]["items"].size();

Serial.print("Total Results: ");
Serial.println(totalResults);

PlaylistResult playlistResult;
for (int i = 0; i < totalResults; i++)
{
//Polling track information
JsonObject result = doc["tracks"]["items"][i]["track"];
playlistResult.trackUri = result["uri"].as<const char *>();
playlistResult.trackName = result["name"].as<const char *>();
playlistResult.albumUri = result["album"]["uri"].as<const char *>();
playlistResult.albumName = result["album"]["name"].as<const char *>();

playlistResult.artistName = result["artists"][0]["name"];
playlistResult.artistUri = result["artists"][0]["uri"];

results[i] = playlistResult;

if (i >= limit-1 || !playlistCallback(playlistResult, i, totalResults))
{
//Break at the limit or when indicated
break;
}
}
}
else
{
#ifdef SPOTIFY_SERIAL_OUTPUT
Serial.print(F("deserializeJson() failed with code "));
Serial.println(error.c_str());
#endif
statusCode = -1;
}
}

closeClient();
return statusCode;
}

int SpotifyArduino::commonGetImage(char *imageUrl)
{
#ifdef SPOTIFY_DEBUG
Expand Down
20 changes: 19 additions & 1 deletion src/SpotifyArduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#define SPOTIFY_SEEK_ENDPOINT "/v1/me/player/seek"

#define SPOTIFY_PLAYLIST_ENDPOINT "/v1/playlists/"

#define SPOTIFY_TOKEN_ENDPOINT "/api/token"

#define SPOTIFY_NUM_ALBUM_IMAGES 3 // Max spotify returns is 3, but the third one is probably too big for an ESP

#define SPOTIFY_MAX_NUM_ARTISTS 5
#define SPOTIFY_MAX_NUM_ARTISTS 5

#define SPOTIFY_ACCESS_TOKEN_LENGTH 309

Expand Down Expand Up @@ -146,6 +148,16 @@ struct SearchResult
int numImages;
};

struct PlaylistResult
{
const char *albumName;
const char *albumUri;
const char *trackName;
const char *trackUri;
const char *artistName;
const char *artistUri;
};

struct CurrentlyPlaying
{
SpotifyArtist artists[SPOTIFY_MAX_NUM_ARTISTS];
Expand All @@ -167,6 +179,8 @@ typedef void (*processCurrentlyPlaying)(CurrentlyPlaying currentlyPlaying);
typedef void (*processPlayerDetails)(PlayerDetails playerDetails);
typedef bool (*processDevices)(SpotifyDevice device, int index, int numDevices);
typedef bool (*processSearch)(SearchResult result, int index, int numResults);
typedef bool (*processPlaylist)(PlaylistResult result, int index, int numResults);


class SpotifyArduino
{
Expand Down Expand Up @@ -207,6 +221,9 @@ class SpotifyArduino
//Search
int searchForSong(String query, int limit, processSearch searchCallback, SearchResult results[]);

//Playlist
int getPlaylist(String query, int limit, String market, processPlaylist playlistCallback, PlaylistResult results[]);

// Image methods
bool getImage(char *imageUrl, Stream *file);
bool getImage(char *imageUrl, uint8_t **image, int *imageLength);
Expand All @@ -216,6 +233,7 @@ class SpotifyArduino
int playerDetailsBufferSize = 2000;
int getDevicesBufferSize = 3000;
int searchDetailsBufferSize = 3000;
int playlistDetailsBufferSize = 3000;
bool autoTokenRefresh = true;
Client *client;
void lateInit(const char *clientId, const char *clientSecret, const char *refreshToken = "");
Expand Down