diff --git a/SpotifyDemo/CMakeLists.txt b/SpotifyDemo/CMakeLists.txt index c2411e0..1d37463 100644 --- a/SpotifyDemo/CMakeLists.txt +++ b/SpotifyDemo/CMakeLists.txt @@ -14,16 +14,16 @@ find_path (CPPCODEC_INCLUDE_DIRS "cppcodec/base32_crockford.hpp") set (SOURCES - "${CMAKE_CURRENT_SOURCE_DIR}/src/SpotifyDemo.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/src/SpotifyDemo.cpp" ) set (SD_INCLUDE_DIR - "${CMAKE_CURRENT_SOURCE_DIR}/include" - ) + "${CMAKE_CURRENT_SOURCE_DIR}/include" + ) set (HEADERS - "${SD_INCLUDE_DIR}/Models.h" + "${SD_INCLUDE_DIR}/Models.h" ) include_directories ("${SD_INCLUDE_DIR}") diff --git a/SpotifyDemo/client_information.json b/SpotifyDemo/client_information.json index 93adec0..0cf1a8f 100644 --- a/SpotifyDemo/client_information.json +++ b/SpotifyDemo/client_information.json @@ -1,4 +1,4 @@ { "client_id": "id", "client_secret": "secret" -} \ No newline at end of file +} diff --git a/SpotifyDemo/include/Models.h b/SpotifyDemo/include/Models.h index 16e9f27..a1e76dd 100644 --- a/SpotifyDemo/include/Models.h +++ b/SpotifyDemo/include/Models.h @@ -6,71 +6,71 @@ namespace Models { - template - class Song - { - public: - Song() = default; + template + class Song + { + public: + Song() = default; - Str title; - Str artist; - Str album; - Str released; - Dur duration; - }; + Str title; + Str artist; + Str album; + Str released; + Dur duration; + }; - template - class Album - { - public: - Album() = default; + template + class Album + { + public: + Album() = default; - Str title; - Str released; - std::vector> songs; - }; + Str title; + Str released; + std::vector> songs; + }; - template - class ClientInformation - { - public: - ClientInformation() = default; - ClientInformation(Str& id, Str& secret) : - client_id(std::move(id)), client_secret(std::move(secret)) - { - } - ClientInformation(Str&& id, Str&& secret) : - client_id(id), client_secret(secret) - { - } + template + class ClientInformation + { + public: + ClientInformation() = default; + ClientInformation(Str& id, Str& secret) : + client_id(std::move(id)), client_secret(std::move(secret)) + { + } + ClientInformation(Str&& id, Str&& secret) : + client_id(id), client_secret(secret) + { + } - auto is_empty() - { - return (client_id.empty() && client_secret.empty()) ? true : false; - } + auto is_empty() + { + return (client_id.empty() && client_secret.empty()) ? true : false; + } - Str client_id; - Str client_secret; - }; + Str client_id; + Str client_secret; + }; - template - class TokenResp - { - public: - auto is_empty() - { - return this->access_token.empty(); - } + template + class TokenResp + { + public: + auto is_empty() + { + return this->access_token.empty(); + } - Str access_token; - Str token_type; - Num expires_in; - Str scope; - }; + Str access_token; + Str token_type; + Num expires_in; + Str scope; + }; } -#endif \ No newline at end of file +#endif diff --git a/SpotifyDemo/include/SpotifyCall.hpp b/SpotifyDemo/include/SpotifyCall.hpp index 47089de..276c176 100644 --- a/SpotifyDemo/include/SpotifyCall.hpp +++ b/SpotifyDemo/include/SpotifyCall.hpp @@ -13,163 +13,163 @@ namespace Spotify { - template> - class SpotifyCall - { - public: - SpotifyCall() = default; - SpotifyCall(Tok& tok) : token(tok) - { - } - SpotifyCall(Tok&& tok) : token(std::move(tok)) - { - } + template> + class SpotifyCall + { + public: + SpotifyCall() = default; + SpotifyCall(Tok& tok) : token(tok) + { + } + SpotifyCall(Tok&& tok) : token(std::move(tok)) + { + } - template - auto search_songs(Str&& title) - { - constexpr auto limit = 49; + template + auto search_songs(Str&& title) + { + constexpr auto limit = 49; - std::vector> albums; - albums.reserve(limit); + std::vector> albums; + albums.reserve(limit); - std::string search_query("name:"); - search_query.append(delimit_search_query(title)); - + std::string search_query("name:"); + search_query.append(delimit_search_query(title)); + - const auto uri = search_uri(); - const auto authorization = bearer_authorization(); + const auto uri = search_uri(); + const auto authorization = bearer_authorization(); - Str limit_str(std::to_string(limit)); + Str limit_str(std::to_string(limit)); - auto resp = cpr::Get(cpr::Url{ uri }, - cpr::Parameters{ {"type", "track"}, - {"limit", limit_str}, - {"q", search_query} }, - cpr::Header{ {"Authorization", authorization.c_str()} }); + auto resp = cpr::Get(cpr::Url{ uri }, + cpr::Parameters{ {"type", "track"}, + {"limit", limit_str}, + {"q", search_query} }, + cpr::Header{ {"Authorization", authorization.c_str()} }); - if (resp.status_code == 200) { - parse_albums(albums, std::move(resp.text)); - } + if (resp.status_code == 200) { + parse_albums(albums, std::move(resp.text)); + } - return albums; - } + return albums; + } - template>> - void print_songs_to_console(Cont &albums) - { - std::cout << "Printing songs to the console\n"; + template>> + void print_songs_to_console(Cont &albums) + { + std::cout << "Printing songs to the console\n"; - std::for_each(albums.begin(), albums.end(), [](auto album) { - auto song = album.songs.at(0); + std::for_each(albums.begin(), albums.end(), [](auto album) { + auto song = album.songs.at(0); - std::cout << "Title: " << song.title << "\n"; - std::cout << "Artist: " << song.artist << "\n"; - std::cout << "Album: " << album.title << "\n"; - std::cout << "Released Date: " << song.released << "\n"; - std::cout << "Duration (ms): " << song.duration << "\n"; - std::cout << "\n"; - }); + std::cout << "Title: " << song.title << "\n"; + std::cout << "Artist: " << song.artist << "\n"; + std::cout << "Album: " << album.title << "\n"; + std::cout << "Released Date: " << song.released << "\n"; + std::cout << "Duration (ms): " << song.duration << "\n"; + std::cout << "\n"; + }); - std::cout << "\n"; - } + std::cout << "\n"; + } - private: - template - auto delimit_search_query(Str &&title) - { - return std::regex_replace(title, std::regex(" "), "%20"); - } + private: + template + auto delimit_search_query(Str &&title) + { + return std::regex_replace(title, std::regex(" "), "%20"); + } - auto bearer_authorization() - { - std::string authorization("Bearer "); - authorization.append(this->token.access_token); + auto bearer_authorization() + { + std::string authorization("Bearer "); + authorization.append(this->token.access_token); - return authorization; - } + return authorization; + } - template, typename Vec = std::vector, - typename Str = std::string> - void parse_albums(Vec &alb, Str &&resp) - { - auto obj = nlohmann::json::parse(resp); + template, typename Vec = std::vector, + typename Str = std::string> + void parse_albums(Vec &alb, Str &&resp) + { + auto obj = nlohmann::json::parse(resp); - for (auto& item : obj["tracks"]["items"]) { - auto album_json = item["album"]; - auto artists_json = item["artists"]; + for (auto& item : obj["tracks"]["items"]) { + auto album_json = item["album"]; + auto artists_json = item["artists"]; - Alb album; - album.title = album_json["name"].get(); - album.released = album_json["release_date"].get(); + Alb album; + album.title = album_json["name"].get(); + album.released = album_json["release_date"].get(); - Models::Song<> song; - song.title = item["name"].get(); - song.duration = item["duration_ms"].get(); - song.artist = artists_json[0]["name"].get(); - song.released = album.released; - song.album = album.title; + Models::Song<> song; + song.title = item["name"].get(); + song.duration = item["duration_ms"].get(); + song.artist = artists_json[0]["name"].get(); + song.released = album.released; + song.album = album.title; - std::vector> songs; - songs.push_back(song); + std::vector> songs; + songs.push_back(song); - album.songs = songs; + album.songs = songs; - alb.push_back(album); - } - } + alb.push_back(album); + } + } - auto saved_albums_response_body() - { - nlohmann::json obj; + auto saved_albums_response_body() + { + nlohmann::json obj; - std::string uri(base_uri()); - uri.append("/"); - uri.append(album_saved()); + std::string uri(base_uri()); + uri.append("/"); + uri.append(album_saved()); - std::string auth_header("Bearer "); - auth_header.append(this->token.access_token); + std::string auth_header("Bearer "); + auth_header.append(this->token.access_token); - auto resp = cpr::Get(cpr::Url(uri), - cpr::Header{{"Authorization", auth_header.c_str()}} - ); + auto resp = cpr::Get(cpr::Url(uri), + cpr::Header{{"Authorization", auth_header.c_str()}} + ); - if (resp.status_code == 200) { - obj = nlohmann::json::parse(resp.text); - } + if (resp.status_code == 200) { + obj = nlohmann::json::parse(resp.text); + } - return obj; - } + return obj; + } - template - auto search_uri() - { - Str uri(base_uri()); - uri.append("/"); - uri.append(search_item_endpoint()); + template + auto search_uri() + { + Str uri(base_uri()); + uri.append("/"); + uri.append(search_item_endpoint()); - return uri; - } + return uri; + } - constexpr auto base_uri() noexcept - { - return "https://api.spotify.com/v1"; - } + constexpr auto base_uri() noexcept + { + return "https://api.spotify.com/v1"; + } - constexpr auto album_saved() noexcept - { - return "me/albums"; - } - constexpr auto search_item_endpoint() noexcept - { - return "search"; - } + constexpr auto album_saved() noexcept + { + return "me/albums"; + } + constexpr auto search_item_endpoint() noexcept + { + return "search"; + } - Tok token; - }; + Tok token; + }; } -#endif \ No newline at end of file +#endif diff --git a/SpotifyDemo/include/TokenRetrieval.hpp b/SpotifyDemo/include/TokenRetrieval.hpp index 1466b98..c707190 100644 --- a/SpotifyDemo/include/TokenRetrieval.hpp +++ b/SpotifyDemo/include/TokenRetrieval.hpp @@ -14,100 +14,100 @@ namespace Manager { - template - class TokenRetrieval - { - public: - TokenRetrieval() = default; - TokenRetrieval(Models::ClientInformation &info) : - client_information(std::move(info)) - { - } - TokenRetrieval(Models::ClientInformation &&info) : - client_information(info) - { - } + template + class TokenRetrieval + { + public: + TokenRetrieval() = default; + TokenRetrieval(Models::ClientInformation &info) : + client_information(std::move(info)) + { + } + TokenRetrieval(Models::ClientInformation &&info) : + client_information(info) + { + } - template - auto retrieve_token() - { - if (this->client_information.is_empty()) { - return TokResp(); - } + template + auto retrieve_token() + { + if (this->client_information.is_empty()) { + return TokResp(); + } - auto token = make_call(); + auto token = make_call(); - return (token.is_empty()) ? TokResp() : token; - } + return (token.is_empty()) ? TokResp() : token; + } - private: - template - auto make_call() - { - TokResp resp; + private: + template + auto make_call() + { + TokResp resp; - Str authorization("Basic "); - authorization.append(encoded_authorization()); + Str authorization("Basic "); + authorization.append(encoded_authorization()); - const auto uri = construct_uri(spotify_uri(), spotify_token_endpoint()); - auto r = cpr::Post(cpr::Url{ uri }, - cpr::Parameters{ {"grant_type", "client_credentials" }}, - cpr::Header{ {"Authorization", authorization.c_str()} } - ); + const auto uri = construct_uri(spotify_uri(), spotify_token_endpoint()); + auto r = cpr::Post(cpr::Url{ uri }, + cpr::Parameters{ {"grant_type", "client_credentials" }}, + cpr::Header{ {"Authorization", authorization.c_str()} } + ); - if (r.status_code == 200) { - auto token = nlohmann::json::parse(r.text); - resp.access_token = token["access_token"].get(); - resp.token_type = token["token_type"].get(); - resp.expires_in = token["expires_in"].get(); - resp.scope = token["scope"].get(); - } + if (r.status_code == 200) { + auto token = nlohmann::json::parse(r.text); + resp.access_token = token["access_token"].get(); + resp.token_type = token["token_type"].get(); + resp.expires_in = token["expires_in"].get(); + resp.scope = token["scope"].get(); + } - return resp; - } + return resp; + } - auto encoded_authorization() - { - Str unencoded(client_information.client_id); - unencoded.append(":"); - unencoded.append(client_information.client_secret); + auto encoded_authorization() + { + Str unencoded(client_information.client_id); + unencoded.append(":"); + unencoded.append(client_information.client_secret); - std::vector v(unencoded.begin(), unencoded.end()); + std::vector v(unencoded.begin(), unencoded.end()); - return cppcodec::base64_rfc4648::encode(v); - } + return cppcodec::base64_rfc4648::encode(v); + } - template - auto construct_uri(Ch *base, Ch *endpoint) - { - Str uri(base); + template + auto construct_uri(Ch *base, Ch *endpoint) + { + Str uri(base); - if (uri.at(uri.size() - 1) != '/') { - uri.append("/"); - } + if (uri.at(uri.size() - 1) != '/') { + uri.append("/"); + } - uri.append(endpoint); + uri.append(endpoint); - return uri; - } + return uri; + } - auto constexpr spotify_uri() noexcept - { - return "https://accounts.spotify.com"; - } + auto constexpr spotify_uri() noexcept + { + return "https://accounts.spotify.com"; + } - auto constexpr spotify_token_endpoint() noexcept - { - return "api/token"; - } + auto constexpr spotify_token_endpoint() noexcept + { + return "api/token"; + } - Models::ClientInformation client_information; - }; + Models::ClientInformation client_information; + }; } -#endif \ No newline at end of file +#endif diff --git a/SpotifyDemo/src/SpotifyDemo.cpp b/SpotifyDemo/src/SpotifyDemo.cpp index 4636e41..6ffc877 100644 --- a/SpotifyDemo/src/SpotifyDemo.cpp +++ b/SpotifyDemo/src/SpotifyDemo.cpp @@ -19,47 +19,47 @@ using namespace Models; template auto retrieve_client_information(Str &&path) { - std::fstream config_file(path, std::ios::in); + std::fstream config_file(path, std::ios::in); - std::stringstream buffer; - buffer << config_file.rdbuf(); + std::stringstream buffer; + buffer << config_file.rdbuf(); - config_file.close(); + config_file.close(); - auto client_json = nlohmann::json::parse(buffer.str()); - std::string id(client_json["client_id"].get()); - std::string secret(client_json["client_secret"].get()); + auto client_json = nlohmann::json::parse(buffer.str()); + std::string id(client_json["client_id"].get()); + std::string secret(client_json["client_secret"].get()); - Conf client_information(std::move(id), std::move(secret)); + Conf client_information(std::move(id), std::move(secret)); - return client_information; + return client_information; } int main(int argc, char **argv) { - std::cout << "Starting SpotfyDemo\n"; + std::cout << "Starting SpotfyDemo\n"; - if (argc < 2) { - std::cout << "Provide path to the client information json file\n"; + if (argc < 2) { + std::cout << "Provide path to the client information json file\n"; - return -1; - } + return -1; + } - std::string path(std::move(argv[1])); + std::string path(std::move(argv[1])); - auto client_info = retrieve_client_information, - std::string>(std::move(path)); + auto client_info = retrieve_client_information, + std::string>(std::move(path)); - Manager::TokenRetrieval<> tok_mgr(std::move(client_info)); - auto resp = tok_mgr.retrieve_token>(); + Manager::TokenRetrieval<> tok_mgr(std::move(client_info)); + auto resp = tok_mgr.retrieve_token>(); - Spotify::SpotifyCall<> spotify(std::move(resp)); - std::string song_title("Heave"); + Spotify::SpotifyCall<> spotify(std::move(resp)); + std::string song_title("Heave"); - auto albums = spotify.search_songs(song_title); - spotify.print_songs_to_console(albums); + auto albums = spotify.search_songs(song_title); + spotify.print_songs_to_console(albums); - return 0; + return 0; }