From 0839731ee89734521f8c127f6b9f2fe97b195c39 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Wed, 29 Dec 2021 15:58:14 -0500 Subject: [PATCH 1/9] upload-meta command --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 2ab37e9..f2aa845 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,12 @@ The program has been built and can be executed by the binary file *icd*. For inf ### Uploading Song ``icd upload -u spacecadet -p stellar40 -h https://icarus.com -s /path/of/song.mp3`` +### Uploading Song with metadata + +```BASH +icd upload-meta -u spacecadet -p stellar40 -h https://icarus.com -s /path/of/song.mp3 -m /path/to/metadata/config/collection.json -ca /path/to/cover/art/image.png +``` + ### Retrieving Song in json ``icd retrieve -u spacecadet -p stellar40 -h https://icarus.com -rt songs`` From 9930aab9854063cba20772d180b81f0f5a7ce8b0 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Fri, 31 Dec 2021 16:00:45 -0500 Subject: [PATCH 2/9] Updated Readme --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index f2aa845..4d2ecc5 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,13 @@ The program has been built and can be executed by the binary file *icd*. For inf icd upload-meta -u spacecadet -p stellar40 -h https://icarus.com -s /path/of/song.mp3 -m /path/to/metadata/config/collection.json -ca /path/to/cover/art/image.png ``` +### Uploading Song with metadata from directory + +```BASH +icd upload-meta -u spacecadet -p stellar40 -h https://icarus.com -smca /path/where/songs/and/metadata/exist +``` + + ### Retrieving Song in json ``icd retrieve -u spacecadet -p stellar40 -h https://icarus.com -rt songs`` From 14d3c9acc638b7438442a85c5dc1bead11c938dc Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Fri, 31 Dec 2021 19:09:31 -0500 Subject: [PATCH 3/9] 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) { From 3e25dd77b5f85f13cdc77cb81e2dfa328b755672 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Fri, 31 Dec 2021 22:15:17 -0500 Subject: [PATCH 4/9] Updates Updating required flags for uploading a song with metadata --- CMakeLists.txt | 1 + README.md | 2 +- include/Managers/ActionManager.h | 54 ++++++++++++++++++----- include/Managers/CommitManager.h | 11 ++++- include/Models/Song.h | 4 ++ include/Utilities/Checks.h | 30 +++++++++++++ include/Utilities/Conversions.h | 9 ++++ src/Managers/ActionManager.cpp | 43 +++++++----------- src/Managers/CommitManager.cpp | 75 +++++++++++++++++++++++++------- src/Models/Song.cpp | 16 +++++++ src/Syncers/Upload.cpp | 59 +++++++++++++++++++++---- 11 files changed, 240 insertions(+), 64 deletions(-) create mode 100644 include/Utilities/Checks.h create mode 100644 src/Models/Song.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b75850..784b90c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ set(SOURCES src/Managers/FileManager.cpp src/Managers/TokenManager.cpp src/Managers/UserManager.cpp + src/Models/Song.cpp src/Parsers/APIParser.cpp src/Syncers/Delete.cpp src/Syncers/Download.cpp diff --git a/README.md b/README.md index 4d2ecc5..8c42e1c 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ The program has been built and can be executed by the binary file *icd*. For inf ### Uploading Song with metadata ```BASH -icd upload-meta -u spacecadet -p stellar40 -h https://icarus.com -s /path/of/song.mp3 -m /path/to/metadata/config/collection.json -ca /path/to/cover/art/image.png +icd upload-meta -u spacecadet -p stellar40 -h https://icarus.com -s /path/of/song.mp3 -t 1 -m /path/to/metadata/config/collection.json -ca /path/to/cover/art/image.png ``` ### Uploading Song with metadata from directory diff --git a/include/Managers/ActionManager.h b/include/Managers/ActionManager.h index bab8575..51f638e 100644 --- a/include/Managers/ActionManager.h +++ b/include/Managers/ActionManager.h @@ -19,26 +19,58 @@ 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", + constexpr std::array allFlags{"-u", "-p", "-t", "-h", "-s", "-sd", "-sr", "-d", "-D", "-b", "-rt", "-nc", - "-m", "-ca", "-smca"}; + "-m", "-ca", "-smca", "-t"}; return allFlags; } constexpr std::array supportedActions() 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(); + // Checks to see if the flag is valid + template + bool isValidFlag(const Str flag) + { + const auto flags = supportedFlags(); + const auto i = std::find_if(flags.begin(), flags.end(), [&](const Str &f) + { + return f.compare(flag) == 0 ? true : false; + }); + + auto result = i != flags.end() ? true : false; + + return result; + } + + template + bool doesFlagHaveValue(const Str flag) + { + const auto flags = parsedFlags(); + auto i = std::find_if(flags.begin(), flags.end(), [&](const Str &f) + { + return f.compare(flag) == 0 ? true : false; + }); + + if (i != flags.end()) + { + if (++i != flags.end() && !isValidFlag(*i)) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } std::vector parsedFlags(); diff --git a/include/Managers/CommitManager.h b/include/Managers/CommitManager.h index 04d77f0..fdc82d1 100644 --- a/include/Managers/CommitManager.h +++ b/include/Managers/CommitManager.h @@ -60,9 +60,18 @@ namespace Managers // // Expects // * Song - mp3 file path + // * TrackID - track number to chose from when retrieving metadata. "1" and "1:1" are similar // * Metadata - Source file containing metadata of the song // * Cover art - path to image cover art - void uploadSingleSong(); + // TODO: Change the name + void uploadSongWithMetadata(); + + // Expects the song path, trackID, metadata file path, and cover path + void singTargetUpload(const std::string &songPath, const std::string &trackID, + const std::string &metaPath, const std::string &coverPath); + // Expects the source directory that contains songs, a metadata file, and cover image + void multiTargetUpload(const std::string &sourcePath); + // Checks for the no confirm flag. Used when uploading songs from a directory bool checkForNoConfirm() diff --git a/include/Models/Song.h b/include/Models/Song.h index 3f9f76a..b2ea9d9 100644 --- a/include/Models/Song.h +++ b/include/Models/Song.h @@ -18,6 +18,10 @@ namespace Models std::cout<<"\n"; } + // TODO: Incomplete implementation + std::string toMetadataJson(); + + int id; std::string title; std::string artist; diff --git a/include/Utilities/Checks.h b/include/Utilities/Checks.h new file mode 100644 index 0000000..0760fb7 --- /dev/null +++ b/include/Utilities/Checks.h @@ -0,0 +1,30 @@ +#ifndef CHECKS_H_ +#define CHECKS_H_ + +#include +#include +#include + +namespace Utilities +{ + class Checks + { + public: + Checks() = delete; + + static bool isNumber(const std::string &val) + { + return !val.empty() && std::find_if(val.begin(), + val.end(), [](char c) + { + return !std::isdigit(c); + }) == val.end(); + } + private: + }; +} + +#endif + + + diff --git a/include/Utilities/Conversions.h b/include/Utilities/Conversions.h index d92d060..1e89994 100644 --- a/include/Utilities/Conversions.h +++ b/include/Utilities/Conversions.h @@ -11,6 +11,15 @@ namespace Utilities public: Conversions(); + + static void toLowerChar(char &c) + { + if (std::isalpha(c)) + { + c = std::tolower(c); + } + } + void initializeValues(); template diff --git a/src/Managers/ActionManager.cpp b/src/Managers/ActionManager.cpp index 7e13855..04e7bcf 100644 --- a/src/Managers/ActionManager.cpp +++ b/src/Managers/ActionManager.cpp @@ -52,40 +52,29 @@ namespace Managers const auto flagVals = parsedFlags(); - Flags flg; - - auto allSupportedFlags = supportedFlags(); - - for (auto flag : flagVals) + for (auto flag = flagVals.begin(); flag != flagVals.end(); ++flag) { - if (flag.compare("-nc") == 0) - { - flg.flag = flag; - flags.push_back(flg); - continue; - } - if (flag.size() > 3 || isNumber(flag)) - { - flg.value = flag; + Flags flg; + cout<<"Value: "<<*flag<<"\n"; - flags.push_back(flg); - flg = Flags{}; - continue; - } - - if (std::any_of(allSupportedFlags.begin(), allSupportedFlags.end(), - [&](const char *val) - { - return !flag.compare(val); - })) + if (isValidFlag(*flag) && doesFlagHaveValue(*flag)) { - flg.flag = flag; + cout<<"Flag has value\n"; + flg.flag = *flag; + flg.value = *(++flag); + } + else if (isValidFlag(*flag)) + { + cout<<"Flag does not have a value\n"; + flg.flag = *flag; } else { - cout<<"Flag is not valid"<icaAction.retrieveFlagValue("-s"); const auto metadataPath = this->icaAction.retrieveFlagValue("-m"); const auto coverPath = this->icaAction.retrieveFlagValue("-ca"); + const auto trackID = this->icaAction.retrieveFlagValue("-t"); const auto singleTarget = !songPath.empty() && !metadataPath.empty() && - !coverPath.empty() ? true : false; + !coverPath.empty() && !trackID.empty() ? true : false; const auto uni = this->icaAction.retrieveFlagValue("-smca"); const auto multiTarget = !uni.empty() ? true : false; @@ -260,20 +257,63 @@ namespace Managers return; } - cout<<"song path: "<title; + + return s.dump(); + } +} \ No newline at end of file diff --git a/src/Syncers/Upload.cpp b/src/Syncers/Upload.cpp index 3796e7b..98d3554 100644 --- a/src/Syncers/Upload.cpp +++ b/src/Syncers/Upload.cpp @@ -6,6 +6,7 @@ #include #include"Syncers/Upload.h" +#include"Utilities/Conversions.h" using std::cout; using std::cin; @@ -24,6 +25,7 @@ using namespace cpr; namespace Syncers { + #pragma region Functions Song Upload::uploadSong(Song& song) { try @@ -76,17 +78,13 @@ namespace Syncers 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; } - else if (answer == 'n' || answer == 'N') - { - confirmUpload = false; - break; - } } if (!confirmUpload) @@ -110,12 +108,55 @@ namespace Syncers void Upload::uploadSongWithMetadata(Managers::CommitManager::Album &album, Models::Song& song, Models::CoverArt &cover) { - // TODO: Implement + this->api.endpoint.append("/upload/with/data"); + + try + { + auto url = retrieveUrl(); + + cout<<"url "<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"< Upload::retrieveAllSongsFromDirectory(const std::string& directory, bool recursive) { std::vector allSongs; + if (recursive) { for (auto p: fs::recursive_directory_iterator(directory)) @@ -166,7 +207,7 @@ namespace Syncers } - #pragma + #pragma region Testing void Upload::printSongDetails() { cout<<"Song details: "< Date: Sat, 1 Jan 2022 00:39:35 -0500 Subject: [PATCH 5/9] Got functionality working --- README.md | 16 +++-- include/Managers/CommitManager.h | 104 ++++++++++++++++++++++++++++++- include/Models/Song.h | 1 - include/Utilities/Checks.h | 40 +++++++++++- src/Managers/CommitManager.cpp | 93 ++++++++++++++++----------- src/Models/Song.cpp | 6 ++ src/Parsers/APIParser.cpp | 3 - src/Syncers/Upload.cpp | 6 +- 8 files changed, 221 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 8c42e1c..6b02d47 100644 --- a/README.md +++ b/README.md @@ -35,10 +35,14 @@ cmake --build . -j The program has been built and can be executed by the binary file *icd*. For information on how to use icd, merely execute the program without any command line arguments. ### Downloading Song -``icd download -u spacecadet -p stellar40 -h https://icarus.com -b 15`` +``BASH +icd download -u spacecadet -p stellar40 -h https://icarus.com -b 15 +``` ### Uploading Song -``icd upload -u spacecadet -p stellar40 -h https://icarus.com -s /path/of/song.mp3`` +```BASH +icd upload -u spacecadet -p stellar40 -h https://icarus.com -s /path/of/song.mp3 +``` ### Uploading Song with metadata @@ -54,10 +58,14 @@ icd upload-meta -u spacecadet -p stellar40 -h https://icarus.com -smca /path/whe ### Retrieving Song in json -``icd retrieve -u spacecadet -p stellar40 -h https://icarus.com -rt songs`` +```Bash +icd retrieve -u spacecadet -p stellar40 -h https://icarus.com -rt songs +``` ### Deleting Song -``icd delete -u spacecadet -p stellar40 -h https://icarus.com -D 15`` +```BASH +icd delete -u spacecadet -p stellar40 -h https://icarus.com -D 15 +``` ## Contributing diff --git a/include/Managers/CommitManager.h b/include/Managers/CommitManager.h index fdc82d1..73ff50f 100644 --- a/include/Managers/CommitManager.h +++ b/include/Managers/CommitManager.h @@ -10,6 +10,7 @@ #include"Models/IcarusAction.h" #include"Models/Song.h" #include"Models/Token.h" +#include"Utilities/Checks.h" namespace Managers { @@ -63,15 +64,116 @@ namespace Managers // * TrackID - track number to chose from when retrieving metadata. "1" and "1:1" are similar // * Metadata - Source file containing metadata of the song // * Cover art - path to image cover art - // TODO: Change the name void uploadSongWithMetadata(); // Expects the song path, trackID, metadata file path, and cover path void singTargetUpload(const std::string &songPath, const std::string &trackID, const std::string &metaPath, const std::string &coverPath); // Expects the source directory that contains songs, a metadata file, and cover image + // Disc and Track is retrieved from the filename if the filename conforms to a standard. + // If not, then the disc and track will default to 1 + // + // Standards + // * track01.mp3 - Disc 1, Track 1 + // * track05d02.mp3 - Disc 2, Track 5 void multiTargetUpload(const std::string &sourcePath); + // Standards + // * track01.mp3 - Disc 1, Track 1 + // * track05d02.mp3 - Disc 2, Track 5 + template + void initializeDiscAndTrack(Song &song) + { + auto disc = 1; + auto track = 1; + // If 1 go with first standard, if 2 go with the second, if 0 then will default to 1 for disc and track + auto mode = 0; + const Str &songPath = song.songPath; + + auto trd = song.songPath.find("trackd"); + auto tr = song.songPath.find("track"); + + if (tr != Str::npos) + { + mode = 1; + } + + if (trd != Str::npos) + { + mode = 2; + } + + auto dl = [](char c, char t){ return c == t; }; + auto d = Utilities::Checks::itemIterInContainer(songPath, 'd', dl); + auto k = Utilities::Checks::itemIterInContainer(songPath, 'k', dl); + auto dot = Utilities::Checks::itemIterInContainer(songPath, '.', dl); + + switch(mode) + { + case 1: + { + if (k != songPath.end() && dot != songPath.end()) + { + auto tStr = std::string(++k, dot); + std::cout << "TStr: " << tStr<<"\n"; + + if (Utilities::Checks::isNumber(tStr)) + { + track = std::atoi(tStr.c_str()); + } + } + break; + } + case 2: + { + if (k != songPath.end() && dot != songPath.end() && d != songPath.end()) + { + auto tStr = std::string(++k, d); + auto dStr = std::string(++d, dot); + std::cout<<"DStr: "< + void parseDiscAndTrack(Song &song, const Str &trackID) + { + auto sep = [](char c, char t) { return c == t; }; + auto separator = Utilities::Checks::itemIterInContainer(trackID, ':', sep); + + if (separator != trackID.end()) + { + auto dStr = Str(trackID.begin(), separator); + auto tStr = Str(++separator, trackID.end()); + + song.disc = std::atoi(dStr.c_str()); + song.track = std::atoi(tStr.c_str()); + } + else + { + auto isNumber = Utilities::Checks::isNumber(trackID); + if (isNumber) + { + song.track = std::atoi(trackID.c_str()); + } + } + } + // Checks for the no confirm flag. Used when uploading songs from a directory bool checkForNoConfirm() diff --git a/include/Models/Song.h b/include/Models/Song.h index b2ea9d9..4cafbe3 100644 --- a/include/Models/Song.h +++ b/include/Models/Song.h @@ -18,7 +18,6 @@ namespace Models std::cout<<"\n"; } - // TODO: Incomplete implementation std::string toMetadataJson(); diff --git a/include/Utilities/Checks.h b/include/Utilities/Checks.h index 0760fb7..b4c186d 100644 --- a/include/Utilities/Checks.h +++ b/include/Utilities/Checks.h @@ -12,7 +12,7 @@ namespace Utilities public: Checks() = delete; - static bool isNumber(const std::string &val) + static auto isNumber(const std::string &val) { return !val.empty() && std::find_if(val.begin(), val.end(), [](char c) @@ -20,6 +20,44 @@ namespace Utilities return !std::isdigit(c); }) == val.end(); } + + // Note: Not implemented + template + static auto itemInContainer(const Container container, const Item item, Func func) + { + auto result = false; + auto i = std::find_if(container.begin(), container.end(), [&](Item i) + { + return func(item, i); + }); + + if (i != container.end()) + { + result = true; + } + + return result; + } + + template + static auto itemIterInContainer(const Container &container, const Item &item, Func func) + { + auto result = false; + // std::cout<(song, trackID); - if (separator != trackID.end()) - { - cout<<"Found colon\n"; - auto dStr = string(trackID.begin(), separator); - auto tStr = string(++separator, trackID.end()); - - cout<<"disc "<>(album.songs, song, c); if (sng == album.songs.end()) { - cout<<"Not found with disc "< songs; + Models::CoverArt cover; + string metadataPath; + + for (auto &p: fs::directory_iterator(sourcePath)) + { + const auto &pp = p.path(); + const auto stem = pp.stem(); + const auto file = pp.filename(); + const auto extension = pp.extension(); + + cout<<"Stem "<(song); + + songs.emplace_back(std::move(song)); + } + else if (extension.compare(".jpg") == 0 || extension.compare(".png") == 0) + { + cover.path.assign(pp.string()); + } + else if (extension.compare(".json") == 0) + { + metadataPath.assign(pp.string()); + } + } + + auto album = retrieveMetadata(metadataPath); + + Upload up(api, token); + + for (auto &song : songs) + { + up.uploadSongWithMetadata(album, song, cover); + } } #pragma region private diff --git a/src/Models/Song.cpp b/src/Models/Song.cpp index b149918..49338a7 100644 --- a/src/Models/Song.cpp +++ b/src/Models/Song.cpp @@ -10,6 +10,12 @@ namespace Models { nlohmann::json s; s["title"] = this->title; + s["artist"] = this->artist; + s["album"] = this->album; + s["genre"] = this->genre; + s["year"] = this->year; + s["track"] = this->track; + s["disc"] = this->disc; return s.dump(); } diff --git a/src/Parsers/APIParser.cpp b/src/Parsers/APIParser.cpp index 4e8746b..3d62019 100644 --- a/src/Parsers/APIParser.cpp +++ b/src/Parsers/APIParser.cpp @@ -43,9 +43,6 @@ namespace Parsers } - // TODO: For now I will hard code - // the api version since I am only - // on version 1 api.version = "v1"; } #pragma functions diff --git a/src/Syncers/Upload.cpp b/src/Syncers/Upload.cpp index 98d3554..daaaa88 100644 --- a/src/Syncers/Upload.cpp +++ b/src/Syncers/Upload.cpp @@ -108,7 +108,7 @@ namespace Syncers void Upload::uploadSongWithMetadata(Managers::CommitManager::Album &album, Models::Song& song, Models::CoverArt &cover) { - this->api.endpoint.append("/upload/with/data"); + this->api.endpoint.assign("song/data/upload/with/data"); try { @@ -133,8 +133,9 @@ namespace Syncers const auto meta = s.dump(); - // cout<<"\n\nMeta:\n"< Date: Sun, 9 Jan 2022 00:31:43 -0500 Subject: [PATCH 6/9] Saving changes --- CMakeLists.txt | 54 +++++++++++++++++++------------- include/Managers/ActionManager.h | 2 ++ include/Managers/CommitManager.h | 3 ++ include/Models/Flags.h | 7 ----- include/Syncers/Upload.h | 21 +++++++------ include/Utilities/Conversions.h | 3 ++ src/Managers/ActionManager.cpp | 8 ----- src/Syncers/Upload.cpp | 32 +++++-------------- 8 files changed, 60 insertions(+), 70 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 784b90c..d0161e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.12) +cmake_minimum_required(VERSION 3.20) project(IcarusDownloadManager) @@ -9,29 +9,41 @@ message(STATUS "Checking compiler flags for C++17 support.") # Set C++17 support flags for various compilers include(CheckCXXCompilerFlag) -check_cxx_compiler_flag("-std=c++17" COMPILER_SUPPORTS_CXX17) -check_cxx_compiler_flag("-std=c++0x" COMPILER_SUPPORTS_CXX0X) +if(WIN32) + message("Windows") + set(vs_ver 19.29.30138) -if(COMPILER_SUPPORTS_CXX17) - message(STATUS "C++17 is supported.") + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL ${vs_ver}) + message("Visual Studio version is at least ${vs_ver}") - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - - if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -stdlib=libc++") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") - endif() -elseif(COMPILER_SUPPORTS_CXX0X) - message(STATUS "C++0x is supported.") - if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") - endif() + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++latest") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++latest") + endif() else() - message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++17 support. Please use a different C++ compiler.") + check_cxx_compiler_flag("-std=c++17" COMPILER_SUPPORTS_CXX17) + check_cxx_compiler_flag("-std=c++0x" COMPILER_SUPPORTS_CXX0X) + + if(COMPILER_SUPPORTS_CXX17) + message(STATUS "C++17 is supported.") + + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + + if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -stdlib=libc++") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") + endif() + elseif(COMPILER_SUPPORTS_CXX0X) + message(STATUS "C++0x is supported.") + if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + endif() + else() + message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++17 support. Please use a different C++ compiler.") + endif() endif() diff --git a/include/Managers/ActionManager.h b/include/Managers/ActionManager.h index 9661c5c..66bc3e1 100644 --- a/include/Managers/ActionManager.h +++ b/include/Managers/ActionManager.h @@ -78,6 +78,8 @@ private: void printAction() noexcept; void printFlags() noexcept; + std::vector parsedFlags(); + std::string action; std::vector flags; diff --git a/include/Managers/CommitManager.h b/include/Managers/CommitManager.h index f4826b6..2506637 100644 --- a/include/Managers/CommitManager.h +++ b/include/Managers/CommitManager.h @@ -55,6 +55,9 @@ private: void downloadSong(); void retrieveObjects(); void uploadSong(); + + Models::Token parseToken(Models::API); + // 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. diff --git a/include/Models/Flags.h b/include/Models/Flags.h index aa03c4d..96206f5 100644 --- a/include/Models/Flags.h +++ b/include/Models/Flags.h @@ -13,13 +13,6 @@ public: std::string value; }; - -struct Flags -{ - std::string flag; - std::string value; -}; - } #endif diff --git a/include/Syncers/Upload.h b/include/Syncers/Upload.h index 993f0c0..49b7ce1 100644 --- a/include/Syncers/Upload.h +++ b/include/Syncers/Upload.h @@ -1,18 +1,18 @@ #ifndef UPLOAD_H_ #define UPLOAD_H_ -#include -#include -#include +#include +#include +#include -#include +#include -#include"Managers/CommitManager.h" -#include"Managers/FileManager.h" -#include"Models/API.h" -#include"Models/Song.h" -#include"Models/Token.h" -#include"Models/UploadForm.h" +#include "Managers/CommitManager.h" +#include "Managers/FileManager.h" +#include "Models/API.h" +#include "Models/Song.h" +#include "Models/Token.h" +#include "Models/UploadForm.h" namespace fs = std::filesystem; @@ -23,6 +23,7 @@ namespace Syncers class Upload { public: + Upload() = default; Upload(Models::API api, Models::Token token) : m_token(token), api(api) { this->api.endpoint = "song/data"; diff --git a/include/Utilities/Conversions.h b/include/Utilities/Conversions.h index f56abf2..3bfa5a4 100644 --- a/include/Utilities/Conversions.h +++ b/include/Utilities/Conversions.h @@ -21,6 +21,9 @@ public: } void initializeValues(); + + template + void printValue(T val); private: }; diff --git a/src/Managers/ActionManager.cpp b/src/Managers/ActionManager.cpp index a27f325..697f5d4 100644 --- a/src/Managers/ActionManager.cpp +++ b/src/Managers/ActionManager.cpp @@ -36,14 +36,6 @@ IcarusAction ActionManager::retrieveIcarusAction() const return icarusAction; } -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() diff --git a/src/Syncers/Upload.cpp b/src/Syncers/Upload.cpp index c97ff2e..d00ed66 100644 --- a/src/Syncers/Upload.cpp +++ b/src/Syncers/Upload.cpp @@ -1,12 +1,11 @@ -#include -#include -#include +#include +#include +#include -#include -#include +#include "cpr/cpr.h" -#include"Syncers/Upload.h" -#include"Utilities/Conversions.h" +#include "Syncers/Upload.h" +#include "Utilities/Conversions.h" using std::cout; using std::cin; @@ -27,11 +26,6 @@ namespace Syncers { #pragma region Constructors -Upload::Upload() { } -Upload::Upload(API api) : api(api) -{ - this->api.endpoint = "song/data"; -} #pragma endregion @@ -97,13 +91,6 @@ void Upload::uploadSongsFromDirectory(const std::string& directory, } } - if (!confirmUpload) - { - confirmUpload = false; - break; - } - } - cout << "uploading songs\n"; for (auto& song: songs) { @@ -126,10 +113,9 @@ void Upload::uploadSongWithMetadata(Managers::CommitManager::Album &album, Model auto url = retrieveUrl(); cout<<"url "<m_token.tokenType}; + 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; @@ -146,7 +132,6 @@ void Upload::uploadSongWithMetadata(Managers::CommitManager::Album &album, Model cout<<"\n\nMeta:\n"< Date: Sun, 9 Jan 2022 02:04:56 -0500 Subject: [PATCH 7/9] Updated Readme --- CMakeLists.txt | 13 ++++++++++--- README.md | 2 +- conanfile.txt | 12 ++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0161e1..63c269e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,8 +16,11 @@ if(WIN32) if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL ${vs_ver}) message("Visual Studio version is at least ${vs_ver}") - set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++latest") - set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++latest") + set(CMAKE_CXX_STANDARD_COMPILE_OPTION "-std:c++latest") + set(CMAKE_CXX_EXTENSION_COMPILE_OPTION "-std:c++latest") + + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) endif() else() check_cxx_compiler_flag("-std=c++17" COMPILER_SUPPORTS_CXX17) @@ -67,7 +70,11 @@ set(IDM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") # conan -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +set(CONAN_BUILDINFO +${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) + +message("conan build info ${CONAN_BUILDINFO}") +include(${CONAN_BUILDINFO}) conan_basic_setup() include_directories(${CPR_INCLUDE_DIRS} ${IDM_INCLUDE_DIR}) diff --git a/README.md b/README.md index 6b02d47..16e8363 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ cmake --build . -j The program has been built and can be executed by the binary file *icd*. For information on how to use icd, merely execute the program without any command line arguments. ### Downloading Song -``BASH +```BASH icd download -u spacecadet -p stellar40 -h https://icarus.com -b 15 ``` diff --git a/conanfile.txt b/conanfile.txt index 1a26411..cf5429e 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -6,3 +6,15 @@ cpr/1.7.2 [generators] cmake + +[options] +openssl:shared=False +libcurl:shared=False +cpr:shared=False +libcurl:with_ssl=openssl +libcurl:with_ftp=False +libcurl:with_gopher=False +libcurl:with_imap=False +libcurl:with_pop3=False +libcurl:with_smb=False +libcurl:with_smtp=False \ No newline at end of file From c8e8c1a460f1f68c25c43354e69a60540ca82c86 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Sun, 9 Jan 2022 02:16:51 -0500 Subject: [PATCH 8/9] Changed cmake version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63c269e..a9f6ce7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.14) project(IcarusDownloadManager) From d9962749c8cea17ddd24d7c43601c859e15cbceb Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Sun, 9 Jan 2022 18:06:43 -0500 Subject: [PATCH 9/9] Ready for release --- README.md | 13 +++++++--- include/Models/Song.h | 46 ++++++++++++++++++++++++++++++++-- src/Main.cpp | 2 +- src/Managers/CommitManager.cpp | 39 ++++++++++++++++------------ src/Syncers/Upload.cpp | 5 ++-- 5 files changed, 80 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 16e8363..4434a28 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ IcarusDownloadManager is a Linux CLI software client application that has the fe * C++ with C++17 features * CMake -* GCC >= 9 +* GCC >= 9 or Visual Studio >= 16 [2019] * [conan](https://github.com/conan-io/conan) * [json](https://github.com/nlohmann/json) * [openssl](https://github.com/openssl/openssl) @@ -28,18 +28,20 @@ cd build conan install .. --build -cmake -DCMAKE_BUILD_TYPE=RELEASE -cmake --build . -j +cmake .. +cmake --build . --config release -j ``` The program has been built and can be executed by the binary file *icd*. For information on how to use icd, merely execute the program without any command line arguments. ### Downloading Song + ```BASH icd download -u spacecadet -p stellar40 -h https://icarus.com -b 15 ``` ### Uploading Song + ```BASH icd upload -u spacecadet -p stellar40 -h https://icarus.com -s /path/of/song.mp3 ``` @@ -53,16 +55,18 @@ icd upload-meta -u spacecadet -p stellar40 -h https://icarus.com -s /path/of/son ### Uploading Song with metadata from directory ```BASH -icd upload-meta -u spacecadet -p stellar40 -h https://icarus.com -smca /path/where/songs/and/metadata/exist +icd upload-meta -u spacecadet -p stellar40 -h https://icarus.com -smca /path/where/songs/and/metadata/exists/ ``` ### Retrieving Song in json + ```Bash icd retrieve -u spacecadet -p stellar40 -h https://icarus.com -rt songs ``` ### Deleting Song + ```BASH icd delete -u spacecadet -p stellar40 -h https://icarus.com -D 15 ``` @@ -74,6 +78,7 @@ Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on the code of conduc ## Versioning +[v0.2.0](https://github.com/kdeng00/IcarusDownloadManager/releases/tag/v0.2.0) [v0.1.1](https://github.com/kdeng00/IcarusDownloadManager/releases/tag/v0.1.1) [v0.1.0](https://github.com/kdeng00/IcarusDownloadManager/releases/tag/0.1.0) diff --git a/include/Models/Song.h b/include/Models/Song.h index 8512666..a66c787 100644 --- a/include/Models/Song.h +++ b/include/Models/Song.h @@ -1,8 +1,9 @@ #ifndef SONG_H_ #define SONG_H_ -#include -#include +#include +#include +#include namespace Models @@ -19,6 +20,44 @@ public: std::cout<<"\n"; } + std::string song_path() noexcept + { + std::stringstream buffer; + + buffer << this->directory; + + const auto count = this->directory.size(); + + if (this->directory.at(count - 1) != '/' || this->directory.at(count - 1) != '\\') + { + buffer << "/"; + } + + buffer << this->filename; + + return buffer.str(); + } + + int generate_filename_from_track() + { + auto result = 0; + std::stringstream buffer; + buffer << "track"; + + // NOTE: Multiple discs in one directory is not being addressed + if (this->track < 10) + { + buffer << "0"; + } + + buffer << this->track << ".mp3"; + + + this->filename.assign(buffer.str()); + + return result; + } + std::string toMetadataJson(); @@ -32,7 +71,10 @@ public: int track; int disc; std::string data; + [[deprecated("Use song_path() function instead")]] std::string songPath; + std::string filename; + std::string directory; }; class CoverArt diff --git a/src/Main.cpp b/src/Main.cpp index 965792e..eada2a0 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -14,7 +14,7 @@ using Managers::CommitManager; constexpr static auto IcarusDownloadManager_version() { - return "v0.1.2"; + return "v0.2.0"; } void printHelp() diff --git a/src/Managers/CommitManager.cpp b/src/Managers/CommitManager.cpp index 956d7b8..0fec9ac 100644 --- a/src/Managers/CommitManager.cpp +++ b/src/Managers/CommitManager.cpp @@ -1,23 +1,23 @@ #include"Managers/CommitManager.h" -#include -#include -#include -#include +#include +#include +#include +#include -#include"nlohmann/json.hpp" +#include "nlohmann/json.hpp" -#include"Models/API.h" -#include"Models/Song.h" -#include"Models/Token.h" -#include"Parsers/APIParser.h" -#include"Syncers/Delete.h" -#include"Syncers/Download.h" -#include"Syncers/RetrieveRecords.h" -#include"Syncers/Upload.h" +#include "Models/API.h" +#include "Models/Song.h" +#include "Models/Token.h" +#include "Parsers/APIParser.h" +#include "Syncers/Delete.h" +#include "Syncers/Download.h" +#include "Syncers/RetrieveRecords.h" +#include "Syncers/Upload.h" -#include"Managers/TokenManager.h" -#include"Managers/UserManager.h" +#include "Managers/TokenManager.h" +#include "Managers/UserManager.h" using std::cout; using std::endl; @@ -308,7 +308,9 @@ void CommitManager::singTargetUpload(const std::string &songPath, const std::str } song = *sng; - song.songPath = songPath; + const auto p = fs::path(songPath); + song.directory = p.parent_path.string(); + song.generate_filename_from_track(); Models::CoverArt cover; cover.title = song.title; @@ -363,6 +365,8 @@ void CommitManager::multiTargetUpload(const std::string &sourcePath) } auto album = retrieveMetadata(metadataPath); + songs.clear(); + songs.assign(album.songs.begin(), album.songs.end()); Upload up(api, token); @@ -399,6 +403,9 @@ CommitManager::Album CommitManager::retrieveMetadata(const std::string_view path song.album = album.album; song.year = album.year; song.genre = album.genre; + song.generate_filename_from_track(); + const auto p = fs::path(path); + song.directory = p.parent_path().string(); album.songs.push_back(song); } diff --git a/src/Syncers/Upload.cpp b/src/Syncers/Upload.cpp index d00ed66..006691b 100644 --- a/src/Syncers/Upload.cpp +++ b/src/Syncers/Upload.cpp @@ -112,7 +112,7 @@ void Upload::uploadSongWithMetadata(Managers::CommitManager::Album &album, Model { auto url = retrieveUrl(); - cout<<"url "<m_token.tokenType); auth.append(" " + this->m_token.accessToken); @@ -131,10 +131,11 @@ void Upload::uploadSongWithMetadata(Managers::CommitManager::Album &album, Model const auto meta = s.dump(); cout<<"\n\nMeta:\n"<