Formatting changes

This commit is contained in:
kdeng00
2020-11-28 18:38:29 -05:00
parent 5f22129462
commit 9ecb23ade3
6 changed files with 281 additions and 281 deletions
+4 -4
View File
@@ -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}")
+57 -57
View File
@@ -6,71 +6,71 @@
namespace Models
{
template<typename Str = std::string,
typename Num = int,
typename Dur = long>
class Song
{
public:
Song() = default;
template<typename Str = std::string,
typename Num = int,
typename Dur = long>
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<typename Str = std::string,
typename Num = int>
class Album
{
public:
Album() = default;
template<typename Str = std::string,
typename Num = int>
class Album
{
public:
Album() = default;
Str title;
Str released;
std::vector<Song<>> songs;
};
Str title;
Str released;
std::vector<Song<>> songs;
};
template<typename Str = std::string>
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<typename Str = std::string>
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<typename Str = std::string,
typename Num = int>
class TokenResp
{
public:
auto is_empty()
{
return this->access_token.empty();
}
template<typename Str = std::string,
typename Num = int>
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
+120 -120
View File
@@ -13,163 +13,163 @@
namespace Spotify
{
template<typename Tok = Models::TokenResp<std::string>>
class SpotifyCall
{
public:
SpotifyCall() = default;
SpotifyCall(Tok& tok) : token(tok)
{
}
SpotifyCall(Tok&& tok) : token(std::move(tok))
{
}
template<typename Tok = Models::TokenResp<std::string>>
class SpotifyCall
{
public:
SpotifyCall() = default;
SpotifyCall(Tok& tok) : token(tok)
{
}
SpotifyCall(Tok&& tok) : token(std::move(tok))
{
}
template<typename Str = std::string>
auto search_songs(Str&& title)
{
constexpr auto limit = 49;
template<typename Str = std::string>
auto search_songs(Str&& title)
{
constexpr auto limit = 49;
std::vector<Models::Album<>> albums;
albums.reserve(limit);
std::vector<Models::Album<>> 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<typename Cont = std::vector<Models::Album<std::string>>>
void print_songs_to_console(Cont &albums)
{
std::cout << "Printing songs to the console\n";
template<typename Cont = std::vector<Models::Album<std::string>>>
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<typename Str = std::string>
auto delimit_search_query(Str &&title)
{
return std::regex_replace(title, std::regex(" "), "%20");
}
private:
template<typename Str = std::string>
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 Alb = Models::Album<>, typename Vec = std::vector<Alb>,
typename Str = std::string>
void parse_albums(Vec &alb, Str &&resp)
{
auto obj = nlohmann::json::parse(resp);
template<typename Alb = Models::Album<>, typename Vec = std::vector<Alb>,
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<std::string>();
album.released = album_json["release_date"].get<std::string>();
Alb album;
album.title = album_json["name"].get<std::string>();
album.released = album_json["release_date"].get<std::string>();
Models::Song<> song;
song.title = item["name"].get<std::string>();
song.duration = item["duration_ms"].get<long>();
song.artist = artists_json[0]["name"].get<std::string>();
song.released = album.released;
song.album = album.title;
Models::Song<> song;
song.title = item["name"].get<std::string>();
song.duration = item["duration_ms"].get<long>();
song.artist = artists_json[0]["name"].get<std::string>();
song.released = album.released;
song.album = album.title;
std::vector<Models::Song<>> songs;
songs.push_back(song);
std::vector<Models::Song<>> 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<typename Str = std::string>
auto search_uri()
{
Str uri(base_uri());
uri.append("/");
uri.append(search_item_endpoint());
template<typename Str = std::string>
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
+71 -71
View File
@@ -14,99 +14,99 @@
namespace Manager
{
template<typename Str = std::string>
class TokenRetrieval
{
public:
TokenRetrieval() = default;
TokenRetrieval(Models::ClientInformation<Str> &info) :
client_information(std::move(info))
{
}
TokenRetrieval(Models::ClientInformation<Str> &&info) :
client_information(info)
{
}
template<typename Str = std::string>
class TokenRetrieval
{
public:
TokenRetrieval() = default;
TokenRetrieval(Models::ClientInformation<Str> &info) :
client_information(std::move(info))
{
}
TokenRetrieval(Models::ClientInformation<Str> &&info) :
client_information(info)
{
}
template<typename TokResp>
auto retrieve_token()
{
if (this->client_information.is_empty()) {
return TokResp();
}
template<typename TokResp>
auto retrieve_token()
{
if (this->client_information.is_empty()) {
return TokResp();
}
auto token = make_call<TokResp>();
auto token = make_call<TokResp>();
return (token.is_empty()) ? TokResp() : token;
}
return (token.is_empty()) ? TokResp() : token;
}
private:
template<typename TokResp>
auto make_call()
{
TokResp resp;
private:
template<typename TokResp>
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<Str>();
resp.token_type = token["token_type"].get<Str>();
resp.expires_in = token["expires_in"].get<int>();
resp.scope = token["scope"].get<Str>();
}
if (r.status_code == 200) {
auto token = nlohmann::json::parse(r.text);
resp.access_token = token["access_token"].get<Str>();
resp.token_type = token["token_type"].get<Str>();
resp.expires_in = token["expires_in"].get<int>();
resp.scope = token["scope"].get<Str>();
}
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<char> v(unencoded.begin(), unencoded.end());
std::vector<char> v(unencoded.begin(), unencoded.end());
return cppcodec::base64_rfc4648::encode(v);
}
return cppcodec::base64_rfc4648::encode(v);
}
template<typename Ch = char>
auto construct_uri(Ch *base, Ch *endpoint)
{
Str uri(base);
template<typename Ch = char>
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<Str> client_information;
};
Models::ClientInformation<Str> client_information;
};
}
+24 -24
View File
@@ -19,47 +19,47 @@ using namespace Models;
template<typename Conf, typename Str>
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>());
std::string secret(client_json["client_secret"].get<std::string>());
auto client_json = nlohmann::json::parse(buffer.str());
std::string id(client_json["client_id"].get<std::string>());
std::string secret(client_json["client_secret"].get<std::string>());
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<ClientInformation<std::string>,
std::string>(std::move(path));
auto client_info = retrieve_client_information<ClientInformation<std::string>,
std::string>(std::move(path));
Manager::TokenRetrieval<> tok_mgr(std::move(client_info));
auto resp = tok_mgr.retrieve_token<Models::TokenResp<std::string>>();
Manager::TokenRetrieval<> tok_mgr(std::move(client_info));
auto resp = tok_mgr.retrieve_token<Models::TokenResp<std::string>>();
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;
}