diff --git a/Spotify_v3/.gitignore b/Spotify_v3/.gitignore deleted file mode 100644 index 2dde743..0000000 --- a/Spotify_v3/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -.pio -.vscode/.browse.c_cpp.db* -.vscode/c_cpp_properties.json -.vscode/launch.json -.vscode/ipch -src/config.h -TODO.txt \ No newline at end of file diff --git a/Spotify_v3/.vscode/extensions.json b/Spotify_v3/.vscode/extensions.json deleted file mode 100644 index 080e70d..0000000 --- a/Spotify_v3/.vscode/extensions.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "platformio.platformio-ide" - ], - "unwantedRecommendations": [ - "ms-vscode.cpptools-extension-pack" - ] -} diff --git a/Spotify_v3/include/README b/Spotify_v3/include/README deleted file mode 100644 index 194dcd4..0000000 --- a/Spotify_v3/include/README +++ /dev/null @@ -1,39 +0,0 @@ - -This directory is intended for project header files. - -A header file is a file containing C declarations and macro definitions -to be shared between several project source files. You request the use of a -header file in your project source file (C, C++, etc) located in `src` folder -by including it, with the C preprocessing directive `#include'. - -```src/main.c - -#include "header.h" - -int main (void) -{ - ... -} -``` - -Including a header file produces the same results as copying the header file -into each source file that needs it. Such copying would be time-consuming -and error-prone. With a header file, the related declarations appear -in only one place. If they need to be changed, they can be changed in one -place, and programs that include the header file will automatically use the -new version when next recompiled. The header file eliminates the labor of -finding and changing all the copies as well as the risk that a failure to -find one copy will result in inconsistencies within a program. - -In C, the usual convention is to give header files names that end with `.h'. -It is most portable to use only letters, digits, dashes, and underscores in -header file names, and at most one dot. - -Read more about using header files in official GCC documentation: - -* Include Syntax -* Include Operation -* Once-Only Headers -* Computed Includes - -https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/Spotify_v3/lib/README b/Spotify_v3/lib/README deleted file mode 100644 index 6debab1..0000000 --- a/Spotify_v3/lib/README +++ /dev/null @@ -1,46 +0,0 @@ - -This directory is intended for project specific (private) libraries. -PlatformIO will compile them to static libraries and link into executable file. - -The source code of each library should be placed in a an own separate directory -("lib/your_library_name/[here are source files]"). - -For example, see a structure of the following two libraries `Foo` and `Bar`: - -|--lib -| | -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html -| | -| |--Foo -| | |- Foo.c -| | |- Foo.h -| | -| |- README --> THIS FILE -| -|- platformio.ini -|--src - |- main.c - -and a contents of `src/main.c`: -``` -#include -#include - -int main (void) -{ - ... -} - -``` - -PlatformIO Library Dependency Finder will find automatically dependent -libraries scanning project source files. - -More information about PlatformIO Library Dependency Finder -- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/Spotify_v3/partitions.csv b/Spotify_v3/partitions.csv deleted file mode 100644 index aa6a71c..0000000 --- a/Spotify_v3/partitions.csv +++ /dev/null @@ -1,8 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x180000, -app1, app, ota_1, 0x190000,0x180000, -eeprom, data, 0x99, 0x310000,0x1000, -coredump, data, coredump,0x311000,0x10000, -spiffs, data, spiffs, 0x321000,0xDF000, \ No newline at end of file diff --git a/Spotify_v3/platformio.ini b/Spotify_v3/platformio.ini deleted file mode 100644 index aa216bd..0000000 --- a/Spotify_v3/platformio.ini +++ /dev/null @@ -1,22 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[env:esp32doit-devkit-v1] -platform = espressif32 -board = esp32doit-devkit-v1 -framework = arduino -board_build.partitions = partitions.csv -lib_deps = - plageoj/UrlEncode@^1.0.1 - bblanchon/ArduinoJson@^7.0.3 - esphome/AsyncTCP-esphome@^2.1.2 -monitor_filters = esp32_exception_decoder -monitor_speed = 115200 -build_flags = -Og \ No newline at end of file diff --git a/Spotify_v3/src/SpotifyESP32.cpp b/Spotify_v3/src/SpotifyESP32.cpp deleted file mode 100644 index 4b26c37..0000000 --- a/Spotify_v3/src/SpotifyESP32.cpp +++ /dev/null @@ -1,1556 +0,0 @@ -#include "SpotifyESP32.h" -namespace Spotify_types { - bool SHUFFLE_ON = true; - bool SHUFFLE_OFF = false; - char* REPEAT_OFF = "off"; - char* REPEAT_TRACK = "track"; - char* REPEAT_CONTEXT = "context"; - char* TYPE_ALBUM = "album"; - char* TYPE_ARTIST = "artist"; - char* TYPE_TRACK = "track"; - char* TYPE_PLAYLIST = "playlist"; - char* TYPE_SHOW = "show"; - char* TYPE_EPISODE = "episode"; - char* TYPE_AUDIOBOOK = "audiobook"; - char* TOP_TYPE_ARTIST = "artists"; - char* TOP_TYPE_TRACKS = "tracks"; - char* GROUP_ALBUM = "album"; - char* GROUP_SINGLE = "single"; - char* GROUP_APPEARS_ON = "appears_on"; - char* GROUP_COMPILATION = "compilation"; - char* TIME_RANGE_SHORT = "short_term"; - char* TIME_RANGE_MEDIUM = "medium_term"; - char* TIME_RANGE_LONG = "long_term"; - char* FOLLOW_TYPE_ARTIST = "artist"; - char* FOLLOW_TYPE_USER = "user"; - int SIZE_OF_ID = 40; - int SIZE_OF_URI = 50; -} - -Spotify::Spotify(const char* client_id,const char* client_secret,int server_port, bool debug_on, int max_num_retry): _server(server_port){ - _retry = 0; - _client_id = client_id; - _client_secret = client_secret; - _port = server_port; - _debug_on = debug_on; - if(max_num_retry>0){ - _max_num_retry = max_num_retry; - } - else{ - _max_num_retry = 1; - } -} - -Spotify::Spotify(const char* client_id,const char* client_secret,const char* refresh_token, bool debug_on, int max_num_retry) -{ - _port = 80; - _retry = 0; - _client_id = client_id; - _client_secret = client_secret; - strncpy(_refresh_token, refresh_token,sizeof(_refresh_token)); - _debug_on = debug_on; - if(max_num_retry>0){ - _max_num_retry = max_num_retry; - } - else{ - _max_num_retry = 1; - } -} - -//Login Webserver Functions -std::function callback_fn(Spotify *spotify) { - return [spotify]() { - return spotify->server_on_root(); - }; -}; -bool Spotify::get_refresh_token() { - bool reply = false; - if (!_client.connect("accounts.spotify.com", 443)) { - return false; - } - - String authorization = String(_client_id) + ":" + String(_client_secret); - authorization.trim(); - authorization = "Basic " + base64::encode(authorization); - - String payload = "grant_type=authorization_code&code=" + String(_auth_code) + "&redirect_uri=" + String(_redirect_uri); - - _client.println("POST /api/token HTTP/1.1"); - _client.println("Host: accounts.spotify.com"); - _client.println("User-Agent: ESP32"); - _client.println("Connection: close"); - _client.println("Content-Type: application/x-www-form-urlencoded"); - _client.println("Authorization: " + authorization); - _client.println("Content-Length: " + String(payload.length())); - _client.println(); - _client.println(payload); - - String line; - int http_code = -1; - while (_client.connected()) { - line = _client.readStringUntil('\n'); - if (line.startsWith("HTTP/1.1")) { - http_code = line.substring(9, 12).toInt(); - } - if (line == "\r") { - break; - } - } - - String response; - while (_client.available()) { - response += _client.readStringUntil('\n'); - } - - if (_debug_on) { - Serial.printf("POST \"Refresh token\" Status: %d \n", http_code); - Serial.printf("Reply: %s\n", response.c_str()); - } - - if (http_code >= 200 && http_code <= 299) { - JsonDocument doc; - deserializeJson(doc, response); - const char* temp = doc["refresh_token"]; - strncpy(_refresh_token, temp, sizeof(_refresh_token)); - Serial.printf("Refresh Token: %s\n", _refresh_token); - reply = true; - } else { - reply = false; - } - - _client.stop(); - return reply; -} -/* -bool Spotify::get_refresh_token(){ - char url[40] = "https://accounts.spotify.com/api/token"; - HTTPClient http; - - String authorization = String(_client_id) + ":" + String(_client_secret); - authorization.trim(); - authorization = "Basic " + base64::encode(authorization); - - http.begin(url, _spotify_root_ca); - http.addHeader("Content-Type", "application/x-www-form-urlencoded"); - http.addHeader("Authorization", authorization); - - String payload = "grant_type=authorization_code&code=" + String(_auth_code) + "&redirect_uri=" + String(_redirect_uri); - int http_code = http.POST(payload); - - if (_debug_on) { - Serial.printf("POST \"Refresh token\" Status: %d \n", http_code); - Serial.printf("Reply: %s\n", http.getString().c_str()); - } - if ((http_code >= 200) && (http_code <= 299)) { - String response = http.getString(); - JsonDocument doc; - deserializeJson(doc, response); - const char* temp = doc["refresh_token"]; - strncpy(_refresh_token, temp, sizeof(_refresh_token)); - Serial.printf("Refresh Token: %s\n", _refresh_token); - } - http.end(); - return strcmp(_refresh_token, "") != 0; -}*/ - -void Spotify::server_on_root() { - if (strcmp(_refresh_token, "") == 0) { - if (_server.args() == 0) { - char page[900]; - snprintf(page,sizeof(page),_login_page, _client_id, _redirect_uri); - _server.send(200, "text/html", String(page)); - } else { - if (_server.hasArg("code")) { - strncpy(_auth_code, _server.arg("code").c_str(), sizeof(_auth_code)); - if(_debug_on){ - Serial.printf("Auth Code: %s\n", _auth_code); - } - if(get_refresh_token()){ - char message[500]; - snprintf(message,sizeof(message), "Setup Complete, Refresh Token: %s
You can now close this page", _refresh_token); - _server.send(200, "text/html", message); - } - else{ - _server.send(200, "text/html", "Something went wrong, please try again"); - } - _server.stop(); - } else { - char page[900]; - snprintf(page,sizeof(page),_login_page, _client_id, _redirect_uri); - _server.send(200, "text/html", String(page)); - } - } - } else { - _server.send(200, "text/html", "Spotify setup complete"); - _server.stop(); - } -} - -void Spotify::begin(){ - _client.setCACert(_spotify_root_ca); - if(strcmp(_refresh_token, "") == 0){ - if(_port == 80){ - snprintf(_redirect_uri,sizeof(_redirect_uri), "http://%s/", WiFi.localIP().toString().c_str()); - Serial.printf("Go to this url in your Browser to login to spotify: %s\n", _redirect_uri); - } - else{ - snprintf(_redirect_uri,sizeof(_redirect_uri), "http://%s:%d/", WiFi.localIP().toString().c_str(), _port); - Serial.printf("Go to this url in your Browser to login to spotify: %s\n", _redirect_uri); - } - _server.on("/", HTTP_GET, [this](){ - if(_debug_on){ - Serial.println("Send response to Root"); - } - auto root = callback_fn(this); - root(); - }); - _server.begin(); - if(_debug_on){ - Serial.println("Server started"); - } - } - else{ - if(_debug_on){ - Serial.println("Refresh token already set"); - } - } -} - -void Spotify::handle_client(){ - _server.handleClient(); -} - -bool Spotify::is_auth(){ - return strcmp(_refresh_token, "") != 0; -} - -//Basic functions -response Spotify::RestApi(char* rest_url, char* type, int payload_size, char* payload){ - response response_obj; - int http_code = -1; - String reply = ""; - JsonDocument doc; - init_response(&response_obj); - - if (!_client.connect(_host, 443)) { - response_obj.reply = "Connection failed"; - return response_obj; - } - _client.println(String(type) + " " + String(rest_url) + " HTTP/1.1"); - _client.println("Host: " + String(_host)); - _client.println("User-Agent: ESP32"); - _client.println("Connection: close"); - _client.println("Accept: application/json"); - - _client.println("Authorization: Bearer " + String(_access_token)); - _client.println("Content-Type: application/json"); - if(strcmp(type, "GET") == 0){ - _client.println(); - } - else if(strcmp(type, "PUT") == 0){ - _client.println("Content-Length: " + String(payload_size)); - _client.println(); - _client.println(payload); - } - else if(strcmp(type, "POST") == 0){ - _client.println("Content-Length: " + String(payload_size)); - _client.println(); - _client.println(payload); - } - else if(strcmp(type, "DELETE") == 0){ - _client.println(); - _client.println(payload); - } - int line_num = 0; - while (_client.connected()) { - String line = _client.readStringUntil('\n'); - if(!line_num){ - http_code = line.substring(9,12).toInt(); - } - if (line == "\r") { - break; - } - line_num++; - if(_debug_on){ - Serial.println(line); - } - } - response_obj.status_code = http_code; - while(_client.available()){ - reply = reply + _client.readStringUntil('\n') + "\n"; - } - deserializeJson(doc, reply); - if(_debug_on){ - const char* endpoint = extract_endpoint(rest_url); - Serial.printf("%s \"%s\" Status: %i\n", type, endpoint, http_code); - Serial.printf("Reply: %s\n", reply.c_str()); - } - if ((http_code >= 200)&&(http_code <= 299)){ - response_obj.reply = reply; - } - else if(_retry<=_max_num_retry){ - String message = doc["error"]["message"].as(); - if(message == "Only valid bearer authentication supported"){ - _retry++; - if(get_token()){ - response_obj = RestApi(rest_url, type, payload_size, payload); - } - } - else{ - response_obj.reply = message; - } - } - - _client.stop(); - return response_obj; -} - -response Spotify::RestApiPut(char* rest_url,int payload_size, char* payload){ - return RestApi(rest_url, "PUT", payload_size, payload); -} -response Spotify::RestApiGet(char* rest_url){ - return RestApi(rest_url, "GET"); -} -response Spotify::RestApiPost(char* rest_url,int payload_size, char* payload){ - return RestApi(rest_url, "POST", payload_size, payload); -} -response Spotify::RestApiDelete(char* rest_url, char* payload){ - return RestApi(rest_url, "DELETE", 0, payload); -} -bool Spotify::get_token() { - bool reply = false; - if (!_client.connect("accounts.spotify.com", 443)) { - return false; - } - String authorization = String(_client_id) + ":" + String(_client_secret); - authorization.trim(); - authorization = "Basic " + base64::encode(authorization); - - String payload = "grant_type=refresh_token&refresh_token=" + String(_refresh_token); - - _client.println("POST /api/token HTTP/1.1"); - _client.println("Host: accounts.spotify.com"); - _client.println("User-Agent: ESP32"); - _client.println("Connection: close"); - _client.println("Content-Type: application/x-www-form-urlencoded"); - _client.println("Authorization: " + authorization); - _client.println("Content-Length: " + String(payload.length())); - _client.println(); - _client.println(payload); - - String line; - int http_code = -1; - while (_client.connected()) { - line = _client.readStringUntil('\n'); - if (line.startsWith("HTTP/1.1")) { - http_code = line.substring(9, 12).toInt(); - } - if (line == "\r") { - break; - } - } - - String response; - while (_client.available()) { - response += _client.readStringUntil('\n'); - } - - if (_debug_on) { - Serial.printf("POST \"token\" Status: %d \n", http_code); - Serial.printf("Reply: %s\n", response.c_str()); - } - - if (http_code >= 200 && http_code <= 299) { - JsonDocument doc; - deserializeJson(doc, response); - _access_token = doc["access_token"].as(); - reply = true; - } else { - reply = false; - } - - _client.stop(); - return reply; -} -/* -bool Spotify::get_token(){ - bool reply = false; - HTTPClient http; - char url[40] = "https://accounts.spotify.com/api/token"; - String authorization = String(_client_id) + ":" + String(_client_secret); - authorization.trim(); - authorization = "Basic " + base64::encode(authorization); - http.begin(url, _spotify_root_ca); - http.addHeader("Content-Type", "application/x-www-form-urlencoded"); - http.addHeader("Authorization", authorization); - - String payload = "grant_type=refresh_token&refresh_token=" + String(_refresh_token); - int http_code = http.POST(payload); - if (_debug_on) { - Serial.printf("POST \"token\" Status: %d \n", http_code); - Serial.printf("Reply: %s\n", http.getString().c_str()); - } - if ((http_code >=200)&&(http_code<=299)) { - String response = http.getString(); - JsonDocument doc; - deserializeJson(doc, response); - _access_token = doc["access_token"].as(); - reply = true; - } - else{ - reply = false; - } - http.end(); - return reply; -}*/ - -void Spotify::init_response(response* response_obj){ - response_obj -> status_code = -1; - response_obj -> reply ="If you see this something went wrong, if the issue persists please contact the developer"; -} -char* Spotify::array_to_char(int size, char** array, char* result) { - result[0] = '\0'; - for (int i = 0; i < size; ++i) { - strcat(result, array[i]); - if (i != size - 1) { - strcat(result, ","); - } - } - return result; -} -void Spotify::array_to_json_array(int size, char** array, char* data, int data_size){ - JsonDocument doc; - JsonArray json_array = doc.to(); - for (int i = 0; i char_params; - std::map float_params; - populate_float_values(float_params, recom); - populate_char_values(char_params, recom); - - for (const auto& param : char_params) { - char value[100]; - snprintf(value, sizeof(value), "&%s=%s",param.first, param.second); - strcat(url, value); - } - for(const auto& param : float_params){ - char value[100]; - snprintf(value, sizeof(value), "&%s=%f",param.first, param.second); - strcat(url, value); - } - return RestApiGet(url); -} -bool Spotify::is_valid_value(float param) { - return param >= 0.0 && param <= 1.0; -} -bool Spotify::is_valid_value(int param) { - return param >0; -} -void Spotify::populate_float_values(std::map& float_params, recommendations& recom){ - if (is_valid_value(recom.min_acousticness)) { - float_params["min_acousticness"] = recom.min_acousticness; - } - if (is_valid_value(recom.max_acousticness)) { - float_params["max_acousticness"] = recom.max_acousticness; - } - if (is_valid_value(recom.target_acousticness)) { - float_params["target_acousticness"] = recom.target_acousticness; - } - - if (is_valid_value(recom.min_danceability)) { - float_params["min_danceability"] = recom.min_danceability; - } - if (is_valid_value(recom.max_danceability)) { - float_params["max_danceability"] = recom.max_danceability; - } - if (is_valid_value(recom.target_danceability)) { - float_params["target_danceability"] = recom.target_danceability; - } - - if (is_valid_value(recom.min_duration_ms)) { - float_params["min_duration_ms"] = recom.min_duration_ms; - } - if (is_valid_value(recom.max_duration_ms)) { - float_params["max_duration_ms"] = recom.max_duration_ms; - } - if (is_valid_value(recom.target_duration_ms)) { - float_params["target_duration_ms"] = recom.target_duration_ms; - } - - if (is_valid_value(recom.min_energy)) { - float_params["min_energy"] = recom.min_energy; - } - if (is_valid_value(recom.max_energy)) { - float_params["max_energy"] = recom.max_energy; - } - if (is_valid_value(recom.target_energy)) { - float_params["target_energy"] = recom.target_energy; - } - - if (is_valid_value(recom.min_instrumentalness)) { - float_params["min_instrumentalness"] = recom.min_instrumentalness; - } - if (is_valid_value(recom.max_instrumentalness)) { - float_params["max_instrumentalness"] = recom.max_instrumentalness; - } - if (is_valid_value(recom.target_instrumentalness)) { - float_params["target_instrumentalness"] = recom.target_instrumentalness; - } - - if (is_valid_value(recom.min_key)) { - float_params["min_key"] = recom.min_key; - } - if (is_valid_value(recom.max_key)) { - float_params["max_key"] = recom.max_key; - } - if (is_valid_value(recom.target_key)) { - float_params["target_key"] = recom.target_key; - } - - if (is_valid_value(recom.min_liveness)) { - float_params["min_liveness"] = recom.min_liveness; - } - if (is_valid_value(recom.max_liveness)) { - float_params["max_liveness"] = recom.max_liveness; - } - if (is_valid_value(recom.target_liveness)) { - float_params["target_liveness"] = recom.target_liveness; - } - - if (is_valid_value(recom.min_loudness)) { - float_params["min_loudness"] = recom.min_loudness; - } - if (is_valid_value(recom.max_loudness)) { - float_params["max_loudness"] = recom.max_loudness; - } - if (is_valid_value(recom.target_loudness)) { - float_params["target_loudness"] = recom.target_loudness; - } - - if (is_valid_value(recom.min_mode)) { - float_params["min_mode"] = recom.min_mode; - } - if (is_valid_value(recom.max_mode)) { - float_params["max_mode"] = recom.max_mode; - } - if (is_valid_value(recom.target_mode)) { - float_params["target_mode"] = recom.target_mode; - } - - if (is_valid_value(recom.min_popularity)) { - float_params["min_popularity"] = recom.min_popularity; - } - if (is_valid_value(recom.max_popularity)) { - float_params["max_popularity"] = recom.max_popularity; - } - if (is_valid_value(recom.target_popularity)) { - float_params["target_popularity"] = recom.target_popularity; - } - - if (is_valid_value(recom.min_speechiness)) { - float_params["min_speechiness"] = recom.min_speechiness; - } - if (is_valid_value(recom.max_speechiness)) { - float_params["max_speechiness"] = recom.max_speechiness; - } - if (is_valid_value(recom.target_speechiness)) { - float_params["target_speechiness"] = recom.target_speechiness; - } - - if (is_valid_value(recom.min_tempo)) { - float_params["min_tempo"] = recom.min_tempo; - } - if (is_valid_value(recom.max_tempo)) { - float_params["max_tempo"] = recom.max_tempo; - } - if (is_valid_value(recom.target_tempo)) { - float_params["target_tempo"] = recom.target_tempo; - } - - if (is_valid_value(recom.min_time_signature)) { - float_params["min_time_signature"] = recom.min_time_signature; - } - if (is_valid_value(recom.max_time_signature)) { - float_params["max_time_signature"] = recom.max_time_signature; - } - if (is_valid_value(recom.target_time_signature)) { - float_params["target_time_signature"] = recom.target_time_signature; - } - - if (is_valid_value(recom.min_valence)) { - float_params["min_valence"] = recom.min_valence; - } - if (is_valid_value(recom.max_valence)) { - float_params["max_valence"] = recom.max_valence; - } - if (is_valid_value(recom.target_valence)) { - float_params["target_valence"] = recom.target_valence; - } -} -void Spotify::populate_char_values(std::map& char_params, recommendations& recom){ - char arr[_max_char_size]; - if(is_valid_value(recom.seed_artists_size)){ - char_params["seed_artists"] = array_to_char(recom.seed_artists_size, recom.seed_artists, arr); - } - if(is_valid_value(recom.seed_genres_size)){ - char_params["seed_genres"] = array_to_char(recom.seed_genres_size, recom.seed_genres, arr); - } - if(is_valid_value(recom.seed_tracks_size)){ - char_params["seed_tracks"] = array_to_char(recom.seed_tracks_size, recom.seed_tracks,arr); - } -} -#endif -#ifdef ENABLE_USER -//Users -response Spotify::get_current_user_profile() { - char url[] = "https://api.spotify.com/v1/me"; - - return RestApiGet(url); -} -response Spotify::get_user_top_items(char* type, char* time_range, int limit, int offset) { - char url[100]; - snprintf(url, sizeof(url), "https://api.spotify.com/v1/me/top/%s?time_range=%s&limit=%d&offset=%d", type, time_range, limit, offset); - - return RestApiGet(url); -} -response Spotify::get_user_profile(char* user_id) { - char url[100]; - snprintf(url, sizeof(url), "https://api.spotify.com/v1/users/%s", user_id); - - return RestApiGet(url); -} -response Spotify::follow_playlist(char* playlist_id, bool is_public) { - char url[100]; - snprintf(url, sizeof(url), "https://api.spotify.com/v1/playlists/%s/followers", playlist_id); - char payload[100]; - int payload_size = 0; - snprintf(payload,sizeof(payload), "{\"public\":%s}", is_public ? "true" : "false"); - payload_size = strlen(payload); - - return RestApiPut(url, payload_size, payload); -} -response Spotify::unfollow_playlist(char* playlist_id) { - char url[100]; - snprintf(url, sizeof(url), "https://api.spotify.com/v1/playlists/%s/followers", playlist_id); - - return RestApiDelete(url); -} -response Spotify::get_followed_artists(char* after, char* type, int limit) { - char url[100]; - snprintf(url, sizeof(url), "https://api.spotify.com/v1/me/following?type=%s&after=%s&limit=%d", type, after, limit); - - return RestApiGet(url); -} -response Spotify::follow_artists_or_users(char* type,int size, char** artist_user_ids) { - char url[100]; - snprintf(url, sizeof(url), "https://api.spotify.com/v1/me/following?type=%s", type); - char payload[_max_char_size]; - int payload_size = 0; - array_to_json_array(size, artist_user_ids, payload); - payload_size = strlen(payload); - - return RestApiPut(url, payload_size, payload); -} -response Spotify::unfollow_artists_or_users(char* type,int size, char** artist_user_ids) { - char url[100]; - snprintf(url, sizeof(url), "https://api.spotify.com/v1/me/following?type=%s", type); - char payload[_max_char_size]; - array_to_json_array(size, artist_user_ids, payload); - - return RestApiDelete(url, payload); -} -response Spotify::check_if_user_follows_artists_or_users(char* type,int size, char** artist_user_ids) { - char url[_max_char_size]; - char arr[_max_char_size]; - snprintf(url, sizeof(url), "https://api.spotify.com/v1/me/following/contains?type=%s&ids=%s", type, array_to_char(size, artist_user_ids, arr)); - - return RestApiGet(url); -} -response Spotify::check_if_users_follow_playlist(char* playlist_id,int size, char** user_ids) { - char url[_max_char_size]; - char arr[_max_char_size]; - snprintf(url, sizeof(url), "https://api.spotify.com/v1/playlists/%s/followers/contains?ids=%s", playlist_id, array_to_char(size, user_ids, arr)); - - return RestApiGet(url); -} -#endif -#ifdef ENABLE_SIMPIFIED -//Simplified functions, formatting functions -String Spotify::current_track_name(){ - String track_name = "Something went wrong"; - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - JsonDocument doc; - deserializeJson(doc,data.reply); - track_name = doc["item"]["name"].as(); - } - return track_name; - -} -String Spotify::current_track_id(){ - String track_id = "Something went wrong"; - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - JsonDocument doc; - deserializeJson(doc,data.reply); - track_id = doc["item"]["id"].as(); - } - return track_id; -} -String Spotify::current_device_id(){ - String device_id = "Something went wrong"; - response data = available_devices(); - if((data.status_code>=200)&&(data.status_code<=299)){ - JsonDocument doc; - deserializeJson(doc,data.reply); - JsonArray devices = doc["devices"].as(); - for (JsonVariant device : devices) { - JsonObject deviceObj = device.as(); - - if (deviceObj["is_active"].as()) { - device_id = deviceObj["id"].as(); - break; - } - } - } - return device_id; -} -String Spotify::current_artist_names(){ - String artist_names = "Something went wrong"; - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - JsonDocument doc; - deserializeJson(doc,data.reply); - JsonArray array = doc["item"]["artists"]; - int len = array.size(); - artist_names = ""; - for (int i = 0; i(); - if (i=200)&&(data.status_code<=299)){ - JsonDocument doc; - deserializeJson(doc,data.reply); - JsonArray devices = doc["devices"].as(); - for (JsonVariant device : devices) { - JsonObject deviceObj = device.as(); - if (deviceObj["is_active"].as()) { - snprintf(device_id,sizeof(device_id), "%s", deviceObj["id"].as().c_str()); - break; - } - } - } - return device_id; -} -char* Spotify::current_track_name(char * track_name){ - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - JsonDocument doc; - deserializeJson(doc,data.reply); - snprintf(track_name,sizeof(track_name), "%s", doc["item"]["name"].as().c_str()); - } - return track_name; -} -char* Spotify::current_track_id(char * track_id){ - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - JsonDocument doc; - deserializeJson(doc,data.reply); - snprintf(track_id,sizeof(track_id), "%s", doc["item"]["id"].as().c_str()); - } - return track_id; -} -char* Spotify::current_artist_names(char * artist_names){ - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - JsonDocument doc; - deserializeJson(doc,data.reply); - JsonArray array = doc["item"]["artists"]; - int len = array.size(); - artist_names[0] = '\0'; - for (int i = 0; i().c_str()); - if (i=200)&&(data.status_code<=299)){ - JsonDocument doc; - deserializeJson(doc,data.reply); - is_playing = doc["is_playing"].as(); - } - return is_playing; -} -bool Spotify::volume_modifyable(){ - bool volume_modifyable = false; - response data = current_playback_state(); - if((data.status_code>=200)&&(data.status_code<=299)){ - JsonDocument doc; - deserializeJson(doc,data.reply); - volume_modifyable = doc["device"]["supports_volume"]; - } - return volume_modifyable; -} -#endif -char Spotify::convert_id_to_uri(char* id, char* type){ - char uri[_size_of_uri]; - snprintf(uri,_size_of_uri, "spotify:%s:%s", type, id); - return *uri; -} -char* Spotify::convert_id_to_uri(char* id, char* type,char * uri){ - snprintf(uri,sizeof(uri), "spotify:%s:%s", type, id); - return uri; -} -void print_response(response response_obj){ - Serial.printf("Status: %d\n", response_obj.status_code); - Serial.printf("Reply: %s\n", response_obj.reply.c_str()); -} \ No newline at end of file diff --git a/Spotify_v3/src/SpotifyESP32.h b/Spotify_v3/src/SpotifyESP32.h deleted file mode 100644 index 2d2d800..0000000 --- a/Spotify_v3/src/SpotifyESP32.h +++ /dev/null @@ -1,830 +0,0 @@ -#ifndef SpotifyESP32 -#define SpotifyESP32 - -#define ENABLE_PLAYER -#define ENABLE_ALBUM -#define ENABLE_ARTIST -#define ENABLE_AUDIOBOOKS -#define ENABLE_CATEGORIES -#define ENABLE_CHAPTERS -#define ENABLE_EPISODES -#define ENABLE_GENRES -#define ENABLE_MARKETS -#define ENABLE_PLAYLISTS -#define ENABLE_SEARCH -#define ENABLE_SHOWS -#define ENABLE_TRACKS -#define ENABLE_USER -#define ENABLE_SIMPIFIED - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - - -namespace Spotify_types { - extern bool SHUFFLE_ON; - extern bool SHUFFLE_OFF; - extern char* REPEAT_OFF; - extern char* REPEAT_TRACK; - extern char* REPEAT_CONTEXT; - extern char* TYPE_ALBUM; - extern char* TYPE_ARTIST; - extern char* TYPE_TRACK; - extern char* TYPE_SHOW; - extern char* TYPE_EPISODE; - extern char* TYPE_AUDIOBOOK; - extern char* TYPE_PLAYLIST; - extern char* TOP_TYPE_ARTIST; - extern char* TOP_TYPE_TRACKS; - extern char* GROUP_ALBUM; - extern char* GROUP_SINGLE; - extern char* GROUP_APPEARS_ON; - extern char* GROUP_COMPILATION; - extern char* TIME_RANGE_SHORT; - extern char* TIME_RANGE_MEDIUM; - extern char* TIME_RANGE_LONG; - extern char* FOLLOW_TYPE_ARTIST; - extern char* FOLLOW_TYPE_USER; - extern int SIZE_OF_ID; - extern int SIZE_OF_URI; - -} - -/// @brief Response object containing http status code and reply -typedef struct{ - int status_code; - String reply; -} response; - -/// @brief Recommendation object, used to create recommendations -struct recommendations { - char** seed_artists; - int seed_artists_size = 0; - char** seed_genres; - int seed_genres_size = 0; - char** seed_tracks; - int seed_tracks_size = 0; - float min_acousticness = -1.0; - float max_acousticness = -1.0; - float target_acousticness = -1.0; - float min_danceability = -1.0; - float max_danceability = -1.0; - float target_danceability = -1.0; - float min_duration_ms = -1.0; - float max_duration_ms = -1.0; - float target_duration_ms = -1.0; - float min_energy = -1.0; - float max_energy = -1.0; - float target_energy = -1.0; - float min_instrumentalness = -1.0; - float max_instrumentalness = -1.0; - float target_instrumentalness = -1.0; - float min_key = -1.0; - float max_key = -1.0; - float target_key = -1.0; - float min_liveness = -1.0; - float max_liveness = -1.0; - float target_liveness = -1.0; - float min_loudness = -1.0; - float max_loudness = -1.0; - float target_loudness = -1.0; - float min_mode = -1.0; - float max_mode = -1.0; - float target_mode = -1.0; - float min_popularity = -1.0; - float max_popularity = -1.0; - float target_popularity = -1.0; - float min_speechiness = -1.0; - float max_speechiness = -1.0; - float target_speechiness = -1.0; - float min_tempo = -1.0; - float max_tempo = -1.0; - float target_tempo = -1.0; - float min_time_signature = -1.0; - float max_time_signature = -1.0; - float target_time_signature = -1.0; - float min_valence = -1.0; - float max_valence = -1.0; - float target_valence = -1.0; -}; - -/// @brief Print response object -/// @param response_obj Response object to print -void print_response(response response_obj); -class Spotify { - public: - ///@brief Constructor for Spotify object without refresh token - ///@param client_id Client id from Spotify(Required) - ///@param client_secret Client secret from Spotify(Required) - ///@param server_port Port for the server to run on(default 80, if 80 is already used use anything above 1024) - ///@param debug_on Debug mode on or off(default off) - ///@param max_num_retry Max number of retries for a request(default 3) - Spotify(const char* client_id,const char* client_secret, int server_port = 80, bool debug_on = false, int max_num_retry = 3); - ///@brief Constructor for Spotify object with refresh token - ///@param client_id Client id from Spotify(Required) - ///@param client_secret Client secret from Spotify(Required) - ///@param refresh_token Refresh token from Spotify(Required) if not authenticated use other constructor - ///@param debug_on Debug mode on or off(default off) - ///@param max_num_retry Max number of retries for a request(default 3) - Spotify(const char* client_id,const char* client_secret,const char* refresh_token, bool debug_on = false, int max_num_retry = 3); - /// @brief start the server and begin authentication - void begin(); - /// @brief handle client requests necessary for authentication - void handle_client(); - /// @brief Check if user is authenticated - /// @return true if user is authenticated - bool is_auth(); - #ifdef ENABLE_PLAYER - ///@brief Get information about the user's current playback state, including track, track progress, and active device. - ///@return response object containing http status code and reply - response currently_playing(); - ///@brief Start or resume playback. If no device_id is provided, the user's currently active device is the target. - ///@param context_uri Spotify URI of the context to play (Required) - ///@param offset Indicates from where in the context playback should start, Only works with albums or Playlists. NEEDS TO BE SET (0) IF ONLY URI IS PROVIDED - ///@param position_ms Indicates from what position in the context playback should start in milliseconds(Optional) - ///@param device_id Id of the device this command is targeting (Optional) - ///@return response object containing http status code and reply - response start_resume_playback(char* context_uri, int offset, int position_ms = 0, char* device_id = nullptr); - ///@brief Start or resume playback. If no device_id is provided, the user's currently active device is the target. - ///@param size Number of uris in uris array - ///@param uris Array of Spotify URIs of the tracks to play - ///@param device_id Id of the device this command is targeting (Optional) - ///@return response object containing http status code and reply - response start_resume_playback(int size, char ** uris ,char* device_id = nullptr); - ///@brief Start or resume playback. If no device_id is provided, the user's currently active device is the target. Targets the currently playing context. - ///@return response object containing http status code and reply - response start_resume_playback(char* device_id = nullptr); - ///@brief Pause playback on Spotify - ///@return response object containing http status code and reply - response pause_playback(); - ///@brief Skip to next track - ///@return response object containing http status code and reply - response skip(); - ///@brief Skip to previous track - ///@return response object containing http status code and reply - response previous(); - ///@brief get information about the user's available devices - ///@return response object containing http status code and reply - response available_devices(); - ///@brief get information about the user's current playback state, including track, track progress, and active device, shuffle etc. - ///@return response object containing http status code and reply - response current_playback_state(); - ///@brief Get recently played tracks - ///@param limit The maximum number of items to return. Default: 10. Minimum: 1. Maximum: 50 - response recently_played_tracks(int limit = 10); - ///@brief Seek to position of current context - ///@param time_ms Position in milliseconds to seek to, if the value is greater than the length of the track the player will skip to the next track - ///@return response object containing http status code and reply - response seek_to_position(int time_ms); - ///@brief get users queue, response can be empty or containing episode or track objects - ///@return response object containing http status code and reply - response get_queue(); - ///@Brief Set repeat mode, allowed values are REPEAT_OFF, REPEAT_TRACK, REPEAT_CONTEXT - ///@param mode Repeat mode - ///@return response object containing http status code and reply - response repeat_mode(char* mode); - ///@Brief Set shuffle mode, allowed values are SHUFFLE_ON, SHUFFLE_OFF - ///@param mode Shuffle mode - ///@return response object containing http status code and reply - response shuffle(bool mode); - ///@Brief Transfer playback to another device - ///@param device_id Id of the device this command is targeting - ///@return response object containing http status code and reply - response transfer_playback(char* device_id); - ///@Brief Set volume, does not work with all devices(eg. does not work on Phones) - ///@param value Volume value between 0 and 100 - ///@return response object containing http status code and reply - response set_volume(int value); - ///@Brief Add context to queue - ///@param context_uri Spotify URI of the context to add to queue - response add_to_queue(char* context_uri); - #endif - #ifdef ENABLE_ALBUM - ///@brief Get Spotify information for a single album. - ///@param album_id Spotify ID of the album - ///@return response object containing http status code and reply - response get_album(char* album_id); - ///@brief Get Spotify information for multiple albums identified by their Spotify IDs. - ///@param size Number of album ids in album_ids array - ///@param album_ids Array of Spotify IDs of the albums - ///@return response object containing http status code and reply - response get_albums(int size, char** album_ids); - ///@brief Get Spotify information about an album's tracks. - ///@param album_id Spotify ID of the album - ///@param limit The maximum number of tracks to return. Default: 10. Minimum: 1. Maximum: 50 - ///@param offset The index of the first track to return. Default: 0 (the first object). Use with limit to get the next set of tracks. - ///@return response object containing http status code and reply - response get_album_tracks(char* album_id, int limit = 10, int offset = 0); - ///@brief Get Albums saved to the current user's music library. - ///@param limit The maximum number of albums to return. Default: 10. Minimum: 1. Maximum: 50 - ///@param offset The index of the first album to return. Default: 0 (the first object). Use with limit to get the next set of albums. - ///@return response object containing http status code and reply - response get_users_saved_albums(int limit = 10, int offset = 0); - ///@brief Save one or more albums to the current user's music library. - ///@param size Number of album ids in album_ids array - ///@param album_ids Array of Spotify IDs of the albums - ///@return response object containing http status code and reply - response save_albums_for_current_user(int size, char** album_ids); - ///@brief Remove one or more albums from the current user's music library. - ///@param size Number of album ids in album_ids array - ///@param album_ids Array of Spotify IDs of the albums - ///@return response object containing http status code and reply - response remove_users_saved_albums(int size, char** album_ids); - ///@brief Check if one or more albums is already saved in the current Spotify user's music library. - ///@param size Number of album ids in album_ids array - ///@param album_ids Array of Spotify IDs of the albums - ///@return response object containing http status code and reply - response check_useres_saved_albums(int size, char** album_ids); - ///@brief Get a list of new album releases featured in Spotify - ///@param limit The maximum number of items to return. Default: 10. Minimum: 1. Maximum: 50 - ///@param offset The index of the first item to return. Default: 0 (the first object). Use with limit to get the next set of items. - ///@param country A country: an ISO 3166-1 alpha-2 country code. Provide this parameter if you want the list of returned items to be relevant to a particular country. - ///@return response object containing http status code and reply - response get_new_releases(int limit = 10, int offset = 0, char* country = nullptr); - #endif - #ifdef ENABLE_ARTIST - ///@brief Get Spotify information for a single artist - ///@param artist_id Spotify ID of the artist - ///@return response object containing http status code and reply - response get_artist(char* artist_id); - ///@brief Get Spotify information for multiple artists - ///@param size Number of artist ids in artist_ids array - ///@param artist_ids Array of Spotify IDs of the artists - ///@return response object containing http status code and reply - response get_several_artists(int size, char** artist_ids); - ///@brief Get Spotify information about an artist's albums - ///@param artist_id Spotify ID of the artist - ///@param size_groups Number of groups in include_groups array - ///@param include_groups Array of groups to include in the response. Valid values are GROUP_ALBUM, GROUP_SINGLE, GROUP_APPEARS_ON, GROUP_COMPILATION or any combination of these. - ///@param limit The maximum number of items to return. Default: 10. Minimum: 1. Maximum: 50 - ///@param offset The index of the first album to return. Default: 0 (the first object). Use with limit to get the next set of albums. - ///@return response object containing http status code and reply - response get_artist_albums(char* artist_id,int size_groups, char** include_groups, int limit = 10, int offset = 0); - ///@brief Get Spotify information about an artist's top tracks - ///@param artist_id Spotify ID of the artist - ///@param country An ISO 3166-1 alpha-2 country code or the string from_token. Provide this parameter if you want the list of returned items to be relevant to a particular country. - ///@return response object containing http status code and reply - response get_artist_top_tracks(char* artist_id, char* country = nullptr); - ///@brief Get Spotify information about artists related to a single artist - ///@param artist_id Spotify ID of the artist - ///@return response object containing http status code and reply - response get_artist_related_artist(char* artist_id); - #endif - #ifdef ENABLE_AUDIOBOOKS - ///@brief Get Spotify information for a single audiobook(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - ///@param audiobook_id Spotify ID of the audiobook - ///@return response object containing http status code and reply - response get_audiobook(char* audiobook_id); - ///@brief Get Spotify information for multiple audiobooks(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - ///@param size Number of audiobook ids in audiobook_ids array - ///@param audiobook_ids Array of Spotify IDs of the audiobooks - ///@return response object containing http status code and reply - response get_several_audiobooks(int size, char** audiobook_ids); - ///@brief Get Spotify information about an audiobook's chapters(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - ///@param audiobook_id Spotify ID of the audiobook - ///@param limit The maximum number of items to return. Default: 10. Minimum: 1. Maximum: 50 - ///@param offset The index of the first chapter to return. Default: 0 (the first object). Use with limit to get the next set of chapters. - ///@return response object containing http status code and reply - response get_audiobook_chapters(char* audiobook_id, int limit = 10, int offset = 0); - /// @brief Get users saved audiobooks(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_users_audiobooks(int limit = 10, int offset = 0); - /// @brief Save one or more audiobooks to the current user's music library(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - /// @param size Number of audiobook ids in audiobook_ids array - /// @param audiobook_ids Array of Spotify IDs of the audiobooks - /// @return response object containing http status code and reply - response save_audiobooks_for_current_user(int size, char** audiobook_ids); - /// @brief Remove one or more audiobooks from the current user's music library(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - /// @param size Number of audiobook ids in audiobook_ids array - /// @param audiobook_ids Array of Spotify IDs of the audiobooks - /// @return response object containing http status code and reply - response remove_audiobooks_for_current_user(int size, char** audiobook_ids); - /// @brief Check if one or more audiobooks is already saved in the current Spotify user's music library(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - /// @param size Number of audiobook ids in audiobook_ids array - /// @param audiobook_ids Array of Spotify IDs of the audiobooks - /// @return response object containing http status code and reply - response check_users_saved_audiobooks(int size, char** audiobook_ids); - #endif - #ifdef ENABLE_CATEGORIES - ///@brief Get a list of categories used to tag items in Spotify - ///@param limit The maximum number of items to return - ///@param offset The index of the first item to return - ///@param country An ISO 3166-1 alpha-2 country code, if ommited the returned items will not be country-specific - ///@param locale The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, joined by an underscore, if ommited the response defaults to American English - ///@return response object containing http status code and reply - response get_several_browse_categories(int limit = 10, int offset = 0, char* country = nullptr, char* locale = nullptr); - ///@brief Get a single category used to tag items in Spotify - ///@param category_id Spotify category ID of the category - ///@param country An ISO 3166-1 alpha-2 country code, if ommited the returned items will not be country-specific - ///@param locale The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, joined by an underscore, if ommited the response defaults to American English - ///@return response object containing http status code and reply - response get_single_browse_category(char* category_id, char* country = nullptr, char* locale = nullptr); - #endif - #ifdef ENABLE_CHAPTERS - ///@brief Get Spotify information for a single chapter, Only Available in US, UK, Canada, Ireland, New Zealand and Australia - ///@param chapter_id Spotify ID of the chapter - ///@return response object containing http status code and reply - response get_chapter(char* chapter_id); - ///@brief Get Spotify information for multiple chapters, Only Available in US, UK, Canada, Ireland, New Zealand and Australia - ///@param size Number of chapter ids in chapter_ids array - ///@param chapter_ids Array of Spotify IDs of the chapters - ///@return response object containing http status code and reply - response get_several_chapters(int size, char** chapter_ids); - #endif - #ifdef ENABLE_EPISODES - ///@brief Get Spotify information for a single episode - ///@param episode_id Spotify ID of the episode - ///@return response object containing http status code and reply - response get_episode(char* episode_id); - ///@brief Get Spotify information for multiple episodes - ///@param size Number of episode ids in episode_ids array - ///@param episode_ids Array of Spotify IDs of the episodes - ///@return response object containing http status code and reply - response get_several_episodes(int size, char** episode_ids); - ///@brief Get users saved episodes - ///@param limit The maximum number of items to return, - ///@param offset The index of the first item to return - ///@return response object containing http status code and reply - response get_users_saved_episodes(int limit = 10, int offset = 0); - ///@brief Save one or more episodes to the current user's music library - ///@param size Number of episode ids in episode_ids array - ///@param episode_ids Array of Spotify IDs of the episodes - ///@return response object containing http status code and reply - response save_episodes_for_current_user(int size, char** episode_ids); - ///@brief Remove one or more episodes from the current user's music library - ///@param size Number of episode ids in episode_ids array - ///@param episode_ids Array of Spotify IDs of the episodes - ///@return response object containing http status code and reply - response remove_episodes_for_current_user(int size, char** episode_ids); - ///@brief Check if one or more episodes is already saved in the current Spotify user's music library - ///@param size Number of episode ids in episode_ids array - ///@param episode_ids Array of Spotify IDs of the episodes - ///@return response object containing http status code and reply - response check_users_saved_episodes(int size, char** episode_ids); - #endif - #ifdef ENABLE_GENRES - ///@brief Get a list of available genre seeds for recommendations - ///@return response object containing http status code and reply - response get_available_genre_seeds(); - #endif - #ifdef ENABLE_MARKETS - ///@brief Get a list of available markets for recommendations - ///@return response object containing http status code and reply - response get_available_markets(); - #endif - #ifdef ENABLE_PLAYLISTS - ///@brief Get Spotify information for a single playlist - ///@param playlist_id Spotify ID of the playlist - ///@param size Number of fields in fields array - ///@param fields Array of fields to return, leave empty to return all fields - ///@param additional_types A comma-separated list of item types that your client supports besides the default track type. Valid types are: track and episode. - ///@return response object containing http status code and reply - response get_playlist(char* playlist_id,int size = 0, char** fields = nullptr,int size_of_additional_types = 0, char ** additional_types = nullptr); - /// @brief Change details of a playlist - /// @param playlist_id ID of the playlist - /// @param name Set the name of the playlist - /// @param is_public Set the playlist to public or not - /// @param is_collaborative Set the playlist to collaborative or not - /// @param description Set the description of the playlist - /// @return response object containing http status code and reply - response change_playlist_details(char* playlist_id, char* name, bool is_public, bool is_collaborative, char* description); - /// @brief Get Items of a playlist - /// @param playlist_id Id of the playlist - /// @param fields Filters for the query: a comma-separated list of the fields to return. If omitted, all fields are returned. For example, to get just the total number of items and the request limit: - /// @param limit Number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_playlist_items(char* playlist_id, char* fields, int limit = 10, int offset = 0); - /// @brief Either reorder or replace items in a playlist depending on the request's parameters - /// @param playlist_id Id of the playlist - /// @param size Size of uris array - /// @param uris Array of Spotify URIs this will overwrite all existing items in the playlist, If items should only be reordered pass nullptr - /// @param range_length The position of the first item to be reordered. - /// @param range_start The position where the items should be inserted. - /// @param insert_before The amount of items to be reordered. - /// @return response object containing http status code and reply - response update_playlist_items(char* playlist_id, int size, char** uris = nullptr, int range_length = 1, int range_start = 0, int insert_before = 1 ); - /// @brief Add items to a playlist - /// @param playlist_id Id of the playlist - /// @param size Size of uris array - /// @param uris Array of Spotify URIs of the items to add - /// @param position The position to insert the items, a zero-based index - /// @return response object containing http status code and reply - response add_items_to_playlist(char* playlist_id, int size, char** uris, int position = 0); - /// @brief Remove items from a playlist - /// @param playlist_id Id of the playlist - /// @param size Size of uris array - /// @param uris Array of Spotify URIs of the items to remove - /// @return response object containing http status code and reply - response remove_playlist_items(char* playlist_id, int size, char** uris); - /// @brief Get a list of users playlists - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_current_users_playlists(int limit = 10, int offset = 0); - /// @brief get a users playlist - /// @param user_id Id of the user - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_user_playlists(char* user_id,int limit = 10, int offset = 0); - /// @brief Create a playlist - /// @param user_id Id of the user - /// @param name Name of the playlist - /// @param is_public Set the playlist to public or not - /// @param is_collaborative Set the playlist to collaborative or not - /// @param description Description of the playlist - /// @return response object containing http status code and reply - response create_playlist(char* user_id, char* name, bool is_public, bool is_collaborative, char* description); - /// @brief Get a list of Spotify featured playlists - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @param timestamp A timestamp in ISO 8601 format: yyyy-MM-ddTHH:mm:ss if ommited current utc time is used - /// @param country An ISO 3166-1 alpha-2 country code, Provide this to ensure that the category exists for a particular country. - /// @param locale The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, joined by an underscore, if ommited the response defaults to American English - /// @return response object containing http status code and reply - response get_featured_playlists( int limit = 10, int offset = 0, char* timestamp = nullptr, char* country = nullptr, char* locale = nullptr); - /// @brief Get a list of Spotify playlists tagged with a particular category. - /// @param category_id Category ID can be got from get_several_browse_categories - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @param country The country: an ISO 3166-1 alpha-2 country code, Provide this to ensure that the category exists for a particular country. - /// @return response object containing http status code and reply - response get_category_playlists(char* category_id, int limit = 10, int offset = 0, char* country = nullptr); - /// @brief Get a cover image of a playlist - /// @param playlist_id Id of the playlist - /// @return response object containing http status code and reply - response get_playlist_cover_image(char* playlist_id); - /// @brief Upload a custom cover image of a playlist - /// @param playlist_id Id of the playlist - /// @param data Image data - /// @param market An ISO 3166-1 alpha-2 country code, Provide this parameter if you want to apply Track Relinking - /// @return response object containing http status code and reply - response add_custom_playlist_cover_image(char* playlist_id, char* data); - #endif - #ifdef ENABLE_SEARCH - /// @brief Search for an item - /// @param q Search query keywords and optional field filters and operators - /// @param type_size Number of item types in type array - /// @param type An array of item types to search across - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @param market An ISO 3166-1 alpha-2 country code or the string from_token. Provide this parameter if you want the list of returned items to be relevant to a particular country. - /// @return response object containing http status code and reply - response search(char* q,int type_size , char** type , int limit = 10, int offset = 0, char* market = nullptr); - #endif - #ifdef ENABLE_SHOWS - /// @brief Get Spotify information for a single show - /// @param show_id Spotify ID of the show - /// @return response object containing http status code and reply - response get_show(char* show_id); - /// @brief Get Spotify information for multiple shows - /// @param size Number of show ids in show_ids array - /// @param show_ids Array of Spotify IDs of the shows - /// @return response object containing http status code and reply - response get_several_shows(int size, char** show_ids); - /// @brief Get Spotify information about a show's episodes - /// @param show_id Spotify ID of the show - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_show_episodes(char* show_id, int limit = 10, int offset = 0); - /// @brief Get users saved shows - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_users_saved_shows(int limit = 10, int offset = 0); - /// @brief Save one or more shows to the current user's music library - /// @param size Number of show ids in show_ids array - /// @param show_ids Array of Spotify IDs of the shows - /// @return response object containing http status code and reply - response save_shows_for_current_user(int size, char** show_ids); - /// @brief Remove one or more shows from the current user's music library - /// @param size Number of show ids in show_ids array - /// @param show_ids Array of Spotify IDs of the shows - /// @return response object containing http status code and reply - response remove_shows_for_current_user(int size, char** show_ids); - /// @brief Check if one or more shows is already saved in the current Spotify user's music library - /// @param size Number of show ids in show_ids array - /// @param show_ids Array of Spotify IDs of the shows - /// @return response object containing http status code and reply - response check_users_saved_shows(int size, char** show_ids); - #endif - #ifdef ENABLE_TRACKS - /// @brief Get Spotify information for a single track - /// @param track_id Spotify ID of the track - /// @return response object containing http status code and reply - response get_track(char* track_id); - /// @brief Get Spotify information for multiple tracks - /// @param size Number of track ids in track_ids array - /// @param track_ids Array of Spotify IDs of the tracks - /// @return response object containing http status code and reply - response get_several_tracks(int size, char** track_ids); - /// @brief Get users saved tracks - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_user_saved_tracks(int limit = 10, int offset = 0); - /// @brief Save one or more tracks to the current user's music library - /// @param size Number of track ids in track_ids array - /// @param track_ids Array of Spotify IDs of the tracks - /// @return response object containing http status code and reply - response save_tracks_for_current_user(int size, char** track_ids); - /// @brief Remove one or more tracks from the current user's music library - /// @param size Number of track ids in track_ids array - /// @param track_ids Array of Spotify IDs of the tracks - /// @return response object containing http status code and reply - response remove_user_saved_tracks(int size, char** track_ids); - /// @brief Check if one or more tracks is already saved in the current Spotify user's music library - /// @param size Number of track ids in track_ids array - /// @param track_ids Array of Spotify IDs of the tracks - /// @return response object containing http status code and reply - response check_user_saved_tracks(int size, char** track_ids); - /// @brief Get audio features for multiple tracks - /// @param size Number of track ids in track_ids array - /// @param track_ids Array of Spotify IDs of the tracks - /// @return response object containing http status code and reply - response get_tracks_audio_features(int size, char** track_ids); - /// @brief Get audio features for a single track - /// @param track_id Spotify ID of the track - /// @return response object containing http status code and reply - response get_track_audio_features(char* track_id); - /// @brief Get audio analysis for a single track - /// @param track_id Spotify ID of the track - /// @return response object containing http status code and reply - response get_track_audio_analysis(char* track_id); - /// @brief Get a list of new album releases featured in Spotify - /// @param recom Recommendation object containing atleast one seed - /// @param limit The maximum number of items to return - /// @return response object containing http status code and reply - response get_recommendations(recommendations& recom, int limit = 10); - #endif - #ifdef ENABLE_USER - /// @brief Get detailed profile information about the current user (including the current user's username) - /// @return response object containing http status code and reply - response get_current_user_profile(); - /// @brief Get users top items - /// @param type The type of item to get, Valid values are: artists or tracks - /// @param time_range Over what time frame the affinities are computed, Valid values are: long_term, medium_term, short_term - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_user_top_items(char* type, char* time_range = "medium_term", int limit = 10, int offset = 0); - /// @brief Get a users profile - /// @param user_id Id of the user - /// @return response object containing http status code and reply - response get_user_profile(char* user_id); - /// @brief Follow a playlist - /// @param playlist_id The Id of the playlist - /// @param is_public If true the playlist will be included in user's public playlists, if false it will remain private. - /// @return response object containing http status code and reply - response follow_playlist(char* playlist_id, bool is_public); - /// @brief Unfollow a playlist - /// @param playlist_id The Id of the playlist - /// @return response object containing http status code and reply - response unfollow_playlist(char* playlist_id); - /// @brief get users followed artists - /// @param after The last artist ID retrieved from the previous request - /// @param type The ID type, currently only artist is supported - /// @param limit The maximum number of items to return - /// @return response object containing http status code and reply - response get_followed_artists(char* after, char* type = "artist", int limit = 10); - /// @brief Follow artists or users - /// @param type The ID type, artist or user - /// @param size Number of artist or user ids in artist_user_ids array - /// @param artist_user_ids Array of Spotify IDs of the artists or users - /// @return response object containing http status code and reply - response follow_artists_or_users(char* type, int size, char** artist_user_ids); - /// @brief Unfollow artists or users - /// @param type The ID type, artist or user - /// @param size Number of artist or user ids in artist_user_ids array - /// @param artist_user_ids Array of Spotify IDs of the artists or users - /// @return response object containing http status code and reply - response unfollow_artists_or_users(char* type, int size, char** artist_user_ids); - /// @brief Check if users follow artists or users - /// @param type The ID type, artist or user - /// @param size Number of artist or user ids in artist_user_ids array - /// @param artist_user_ids Array of Spotify IDs of the artists or users - /// @return response object containing http status code and reply - response check_if_user_follows_artists_or_users(char* type, int size, char** artist_user_ids); - /// @brief Check if users follow a playlist - /// @param playlist_id The ID of the playlist - /// @param size Number of user ids in user_ids array - /// @param user_ids Array of Spotify IDs of the users - /// @return response object containing http status code and reply - response check_if_users_follow_playlist(char* playlist_id, int size, char** user_ids); - #endif - #ifdef ENABLE_SIMPIFIED - /// @brief Get Current track name - /// @return Current track name as String - String current_track_name(); - /// @brief Get Current track id - /// @return Current track id as String - String current_track_id(); - /// @brief Get Current device id - /// @return Current device id as String - String current_device_id(); - /// @brief Get Current artist names - /// @return Current artist names as String - String current_artist_names(); - /// @brief Get Current device id - /// @param char array to store device id - /// @return Current device id as pointer to char array - char* current_device_id(char* device_id); - /// @brief Get Current track id - /// @param char array to store track id - /// @return Current track id as pointer to char array - char* current_track_id(char* track_id); - /// @brief Get Current track name - /// @param char array to store track name - /// @return Current track name as pointer to char array - char* current_track_name(char* track_name); - /// @brief Get Current artist names - /// @param char array to store artist names - /// @return Current artist names as pointer to char array - char* current_artist_names(char* artist_names); - /// @brief Get if device is playing - /// @return true if device is playing - bool is_playing(); - /// @brief Get if it is possible to modify volume on current device - /// @return true if it is possible to modify volume on current device - bool volume_modifyable(); - #endif - /// @brief Convert ID to URI - /// @param id ID to convert - /// @param type Type of ID - /// @return URI as char - char convert_id_to_uri(char* id, char* type); - /// @brief Convert ID to URI - /// @param id ID to convert - /// @param type Type of ID - /// @param uri char array to store URI - /// @return URI as pointer to char array - char* convert_id_to_uri(char* id, char* type, char* uri); - - private: - WebServer _server; - WiFiClientSecure _client; - const char* _host = "api.spotify.com"; - /// @brief Maximum number of items in one request - static const int _max_num_items = 20; - /// @brief Maximum size of char array(35 been the size of a uri + comma + 150 as buffer for url etc.) - static const int _max_char_size = 35*_max_num_items + 150; - /// @brief Size of a uri - static const int _size_of_uri = 45; - /// @brief Size of an id - static const int _size_of_id = 25; - /// @brief Maximum number of items in one request - int _max_num_retry = 3; - /// @brief Users set redirect uri - char _redirect_uri[100] = ""; - /// @brief Users refresh token - char _refresh_token[200] = ""; - /// @brief user auth code - char _auth_code[800] = ""; - /// @brief Users set client id - const char* _client_id; - /// @brief Users set client secret - const char* _client_secret; - /// @brief Current number of retries - int _retry; - /// @brief Debug mode - bool _debug_on; - /// @brief port - int _port; - /// @brief Access token - String _access_token; - /// @brief Root login Page - void server_on_root(); - /// @brief Get refresh token from auth code - bool get_refresh_token(); - /// @brief Currying function for callback_login_page - friend std::function callback_fn(Spotify *spotify); - /// @brief Get Access Token with refresh token - /// @return Bool if token was successfully retrieved - bool get_token(); - /// @brief Initialize response object - /// @param response_obj Response object to initialize - void init_response(response* response_obj); - /// @brief Make request to Spotify API - /// @param rest_url URL to make request to - /// @param type Type of request - /// @param payload_size Size of payload - /// @param payload Payload to send - response RestApi(char* rest_url, char* type, int payload_size = 0, char* payload = nullptr); - /// @brief Make PUT request to Spotify API - /// @param rest_url URL to make request to - /// @param payload_size Size of payload - /// @param payload Payload to send - /// @return Response object containing http status code and reply - response RestApiPut(char* rest_url, int payload_size = 0, char* payload = nullptr); - /// @brief Make POST request to Spotify API - /// @param rest_url URL to make request to - /// @param payload_size Size of payload - /// @param payload Payload to send - /// @return Response object containing http status code and reply - response RestApiPost(char* rest_url, int payload_size = 0, char* payload = nullptr); - /// @brief Make DELETE request to Spotify API - /// @param rest_url URL to make request to - /// @param payload Payload to send - /// @return Response object containing http status code and reply - response RestApiDelete(char* rest_url, char* payload = nullptr); - /// @brief Make GET request to Spotify API - /// @param rest_url URL to make request to - /// @return Response object containing http status code and reply - response RestApiGet(char* rest_url); - /// @brief Convert array of chars to one char array, seperated by comma - /// @param size Size of array - /// @param array Array to convert - /// @param result Array to store result - /// @return Pointer to result array - char* array_to_char(int size, char** array, char* result); - /// @brief Convert array of chars to one json array - /// @param size Size of array - /// @param array Array to convert - /// @param data Array to store result - /// @param data_size Size of data array - /// @return Pointer to data array - void array_to_json_array(int size, char** array, char* data, int data_size = _max_char_size);//Convert array of chars to one json array - #ifdef ENABLE_TRACKS - /// @brief Check if recommendation value is valid - /// @param param Float value to check - /// @return Bool if value is valid - bool is_valid_value(float param); - /// @brief Check if recommendation value is valid - /// @param param Int value to check - /// @return Bool if value is valid - bool is_valid_value(int param); - /// @brief Populate recommendation char values - /// @param map Map to populate - /// @param recom recommendation object - /// @return Void - void populate_char_values(std::map& map, recommendations& recom); - /// @brief Populate recommendation float values - /// @param map Map to populate - /// @param recom recommendation object - /// @return Void - void populate_float_values(std::map& map, recommendations& recom); - #endif - /// @brief Extract endpoint from url with regex - const char * extract_endpoint(const char* rest_url); - /// @brief Root CA for Spotify API - const char* _spotify_root_ca PROGMEM= \ - "-----BEGIN CERTIFICATE-----\n"\ - "MIIEyDCCA7CgAwIBAgIQDPW9BitWAvR6uFAsI8zwZjANBgkqhkiG9w0BAQsFADBh\n"\ - "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"\ - "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\n"\ - "MjAeFw0yMTAzMzAwMDAwMDBaFw0zMTAzMjkyMzU5NTlaMFkxCzAJBgNVBAYTAlVT\n"\ - "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMzAxBgNVBAMTKkRpZ2lDZXJ0IEdsb2Jh\n"\ - "bCBHMiBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTCCASIwDQYJKoZIhvcNAQEBBQAD\n"\ - "ggEPADCCAQoCggEBAMz3EGJPprtjb+2QUlbFbSd7ehJWivH0+dbn4Y+9lavyYEEV\n"\ - "cNsSAPonCrVXOFt9slGTcZUOakGUWzUb+nv6u8W+JDD+Vu/E832X4xT1FE3LpxDy\n"\ - "FuqrIvAxIhFhaZAmunjZlx/jfWardUSVc8is/+9dCopZQ+GssjoP80j812s3wWPc\n"\ - "3kbW20X+fSP9kOhRBx5Ro1/tSUZUfyyIxfQTnJcVPAPooTncaQwywa8WV0yUR0J8\n"\ - "osicfebUTVSvQpmowQTCd5zWSOTOEeAqgJnwQ3DPP3Zr0UxJqyRewg2C/Uaoq2yT\n"\ - "zGJSQnWS+Jr6Xl6ysGHlHx+5fwmY6D36g39HaaECAwEAAaOCAYIwggF+MBIGA1Ud\n"\ - "EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFHSFgMBmx9833s+9KTeqAx2+7c0XMB8G\n"\ - "A1UdIwQYMBaAFE4iVCAYlebjbuYP+vq5Eu0GF485MA4GA1UdDwEB/wQEAwIBhjAd\n"\ - "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYIKwYBBQUHAQEEajBoMCQG\n"\ - "CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQAYIKwYBBQUHMAKG\n"\ - "NGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RH\n"\ - "Mi5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29t\n"\ - "L0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDA9BgNVHSAENjA0MAsGCWCGSAGG/WwC\n"\ - "ATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgGBmeBDAECAzANBgkqhkiG\n"\ - "9w0BAQsFAAOCAQEAkPFwyyiXaZd8dP3A+iZ7U6utzWX9upwGnIrXWkOH7U1MVl+t\n"\ - "wcW1BSAuWdH/SvWgKtiwla3JLko716f2b4gp/DA/JIS7w7d7kwcsr4drdjPtAFVS\n"\ - "slme5LnQ89/nD/7d+MS5EHKBCQRfz5eeLjJ1js+aWNJXMX43AYGyZm0pGrFmCW3R\n"\ - "bpD0ufovARTFXFZkAdl9h6g4U5+LXUZtXMYnhIHUfoyMo5tS58aI7Dd8KvvwVVo4\n"\ - "chDYABPPTHPbqjc1qCmBaZx2vN4Ye5DUys/vZwP9BFohFrH/6j/f3IL16/RZkiMN\n"\ - "JCqVJUzKoZHm1Lesh3Sz8W2jmdv51b2EQJ8HmA==\n"\ - "-----END CERTIFICATE-----\n"; - - const char* _login_page PROGMEM = R"=====( - - - ESP Spotify Login - - -
-

