From 14d3c9acc638b7438442a85c5dc1bead11c938dc Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Fri, 31 Dec 2021 19:09:31 -0500 Subject: [PATCH] Made progress --- include/Managers/ActionManager.h | 20 +++- include/Managers/CommitManager.h | 54 ++++++++++- include/Models/Flags.h | 3 +- include/Models/IcarusAction.h | 35 ++++++- include/Models/Song.h | 21 ++++- include/Syncers/Upload.h | 14 ++- src/Main.cpp | 2 + src/Managers/ActionManager.cpp | 30 ++---- src/Managers/CommitManager.cpp | 154 +++++++++++++++++++++++++++++-- src/Syncers/Upload.cpp | 22 ++--- 10 files changed, 296 insertions(+), 59 deletions(-) diff --git a/include/Managers/ActionManager.h b/include/Managers/ActionManager.h index 63afb3b..bab8575 100644 --- a/include/Managers/ActionManager.h +++ b/include/Managers/ActionManager.h @@ -1,6 +1,7 @@ #ifndef ACTIONMANAGER_H_ #define ACTIONMANAGER_H_ +#include #include #include #include @@ -18,11 +19,24 @@ namespace Managers Models::IcarusAction retrieveIcarusAction() const; private: - constexpr std::array supportedFlags() noexcept; + constexpr std::array supportedFlags() noexcept + { + constexpr std::array allFlags{"-u", "-p", "-t", "-h", "-s", + "-sd", "-sr", "-d", "-D", "-b", "-rt", "-nc", + "-m", "-ca", "-smca"}; + + return allFlags; + } constexpr std::array supportedActions() noexcept; - bool isNumber(const std::string_view) noexcept; - + bool isNumber(const std::string_view val) noexcept + { + return !val.empty() && std::find_if(val.begin(), + val.end(), [](char c) + { + return !std::isdigit(c); + }) == val.end(); + } void initialize(); void validateFlags(); diff --git a/include/Managers/CommitManager.h b/include/Managers/CommitManager.h index 4c2aa94..04d77f0 100644 --- a/include/Managers/CommitManager.h +++ b/include/Managers/CommitManager.h @@ -2,11 +2,14 @@ #define COMMITMANAGER_H_ #include +#include #include +#include #include"Models/API.h" -#include"Models/Token.h" #include"Models/IcarusAction.h" +#include"Models/Song.h" +#include"Models/Token.h" namespace Managers { @@ -22,6 +25,24 @@ namespace Managers songs }; + // Used for parsing songs from the metadata file + class Album + { + public: + Album() = default; + + void printInfo(); + + + std::string album; + std::string albumArtist; + std::string genre; + int year; + int trackCount; + int discCount; + std::vector songs; + }; + private: enum class ActionValues; @@ -33,15 +54,44 @@ namespace Managers void downloadSong(); void retrieveObjects(); void uploadSong(); + // Uploads a single song. The song is constructed from a metadata file that contains + // information about the album the song is from. Also, the cover art of the song must + // be present. + // + // Expects + // * Song - mp3 file path + // * Metadata - Source file containing metadata of the song + // * Cover art - path to image cover art + void uploadSingleSong(); + + // Checks for the no confirm flag. Used when uploading songs from a directory + bool checkForNoConfirm() + { + for (const auto &arg: this->icaAction.flags) + { + if (arg.flag.compare("-nc") == 0) + { + return true; + } + } + + return false; + } + + + Album retrieveMetadata(const std::string_view path); + std::string retrieveFileContent(const std::string_view path); enum class ActionValues { deleteAct, downloadAct, retrieveAct, - uploadAct + uploadAct, + UPLOAD_SONG_WITH_METADATA // Uploads the song with metadata, including cover art }; + Models::IcarusAction icaAction; }; } diff --git a/include/Models/Flags.h b/include/Models/Flags.h index 6772e10..7f7c557 100644 --- a/include/Models/Flags.h +++ b/include/Models/Flags.h @@ -5,8 +5,9 @@ namespace Models { - struct Flags + class Flags { + public: std::string flag; std::string value; }; diff --git a/include/Models/IcarusAction.h b/include/Models/IcarusAction.h index 9a32775..c6f8d1a 100644 --- a/include/Models/IcarusAction.h +++ b/include/Models/IcarusAction.h @@ -2,14 +2,47 @@ #define ICARUSACTION_H_ #include +#include +#include #include +#include #include"Flags.h" namespace Models { - struct IcarusAction + class IcarusAction { + public: + std::string retrieveFlagValue(const std::string_view flag) + { + std::string value; + + const auto fg = std::find_if(flags.begin(), flags.end(), [&](Flags f) + { + return f.flag.compare(flag) == 0 ? true : false; + }); + + if (fg != flags.end()) + { + value.assign(fg->value); + } + + return value; + } + void print_action_and_flags() noexcept + { + std::cout<<"Action: "<action<<"\n"; + std::cout<<"Flag count: "<flags.size()<<"\n"; + + for (const auto &flag : this->flags) + { + std::cout<<"flag "< flags; }; diff --git a/include/Models/Song.h b/include/Models/Song.h index 4ed0017..3f9f76a 100644 --- a/include/Models/Song.h +++ b/include/Models/Song.h @@ -2,12 +2,22 @@ #define SONG_H_ #include +#include namespace Models { - struct Song + class Song { + public: + Song() = default; + + void printInfo() + { + std::cout<<"Title: "<title<<"\n"; + std::cout<<"\n"; + } + int id; std::string title; std::string artist; @@ -16,9 +26,18 @@ namespace Models int year; int duration; int track; + int disc; std::string data; std::string songPath; }; + + class CoverArt + { + public: + int id; + std::string title; + std::string path; + }; } #endif diff --git a/include/Syncers/Upload.h b/include/Syncers/Upload.h index 5b9890d..527300b 100644 --- a/include/Syncers/Upload.h +++ b/include/Syncers/Upload.h @@ -7,6 +7,7 @@ #include +#include"Managers/CommitManager.h" #include"Managers/FileManager.h" #include"Models/API.h" #include"Models/Song.h" @@ -21,16 +22,19 @@ namespace Syncers class Upload { public: - Upload(); - Upload(Models::API); + Upload(Models::API api, Models::Token token) : m_token(token), api(api) + { + this->api.endpoint = "song/data"; + } - Models::Song uploadSong(const Models::Token&, Models::Song&); - void uploadSongsFromDirectory(const Models::Token&, - const std::string&, const bool, bool); + Models::Song uploadSong(Models::Song&); + void uploadSongsFromDirectory(const std::string&, const bool, bool); + void uploadSongWithMetadata(Managers::CommitManager::Album&, Models::Song&, Models::CoverArt&); private: Managers::FileManager fMgr; Models::API api; Models::Song song; + Models::Token m_token; std::vector retrieveAllSongsFromDirectory(const std::string&, bool); diff --git a/src/Main.cpp b/src/Main.cpp index 35e5550..965792e 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -62,6 +62,8 @@ int main(int argc, char** argv) ActionManager actMgr(argv, argc); auto chosenAction = actMgr.retrieveIcarusAction(); + chosenAction.print_action_and_flags(); + CommitManager commitMgr(chosenAction); commitMgr.commitAction(); diff --git a/src/Managers/ActionManager.cpp b/src/Managers/ActionManager.cpp index ba49d7b..7e13855 100644 --- a/src/Managers/ActionManager.cpp +++ b/src/Managers/ActionManager.cpp @@ -36,23 +36,6 @@ namespace Managers } - constexpr std::array ActionManager::supportedFlags() noexcept - { - constexpr std::array allFlags{"-u", "-p", "-t", "-h", "-s", - "-sd", "-sr", "-d", "-D", "-b", "-rt", "-nc"}; - - return allFlags; - } - - - bool ActionManager::isNumber(string_view val) noexcept - { - return !val.empty() && std::find_if(val.begin(), - val.end(), [](char c) - { - return !std::isdigit(c); - }) == val.end(); - } void ActionManager::initialize() { @@ -62,13 +45,14 @@ namespace Managers transform(action.begin(), action.end(), action.begin(), ::tolower); } + void ActionManager::validateFlags() { - cout<<"Validating flags"< 3 || isNumber(flag)) { flg.value = flag; - //cout<<"flag value "< ActionManager::parsedFlags() { - auto parsed = vector(); + vector parsed; + parsed.reserve(paramCount); for (auto i = 2; i < paramCount; ++i) { diff --git a/src/Managers/CommitManager.cpp b/src/Managers/CommitManager.cpp index e371589..22bb33d 100644 --- a/src/Managers/CommitManager.cpp +++ b/src/Managers/CommitManager.cpp @@ -1,6 +1,11 @@ #include"Managers/CommitManager.h" #include +#include +#include +#include + +#include"nlohmann/json.hpp" #include"Models/API.h" #include"Models/Song.h" @@ -31,6 +36,8 @@ using Syncers::Download; using Syncers::RetrieveRecords; using Syncers::Upload; +namespace filesystem = std::filesystem; + namespace Managers { #pragma @@ -44,6 +51,7 @@ namespace Managers { auto action = icaAction.action; cout<<"Commiting "<icaAction.retrieveFlagValue("-s"); + const auto metadataPath = this->icaAction.retrieveFlagValue("-m"); + const auto coverPath = this->icaAction.retrieveFlagValue("-ca"); + const auto singleTarget = !songPath.empty() && !metadataPath.empty() && + !coverPath.empty() ? true : false; + + const auto uni = this->icaAction.retrieveFlagValue("-smca"); + const auto multiTarget = !uni.empty() ? true : false; + + if (singleTarget && multiTarget) + { + cout<<"Cannot upload from source and directory\n"; + return; + } + + cout<<"song path: "<(); + album.albumArtist = serialized["album_artist"].get(); + album.genre = serialized["genre"].get(); + album.year = serialized["year"].get(); + album.trackCount = serialized["track_count"].get(); + album.discCount = serialized["disc_count"].get(); + album.songs.reserve(album.trackCount); + + for (auto &j : serialized["tracks"]) + { + Song song; + song.title = j["title"].get(); + song.track = j["track"].get(); + song.disc = j["disc"].get(); + song.artist = j["artist"].get(); + song.album = album.album; + song.year = album.year; + song.genre = album.genre; + + album.songs.push_back(song); + } + + return album; + } + + string CommitManager::retrieveFileContent(const std::string_view path) + { + string path_str(path); + string value; + + std::stringstream buffer; + std::fstream file(path_str, std::ios::in); + buffer<album<<"\n"; + std::cout<<"Album Artist: "<albumArtist<<"\n"; + std::cout<<"Genre: "<genre<<"\n"; + std::cout<<"Year: "<year<<"\n"; + std::cout<<"Track count: "<trackCount<<"\n"; + std::cout<<"Disc count: "<discCount<<"\n"; + std::cout<<"\n"; + } + #pragma Functions } diff --git a/src/Syncers/Upload.cpp b/src/Syncers/Upload.cpp index 7bb8d57..3796e7b 100644 --- a/src/Syncers/Upload.cpp +++ b/src/Syncers/Upload.cpp @@ -24,22 +24,15 @@ using namespace cpr; namespace Syncers { - Upload::Upload() { } - Upload::Upload(API api) : api(api) - { - this->api.endpoint = "song/data"; - } - - - Song Upload::uploadSong(const Models::Token& token, Song& song) + Song Upload::uploadSong(Song& song) { try { auto url = retrieveUrl(); cout<<"url "<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}}}, @@ -70,8 +63,7 @@ namespace Syncers return song; } - void Upload::uploadSongsFromDirectory(const Models::Token& token, - const std::string& directory, + void Upload::uploadSongsFromDirectory(const std::string& directory, const bool noConfirm, bool recursive = false) { try @@ -106,7 +98,7 @@ namespace Syncers cout << "uploading songs\n"; for (auto& song: songs) { - song = uploadSong(token, song); + song = uploadSong(song); } } catch (exception& e) @@ -116,6 +108,10 @@ namespace Syncers } + void Upload::uploadSongWithMetadata(Managers::CommitManager::Album &album, Models::Song& song, Models::CoverArt &cover) + { + // TODO: Implement + } std::vector Upload::retrieveAllSongsFromDirectory(const std::string& directory, bool recursive) {