You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

114 lines
3.5 KiB

#include "spotify.h"
#include "cpr/cprtypes.h"
#include "cpr/parameters.h"
#include <nlohmann/json.hpp>
#include <cpr/cpr.h>
#include <istream>
#include <sstream>
#include <string>
#include <spdlog/spdlog.h>
#include <iostream>
#include <cstdio>
#include "Base64.hpp"
#include <optional>
using json = nlohmann::json;
void spotify::verify_logged_in() {
/*
*
* Would be a good idea to just requrst a page to chek. but the /me
* endpoint is for logged in users i guess? and this iis jut an app.
*
cpr::Response r = cpr::Get(cpr::Url{API_NAME_BASE + "v1/me"},cpr::Header{{"Authorization", "Bearer " + access_token}});
std::istringstream isj {r.text};
json auth_response;
try {
isj >> auth_response;
} catch (json::exception & e) {
std::cout << e.id << r.text;
}
if (auth_response.count("display_name")) {
std::cout << "Logged in as " << auth_response["display_name"] << std::endl << auth_response["href"] << std::endl;
} else {
std::cout << "Failed to log in" << std::endl << auth_response.dump(4) << std::endl;
}
*/
}
spotify::spotify(std::string access_token) : access_token(access_token) {
auth_header = cpr::Header{{"Authorization", "Bearer " + access_token}};
verify_logged_in();
}
spotify::spotify(std::string client_id, std::string client_secret) {
auto ascii_token = client_id + ":" + client_secret;
size_t buf_length = base64::get_encoded_length(ascii_token.length());
auto buf = std::make_unique<uint8_t[]>(buf_length);
std::string auth_token;
base64::encode((uint8_t *)(ascii_token.c_str()), ascii_token.length(), buf.get(), buf_length);
auth_token = std::string {(char *)buf.get(), buf_length};
cpr::Response r = cpr::Post(cpr::Url{"https://accounts.spotify.com/api/token"},cpr::Header{{"Authorization", "Basic " + auth_token}}, cpr::Parameters{{"grant_type", "client_credentials"}});
std::istringstream isj {r.text};
json auth_response;
if (r.status_code == 200) {
isj >> auth_response;
} else {
spdlog::error("Login error {} {}",r.status_code, r.status_line);
}
if (auth_response.count("access_token")) {
access_token = auth_response["access_token"];
std::cout << "Successfully logged into spotify" << std::endl << "Access token: " << access_token << std::endl;
} else {
std::cout << "Unable to log into spotify:" << std::endl << auth_response.dump(4) << std::endl;
exit (1);
}
auth_header = cpr::Header{{"Authorization", "Bearer " + access_token}};
verify_logged_in();
}
std::optional<json> spotify::get_track(std::string track_id) {
auto r = cpr::Get(cpr::Url{API_NAME_BASE + "v1/tracks/" + track_id}, auth_header);
if (r.status_code == 200) {
std::istringstream isj {r.text};
json info ;
try {
isj >> info;
} catch (json::exception & e) {
std::cout << "Json error" << std::endl;
}
return info;
} else {
std::cout << r.text << std::endl;
return {};
}
}
/*
* Parse track link from a spotify url like:
*
* https://open.spotify.com/track/4UO1pfxi5fDbxshrwwznJ2?si=BtN9Yn_JQXSHGUa4CEZKvQ&utm_source=copy-link
*
*
*/
std::optional<std::string> spotify::track_id_from_link(std::string link) {
const std::string start = "spotify.com/track/";
auto f = link.find(start);
if (f == std::string::npos) {
return {};
}
auto end = link.find("?", f);
auto begin = f + start.length();
return link.substr(begin, end - begin);
}