Spotify Login

- Log in to spotify -
- - - )====="; -}; -#endif \ No newline at end of file diff --git a/Spotify_v3/src/config.h b/Spotify_v3/src/config.h deleted file mode 100644 index 48866be..0000000 --- a/Spotify_v3/src/config.h +++ /dev/null @@ -1,8 +0,0 @@ -const char* SSID = "Rebweg10D"; -const char* PASSWORD = "Bitte_eintreten"; -/*const char* SSID = "rdv-66754"; -const char* PASSWORD = "1234567890";*/ -const char* CLIENT_ID = "4a60dc25e5eb43e29161a0b00d296ff7"; -const char* CLIENT_SECRET = "d65a695928b34a4ea3a0e66d9120b911"; -const char* REFRESH_TOKEN = "AQC_3lM_jUt1Zgag5UO4qtOZcqCHSprkjsq6tvamaH2nXjn5xSyU0yuFXpi1M1YTNPyHEaBHpe1nWTOA_PkalojPGY8XfxS0kxFjFaZxbE2B4sQvVvSfgi6JIZrwYIwWYuo"; -int PORT = 8000; \ No newline at end of file diff --git a/Spotify_v3/src/main.cpp b/Spotify_v3/src/main.cpp deleted file mode 100644 index b9d65d9..0000000 --- a/Spotify_v3/src/main.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include -#include "SpotifyESP32.h" -#include "config.h" -using namespace Spotify_types; - -void connect_to_wifi(); -void check_all(); -void check_one(response r); -Spotify sp(CLIENT_ID, CLIENT_SECRET,REFRESH_TOKEN, false); - -void setup() { - Serial.begin(115200); - connect_to_wifi(); - sp.begin(); - while(!sp.is_auth()){ - sp.handle_client(); - } - Serial.println("Authenticated"); - Serial.println(sp.current_artist_names()); - Serial.println("Done"); -} - -void loop() { - // put your main code here, to run repeatedly: -} -void connect_to_wifi(){ - WiFi.begin(SSID, PASSWORD); - Serial.print("Connecting to WiFi..."); - while (WiFi.status() != WL_CONNECTED) { - delay(1000); - Serial.print("."); - } - Serial.printf("\nConnected to WiFi\n"); -} -void check_all(){ - Serial.println("Player"); - check_one(sp.currently_playing()); - /*check_one(sp.start_resume_playback("spotify:track:6xaMXvpkmVow1RAinlthUT")); - check_one(sp.pause_playback()); - check_one(sp.start_resume_playback()); - check_one(sp.skip()); - check_one(sp.previous()); - check_one(sp.available_devices()); - check_one(sp.current_playback_state()); - check_one(sp.recently_played_tracks()); - check_one(sp.seek_to_position(1000)); - check_one(sp.add_to_queue("spotify:track:6xaMXvpkmVow1RAinlthUT")); - check_one(sp.get_queue()); - check_one(sp.repeat_mode(REPEAT_OFF)); - check_one(sp.shuffle(SHUFFLE_ON)); - check_one(sp.transfer_playback("956f01ff586ece9abaa152dd26bc5cc565be5a22")); - check_one(sp.set_volume(100)); - Serial.println("Album"); - check_one(sp.get_album("22pMyI5Ra0xRPDpf21ZWNb")); - char* albums[] = {"22pMyI5Ra0xRPDpf21ZWNb", "5AXd8wp7NNydXNzFAxlXmf"}; - check_one(sp.get_albums(2, albums)); - check_one(sp.get_album_tracks("22pMyI5Ra0xRPDpf21ZWNb")); - check_one(sp.get_users_saved_albums()); - check_one(sp.remove_users_saved_albums(2, albums)); - check_one(sp.save_albums_for_current_user(2, albums)); - check_one(sp.check_useres_saved_albums(2, albums)); - check_one(sp.get_new_releases()); - Serial.println("Artist"); - check_one(sp.get_artist("7keGfmQR4X5w0two1xKZ7d")); - char* artists[] = {"7keGfmQR4X5w0two1xKZ7d", "6LtXxYMIiKSy2EGHnz1f5j"}; - check_one(sp.get_several_artists(2, artists)); - char * group[] = {GROUP_ALBUM, GROUP_SINGLE, GROUP_APPEARS_ON, GROUP_COMPILATION}; - check_one(sp.get_artist_albums("7keGfmQR4X5w0two1xKZ7d", 4, group)); - check_one(sp.get_artist_top_tracks("7keGfmQR4X5w0two1xKZ7d", "DE")); - check_one(sp.get_artist_related_artist("7keGfmQR4X5w0two1xKZ7d")); - Serial.println("Browse"); - check_one(sp.get_several_browse_categories()); - check_one(sp.get_single_browse_category("dinner")); - Serial.println("Episode"); - check_one(sp.get_episode("3mbWNOW6PwYGrXANw2JJDU")); - char* episodes[] = {"3mbWNOW6PwYGrXANw2JJDU", "4hwEvITXPZvcvL8UCVEp6Q"}; - check_one(sp.get_several_episodes(2, episodes)); - check_one(sp.get_users_saved_episodes()); - check_one(sp.save_episodes_for_current_user(2, episodes)); - check_one(sp.remove_episodes_for_current_user(2, episodes)); - check_one(sp.check_users_saved_episodes(2, episodes)); - Serial.println("Markets and Genres"); - check_one(sp.get_available_genre_seeds()); - check_one(sp.get_available_markets()); - Serial.println("Playlists"); - check_one(sp.get_playlist("37i9dQZF1EQn4jwNIohw50")); - check_one(sp.change_playlist_details("39Swnx8UEHw4FK9FlQHCov", "New Name", false, false, "New Description")); - check_one(sp.get_playlist_items("37i9dQZF1EQn4jwNIohw50","items(added_by.id,track(name,href,album(name,href)))")); - char* tracks[] = {"spotify:track:6xaMXvpkmVow1RAinlthUT", "spotify:track:6xaMXvpkmVow1RAinlthUT"}; - check_one(sp.update_playlist_items("39Swnx8UEHw4FK9FlQHCov", 2, tracks)); - check_one(sp.remove_playlist_items("39Swnx8UEHw4FK9FlQHCov", 2, tracks)); - check_one(sp.add_items_to_playlist("39Swnx8UEHw4FK9FlQHCov", 2, tracks)); - check_one(sp.get_current_users_playlists()); - check_one(sp.get_user_playlists("spotify")); - check_one(sp.create_playlist("adix3gjuq0g570rwufhfcw89o","New Playlist", false,true, "New Description")); - check_one(sp.get_featured_playlists()); - check_one(sp.get_category_playlists("dinner")); - check_one(sp.get_playlist_cover_image("37i9dQZF1EQn4jwNIohw50")); - check_one(sp.add_custom_playlist_cover_image("39Swnx8UEHw4FK9FlQHCov", "/9j/2wCEABoZGSccJz4lJT5CLy8vQkc9Ozs9R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0cBHCcnMyYzPSYmPUc9Mj1HR0dEREdHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR//dAAQAAf/uAA5BZG9iZQBkwAAAAAH/wAARCAABAAEDACIAAREBAhEB/8QASwABAQAAAAAAAAAAAAAAAAAAAAYBAQAAAAAAAAAAAAAAAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAARAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwAAARECEQA/AJgAH//Z")); - Serial.println("Search"); - char* types[] = {TYPE_ALBUM, TYPE_ARTIST, TYPE_PLAYLIST, TYPE_TRACK}; - check_one(sp.search("remaster%2520track%3ADoxy%2520artist%3AMiles%2520Davis", 4, types)); - Serial.println("Shows"); - check_one(sp.get_show("5icRmO26ZsDWsNjUy5rssH")); - char* shows[] = {"5icRmO26ZsDWsNjUy5rssH", "3wBfqov60qDZbEVjPHo0a8"}; - check_one(sp.get_several_shows(2, shows)); - check_one(sp.get_show_episodes("5icRmO26ZsDWsNjUy5rssH")); - check_one(sp.get_users_saved_shows()); - check_one(sp.save_shows_for_current_user(2, shows)); - check_one(sp.remove_shows_for_current_user(2, shows)); - check_one(sp.check_users_saved_shows(2, shows)); - Serial.println("Tracks"); - check_one(sp.get_track("49A10weBfgwg4TUM3My7iv")); - char* tracks[] = {"49A10weBfgwg4TUM3My7iv", "3qhlB30KknSejmIvZZLjOD"}; - check_one(sp.get_several_tracks(2, tracks)); - check_one(sp.get_user_saved_tracks()); - check_one(sp.save_tracks_for_current_user(2, tracks)); - check_one(sp.remove_user_saved_tracks(2, tracks)); - check_one(sp.check_user_saved_tracks(2, tracks)); - check_one(sp.get_tracks_audio_features(2, tracks)); - check_one(sp.get_track_audio_analysis("49A10weBfgwg4TUM3My7iv")); - check_one(sp.get_track_audio_features("49A10weBfgwg4TUM3My7iv")); - recommendations r; - char* seed_artists[] = {"4NHQUGzhtTLFvgF5SZesLK"}; - r.seed_artists = seed_artists; - r.seed_artists_size = 1; - r.target_acousticness = 0.5; - r.target_danceability = 0.5; - check_one(sp.get_recommendations(r, 2)); - Serial.println("User"); - check_one(sp.get_current_user_profile()); - check_one(sp.get_user_profile("spotify")); - check_one(sp.get_user_top_items(TOP_TYPE_ARTIST)); - check_one(sp.follow_playlist("37i9dQZF1EQn4jwNIohw50", false)); - check_one(sp.unfollow_playlist("37i9dQZF1EQn4jwNIohw50")); - char* users[] = {"spotify"}; - check_one(sp.check_if_users_follow_playlist("37i9dQZF1EQn4jwNIohw50",1, users)); - check_one(sp.get_followed_artists("")); - check_one(sp.follow_artists_or_users(FOLLOW_TYPE_USER, 1, users)); - check_one(sp.unfollow_artists_or_users(FOLLOW_TYPE_USER, 1, users)); - check_one(sp.check_if_user_follows_artists_or_users(FOLLOW_TYPE_USER, 1, users));*/ -} -void check_one(response r){ - if(r.status_code < 200 or r.status_code > 300){ - Serial.printf("Error: %d\n", r.status_code); - Serial.println(r.reply); - } -} \ No newline at end of file diff --git a/Spotify_v3/test/README b/Spotify_v3/test/README deleted file mode 100644 index 9b1e87b..0000000 --- a/Spotify_v3/test/README +++ /dev/null @@ -1,11 +0,0 @@ - -This directory is intended for PlatformIO Test Runner and project tests. - -Unit Testing is a software testing method by which individual units of -source code, sets of one or more MCU program modules together with associated -control data, usage procedures, and operating procedures, are tested to -determine whether they are fit for use. Unit testing finds problems early -in the development cycle. - -More information about PlatformIO Unit Testing: -- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html