Merge branch 'master' into support_new_upload_endpoint

This commit is contained in:
Kun Deng
2022-01-08 23:46:43 -05:00
committed by GitHub
35 changed files with 1815 additions and 1706 deletions
+48 -46
View File
@@ -1,9 +1,9 @@
#include"Syncers/Delete.h"
#include "Syncers/Delete.h"
#include<exception>
#include<iostream>
#include <exception>
#include <iostream>
#include<cpr/cpr.h>
#include <cpr/cpr.h>
using std::cout;
using std::endl;
@@ -16,47 +16,49 @@ using Models::Token;
namespace Syncers
{
#pragma
Delete::Delete(API api)
{
this->api = api;
this->api.endpoint = "song/data";
}
#pragma Constructors
#pragma
void Delete::deleteSong(const Token token, Song song)
{
try
{
auto url = retrieveUrl(song);
string auth{token.tokenType};
auth.append(" " + token.accessToken);
auto r = cpr::Delete(cpr::Url(url),
cpr::Header{{"authorization", auth}});
auto statusCode = r.status_code;
cout<<"Status code "<<statusCode<<endl;
}
catch (exception e)
{
auto msg = e.what();
cout<<msg<<endl;
}
cout<<"Finished"<<endl;
}
string Delete::retrieveUrl(Song song)
{
string url{api.url + "api/" + api.version + "/" +
api.endpoint + "/"};
url.append(std::to_string(song.id));
cout<<"url "<<url<<endl;
return url;
}
#pragma Functions
#pragma region Constructors
Delete::Delete(API api)
{
this->api = api;
this->api.endpoint = "song/data";
}
#pragma endregion
#pragma region Functions
void Delete::deleteSong(const Token token, Song song)
{
try
{
auto url = retrieveUrl(song);
string auth{token.tokenType};
auth.append(" " + token.accessToken);
auto r = cpr::Delete(cpr::Url(url),
cpr::Header{{"authorization", auth}});
auto statusCode = r.status_code;
cout<<"Status code "<<statusCode<<endl;
}
catch (exception e)
{
auto msg = e.what();
cout<<msg<<endl;
}
cout<<"Finished"<<endl;
}
string Delete::retrieveUrl(Song song)
{
string url{api.url + "api/" + api.version + "/" +
api.endpoint + "/"};
url.append(std::to_string(song.id));
cout<<"url "<<url<<endl;
return url;
}
#pragma endregion
}
+76 -74
View File
@@ -1,10 +1,10 @@
#include"Syncers/Download.h"
#include "Syncers/Download.h"
#include<exception>
#include<iostream>
#include<fstream>
#include <exception>
#include <iostream>
#include <fstream>
#include<cpr/cpr.h>
#include <cpr/cpr.h>
using std::cout;
using std::endl;
@@ -18,74 +18,76 @@ using Models::Token;
namespace Syncers
{
#pragma
Download::Download() { }
Download::Download(API api)
{
this->api = api;
this->api.endpoint = "song/data";
}
Download::Download(string filePath)
{
downloadFilePath = filePath;
}
#pragma Constructors
#pragma
void Download::downloadSong(const Token token, Song song)
{
try
{
string url = retrieveUrl(song);
song.songPath.append("track.mp3");
cout<<"song path "<<song.songPath<<endl;
string auth{token.tokenType};
auth.append(" " + token.accessToken);
auto r = cpr::Get(cpr::Url(url),
cpr::Header{{"Content-type", "audio/mpeg"},
{"Authorization", auth}});
int statusCode = r.status_code;
if (statusCode == OK) {
song.data = r.text;
saveSong(song);
}
cout<<"finsihed with status code "<<statusCode<<endl;
}
catch (exception e)
{
auto msg = e.what();
cout<<msg<<endl;
}
}
string Download::retrieveUrl(Song song)
{
string url{api.url + "api/" + api.version + "/" +
api.endpoint + "/"};
url.append(std::to_string(song.id));
cout<<"url "<<url<<endl;
return url;
}
void Download::saveSong(Song& song)
{
cout<<"\nSaving song to: "<<song.songPath<<endl;
int bufferLength = song.data.length();
const char *data = song.data.c_str();
cout<<"buff length "<<bufferLength<<endl;
ofstream saveSong{song.songPath, std::ios::binary};
saveSong.write(data, bufferLength);
saveSong.close();
}
#pragma Functions
#pragma region Constructors
Download::Download() { }
Download::Download(API api)
{
this->api = api;
this->api.endpoint = "song/data";
}
Download::Download(string filePath)
{
downloadFilePath = filePath;
}
#pragma endregion
#pragma region Functions
void Download::downloadSong(const Token token, Song song)
{
try
{
string url = retrieveUrl(song);
song.songPath.append("track.mp3");
cout<<"song path "<<song.songPath<<endl;
string auth{token.tokenType};
auth.append(" " + token.accessToken);
auto r = cpr::Get(cpr::Url(url),
cpr::Header{{"Content-type", "audio/mpeg"},
{"Authorization", auth}});
int statusCode = r.status_code;
if (statusCode == OK) {
song.data = r.text;
saveSong(song);
}
cout<<"finsihed with status code "<<statusCode<<endl;
}
catch (exception e)
{
auto msg = e.what();
cout<<msg<<endl;
}
}
string Download::retrieveUrl(Song song)
{
string url{api.url + "api/" + api.version + "/" +
api.endpoint + "/"};
url.append(std::to_string(song.id));
cout<<"url "<<url<<endl;
return url;
}
void Download::saveSong(Song& song)
{
cout<<"\nSaving song to: "<<song.songPath<<endl;
int bufferLength = song.data.length();
const char *data = song.data.c_str();
cout<<"buff length "<<bufferLength<<endl;
ofstream saveSong{song.songPath, std::ios::binary};
saveSong.write(data, bufferLength);
saveSong.close();
}
#pragma endregion
}
+41 -36
View File
@@ -20,43 +20,48 @@ using Utilities::Conversions;
namespace Syncers
{
RetrieveRecords::RetrieveRecords() { }
RetrieveRecords::RetrieveRecords(API api, Token token)
: token(token), api(api) { }
#pragma region Constructors
RetrieveRecords::RetrieveRecords() { }
RetrieveRecords::RetrieveRecords(API api, Token token)
: token(token), api(api) { }
#pragma endregion
void RetrieveRecords::retrieve(CommitManager::RetrieveTypes type)
#pragma region Functions
void RetrieveRecords::retrieve(CommitManager::RetrieveTypes type)
{
switch (type)
{
switch (type)
{
case CommitManager::RetrieveTypes::songs:
fetchSongs();
break;
default:
break;
}
}
void RetrieveRecords::fetchSongs()
{
cout<<"fetching songs"<<endl;
auto url = api.url + "api/" + api.version + "/" + "song";
auto auth = token.tokenType;
auth.append(" " + token.accessToken);
auto r = cpr::Get(cpr::Url{url},
cpr::Header{{"authorization", auth},
});
if (r.status_code != (int)Result::OK) {
cout<<"something went wrong\n";
cout<<"status code: "<<r.status_code<<endl;
cout<<"message: "<<r.text<<endl;
return;
}
auto songData = nlohmann::json::parse(r.text);
ofstream writeData{};
writeData.open("songs.json");
writeData<<songData.dump(4);
writeData.close();
case CommitManager::RetrieveTypes::songs:
fetchSongs();
break;
default:
break;
}
}
void RetrieveRecords::fetchSongs()
{
cout<<"fetching songs"<<endl;
auto url = api.url + "api/" + api.version + "/" + "song";
auto auth = token.tokenType;
auth.append(" " + token.accessToken);
auto r = cpr::Get(cpr::Url{url},
cpr::Header{{"authorization", auth},
});
if (r.status_code != (int)Result::OK) {
cout<<"something went wrong\n";
cout<<"status code: "<<r.status_code<<endl;
cout<<"message: "<<r.text<<endl;
return;
}
auto songData = nlohmann::json::parse(r.text);
ofstream writeData{};
writeData.open("songs.json");
writeData<<songData.dump(4);
writeData.close();
}
#pragma endregion
}
+211 -208
View File
@@ -25,192 +25,206 @@ using namespace cpr;
namespace Syncers
{
#pragma region Functions
Song Upload::uploadSong(Song& song)
#pragma region Constructors
Upload::Upload() { }
Upload::Upload(API api) : api(api)
{
this->api.endpoint = "song/data";
}
#pragma endregion
#pragma region Functions
Song Upload::uploadSong(Song& song)
{
try
{
try
{
auto url = retrieveUrl();
auto url = retrieveUrl();
cout<<"url "<<url<<endl;
string auth{this->m_token.tokenType};
auth.append(" " + this->m_token.accessToken);
auto r = cpr::Post(cpr::Url{url},
cpr::Multipart{{"key", "small value"},
{"file", cpr::File{song.songPath}}},
cpr::Header{{"authorization", auth}}
);
cout << "status code: " << r.status_code<< std::endl;
cout << r.text << endl;
auto result = nlohmann::json::parse(r.text);
cout<<"Finished"<<endl;
song.id = result["id"].get<int>();
song.title = result["title"].get<std::string>();
song.artist = result["artist"].get<std::string>();
song.album = result["album"].get<std::string>();
song.genre = result["genre"].get<std::string>();
song.year = result["year"].get<int>();
song.duration = result["duration"].get<int>();
song.track = result["track"].get<int>();
return song;
}
catch (exception& e)
{
auto msg = e.what();
cout<<msg<<endl;
}
return song;
}
void Upload::uploadSongsFromDirectory(const std::string& directory,
const bool noConfirm, bool recursive = false)
{
try
{
auto songs = retrieveAllSongsFromDirectory(directory, recursive);
auto confirmUpload = true;
while (!noConfirm)
{
auto answer = 'a';
cout << "are you sure you want to upload " << songs.size() << " songs? [y/n]";
cin >> answer;
Utilities::Conversions::toLowerChar(answer);
if (answer == 'y' || answer == 'Y')
{
confirmUpload = true;
break;
}
}
if (!confirmUpload)
{
cout << "exiting...\n";
std::exit(-1);
}
cout << "uploading songs\n";
for (auto& song: songs)
{
song = uploadSong(song);
}
}
catch (exception& e)
{
cout<<e.what()<<endl;
}
}
void Upload::uploadSongWithMetadata(Managers::CommitManager::Album &album, Models::Song& song, Models::CoverArt &cover)
{
this->api.endpoint.assign("song/data/upload/with/data");
try
{
auto url = retrieveUrl();
cout<<"url "<<url<<endl;
string auth{this->m_token.tokenType};
auth.append(" " + this->m_token.accessToken);
// const auto meta = song.toMetadataJson();
nlohmann::json s;
s["title"] = song.title;
s["album"] = album.album;
s["album_artist"] = album.albumArtist;
s["artist"] = song.artist;
s["year"] = album.year;
s["genre"] = album.genre;
s["disc"] = song.disc;
s["track"] = song.track;
s["disc_count"] = album.discCount;
s["track_count"] = album.trackCount;
const auto meta = s.dump();
cout<<"\n\nMeta:\n"<<meta<<"\n";
/**
auto multipart = cpr::Multipart{{"cover", cpr::File{cover.path}},
{"metadata", meta},
{"file", cpr::File{song.songPath}}};
auto r = cpr::Post(cpr::Url{url}, multipart,
cpr::Header{{"authorization", auth}}
cout<<"url "<<url<<endl;
string auth{this->m_token.tokenType};
auth.append(" " + this->m_token.accessToken);
auto r = cpr::Post(cpr::Url{url},
cpr::Multipart{{"key", "small value"},
{"file", cpr::File{song.songPath}}},
cpr::Header{{"authorization", auth}}
);
cout << "status code: " << r.status_code<< std::endl;
cout << r.text << endl;
*/
}
catch (exception &e)
{
auto msg = e.what();
cout<<"Error: "<<msg<<"\n";
}
}
std::vector<Song> Upload::retrieveAllSongsFromDirectory(const std::string& directory,
bool recursive)
{
std::vector<Song> allSongs;
if (recursive)
{
for (auto p: fs::recursive_directory_iterator(directory))
{
auto song = retrieveSongPath(p);
if (!song.songPath.empty())
allSongs.push_back(song);
}
}
else
{
for (auto p: fs::directory_iterator(directory))
{
auto song = retrieveSongPath(p);
if (!song.songPath.empty())
allSongs.push_back(song);
}
}
return allSongs;
}
string Upload::retrieveUrl()
{
const string url{api.url + "api/" + api.version + "/" +
api.endpoint};
return url;
}
Song Upload::retrieveSongPath(fs::directory_entry& dirEntry)
{
constexpr auto mp3Ext = ".mp3";
Song song;
if (fs::is_regular_file(dirEntry.path()))
{
const auto ext = dirEntry.path().extension().string();
if (ext.compare(mp3Ext) == 0)
{
cout << "found mp3 file" << endl;
song.songPath = dirEntry.path().string();
}
}
cout << "status code: " << r.status_code<< std::endl;
cout << r.text << endl;
auto result = nlohmann::json::parse(r.text);
cout<<"Finished"<<endl;
song.id = result["id"].get<int>();
song.title = result["title"].get<std::string>();
song.artist = result["artist"].get<std::string>();
song.album = result["album"].get<std::string>();
song.genre = result["genre"].get<std::string>();
song.year = result["year"].get<int>();
song.duration = result["duration"].get<int>();
song.track = result["track"].get<int>();
return song;
}
catch (exception& e)
{
auto msg = e.what();
cout<<msg<<endl;
}
return song;
}
void Upload::uploadSongsFromDirectory(const std::string& directory,
const bool noConfirm, bool recursive = false)
{
try
{
auto songs = retrieveAllSongsFromDirectory(directory, recursive);
auto confirmUpload = true;
while (!noConfirm)
{
auto answer = 'a';
cout << "are you sure you want to upload " << songs.size() << " songs? [y/n]";
cin >> answer;
Utilities::Conversions::toLowerChar(answer);
if (answer == 'y' || answer == 'Y')
{
confirmUpload = true;
break;
}
}
if (!confirmUpload)
{
confirmUpload = false;
break;
}
}
cout << "uploading songs\n";
for (auto& song: songs)
{
song = uploadSong(song);
}
}
catch (exception& e)
{
cout<<e.what()<<endl;
}
}
#pragma region Testing
void Upload::printSongDetails()
void Upload::uploadSongWithMetadata(Managers::CommitManager::Album &album, Models::Song& song, Models::CoverArt &cover)
{
this->api.endpoint.assign("song/data/upload/with/data");
try
{
auto url = retrieveUrl();
cout<<"url "<<url<<endl;
string auth{this->m_token.tokenType};
auth.append(" " + this->m_token.accessToken);
// const auto meta = song.toMetadataJson();
nlohmann::json s;
s["title"] = song.title;
s["album"] = album.album;
s["album_artist"] = album.albumArtist;
s["artist"] = song.artist;
s["year"] = album.year;
s["genre"] = album.genre;
s["disc"] = song.disc;
s["track"] = song.track;
s["disc_count"] = album.discCount;
s["track_count"] = album.trackCount;
const auto meta = s.dump();
cout<<"\n\nMeta:\n"<<meta<<"\n";
/**
auto multipart = cpr::Multipart{{"cover", cpr::File{cover.path}},
{"metadata", meta},
{"file", cpr::File{song.songPath}}};
auto r = cpr::Post(cpr::Url{url}, multipart,
cpr::Header{{"authorization", auth}}
);
cout << "status code: " << r.status_code<< std::endl;
cout << r.text << endl;
*/
}
catch (exception &e)
{
auto msg = e.what();
cout<<"Error: "<<msg<<"\n";
}
}
std::vector<Song> Upload::retrieveAllSongsFromDirectory(const std::string& directory,
bool recursive)
{
std::vector<Song> allSongs;
if (recursive)
{
for (auto p: fs::recursive_directory_iterator(directory))
{
auto song = retrieveSongPath(p);
if (!song.songPath.empty())
allSongs.push_back(song);
}
}
else
{
for (auto p: fs::directory_iterator(directory))
{
auto song = retrieveSongPath(p);
if (!song.songPath.empty())
allSongs.push_back(song);
}
}
return allSongs;
}
string Upload::retrieveUrl()
{
const string url{api.url + "api/" + api.version + "/" +
api.endpoint};
return url;
}
Song Upload::retrieveSongPath(fs::directory_entry& dirEntry)
{
constexpr auto mp3Ext = ".mp3";
Song song;
if (fs::is_regular_file(dirEntry.path()))
{
const auto ext = dirEntry.path().extension().string();
if (ext.compare(mp3Ext) == 0)
{
cout << "found mp3 file" << endl;
song.songPath = dirEntry.path().string();
}
}
return song;
}
#pragma region Testing
void Upload::printSongDetails(std::vector<Song>& songs)
{
for (auto& song: songs)
{
cout<<"Song details: "<<endl;
cout<<"Id: "<<song.id<<endl;
@@ -220,36 +234,25 @@ namespace Syncers
cout<<"Genre: "<<song.genre<<endl;
cout<<"Year: "<<song.year<<endl;
cout<<"Duration: "<<song.duration<<endl;
cout<<"Path: "<<song.songPath<<endl;
}
void Upload::printSongDetails(std::vector<Song>& songs)
{
for (auto& song: songs)
{
cout<<"Song details: "<<endl;
cout<<"Id: "<<song.id<<endl;
cout<<"Title: "<<song.title<<endl;
cout<<"Artist: "<<song.artist<<endl;
cout<<"Album: "<<song.album<<endl;
cout<<"Genre: "<<song.genre<<endl;
cout<<"Year: "<<song.year<<endl;
cout<<"Duration: "<<song.duration<<endl;
cout<<"Path: "<<song.songPath<<endl;
}
}
void Upload::printJsonData(const json& obj)
{
cout<<endl<<endl<<"JSon data: "<<endl;
cout<<"id: "<<obj["id"]<<endl;
cout<<"title: "<<obj["title"]<<endl;
cout<<"artist: "<<obj["artist"]<<endl;
cout<<"album: "<<obj["album"]<<endl;
cout<<"genre: "<<obj["genre"]<<endl;
cout<<"year: "<<obj["year"]<<endl;
cout<<"duration: "<<obj["duration"]<<endl;
cout<<"song_data: "<<obj["song_data"]<<endl;
cout<<endl<<endl;;
}
#pragma endregion
#pragma endregion
}
void Upload::printJsonData(const json& obj)
{
cout<<endl<<endl<<"JSon data: "<<endl;
cout<<"id: "<<obj["id"]<<endl;
cout<<"title: "<<obj["title"]<<endl;
cout<<"artist: "<<obj["artist"]<<endl;
cout<<"album: "<<obj["album"]<<endl;
cout<<"genre: "<<obj["genre"]<<endl;
cout<<"year: "<<obj["year"]<<endl;
cout<<"duration: "<<obj["duration"]<<endl;
cout<<"song_data: "<<obj["song_data"]<<endl;
cout<<endl<<endl;;
}
#pragma endregion
#pragma endregion
}