Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7177b01a98 | |||
| 996b84c25c | |||
| 9d8122df5c |
@@ -1,6 +1,17 @@
|
|||||||
# IcarusDownloadManager
|
# IcarusDownloadManager
|
||||||
|
|
||||||
IcarusDownloadManager is a Linux UI software client application that has the feature of uploading and downloading songs from the [Icarus](https://github.com/amazing-username/Icarus) Music Server.
|
IcarusDownloadManager is a Linux CLI software client application that has the feature of uploading and downloading songs from the [Icarus](https://github.com/amazing-username/Icarus) Music Server.
|
||||||
|
|
||||||
|
|
||||||
|
## Built With
|
||||||
|
|
||||||
|
* C++
|
||||||
|
* CMake
|
||||||
|
* GCC
|
||||||
|
* [Hunter](https://github.com/ruslo/hunter)
|
||||||
|
* libCurl
|
||||||
|
* [json](https://github.com/nlohmann/json)
|
||||||
|
* [cpr](http://whoshuu.github.io/cpr/)
|
||||||
|
|
||||||
|
|
||||||
### Getting Started
|
### Getting Started
|
||||||
@@ -16,18 +27,20 @@ cmake --build _builds --config Debug
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
The program has been built and can be executed by the binary file *icd*
|
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``
|
||||||
|
|
||||||
## Built With
|
### Uploading Song
|
||||||
|
``icd upload -u spacecadet -p stellar40 -h https://icarus.com -s /path/of/song.mp3``
|
||||||
|
|
||||||
|
### Retrieving Song in json
|
||||||
|
``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``
|
||||||
|
|
||||||
* C++
|
|
||||||
* CMake
|
|
||||||
* GCC
|
|
||||||
* [Hunter](https://github.com/ruslo/hunter)
|
|
||||||
* libCurl
|
|
||||||
* [json](https://github.com/nlohmann/json)
|
|
||||||
* [cpr](http://whoshuu.github.io/cpr/)
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -35,7 +48,8 @@ Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on the code of conduc
|
|||||||
|
|
||||||
## Versioning
|
## Versioning
|
||||||
|
|
||||||
[v0.1.0](https://github.com/amazing-username/IcarusDownloadManager/releases/tag/0.1.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)
|
||||||
|
|
||||||
## Authors
|
## Authors
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define ACTIONMANAGER_H_
|
#define ACTIONMANAGER_H_
|
||||||
|
|
||||||
#include<string>
|
#include<string>
|
||||||
|
#include<string_view>
|
||||||
#include<array>
|
#include<array>
|
||||||
#include<vector>
|
#include<vector>
|
||||||
|
|
||||||
@@ -17,25 +18,23 @@ namespace Managers
|
|||||||
|
|
||||||
Models::IcarusAction retrieveIcarusAction() const;
|
Models::IcarusAction retrieveIcarusAction() const;
|
||||||
private:
|
private:
|
||||||
bool isNumber(std::string);
|
constexpr std::array<const char*, 12> supportedFlags() noexcept;
|
||||||
|
constexpr std::array<const char*, 4> supportedActions() noexcept;
|
||||||
|
|
||||||
|
bool isNumber(const std::string_view) noexcept;
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
void validateFlags();
|
void validateFlags();
|
||||||
|
|
||||||
std::vector<std::string> parsedFlags();
|
std::vector<std::string> parsedFlags();
|
||||||
|
|
||||||
void printAction();
|
void printAction() noexcept;
|
||||||
void printFlags();
|
void printFlags() noexcept;
|
||||||
|
|
||||||
std::string action;
|
std::string action;
|
||||||
std::array<std::string, 4> supportedActions{
|
|
||||||
"download", "upload", "retrieve", "delete"
|
|
||||||
};
|
|
||||||
std::array<std::string, 11> supportedFlags{
|
|
||||||
"-u", "-p", "-t", "-h", "-s", "-sd",
|
|
||||||
"-sr", "-d", "-D", "-b", "-rt"
|
|
||||||
};
|
|
||||||
std::vector<Models::Flags> flags;
|
std::vector<Models::Flags> flags;
|
||||||
|
|
||||||
char **params;
|
char **params;
|
||||||
int paramCount;
|
int paramCount;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,12 +17,16 @@ namespace Managers
|
|||||||
|
|
||||||
void commitAction();
|
void commitAction();
|
||||||
|
|
||||||
enum RetrieveTypes
|
enum class RetrieveTypes
|
||||||
{
|
{
|
||||||
songs
|
songs
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class ActionValues;
|
||||||
|
|
||||||
|
std::map<std::string, ActionValues> mapActions() noexcept;
|
||||||
|
|
||||||
Models::Token parseToken(Models::API);
|
Models::Token parseToken(Models::API);
|
||||||
|
|
||||||
void deleteSong();
|
void deleteSong();
|
||||||
@@ -30,7 +34,7 @@ namespace Managers
|
|||||||
void retrieveObjects();
|
void retrieveObjects();
|
||||||
void uploadSong();
|
void uploadSong();
|
||||||
|
|
||||||
enum ActionValues
|
enum class ActionValues
|
||||||
{
|
{
|
||||||
deleteAct,
|
deleteAct,
|
||||||
downloadAct,
|
downloadAct,
|
||||||
@@ -38,12 +42,6 @@ namespace Managers
|
|||||||
uploadAct
|
uploadAct
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<std::string, ActionValues> mapActions{
|
|
||||||
{"delete", deleteAct}, {"download", downloadAct},
|
|
||||||
{"retrieve", retrieveAct},
|
|
||||||
{"upload", uploadAct}
|
|
||||||
};
|
|
||||||
|
|
||||||
Models::IcarusAction icaAction;
|
Models::IcarusAction icaAction;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ namespace Syncers
|
|||||||
const int OK = 200;
|
const int OK = 200;
|
||||||
const int UNAUTHORIZED = 401;
|
const int UNAUTHORIZED = 401;
|
||||||
const int NOTFOUND = 404;
|
const int NOTFOUND = 404;
|
||||||
|
|
||||||
|
enum class Result
|
||||||
|
{
|
||||||
|
OK = 200,
|
||||||
|
UNAUTHORIZED = 401,
|
||||||
|
NOTFOUND = 404
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ namespace Syncers
|
|||||||
Upload(Models::API);
|
Upload(Models::API);
|
||||||
|
|
||||||
Models::Song uploadSong(const Models::Token&, Models::Song&);
|
Models::Song uploadSong(const Models::Token&, Models::Song&);
|
||||||
void uploadSongsFromDirectory(const Models::Token&, const std::string&, bool);
|
void uploadSongsFromDirectory(const Models::Token&,
|
||||||
|
const std::string&, const bool, bool);
|
||||||
private:
|
private:
|
||||||
Managers::FileManager fMgr;
|
Managers::FileManager fMgr;
|
||||||
Models::API api;
|
Models::API api;
|
||||||
@@ -40,7 +41,7 @@ namespace Syncers
|
|||||||
|
|
||||||
void printSongDetails();
|
void printSongDetails();
|
||||||
void printSongDetails(std::vector<Models::Song>&);
|
void printSongDetails(std::vector<Models::Song>&);
|
||||||
void printJsonData(nlohmann::json);
|
void printJsonData(const nlohmann::json&);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -31,7 +31,8 @@ void printHelp()
|
|||||||
cout<<"Required for upload\n";
|
cout<<"Required for upload\n";
|
||||||
cout<<"-s path of song\n";
|
cout<<"-s path of song\n";
|
||||||
cout<<"-sd directory where to search for songs to upload (Optional)\n";
|
cout<<"-sd directory where to search for songs to upload (Optional)\n";
|
||||||
cout<<"-sr directory where to recursively search for songs to upload (Optional)\n\n";
|
cout<<"-sr directory where to recursively search for songs to upload (Optional)\n";
|
||||||
|
cout<<"-nc will not prompt the user when uploading from a directory\n\n";
|
||||||
|
|
||||||
cout<<"Required for download\n";
|
cout<<"Required for download\n";
|
||||||
cout<<"-b song id\n";
|
cout<<"-b song id\n";
|
||||||
@@ -50,13 +51,13 @@ int main(int argc, char** argv)
|
|||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
printHelp();
|
printHelp();
|
||||||
return 1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionManager actMgr{argv, argc};
|
ActionManager actMgr(argv, argc);
|
||||||
auto chosenAction = actMgr.retrieveIcarusAction();
|
auto chosenAction = actMgr.retrieveIcarusAction();
|
||||||
|
|
||||||
CommitManager commitMgr{chosenAction};
|
CommitManager commitMgr(chosenAction);
|
||||||
commitMgr.commitAction();
|
commitMgr.commitAction();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
using std::cout;
|
using std::cout;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
using std::string_view;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
using Models::Flags;
|
using Models::Flags;
|
||||||
@@ -27,14 +28,24 @@ namespace Managers
|
|||||||
#pragma
|
#pragma
|
||||||
IcarusAction ActionManager::retrieveIcarusAction() const
|
IcarusAction ActionManager::retrieveIcarusAction() const
|
||||||
{
|
{
|
||||||
auto icarusAction = IcarusAction{};
|
IcarusAction icarusAction;
|
||||||
icarusAction.flags = flags;
|
icarusAction.flags = flags;
|
||||||
icarusAction.action = action;
|
icarusAction.action = action;
|
||||||
|
|
||||||
return icarusAction;
|
return icarusAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ActionManager::isNumber(string val)
|
|
||||||
|
constexpr std::array<const char*, 12> ActionManager::supportedFlags() noexcept
|
||||||
|
{
|
||||||
|
constexpr std::array<const char*, 12> 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(),
|
return !val.empty() && std::find_if(val.begin(),
|
||||||
val.end(), [](char c)
|
val.end(), [](char c)
|
||||||
@@ -59,8 +70,16 @@ namespace Managers
|
|||||||
|
|
||||||
Flags flg{};
|
Flags flg{};
|
||||||
|
|
||||||
|
auto allSupportedFlags = supportedFlags();
|
||||||
|
|
||||||
for (auto flag : flagVals)
|
for (auto flag : flagVals)
|
||||||
{
|
{
|
||||||
|
if (flag.compare("-nc") == 0)
|
||||||
|
{
|
||||||
|
flg.flag = flag;
|
||||||
|
flags.push_back(flg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (flag.size() > 3 || isNumber(flag))
|
if (flag.size() > 3 || isNumber(flag))
|
||||||
{
|
{
|
||||||
flg.value = flag;
|
flg.value = flag;
|
||||||
@@ -70,10 +89,10 @@ namespace Managers
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::any_of(supportedFlags.begin(), supportedFlags.end(),
|
if (std::any_of(allSupportedFlags.begin(), allSupportedFlags.end(),
|
||||||
[&](string& val)
|
[&](const char *val)
|
||||||
{
|
{
|
||||||
return !val.compare(flag);
|
return !flag.compare(val);
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
//cout<<"flag "<<flag<<endl;
|
//cout<<"flag "<<flag<<endl;
|
||||||
@@ -81,7 +100,7 @@ namespace Managers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout<<"Action is not valid"<<endl;
|
cout<<"Flag is not valid"<<endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,18 +108,19 @@ namespace Managers
|
|||||||
|
|
||||||
vector<string> ActionManager::parsedFlags()
|
vector<string> ActionManager::parsedFlags()
|
||||||
{
|
{
|
||||||
auto parsed = vector<string>{};
|
auto parsed = vector<string>();
|
||||||
|
|
||||||
for (auto i = 2; i < paramCount; ++i)
|
for (auto i = 2; i < paramCount; ++i)
|
||||||
{
|
{
|
||||||
parsed.push_back(std::move(*(params + i)));
|
const std::string flag(std::move(*(params + i)));
|
||||||
|
parsed.push_back(std::move(flag));
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma
|
#pragma
|
||||||
void ActionManager::printAction()
|
void ActionManager::printAction() noexcept
|
||||||
{
|
{
|
||||||
if (action.empty())
|
if (action.empty())
|
||||||
{
|
{
|
||||||
@@ -111,7 +131,7 @@ namespace Managers
|
|||||||
cout<<"Action is "<<action<<endl;
|
cout<<"Action is "<<action<<endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ActionManager::printFlags()
|
void ActionManager::printFlags() noexcept
|
||||||
{
|
{
|
||||||
cout<<"\nPrinting flags..."<<endl;
|
cout<<"\nPrinting flags..."<<endl;
|
||||||
for (auto flag: flags)
|
for (auto flag: flags)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace Managers
|
|||||||
#pragma
|
#pragma
|
||||||
CommitManager::CommitManager(IcarusAction& icaAct) : icaAction(std::move(icaAct))
|
CommitManager::CommitManager(IcarusAction& icaAct) : icaAction(std::move(icaAct))
|
||||||
{ }
|
{ }
|
||||||
#pragma Constructors;
|
#pragma Constructors
|
||||||
|
|
||||||
|
|
||||||
#pragma
|
#pragma
|
||||||
@@ -44,23 +44,42 @@ namespace Managers
|
|||||||
{
|
{
|
||||||
auto action = icaAction.action;
|
auto action = icaAction.action;
|
||||||
cout<<"Commiting "<<action<<" action"<<endl;
|
cout<<"Commiting "<<action<<" action"<<endl;
|
||||||
switch (mapActions[action])
|
switch (mapActions()[action])
|
||||||
{
|
{
|
||||||
case deleteAct:
|
case ActionValues::deleteAct:
|
||||||
deleteSong();
|
deleteSong();
|
||||||
break;
|
break;
|
||||||
case downloadAct:
|
case ActionValues::downloadAct:
|
||||||
downloadSong();
|
downloadSong();
|
||||||
break;
|
break;
|
||||||
case retrieveAct:
|
case ActionValues::retrieveAct:
|
||||||
retrieveObjects();
|
retrieveObjects();
|
||||||
break;
|
break;
|
||||||
case uploadAct:
|
case ActionValues::uploadAct:
|
||||||
uploadSong();
|
uploadSong();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum class ActionValues;
|
||||||
|
|
||||||
|
std::map<std::string, CommitManager::ActionValues>
|
||||||
|
CommitManager::mapActions() noexcept
|
||||||
|
{
|
||||||
|
const std::map<std::string, ActionValues> actions{
|
||||||
|
{"delete", ActionValues::deleteAct},
|
||||||
|
{"download", ActionValues::downloadAct},
|
||||||
|
{"retrieve", ActionValues::retrieveAct},
|
||||||
|
{"upload", ActionValues::uploadAct}
|
||||||
|
};
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Token CommitManager::parseToken(API api)
|
Token CommitManager::parseToken(API api)
|
||||||
{
|
{
|
||||||
cout<<"fetching token"<<endl;
|
cout<<"fetching token"<<endl;
|
||||||
@@ -157,8 +176,9 @@ namespace Managers
|
|||||||
}
|
}
|
||||||
void CommitManager::uploadSong()
|
void CommitManager::uploadSong()
|
||||||
{
|
{
|
||||||
bool uploadSingleSong = true;
|
auto uploadSingleSong = true;
|
||||||
bool recursiveDirectory = false;
|
auto recursiveDirectory = false;
|
||||||
|
auto noConfirm = false;
|
||||||
string songDirectory;
|
string songDirectory;
|
||||||
APIParser apiPrs{icaAction};
|
APIParser apiPrs{icaAction};
|
||||||
auto api = apiPrs.retrieveAPI();
|
auto api = apiPrs.retrieveAPI();
|
||||||
@@ -186,6 +206,10 @@ namespace Managers
|
|||||||
songDirectory = value;
|
songDirectory = value;
|
||||||
uploadSingleSong = false;
|
uploadSingleSong = false;
|
||||||
recursiveDirectory = true;
|
recursiveDirectory = true;
|
||||||
|
}
|
||||||
|
else if (flag.compare("-nc") == 0)
|
||||||
|
{
|
||||||
|
noConfirm = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +222,7 @@ namespace Managers
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout<<"Uploading songs from " << songDirectory << endl;
|
cout<<"Uploading songs from " << songDirectory << endl;
|
||||||
upld.uploadSongsFromDirectory(token, songDirectory, recursiveDirectory);
|
upld.uploadSongsFromDirectory(token, songDirectory, noConfirm, recursiveDirectory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma Functions
|
#pragma Functions
|
||||||
|
|||||||
+32
-3
@@ -8,6 +8,7 @@
|
|||||||
#include"Syncers/Upload.h"
|
#include"Syncers/Upload.h"
|
||||||
|
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
using std::cin;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
using std::exception;
|
using std::exception;
|
||||||
using std::string;
|
using std::string;
|
||||||
@@ -46,6 +47,7 @@ namespace Syncers
|
|||||||
);
|
);
|
||||||
|
|
||||||
cout << "status code: " << r.status_code<< std::endl;
|
cout << "status code: " << r.status_code<< std::endl;
|
||||||
|
cout << r.text << endl;
|
||||||
auto result = nlohmann::json::parse(r.text);
|
auto result = nlohmann::json::parse(r.text);
|
||||||
cout<<"Finished"<<endl;
|
cout<<"Finished"<<endl;
|
||||||
song.id = result["id"].get<int>();
|
song.id = result["id"].get<int>();
|
||||||
@@ -59,7 +61,7 @@ namespace Syncers
|
|||||||
|
|
||||||
return song;
|
return song;
|
||||||
}
|
}
|
||||||
catch (exception e)
|
catch (exception& e)
|
||||||
{
|
{
|
||||||
auto msg = e.what();
|
auto msg = e.what();
|
||||||
cout<<msg<<endl;
|
cout<<msg<<endl;
|
||||||
@@ -70,11 +72,38 @@ namespace Syncers
|
|||||||
|
|
||||||
void Upload::uploadSongsFromDirectory(const Models::Token& token,
|
void Upload::uploadSongsFromDirectory(const Models::Token& token,
|
||||||
const std::string& directory,
|
const std::string& directory,
|
||||||
bool recursive = false)
|
const bool noConfirm, bool recursive = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto songs = retrieveAllSongsFromDirectory(directory, recursive);
|
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;
|
||||||
|
|
||||||
|
if (answer == 'y' || answer == 'Y')
|
||||||
|
{
|
||||||
|
confirmUpload = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (answer == 'n' || answer == 'N')
|
||||||
|
{
|
||||||
|
confirmUpload = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!confirmUpload)
|
||||||
|
{
|
||||||
|
cout << "exiting...\n";
|
||||||
|
std::exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "uploading songs\n";
|
||||||
for (auto& song: songs)
|
for (auto& song: songs)
|
||||||
{
|
{
|
||||||
song = uploadSong(token, song);
|
song = uploadSong(token, song);
|
||||||
@@ -168,7 +197,7 @@ namespace Syncers
|
|||||||
cout<<"Path: "<<song.songPath<<endl;
|
cout<<"Path: "<<song.songPath<<endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Upload::printJsonData(json obj)
|
void Upload::printJsonData(const json& obj)
|
||||||
{
|
{
|
||||||
cout<<endl<<endl<<"JSon data: "<<endl;
|
cout<<endl<<endl<<"JSon data: "<<endl;
|
||||||
cout<<"id: "<<obj["id"]<<endl;
|
cout<<"id: "<<obj["id"]<<endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user