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
+54 -52
View File
@@ -12,78 +12,80 @@
namespace Managers namespace Managers
{ {
class ActionManager
class ActionManager
{
public:
ActionManager(char**, int);
Models::IcarusAction retrieveIcarusAction() const;
private:
constexpr std::array<const char*, 16> supportedFlags() noexcept
{ {
public: constexpr std::array<const char*, 16> allFlags{"-u", "-p", "-t", "-h", "-s",
ActionManager(char**, int); "-sd", "-sr", "-d", "-D", "-b", "-rt", "-nc",
"-m", "-ca", "-smca", "-t"};
Models::IcarusAction retrieveIcarusAction() const; return allFlags;
private: }
constexpr std::array<const char*, 16> supportedFlags() noexcept constexpr std::array<const char*, 4> supportedActions() noexcept;
void initialize();
void validateFlags();
// Checks to see if the flag is valid
template<typename Str>
bool isValidFlag(const Str flag)
{
const auto flags = supportedFlags();
const auto i = std::find_if(flags.begin(), flags.end(), [&](const Str &f)
{ {
constexpr std::array<const char*, 16> allFlags{"-u", "-p", "-t", "-h", "-s", return f.compare(flag) == 0 ? true : false;
"-sd", "-sr", "-d", "-D", "-b", "-rt", "-nc", });
"-m", "-ca", "-smca", "-t"};
return allFlags; auto result = i != flags.end() ? true : false;
}
constexpr std::array<const char*, 4> supportedActions() noexcept;
void initialize(); return result;
void validateFlags(); }
// Checks to see if the flag is valid
template<typename Str> template<typename Str>
bool isValidFlag(const Str flag) bool doesFlagHaveValue(const Str flag)
{
const auto flags = parsedFlags();
auto i = std::find_if(flags.begin(), flags.end(), [&](const Str &f)
{ {
const auto flags = supportedFlags(); return f.compare(flag) == 0 ? true : false;
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; if (i != flags.end())
return result;
}
template<typename Str>
bool doesFlagHaveValue(const Str flag)
{ {
const auto flags = parsedFlags(); if (++i != flags.end() && !isValidFlag<Str>(*i))
auto i = std::find_if(flags.begin(), flags.end(), [&](const Str &f)
{ {
return f.compare(flag) == 0 ? true : false; return true;
});
if (i != flags.end())
{
if (++i != flags.end() && !isValidFlag<Str>(*i))
{
return true;
}
else
{
return false;
}
} }
else else
{ {
return false; return false;
} }
} }
else
{
return false;
}
}
std::vector<std::string> parsedFlags(); void printAction() noexcept;
void printFlags() noexcept;
void printAction() noexcept; std::string action;
void printFlags() noexcept;
std::string action; std::vector<Models::Flags> flags;
std::vector<Models::Flags> flags; char **params;
int paramCount;
};
char **params;
int paramCount;
};
} }
#endif #endif
+186 -184
View File
@@ -14,197 +14,199 @@
namespace Managers namespace Managers
{ {
class CommitManager
class CommitManager
{
public:
CommitManager(Models::IcarusAction&);
void commitAction();
enum class RetrieveTypes
{ {
public: songs
CommitManager(Models::IcarusAction&); };
void commitAction();
enum class RetrieveTypes
{
songs
};
// Used for parsing songs from the metadata file // Used for parsing songs from the metadata file
class Album class Album
{ {
public: public:
Album() = default; Album() = default;
void printInfo(); void printInfo();
std::string album; std::string album;
std::string albumArtist; std::string albumArtist;
std::string genre; std::string genre;
int year; int year;
int trackCount; int trackCount;
int discCount; int discCount;
std::vector<Models::Song> songs; std::vector<Models::Song> songs;
};
private:
enum class ActionValues;
std::map<std::string, ActionValues> mapActions() noexcept;
Models::Token parseToken(Models::API);
void deleteSong();
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
// * 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 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<typename Song, typename Str>
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<char, Str>(songPath, 'd', dl);
auto k = Utilities::Checks::itemIterInContainer<char, Str>(songPath, 'k', dl);
auto dot = Utilities::Checks::itemIterInContainer<char, Str>(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: "<<dStr<<" TStr: " << tStr<<"\n";
if (Utilities::Checks::isNumber(tStr))
{
track = std::atoi(tStr.c_str());
}
else if (Utilities::Checks::isNumber(dStr))
{
disc = std::atoi(dStr.c_str());
}
}
break;
}
}
song.disc = disc;
song.track = track;
}
template<typename Song, typename Str>
void parseDiscAndTrack(Song &song, const Str &trackID)
{
auto sep = [](char c, char t) { return c == t; };
auto separator = Utilities::Checks::itemIterInContainer<char, Str>(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()
{
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,
UPLOAD_SONG_WITH_METADATA // Uploads the song with metadata, including cover art
};
Models::IcarusAction icaAction;
}; };
private:
enum class ActionValues;
std::map<std::string, ActionValues> mapActions() noexcept;
void deleteSong();
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
// * 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 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<typename Song, typename Str>
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<char, Str>(songPath, 'd', dl);
auto k = Utilities::Checks::itemIterInContainer<char, Str>(songPath, 'k', dl);
auto dot = Utilities::Checks::itemIterInContainer<char, Str>(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: "<<dStr<<" TStr: " << tStr<<"\n";
if (Utilities::Checks::isNumber(tStr))
{
track = std::atoi(tStr.c_str());
}
else if (Utilities::Checks::isNumber(dStr))
{
disc = std::atoi(dStr.c_str());
}
}
break;
}
}
song.disc = disc;
song.track = track;
}
template<typename Song, typename Str>
void parseDiscAndTrack(Song &song, const Str &trackID)
{
auto sep = [](char c, char t) { return c == t; };
auto separator = Utilities::Checks::itemIterInContainer<char, Str>(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()
{
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,
UPLOAD_SONG_WITH_METADATA // Uploads the song with metadata, including cover art
};
Models::IcarusAction icaAction;
};
} }
#endif #endif
+18 -16
View File
@@ -5,25 +5,27 @@
namespace Managers namespace Managers
{ {
class FileManager
{
public:
FileManager();
FileManager(std::string);
void saveFile(std::string); class FileManager
void modifyFilePath(std::string); {
public:
FileManager();
FileManager(std::string);
char* retrieveFileBuffer() const; void saveFile(std::string);
int retrieveFileBufferLength() const; void modifyFilePath(std::string);
private:
void readFile(); char* retrieveFileBuffer() const;
int retrieveFileBufferLength() const;
private:
void readFile();
std::string filePath;
char* fileBuffer;
bool fileRead;
int fileBufferLength;
};
std::string filePath;
char* fileBuffer;
bool fileRead;
int fileBufferLength;
};
} }
#endif #endif
+12 -10
View File
@@ -7,17 +7,19 @@
namespace Managers namespace Managers
{ {
class TokenManager
{
public:
TokenManager(const Models::User&);
TokenManager(const Models::User&, Models::API&);
Models::Token requestToken(); class TokenManager
private: {
Models::API api; public:
Models::User user; TokenManager(const Models::User&);
}; TokenManager(const Models::User&, Models::API&);
Models::Token requestToken();
private:
Models::API api;
Models::User user;
};
} }
#endif #endif
+13 -11
View File
@@ -8,19 +8,21 @@
namespace Managers namespace Managers
{ {
class UserManager
{
public:
UserManager(Models::User);
UserManager(const Models::IcarusAction);
Models::User retrieveUser() const; class UserManager
private: {
void parseUserFromActions(); public:
UserManager(Models::User);
UserManager(const Models::IcarusAction);
Models::User retrieveUser() const;
private:
void parseUserFromActions();
Models::User user;
Models::IcarusAction icaAction;
};
Models::User user;
Models::IcarusAction icaAction;
};
} }
#endif #endif
+9 -6
View File
@@ -5,12 +5,15 @@
namespace Models namespace Models
{ {
struct API
{ class API
std::string url; {
std::string endpoint; public:
std::string version; std::string url;
}; std::string endpoint;
std::string version;
};
} }
#endif #endif
+15 -6
View File
@@ -5,12 +5,21 @@
namespace Models namespace Models
{ {
class Flags
{ class Flags
public: {
std::string flag; public:
std::string value; std::string flag;
}; std::string value;
};
struct Flags
{
std::string flag;
std::string value;
};
} }
#endif #endif
+31 -29
View File
@@ -11,41 +11,43 @@
namespace Models namespace Models
{ {
class IcarusAction
class IcarusAction
{
public:
std::string retrieveFlagValue(const std::string_view flag)
{ {
public: std::string value;
std::string retrieveFlagValue(const std::string_view flag)
const auto fg = std::find_if(flags.begin(), flags.end(), [&](Flags f)
{ {
std::string value; return f.flag.compare(flag) == 0 ? true : false;
});
const auto fg = std::find_if(flags.begin(), flags.end(), [&](Flags f) if (fg != flags.end())
{
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: "<<this->action<<"\n"; value.assign(fg->value);
std::cout<<"Flag count: "<<this->flags.size()<<"\n";
for (const auto &flag : this->flags)
{
std::cout<<"flag "<<flag.flag<<" value "<<flag.value<<"\n";
}
std::cout<<"\n";
} }
std::string action; return value;
std::vector<Flags> flags; }
}; void print_action_and_flags() noexcept
{
std::cout<<"Action: "<<this->action<<"\n";
std::cout<<"Flag count: "<<this->flags.size()<<"\n";
for (const auto &flag : this->flags)
{
std::cout<<"flag "<<flag.flag<<" value "<<flag.value<<"\n";
}
std::cout<<"\n";
}
std::string action;
std::vector<Flags> flags;
};
} }
#endif #endif
+31 -29
View File
@@ -7,40 +7,42 @@
namespace Models namespace Models
{ {
class Song
class Song
{
public:
Song() = default;
void printInfo()
{ {
public: std::cout<<"Title: "<<this->title<<"\n";
Song() = default; std::cout<<"\n";
}
void printInfo() std::string toMetadataJson();
{
std::cout<<"Title: "<<this->title<<"\n";
std::cout<<"\n";
}
std::string toMetadataJson();
int id; int id;
std::string title; std::string title;
std::string artist; std::string artist;
std::string album; std::string album;
std::string genre; std::string genre;
int year; int year;
int duration; int duration;
int track; int track;
int disc; int disc;
std::string data; std::string data;
std::string songPath; std::string songPath;
}; };
class CoverArt
{
public:
int id;
std::string title;
std::string path;
};
class CoverArt
{
public:
int id;
std::string title;
std::string path;
};
} }
#endif #endif
+8 -6
View File
@@ -5,12 +5,14 @@
namespace Models namespace Models
{ {
struct Token
{ struct Token
std::string accessToken; {
std::string tokenType; std::string accessToken;
int expiration; std::string tokenType;
}; int expiration;
};
} }
#endif #endif
+7 -5
View File
@@ -6,11 +6,13 @@
namespace Models namespace Models
{ {
struct UploadForm
{ struct UploadForm
std::string url; {
std::string filePath; std::string url;
}; std::string filePath;
};
} }
#endif #endif
+7 -5
View File
@@ -5,11 +5,13 @@
namespace Models namespace Models
{ {
struct User
{ struct User
std::string username; {
std::string password; std::string username;
}; std::string password;
};
} }
#endif #endif
+12 -10
View File
@@ -6,18 +6,20 @@
namespace Parsers namespace Parsers
{ {
class APIParser
{
public:
APIParser(Models::IcarusAction);
Models::API retrieveAPI() const; class APIParser
private: {
void parseAPI(); public:
APIParser(Models::IcarusAction);
Models::API retrieveAPI() const;
private:
void parseAPI();
Models::API api;
Models::IcarusAction icaAct;
};
Models::API api;
Models::IcarusAction icaAct;
};
} }
#endif #endif
+10 -8
View File
@@ -9,15 +9,17 @@
namespace Syncers namespace Syncers
{ {
class Delete : SyncerBase
{
public:
Delete(Models::API);
void deleteSong(const Models::Token, Models::Song); class Delete : SyncerBase
private: {
std::string retrieveUrl(Models::Song); public:
}; Delete(Models::API);
void deleteSong(const Models::Token, Models::Song);
private:
std::string retrieveUrl(Models::Song);
};
} }
#endif #endif
+14 -12
View File
@@ -12,20 +12,22 @@
namespace Syncers namespace Syncers
{ {
class Download : SyncerBase
{
public:
Download();
Download(Models::API);
Download(std::string);
void downloadSong(const Models::Token token, Models::Song); class Download : SyncerBase
private: {
std::string retrieveUrl(Models::Song); public:
Download();
Download(Models::API);
Download(std::string);
void downloadSong(const Models::Token token, Models::Song);
private:
std::string retrieveUrl(Models::Song);
std::string downloadFilePath;
void saveSong(Models::Song&);
};
std::string downloadFilePath;
void saveSong(Models::Song&);
};
} }
#endif #endif
+13 -11
View File
@@ -8,19 +8,21 @@
namespace Syncers namespace Syncers
{ {
class RetrieveRecords: public SyncerBase
{
public:
RetrieveRecords();
RetrieveRecords(Models::API, Models::Token);
void retrieve(Managers::CommitManager::RetrieveTypes); class RetrieveRecords: public SyncerBase
private: {
void fetchSongs(); public:
RetrieveRecords();
RetrieveRecords(Models::API, Models::Token);
void retrieve(Managers::CommitManager::RetrieveTypes);
private:
void fetchSongs();
Models::API api;
Models::Token token;
};
Models::API api;
Models::Token token;
};
} }
#endif #endif
+15 -13
View File
@@ -7,21 +7,23 @@
namespace Syncers namespace Syncers
{ {
class SyncerBase
{
protected:
Models::API api;
const int OK = 200;
const int UNAUTHORIZED = 401;
const int NOTFOUND = 404;
enum class Result class SyncerBase
{ {
OK = 200, protected:
UNAUTHORIZED = 401, Models::API api;
NOTFOUND = 404 const int OK = 200;
}; const int UNAUTHORIZED = 401;
const int NOTFOUND = 404;
enum class Result
{
OK = 200,
UNAUTHORIZED = 401,
NOTFOUND = 404
}; };
};
} }
#endif #endif
+24 -22
View File
@@ -19,34 +19,36 @@ namespace fs = std::filesystem;
namespace Syncers namespace Syncers
{ {
class Upload
class Upload
{
public:
Upload(Models::API api, Models::Token token) : m_token(token), api(api)
{ {
public: this->api.endpoint = "song/data";
Upload(Models::API api, Models::Token token) : m_token(token), api(api) }
{
this->api.endpoint = "song/data";
}
Models::Song uploadSong(Models::Song&); Models::Song uploadSong(Models::Song&);
void uploadSongsFromDirectory(const std::string&, const bool, bool); void uploadSongsFromDirectory(const std::string&, const bool, bool);
void uploadSongWithMetadata(Managers::CommitManager::Album&, Models::Song&, Models::CoverArt&); void uploadSongWithMetadata(Managers::CommitManager::Album&, Models::Song&, Models::CoverArt&);
private: private:
Managers::FileManager fMgr; Managers::FileManager fMgr;
Models::API api; Models::API api;
Models::Song song; Models::Song song;
Models::Token m_token; Models::Token m_token;
std::vector<Models::Song> retrieveAllSongsFromDirectory(const std::string&, std::vector<Models::Song> retrieveAllSongsFromDirectory(const std::string&,
bool); bool);
std::string retrieveUrl(); std::string retrieveUrl();
Models::Song retrieveSongPath(fs::directory_entry&); Models::Song retrieveSongPath(fs::directory_entry&);
void printSongDetails();
void printSongDetails(std::vector<Models::Song>&);
void printJsonData(const nlohmann::json&);
};
void printSongDetails();
void printSongDetails(std::vector<Models::Song>&);
void printJsonData(const nlohmann::json&);
};
} }
#endif #endif
+15 -13
View File
@@ -13,22 +13,24 @@
namespace UI namespace UI
{ {
class AboutWindow: public QDialog, public CommonWindow
{
Q_OBJECT
public:
AboutWindow(QWidget* parent=0);
~AboutWindow() = default;
private: class AboutWindow: public QDialog, public CommonWindow
void connections(); {
void setupWindow(); Q_OBJECT
public:
AboutWindow(QWidget* parent=0);
~AboutWindow() = default;
std::unique_ptr<QLabel> appName; private:
void connections();
void setupWindow();
std::unique_ptr<QLabel> appName;
private slots:
void closeWindow();
};
private slots:
void closeWindow();
};
} }
#endif #endif
+6
View File
@@ -10,6 +10,9 @@
#include<QPushButton> #include<QPushButton>
namespace UI
{
class CommonWindow class CommonWindow
{ {
public: public:
@@ -24,4 +27,7 @@ protected:
std::unique_ptr<QVBoxLayout> subLayoutTwoQt; std::unique_ptr<QVBoxLayout> subLayoutTwoQt;
int windowHeight, windowWidth; int windowHeight, windowWidth;
}; };
}
#endif #endif
+44 -42
View File
@@ -22,61 +22,63 @@
namespace UI namespace UI
{ {
class MainWindow: public QMainWindow, public CommonWindow
{ class MainWindow: public QMainWindow, public CommonWindow
Q_OBJECT {
public: Q_OBJECT
MainWindow(); public:
~MainWindow() = default; MainWindow();
private: ~MainWindow() = default;
void configureDownloadSection(); private:
void configureUploadSection(); void configureDownloadSection();
void configureWindowDimensions(); void configureUploadSection();
void configureWindowProperties(); void configureWindowDimensions();
void connections(); void configureWindowProperties();
void createMenus(); void connections();
void setupMainWidget(); void createMenus();
void setupMainWindow(); void setupMainWidget();
void setupWindowLists(); void setupMainWindow();
void setupWindowLists();
std::unique_ptr<QStackedWidget> widgetStack; std::unique_ptr<QStackedWidget> widgetStack;
std::unique_ptr<QVBoxLayout> stackLayout; std::unique_ptr<QVBoxLayout> stackLayout;
std::unique_ptr<QHBoxLayout> urlPortion; std::unique_ptr<QHBoxLayout> urlPortion;
std::unique_ptr<QHBoxLayout> songPathPortion; std::unique_ptr<QHBoxLayout> songPathPortion;
std::unique_ptr<QWidget> mainWidgetQt; std::unique_ptr<QWidget> mainWidgetQt;
std::unique_ptr<QWidget> uploadSongWidgetQt; std::unique_ptr<QWidget> uploadSongWidgetQt;
std::unique_ptr<QDockWidget> MainDockWidgetQt; std::unique_ptr<QDockWidget> MainDockWidgetQt;
std::unique_ptr<QComboBox> windowComboBox; std::unique_ptr<QComboBox> windowComboBox;
std::unique_ptr<QPushButton> uploadSongQt; std::unique_ptr<QPushButton> uploadSongQt;
std::unique_ptr<QTextEdit> urlQt; std::unique_ptr<QTextEdit> urlQt;
std::unique_ptr<QTextEdit> sourceFilePathQt; std::unique_ptr<QTextEdit> sourceFilePathQt;
std::unique_ptr<QLabel> urlLabel; std::unique_ptr<QLabel> urlLabel;
std::unique_ptr<QLabel> songPath; std::unique_ptr<QLabel> songPath;
std::unique_ptr<QMenu> fileMenuQt; std::unique_ptr<QMenu> fileMenuQt;
std::unique_ptr<QMenu> editMenuQt; std::unique_ptr<QMenu> editMenuQt;
std::unique_ptr<QMenu> helpMenuQt; std::unique_ptr<QMenu> helpMenuQt;
std::unique_ptr<QAction> closeApplicationQt; std::unique_ptr<QAction> closeApplicationQt;
std::unique_ptr<QAction> aboutApplicationQt; std::unique_ptr<QAction> aboutApplicationQt;
std::unique_ptr<AboutWindow> aboutWindow;
signals:
private slots:
void uploadSong();
void exitApplication();
void displaySoftwareInformation();
void setCurrentIndex(int);
};
std::unique_ptr<AboutWindow> aboutWindow;
signals:
private slots:
void uploadSong();
void exitApplication();
void displaySoftwareInformation();
void setCurrentIndex(int);
};
} }
#endif #endif
+13 -15
View File
@@ -6,26 +6,24 @@
namespace Utilities namespace Utilities
{ {
class Conversions
class Conversions
{
public:
Conversions();
static void toLowerChar(char &c)
{ {
public: if (std::isalpha(c))
Conversions();
static void toLowerChar(char &c)
{ {
if (std::isalpha(c)) c = std::tolower(c);
{
c = std::tolower(c);
}
} }
}
void initializeValues(); void initializeValues();
private:
};
template <typename T>
void printValue(T);
private:
};
} }
#endif #endif
+88 -80
View File
@@ -16,103 +16,111 @@ using Models::IcarusAction;
namespace Managers namespace Managers
{ {
#pragma
ActionManager::ActionManager(char **param, int paramCount) : #pragma region Constructors
params(std::move(param)), paramCount(paramCount) ActionManager::ActionManager(char **param, int paramCount) :
{ params(std::move(param)), paramCount(paramCount)
initialize(); {
} initialize();
#pragma Constructors }
#pragma endregion
#pragma #pragma region Functions
IcarusAction ActionManager::retrieveIcarusAction() const IcarusAction ActionManager::retrieveIcarusAction() const
{ {
IcarusAction icarusAction; IcarusAction icarusAction;
icarusAction.flags = flags; icarusAction.flags = flags;
icarusAction.action = action; icarusAction.action = action;
return icarusAction; 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()
{
validateFlags();
void ActionManager::initialize() action = std::move(string{params[1]});
{ transform(action.begin(), action.end(),
validateFlags(); action.begin(), ::tolower);
}
action = std::move(string{params[1]}); void ActionManager::validateFlags()
transform(action.begin(), action.end(), {
action.begin(), ::tolower);
}
void ActionManager::validateFlags()
{
cout<<"Validating flags\n"; cout<<"Validating flags\n";
const auto flagVals = parsedFlags(); const auto flagVals = parsedFlags();
for (auto flag = flagVals.begin(); flag != flagVals.end(); ++flag) for (auto flag = flagVals.begin(); flag != flagVals.end(); ++flag)
{
Flags flg;
cout<<"Value: "<<*flag<<"\n";
if (isValidFlag<string>(*flag) && doesFlagHaveValue<string>(*flag))
{
cout<<"Flag has value\n";
flg.flag = *flag;
flg.value = *(++flag);
}
else if (isValidFlag<string>(*flag))
{
cout<<"Flag does not have a value\n";
flg.flag = *flag;
}
else
{
cout<<"Flag "<<*flag<<" is not valid"<<endl;
exit(1);
}
flags.emplace_back(std::move(flg));
}
}
vector<string> ActionManager::parsedFlags()
{ {
vector<string> parsed; Flags flg;
parsed.reserve(paramCount); cout<<"Value: "<<*flag<<"\n";
for (auto i = 2; i < paramCount; ++i) if (isValidFlag<string>(*flag) && doesFlagHaveValue<string>(*flag))
{ {
const std::string flag(std::move(*(params + i))); cout<<"Flag has value\n";
parsed.emplace_back(std::move(flag)); flg.flag = *flag;
flg.value = *(++flag);
} }
else if (isValidFlag<string>(*flag))
return parsed;
}
#pragma
void ActionManager::printAction() noexcept
{
if (action.empty())
{ {
printf("Action is empty\n"); cout<<"Flag does not have a value\n";
flg.flag = *flag;
} }
else else
{ {
cout<<"Action is "<<action<<endl; cout<<"Flag "<<*flag<<" is not valid"<<endl;
exit(1);
} }
flags.emplace_back(std::move(flg));
} }
void ActionManager::printFlags() noexcept }
{
cout<<"\nPrinting flags..."<<endl; vector<string> ActionManager::parsedFlags()
for (auto flag: flags) {
{ auto parsed = vector<string>();
cout<<"flag "<<flag.flag<<endl;
cout<<"value "<<flag.value<<endl; for (auto i = 2; i < paramCount; ++i)
} {
} const std::string flag(std::move(*(params + i)));
#pragma Testing parsed.push_back(std::move(flag));
#pragma Functions }
return parsed;
}
#pragma region Testing
void ActionManager::printAction() noexcept
{
if (action.empty())
{
printf("Action is empty\n");
}
else
{
cout<<"Action is "<<action<<endl;
}
}
void ActionManager::printFlags() noexcept
{
cout<<"\nPrinting flags..."<<endl;
for (auto flag: flags)
{
cout<<"flag "<<flag.flag<<endl;
cout<<"value "<<flag.value<<endl;
}
}
#pragma endregion
#pragma endregion
} }
+390 -381
View File
@@ -40,390 +40,399 @@ namespace filesystem = std::filesystem;
namespace Managers namespace Managers
{ {
#pragma
CommitManager::CommitManager(IcarusAction& icaAct) : icaAction(std::move(icaAct)) #pragma region Constructors
{ } CommitManager::CommitManager(IcarusAction& icaAct) : icaAction(std::move(icaAct))
#pragma Constructors { }
#pragma endregion
#pragma #pragma region Functions
void CommitManager::commitAction() void CommitManager::commitAction()
{ {
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 ActionValues::deleteAct:
deleteSong();
break;
case ActionValues::downloadAct:
downloadSong();
break;
case ActionValues::retrieveAct:
retrieveObjects();
break;
case ActionValues::uploadAct:
uploadSong();
break;
case ActionValues::UPLOAD_SONG_WITH_METADATA:
uploadSongWithMetadata();
break;
default:
break;
}
}
enum class ActionValues;
std::map<std::string, CommitManager::ActionValues>
CommitManager::mapActions() noexcept
{ {
const std::map<std::string, ActionValues> actions{ case ActionValues::deleteAct:
{"delete", ActionValues::deleteAct}, deleteSong();
{"download", ActionValues::downloadAct}, break;
{"retrieve", ActionValues::retrieveAct}, case ActionValues::downloadAct:
{"upload", ActionValues::uploadAct}, downloadSong();
{"upload-meta", ActionValues::UPLOAD_SONG_WITH_METADATA} break;
}; case ActionValues::retrieveAct:
retrieveObjects();
return actions; break;
case ActionValues::uploadAct:
uploadSong();
break;
case ActionValues::UPLOAD_SONG_WITH_METADATA:
uploadSongWithMetadata();
break;
default:
break;
} }
}
Token CommitManager::parseToken(API api)
{
cout<<"fetching token\n";
UserManager usrMgr{icaAction};
auto user = usrMgr.retrieveUser();
std::map<std::string, CommitManager::ActionValues>
TokenManager tk{user, api}; CommitManager::mapActions() noexcept
{
return tk.requestToken(); const std::map<std::string, ActionValues> actions{
} {"delete", ActionValues::deleteAct},
{"download", ActionValues::downloadAct},
void CommitManager::deleteSong() {"retrieve", ActionValues::retrieveAct},
{ {"upload", ActionValues::uploadAct},
APIParser apiPrs{icaAction}; {"upload-meta", ActionValues::UPLOAD_SONG_WITH_METADATA}
auto api = apiPrs.retrieveAPI(); };
auto token = parseToken(api); return actions;
}
Song song{};
for (auto arg : icaAction.flags)
{
auto flag = arg.flag; Token CommitManager::parseToken(API api)
auto value = arg.value; {
cout<<"fetching token\n";
if (flag.compare("-D") == 0) UserManager usrMgr{icaAction};
{ auto user = usrMgr.retrieveUser();
song.id = atoi(value.c_str());
} TokenManager tk{user, api};
}
return tk.requestToken();
Delete del{api}; }
cout<<"Deleting song..."<<endl;
del.deleteSong(token, song); void CommitManager::deleteSong()
} {
void CommitManager::downloadSong() APIParser apiPrs{icaAction};
{ auto api = apiPrs.retrieveAPI();
cout<<"Starting downloading process..."<<endl;
auto token = parseToken(api);
APIParser apiPrs{icaAction};
auto api = apiPrs.retrieveAPI(); Song song{};
auto token = parseToken(api); for (auto arg : icaAction.flags)
{
Song song{}; auto flag = arg.flag;
auto value = arg.value;
for (auto arg : icaAction.flags)
{ if (flag.compare("-D") == 0)
auto flag = arg.flag; {
auto value = arg.value; song.id = atoi(value.c_str());
}
if (flag.compare("-d") == 0) }
{
song.songPath.assign(arg.value); Delete del{api};
} cout<<"Deleting song..."<<endl;
if (flag.compare("-b") == 0) del.deleteSong(token, song);
{ }
song.id = atoi(value.c_str()); void CommitManager::downloadSong()
} {
} cout<<"Starting downloading process..."<<endl;
Download dnld{api}; APIParser apiPrs{icaAction};
cout<<"downloading song"<<endl; auto api = apiPrs.retrieveAPI();
dnld.downloadSong(token, song);
} auto token = parseToken(api);
void CommitManager::retrieveObjects()
{ Song song{};
cout<<"Starting retrieve process..."<<endl;
for (auto arg : icaAction.flags)
APIParser apiPrs{icaAction}; {
auto api = apiPrs.retrieveAPI(); auto flag = arg.flag;
auto value = arg.value;
auto token = parseToken(api);
RetrieveTypes retrieveType; if (flag.compare("-d") == 0)
{
for (auto arg : icaAction.flags) song.songPath.assign(arg.value);
{ }
auto flag = arg.flag; if (flag.compare("-b") == 0)
auto value = arg.value; {
song.id = atoi(value.c_str());
if (flag.compare("-rt") == 0) }
{ }
if (value.compare("songs") == 0)
{ Download dnld{api};
retrieveType = RetrieveTypes::songs; cout<<"downloading song"<<endl;
break; dnld.downloadSong(token, song);
} }
} void CommitManager::retrieveObjects()
} {
cout<<"Starting retrieve process..."<<endl;
RetrieveRecords songs{api, token};
songs.retrieve(retrieveType); APIParser apiPrs{icaAction};
auto api = apiPrs.retrieveAPI();
}
void CommitManager::uploadSong() auto token = parseToken(api);
{ RetrieveTypes retrieveType;
auto uploadSingleSong = true;
auto recursiveDirectory = false; for (auto arg : icaAction.flags)
const auto noConfirm = checkForNoConfirm(); {
string songDirectory; auto flag = arg.flag;
APIParser apiPrs{icaAction}; auto value = arg.value;
auto api = apiPrs.retrieveAPI();
if (flag.compare("-rt") == 0)
auto token = parseToken(api); {
if (value.compare("songs") == 0)
Song song; {
retrieveType = RetrieveTypes::songs;
for (auto& arg : icaAction.flags) break;
{ }
auto flag = arg.flag; }
auto value = arg.value; }
if (flag.compare("-s") == 0) RetrieveRecords songs{api, token};
{ songs.retrieve(retrieveType);
song.songPath.assign(arg.value);
} }
else if (flag.compare("-sd") == 0)
{ void CommitManager::uploadSong()
songDirectory = value; {
uploadSingleSong = false; auto uploadSingleSong = true;
} auto recursiveDirectory = false;
else if (flag.compare("-sr") == 0) const auto noConfirm = checkForNoConfirm();
{ string songDirectory;
songDirectory = value; APIParser apiPrs{icaAction};
uploadSingleSong = false; auto api = apiPrs.retrieveAPI();
recursiveDirectory = true;
} auto token = parseToken(api);
}
Song song;
Upload upld{api, token};
if (uploadSingleSong) for (auto& arg : icaAction.flags)
{ {
cout<<"Uploading song..."<<endl; auto flag = arg.flag;
upld.uploadSong(song); auto value = arg.value;
}
else if (flag.compare("-s") == 0)
{ {
cout<<"Uploading songs from " << songDirectory << endl; song.songPath.assign(arg.value);
upld.uploadSongsFromDirectory(songDirectory, noConfirm, recursiveDirectory); }
} else if (flag.compare("-sd") == 0)
} {
songDirectory = value;
void CommitManager::uploadSongWithMetadata() uploadSingleSong = false;
{ }
cout<<"Uploading single song with metadata\n\n"; else if (flag.compare("-sr") == 0)
{
// Either the set of "-s", "-m", "-ca", "-t" flags or "-smca" must exist with values songDirectory = value;
// in order to be valid but not both uploadSingleSong = false;
const auto songPath = this->icaAction.retrieveFlagValue("-s"); recursiveDirectory = true;
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() && Upload upld{api, token};
!coverPath.empty() && !trackID.empty() ? true : false; if (uploadSingleSong)
{
const auto uni = this->icaAction.retrieveFlagValue("-smca"); cout<<"Uploading song..."<<endl;
const auto multiTarget = !uni.empty() ? true : false; upld.uploadSong(song);
}
if (singleTarget && multiTarget) else
{ {
cout<<"Cannot upload from source and directory\n"; cout<<"Uploading songs from " << songDirectory << endl;
return; upld.uploadSongsFromDirectory(songDirectory, noConfirm, recursiveDirectory);
} }
}
cout<<"Song path: "<<songPath<<"\n";
cout<<"TrackID: "<<trackID<<"\n";
cout<<"Metadata path: "<<metadataPath<<"\n";
cout<<"Cover Art path: "<<coverPath<<"\n"; void CommitManager::uploadSongWithMetadata()
{
if (singleTarget) cout<<"Uploading single song with metadata\n\n";
{
singTargetUpload(songPath, trackID, metadataPath, coverPath); // Either the set of "-s", "-m", "-ca", "-t" flags or "-smca" must exist with values
} // in order to be valid but not both
else if (multiTarget) const auto songPath = this->icaAction.retrieveFlagValue("-s");
{ const auto metadataPath = this->icaAction.retrieveFlagValue("-m");
multiTargetUpload(uni); const auto coverPath = this->icaAction.retrieveFlagValue("-ca");
} const auto trackID = this->icaAction.retrieveFlagValue("-t");
} const auto singleTarget = !songPath.empty() && !metadataPath.empty() &&
!coverPath.empty() && !trackID.empty() ? true : false;
void CommitManager::singTargetUpload(const std::string &songPath, const std::string &trackID, const auto uni = this->icaAction.retrieveFlagValue("-smca");
const std::string &metaPath, const std::string &coverPath) const auto multiTarget = !uni.empty() ? true : false;
{
APIParser apiPrs(icaAction); if (singleTarget && multiTarget)
auto api = apiPrs.retrieveAPI(); {
const auto token = parseToken(api); cout<<"Cannot upload from source and directory\n";
return;
auto album = retrieveMetadata(metaPath); }
album.printInfo();
cout<<"Song path: "<<songPath<<"\n";
Song song; cout<<"TrackID: "<<trackID<<"\n";
song.track = 1; cout<<"Metadata path: "<<metadataPath<<"\n";
song.disc = 1; cout<<"Cover Art path: "<<coverPath<<"\n";
cout<<"TrackID: "<<trackID<<"\n"; if (singleTarget)
{
parseDiscAndTrack<Song, std::string>(song, trackID); singTargetUpload(songPath, trackID, metadataPath, coverPath);
}
auto c = [](const Song &songA, const Song &songB) { return songA.track == songB.track && songA.disc == songB.disc; }; else if (multiTarget)
auto sng = Utilities::Checks::itemIterInContainer<Song, std::vector<Song>>(album.songs, song, c); {
multiTargetUpload(uni);
if (sng == album.songs.end()) }
{ }
cout<<"Not found with disc "<<song.disc<<" track "<<song.track<<"\n";
std::exit(-1);
} void CommitManager::singTargetUpload(const std::string &songPath, const std::string &trackID,
const std::string &metaPath, const std::string &coverPath)
song = *sng; {
song.songPath = songPath; APIParser apiPrs(icaAction);
auto api = apiPrs.retrieveAPI();
Models::CoverArt cover; const auto token = parseToken(api);
cover.title = song.title;
cover.path = coverPath; auto album = retrieveMetadata(metaPath);
album.printInfo();
Upload up(api, token);
up.uploadSongWithMetadata(album, song, cover); Song song;
} song.track = 1;
song.disc = 1;
void CommitManager::multiTargetUpload(const std::string &sourcePath)
{ cout<<"TrackID: "<<trackID<<"\n";
APIParser apiPrs(icaAction);
auto api = apiPrs.retrieveAPI(); parseDiscAndTrack<Song, std::string>(song, trackID);
const auto token = parseToken(api);
auto c = [](const Song &songA, const Song &songB) { return songA.track == songB.track && songA.disc == songB.disc; };
if (!fs::is_directory(sourcePath)) auto sng = Utilities::Checks::itemIterInContainer<Song, std::vector<Song>>(album.songs, song, c);
{
cout<<sourcePath<<" is not a directory\n"; if (sng == album.songs.end())
std::exit(-1); {
} cout<<"Not found with disc "<<song.disc<<" track "<<song.track<<"\n";
std::exit(-1);
std::vector<Song> songs; }
Models::CoverArt cover;
string metadataPath; song = *sng;
song.songPath = songPath;
for (auto &p: fs::directory_iterator(sourcePath))
{ Models::CoverArt cover;
const auto &pp = p.path(); cover.title = song.title;
const auto stem = pp.stem(); cover.path = coverPath;
const auto file = pp.filename();
const auto extension = pp.extension(); Upload up(api, token);
up.uploadSongWithMetadata(album, song, cover);
cout<<"Stem "<<stem<<" Extension "<<extension<<"\n"; }
if (extension.compare(".mp3") == 0) void CommitManager::multiTargetUpload(const std::string &sourcePath)
{ {
Song song; APIParser apiPrs(icaAction);
song.songPath = pp.string(); auto api = apiPrs.retrieveAPI();
const auto token = parseToken(api);
initializeDiscAndTrack<Song, std::string>(song);
if (!fs::is_directory(sourcePath))
songs.emplace_back(std::move(song)); {
} cout<<sourcePath<<" is not a directory\n";
else if (extension.compare(".jpg") == 0 || extension.compare(".png") == 0) std::exit(-1);
{ }
cover.path.assign(pp.string());
} std::vector<Song> songs;
else if (extension.compare(".json") == 0) Models::CoverArt cover;
{ string metadataPath;
metadataPath.assign(pp.string());
} for (auto &p: fs::directory_iterator(sourcePath))
} {
const auto &pp = p.path();
auto album = retrieveMetadata(metadataPath); const auto stem = pp.stem();
const auto file = pp.filename();
Upload up(api, token); const auto extension = pp.extension();
for (auto &song : songs) cout<<"Stem "<<stem<<" Extension "<<extension<<"\n";
{
up.uploadSongWithMetadata(album, song, cover); if (extension.compare(".mp3") == 0)
} {
} Song song;
song.songPath = pp.string();
#pragma region private
CommitManager::Album CommitManager::retrieveMetadata(const std::string_view path) initializeDiscAndTrack<Song, std::string>(song);
{
CommitManager::Album album; songs.emplace_back(std::move(song));
const auto fileContent = retrieveFileContent(path); }
cout<<"Parsing...\n"; else if (extension.compare(".jpg") == 0 || extension.compare(".png") == 0)
auto serialized = nlohmann::json::parse(fileContent); {
cout<<"Parsed\n"; cover.path.assign(pp.string());
}
album.album = serialized["album"].get<std::string>(); else if (extension.compare(".json") == 0)
album.albumArtist = serialized["album_artist"].get<std::string>(); {
album.genre = serialized["genre"].get<std::string>(); metadataPath.assign(pp.string());
album.year = serialized["year"].get<int>(); }
album.trackCount = serialized["track_count"].get<int>(); }
album.discCount = serialized["disc_count"].get<int>();
album.songs.reserve(album.trackCount); auto album = retrieveMetadata(metadataPath);
for (auto &j : serialized["tracks"]) Upload up(api, token);
{
Song song; for (auto &song : songs)
song.title = j["title"].get<std::string>(); {
song.track = j["track"].get<int>(); up.uploadSongWithMetadata(album, song, cover);
song.disc = j["disc"].get<int>(); }
song.artist = j["artist"].get<std::string>(); }
song.album = album.album;
song.year = album.year; #pragma region private
song.genre = album.genre; CommitManager::Album CommitManager::retrieveMetadata(const std::string_view path)
{
album.songs.push_back(song); CommitManager::Album album;
} const auto fileContent = retrieveFileContent(path);
cout<<"Parsing...\n";
return album; auto serialized = nlohmann::json::parse(fileContent);
} cout<<"Parsed\n";
string CommitManager::retrieveFileContent(const std::string_view path) album.album = serialized["album"].get<std::string>();
{ album.albumArtist = serialized["album_artist"].get<std::string>();
string path_str(path); album.genre = serialized["genre"].get<std::string>();
string value; album.year = serialized["year"].get<int>();
album.trackCount = serialized["track_count"].get<int>();
std::stringstream buffer; album.discCount = serialized["disc_count"].get<int>();
std::fstream file(path_str, std::ios::in); album.songs.reserve(album.trackCount);
buffer<<file.rdbuf();
file.close(); for (auto &j : serialized["tracks"])
{
value.assign(buffer.str()); Song song;
song.title = j["title"].get<std::string>();
return value; song.track = j["track"].get<int>();
} song.disc = j["disc"].get<int>();
#pragma endregion song.artist = j["artist"].get<std::string>();
song.album = album.album;
void CommitManager::Album::printInfo() song.year = album.year;
{ song.genre = album.genre;
std::cout<<"Album: "<<this->album<<"\n";
std::cout<<"Album Artist: "<<this->albumArtist<<"\n"; album.songs.push_back(song);
std::cout<<"Genre: "<<this->genre<<"\n"; }
std::cout<<"Year: "<<this->year<<"\n";
std::cout<<"Track count: "<<this->trackCount<<"\n"; return album;
std::cout<<"Disc count: "<<this->discCount<<"\n"; }
std::cout<<"\n";
} string CommitManager::retrieveFileContent(const std::string_view path)
{
#pragma Functions string path_str(path);
string value;
std::stringstream buffer;
std::fstream file(path_str, std::ios::in);
buffer<<file.rdbuf();
file.close();
value.assign(buffer.str());
return value;
}
#pragma endregion
void CommitManager::Album::printInfo()
{
std::cout<<"Album: "<<this->album<<"\n";
std::cout<<"Album Artist: "<<this->albumArtist<<"\n";
std::cout<<"Genre: "<<this->genre<<"\n";
std::cout<<"Year: "<<this->year<<"\n";
std::cout<<"Track count: "<<this->trackCount<<"\n";
std::cout<<"Disc count: "<<this->discCount<<"\n";
std::cout<<"\n";
}
#pragma region Functions
} }
+58 -51
View File
@@ -11,56 +11,63 @@ using std::string;
namespace Managers namespace Managers
{ {
FileManager::FileManager() {}
FileManager::FileManager(string filePath)
{
this->filePath = filePath;
readFile();
}
#pragma region Constructors
void FileManager::saveFile(string newFilePath) FileManager::FileManager() {}
{ FileManager::FileManager(string filePath)
if (!fileRead) {
readFile(); this->filePath = filePath;
readFile();
ofstream of{newFilePath, ofstream::binary}; }
of.write(fileBuffer, fileBufferLength); #pragma endregion
of.close();
}
#pragma region Functions
void FileManager::readFile() void FileManager::saveFile(string newFilePath)
{ {
ifstream is{filePath, ifstream::binary}; if (!fileRead)
if (is) readFile();
{
is.seekg (0, is.end); ofstream of{newFilePath, ofstream::binary};
fileBufferLength = is.tellg(); of.write(fileBuffer, fileBufferLength);
is.seekg (0, is.beg); of.close();
}
fileBuffer = new char [fileBufferLength];
void FileManager::readFile()
cout<< "Reading "<<fileBufferLength<<" characters... "<<endl;; {
is.read (fileBuffer,fileBufferLength); ifstream is{filePath, ifstream::binary};
if (is)
if (is) {
cout<<"all characters read successfully."; is.seekg (0, is.end);
else fileBufferLength = is.tellg();
cout<<"error: only "<<is.gcount()<<" could be read"; is.seekg (0, is.beg);
cout<<endl;
is.close(); fileBuffer = new char [fileBufferLength];
fileRead = true;
} cout<< "Reading "<<fileBufferLength<<" characters... "<<endl;;
} is.read (fileBuffer,fileBufferLength);
void FileManager::modifyFilePath(string filePath)
{ if (is)
this->filePath = filePath; cout<<"all characters read successfully.";
} else
cout<<"error: only "<<is.gcount()<<" could be read";
char* FileManager::retrieveFileBuffer() const cout<<endl;
{ is.close();
return fileBuffer; fileRead = true;
} }
}
int FileManager::retrieveFileBufferLength() const { return fileBufferLength; } void FileManager::modifyFilePath(string filePath)
{
this->filePath = filePath;
}
char* FileManager::retrieveFileBuffer() const
{
return fileBuffer;
}
int FileManager::retrieveFileBufferLength() const { return fileBufferLength; }
#pragma endregion
} }
+41 -39
View File
@@ -17,44 +17,46 @@ using Models::User;
namespace Managers namespace Managers
{ {
#pragma
TokenManager::TokenManager(const User& user)
{
this->user = user;
}
TokenManager::TokenManager(const User& user, API& api)
{
this->user = user;
this->api = api;
this->api.endpoint = "api/" + api.version
+ "/login";
}
#pragma Constructors
#pragma region Constructors
#pragma TokenManager::TokenManager(const User& user)
Token TokenManager::requestToken() {
{ this->user = user;
Token token{}; }
json usrObj; TokenManager::TokenManager(const User& user, API& api)
{
usrObj["username"] = user.username; this->user = user;
usrObj["password"] = user.password; this->api = api;
this->api.endpoint = "api/" + api.version
cout<<"Sending request for token"<<endl; + "/login";
auto url = api.url + api.endpoint; }
cout<<url<<endl; #pragma endregion
auto r = cpr::Post(cpr::Url{url},
cpr::Body{usrObj.dump()},
cpr::Header{{"Content-Type", "application/json"}}); #pragma region Functions
Token TokenManager::requestToken()
json res = json::parse(r.text); {
token.accessToken = res["token"]; Token token{};
token.tokenType = res["token_type"]; json usrObj;
cout<<"status code "<<r.status_code<<endl; usrObj["username"] = user.username;
usrObj["password"] = user.password;
return token;
} cout<<"Sending request for token"<<endl;
#pragma Functions auto url = api.url + api.endpoint;
cout<<url<<endl;
auto r = cpr::Post(cpr::Url{url},
cpr::Body{usrObj.dump()},
cpr::Header{{"Content-Type", "application/json"}});
json res = json::parse(r.text);
token.accessToken = res["token"];
token.tokenType = res["token_type"];
cout<<"status code "<<r.status_code<<endl;
return token;
}
#pragma endregion
} }
+33 -31
View File
@@ -12,42 +12,44 @@ using Models::User;
namespace Managers namespace Managers
{ {
#pragma
UserManager::UserManager(User user) #pragma region Constructors
{ UserManager::UserManager(User user)
this->user = user; {
} this->user = user;
UserManager::UserManager(const IcarusAction icaAct) }
{ UserManager::UserManager(const IcarusAction icaAct)
this->icaAction = icaAct; {
this->user = User{}; this->icaAction = icaAct;
parseUserFromActions(); this->user = User{};
} parseUserFromActions();
#pragma Constructors }
#pragma endregion
#pragma #pragma region Functions
User UserManager::retrieveUser() const User UserManager::retrieveUser() const
{ {
return user; return user;
} }
void UserManager::parseUserFromActions() void UserManager::parseUserFromActions()
{ {
auto args = icaAction.flags; auto args = icaAction.flags;
for (auto arg : args) for (auto arg : args)
{
auto flag = arg.flag;
if (flag.compare("-u") == 0)
{ {
auto flag = arg.flag; user.username = arg.value;
if (flag.compare("-u") == 0) }
{ if (flag.compare("-p") == 0)
user.username = arg.value; {
} user.password = arg.value;
if (flag.compare("-p") == 0)
{
user.password = arg.value;
}
} }
} }
#pragma Functions }
#pragma endregion
} }
+41 -37
View File
@@ -1,6 +1,6 @@
#include"Parsers/APIParser.h" #include "Parsers/APIParser.h"
#include<iostream> #include <iostream>
using std::cout; using std::cout;
using std::endl; using std::endl;
@@ -10,40 +10,44 @@ using Models::IcarusAction;
namespace Parsers namespace Parsers
{ {
#pragma
APIParser::APIParser(IcarusAction icaAct) : icaAct(icaAct)
{
api = API{};
parseAPI();
}
#pragma endregion
#pragma region Constructors
#pragma APIParser::APIParser(IcarusAction icaAct) : icaAct(icaAct)
API APIParser::retrieveAPI() const {
{ api = API{};
return api; parseAPI();
} }
#pragma endregion
void APIParser::parseAPI()
{
auto flags = icaAct.flags; #pragma region Functions
cout<<"Parsing api"<<endl; API APIParser::retrieveAPI() const
{
for (auto i =0; i < flags.size(); ++i) return api;
{ }
auto arg = flags[i].flag;
auto value = flags[i].value; void APIParser::parseAPI()
{
if (arg.compare("-h") == 0) auto flags = icaAct.flags;
{ cout << "Parsing api" << endl;
api.url = (value[value.size()-1] == '/') ? value : value + "/";
break; for (auto i =0; i < flags.size(); ++i)
} {
auto arg = flags[i].flag;
} auto value = flags[i].value;
api.version = "v1"; if (arg.compare("-h") == 0)
} {
#pragma functions api.url = (value[value.size()-1] == '/') ? value : value + "/";
break;
}
}
// TODO: For now I will hard code
// the api version since I am only
// on version 1
api.version = "v1";
}
#pragma endregion
} }
+48 -46
View File
@@ -1,9 +1,9 @@
#include"Syncers/Delete.h" #include "Syncers/Delete.h"
#include<exception> #include <exception>
#include<iostream> #include <iostream>
#include<cpr/cpr.h> #include <cpr/cpr.h>
using std::cout; using std::cout;
using std::endl; using std::endl;
@@ -16,47 +16,49 @@ using Models::Token;
namespace Syncers namespace Syncers
{ {
#pragma
Delete::Delete(API api)
{
this->api = api;
this->api.endpoint = "song/data";
}
#pragma Constructors
#pragma region Constructors
#pragma Delete::Delete(API api)
void Delete::deleteSong(const Token token, Song song) {
{ this->api = api;
try this->api.endpoint = "song/data";
{ }
auto url = retrieveUrl(song); #pragma endregion
string auth{token.tokenType};
auth.append(" " + token.accessToken);
auto r = cpr::Delete(cpr::Url(url), #pragma region Functions
cpr::Header{{"authorization", auth}}); void Delete::deleteSong(const Token token, Song song)
{
auto statusCode = r.status_code; try
{
cout<<"Status code "<<statusCode<<endl; auto url = retrieveUrl(song);
} string auth{token.tokenType};
catch (exception e) auth.append(" " + token.accessToken);
{ auto r = cpr::Delete(cpr::Url(url),
auto msg = e.what(); cpr::Header{{"authorization", auth}});
cout<<msg<<endl;
} auto statusCode = r.status_code;
cout<<"Finished"<<endl;
} cout<<"Status code "<<statusCode<<endl;
}
string Delete::retrieveUrl(Song song) catch (exception e)
{ {
string url{api.url + "api/" + api.version + "/" + auto msg = e.what();
api.endpoint + "/"}; cout<<msg<<endl;
}
url.append(std::to_string(song.id)); cout<<"Finished"<<endl;
cout<<"url "<<url<<endl; }
return url; string Delete::retrieveUrl(Song song)
} {
#pragma Functions 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 <exception>
#include<iostream> #include <iostream>
#include<fstream> #include <fstream>
#include<cpr/cpr.h> #include <cpr/cpr.h>
using std::cout; using std::cout;
using std::endl; using std::endl;
@@ -18,74 +18,76 @@ using Models::Token;
namespace Syncers 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 region Constructors
#pragma Download::Download() { }
void Download::downloadSong(const Token token, Song song) Download::Download(API api)
{ {
try this->api = api;
{ this->api.endpoint = "song/data";
string url = retrieveUrl(song); }
song.songPath.append("track.mp3"); Download::Download(string filePath)
cout<<"song path "<<song.songPath<<endl; {
string auth{token.tokenType}; downloadFilePath = filePath;
auth.append(" " + token.accessToken); }
#pragma endregion
auto r = cpr::Get(cpr::Url(url),
cpr::Header{{"Content-type", "audio/mpeg"},
{"Authorization", auth}}); #pragma region Functions
void Download::downloadSong(const Token token, Song song)
{
int statusCode = r.status_code; try
{
if (statusCode == OK) { string url = retrieveUrl(song);
song.data = r.text; song.songPath.append("track.mp3");
saveSong(song); cout<<"song path "<<song.songPath<<endl;
} string auth{token.tokenType};
auth.append(" " + token.accessToken);
cout<<"finsihed with status code "<<statusCode<<endl; auto r = cpr::Get(cpr::Url(url),
} cpr::Header{{"Content-type", "audio/mpeg"},
catch (exception e) {"Authorization", auth}});
{
auto msg = e.what();
cout<<msg<<endl; int statusCode = r.status_code;
}
} if (statusCode == OK) {
song.data = r.text;
string Download::retrieveUrl(Song song) saveSong(song);
{ }
string url{api.url + "api/" + api.version + "/" +
api.endpoint + "/"};
cout<<"finsihed with status code "<<statusCode<<endl;
url.append(std::to_string(song.id)); }
cout<<"url "<<url<<endl; catch (exception e)
{
return url; auto msg = e.what();
} cout<<msg<<endl;
}
void Download::saveSong(Song& song) }
{
cout<<"\nSaving song to: "<<song.songPath<<endl; string Download::retrieveUrl(Song song)
int bufferLength = song.data.length(); {
const char *data = song.data.c_str(); string url{api.url + "api/" + api.version + "/" +
cout<<"buff length "<<bufferLength<<endl; api.endpoint + "/"};
ofstream saveSong{song.songPath, std::ios::binary}; url.append(std::to_string(song.id));
saveSong.write(data, bufferLength); cout<<"url "<<url<<endl;
saveSong.close();
} return url;
#pragma Functions }
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 namespace Syncers
{ {
RetrieveRecords::RetrieveRecords() { } #pragma region Constructors
RetrieveRecords::RetrieveRecords(API api, Token token) RetrieveRecords::RetrieveRecords() { }
: token(token), api(api) { } 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();
case CommitManager::RetrieveTypes::songs: break;
fetchSongs(); default:
break; 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();
} }
} }
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 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; cout<<"url "<<url<<endl;
string auth{this->m_token.tokenType}; string auth{this->m_token.tokenType};
auth.append(" " + this->m_token.accessToken); auth.append(" " + this->m_token.accessToken);
auto r = cpr::Post(cpr::Url{url}, auto r = cpr::Post(cpr::Url{url},
cpr::Multipart{{"key", "small value"}, cpr::Multipart{{"key", "small value"},
{"file", cpr::File{song.songPath}}}, {"file", cpr::File{song.songPath}}},
cpr::Header{{"authorization", auth}} 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 << "status code: " << r.status_code<< std::endl; cout << "status code: " << r.status_code<< std::endl;
cout << r.text << endl; cout << r.text << endl;
*/ auto result = nlohmann::json::parse(r.text);
} cout<<"Finished"<<endl;
catch (exception &e) song.id = result["id"].get<int>();
{ song.title = result["title"].get<std::string>();
auto msg = e.what(); song.artist = result["artist"].get<std::string>();
cout<<"Error: "<<msg<<"\n"; song.album = result["album"].get<std::string>();
} song.genre = result["genre"].get<std::string>();
} song.year = result["year"].get<int>();
std::vector<Song> Upload::retrieveAllSongsFromDirectory(const std::string& directory, song.duration = result["duration"].get<int>();
bool recursive) song.track = result["track"].get<int>();
{
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; 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::uploadSongWithMetadata(Managers::CommitManager::Album &album, Models::Song& song, Models::CoverArt &cover)
void Upload::printSongDetails() {
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<<"Song details: "<<endl;
cout<<"Id: "<<song.id<<endl; cout<<"Id: "<<song.id<<endl;
@@ -220,36 +234,25 @@ namespace Syncers
cout<<"Genre: "<<song.genre<<endl; cout<<"Genre: "<<song.genre<<endl;
cout<<"Year: "<<song.year<<endl; cout<<"Year: "<<song.year<<endl;
cout<<"Duration: "<<song.duration<<endl; cout<<"Duration: "<<song.duration<<endl;
cout<<"Path: "<<song.songPath<<endl;
} }
void Upload::printSongDetails(std::vector<Song>& songs) }
{
for (auto& song: songs) void Upload::printJsonData(const json& obj)
{ {
cout<<"Song details: "<<endl; cout<<endl<<endl<<"JSon data: "<<endl;
cout<<"Id: "<<song.id<<endl; cout<<"id: "<<obj["id"]<<endl;
cout<<"Title: "<<song.title<<endl; cout<<"title: "<<obj["title"]<<endl;
cout<<"Artist: "<<song.artist<<endl; cout<<"artist: "<<obj["artist"]<<endl;
cout<<"Album: "<<song.album<<endl; cout<<"album: "<<obj["album"]<<endl;
cout<<"Genre: "<<song.genre<<endl; cout<<"genre: "<<obj["genre"]<<endl;
cout<<"Year: "<<song.year<<endl; cout<<"year: "<<obj["year"]<<endl;
cout<<"Duration: "<<song.duration<<endl; cout<<"duration: "<<obj["duration"]<<endl;
cout<<"Path: "<<song.songPath<<endl; cout<<"song_data: "<<obj["song_data"]<<endl;
}
} cout<<endl<<endl;;
void Upload::printJsonData(const json& obj) }
{ #pragma endregion
cout<<endl<<endl<<"JSon data: "<<endl; #pragma endregion
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
} }
+46 -41
View File
@@ -1,47 +1,52 @@
#include"UI/AboutWindow.h" #include "UI/AboutWindow.h"
using std::unique_ptr; using std::unique_ptr;
namespace UI namespace UI
{ {
AboutWindow::AboutWindow(QWidget* parent): QDialog(parent) #pragma region Constructors
{ AboutWindow::AboutWindow(QWidget* parent): QDialog(parent)
setupWindow(); {
} setupWindow();
}
#pragma endregion
void AboutWindow::setupWindow()
{
windowWidth = 250; #pragma region Functions
windowHeight = 300; void AboutWindow::setupWindow()
{
mainLayoutQt = unique_ptr<QVBoxLayout>{new QVBoxLayout}; windowWidth = 250;
windowHeight = 300;
appName = unique_ptr<QLabel>{new QLabel(tr("IcarusDownloadManager"))};
actionButtonQt = unique_ptr<QPushButton>{new QPushButton(tr("Close"))}; mainLayoutQt = unique_ptr<QVBoxLayout>{new QVBoxLayout};
mainLayoutQt->addWidget(appName.get()); appName = unique_ptr<QLabel>{new QLabel(tr("IcarusDownloadManager"))};
mainLayoutQt->addWidget(actionButtonQt.get()); actionButtonQt = unique_ptr<QPushButton>{new QPushButton(tr("Close"))};
mainLayoutQt->addWidget(appName.get());
setFixedWidth(windowWidth); mainLayoutQt->addWidget(actionButtonQt.get());
setFixedHeight(windowHeight);
setLayout(mainLayoutQt.get()); setFixedWidth(windowWidth);
setFixedHeight(windowHeight);
setWindowTitle("About");
setLayout(mainLayoutQt.get());
connections();
} setWindowTitle("About");
void AboutWindow::connections()
{ connections();
QObject::connect(actionButtonQt.get(), SIGNAL(clicked()), this, }
SLOT(closeWindow())); void AboutWindow::connections()
} {
QObject::connect(actionButtonQt.get(), SIGNAL(clicked()), this,
SLOT(closeWindow()));
void AboutWindow::closeWindow() }
{
this->hide();
} void AboutWindow::closeWindow()
{
this->hide();
}
#pragma endregion
} }
+165 -159
View File
@@ -1,11 +1,11 @@
#include"UI/MainWindow.h" #include "UI/MainWindow.h"
#include<iostream> #include <iostream>
#include<string> #include <string>
#include"Models/UploadForm.h" #include "Models/UploadForm.h"
#include"Syncers/Upload.h" #include "Syncers/Upload.h"
#include"Utilities/Conversions.h" #include "Utilities/Conversions.h"
using std::cout; using std::cout;
using std::endl; using std::endl;
@@ -17,158 +17,164 @@ using Syncers::Upload;
namespace UI namespace UI
{ {
MainWindow::MainWindow()
{
setupMainWindow();
aboutWindow = unique_ptr<AboutWindow>{new AboutWindow};
}
#pragma region Constructors
void MainWindow::configureDownloadSection() MainWindow::MainWindow()
{ {
} setupMainWindow();
void MainWindow::configureUploadSection() aboutWindow = unique_ptr<AboutWindow>{new AboutWindow};
{ }
uploadSongQt = unique_ptr<QPushButton>{new QPushButton(tr("Upload"))}; #pragma endregion
urlQt = unique_ptr<QTextEdit>{new QTextEdit()};
sourceFilePathQt = unique_ptr<QTextEdit>{new QTextEdit()};
#pragma region Functions
urlLabel = unique_ptr<QLabel>{new QLabel(tr("URL"))}; void MainWindow::configureDownloadSection()
songPath = unique_ptr<QLabel>{new QLabel(tr("Song Path"))}; {
}
urlPortion = unique_ptr<QHBoxLayout>{new QHBoxLayout}; void MainWindow::configureUploadSection()
songPathPortion = unique_ptr<QHBoxLayout>{new QHBoxLayout}; {
uploadSongQt = unique_ptr<QPushButton>{new QPushButton(tr("Upload"))};
urlPortion.get()->addWidget(urlLabel.get()); urlQt = unique_ptr<QTextEdit>{new QTextEdit()};
urlPortion.get()->addWidget(urlQt.get()); sourceFilePathQt = unique_ptr<QTextEdit>{new QTextEdit()};
songPathPortion->addWidget(songPath.get()); urlLabel = unique_ptr<QLabel>{new QLabel(tr("URL"))};
songPathPortion->addWidget(sourceFilePathQt.get()); songPath = unique_ptr<QLabel>{new QLabel(tr("Song Path"))};
subLayoutOneQt = unique_ptr<QVBoxLayout>{new QVBoxLayout}; urlPortion = unique_ptr<QHBoxLayout>{new QHBoxLayout};
subLayoutOneQt.get()->addLayout(urlPortion.get()); songPathPortion = unique_ptr<QHBoxLayout>{new QHBoxLayout};
subLayoutOneQt->addLayout(songPathPortion.get());
mainLayoutQt.get()->addLayout(subLayoutOneQt.get()); urlPortion.get()->addWidget(urlLabel.get());
} urlPortion.get()->addWidget(urlQt.get());
void MainWindow::configureWindowDimensions()
{ songPathPortion->addWidget(songPath.get());
windowWidth = 450; songPathPortion->addWidget(sourceFilePathQt.get());
windowHeight = 450;
} subLayoutOneQt = unique_ptr<QVBoxLayout>{new QVBoxLayout};
void MainWindow::configureWindowProperties() subLayoutOneQt.get()->addLayout(urlPortion.get());
{ subLayoutOneQt->addLayout(songPathPortion.get());
setWindowTitle("IcarusDownloadManager"); mainLayoutQt.get()->addLayout(subLayoutOneQt.get());
setFixedHeight(windowHeight); }
setFixedWidth(windowWidth); void MainWindow::configureWindowDimensions()
} {
void MainWindow::connections() windowWidth = 450;
{ windowHeight = 450;
QObject::connect(uploadSongQt.get(), SIGNAL(clicked()), this, SLOT(uploadSong())); }
QObject::connect(closeApplicationQt.get(), SIGNAL(triggered()), this, void MainWindow::configureWindowProperties()
SLOT(exitApplication())); {
QObject::connect(aboutApplicationQt.get(), SIGNAL(triggered()), this, setWindowTitle("IcarusDownloadManager");
SLOT(displaySoftwareInformation())); setFixedHeight(windowHeight);
QObject::connect(windowComboBox.get(), SIGNAL(activated(int)), setFixedWidth(windowWidth);
this, SLOT(setCurrentIndex(int))); }
} void MainWindow::connections()
void MainWindow::createMenus() {
{ QObject::connect(uploadSongQt.get(), SIGNAL(clicked()), this, SLOT(uploadSong()));
fileMenuQt = unique_ptr<QMenu>{menuBar()->addMenu(tr("File"))}; QObject::connect(closeApplicationQt.get(), SIGNAL(triggered()), this,
editMenuQt = unique_ptr<QMenu>{menuBar()->addMenu(tr("Edit"))}; SLOT(exitApplication()));
helpMenuQt = unique_ptr<QMenu>{menuBar()->addMenu(tr("Help"))}; QObject::connect(aboutApplicationQt.get(), SIGNAL(triggered()), this,
SLOT(displaySoftwareInformation()));
closeApplicationQt = unique_ptr<QAction>{new QAction(new QObject(nullptr))}; QObject::connect(windowComboBox.get(), SIGNAL(activated(int)),
closeApplicationQt->setText("Exit Application"); this, SLOT(setCurrentIndex(int)));
}
aboutApplicationQt = unique_ptr<QAction>{new QAction(new QObject(nullptr))}; void MainWindow::createMenus()
aboutApplicationQt->setText("About"); {
fileMenuQt = unique_ptr<QMenu>{menuBar()->addMenu(tr("File"))};
fileMenuQt->addAction(closeApplicationQt.get()); editMenuQt = unique_ptr<QMenu>{menuBar()->addMenu(tr("Edit"))};
helpMenuQt->addAction(aboutApplicationQt.get()); helpMenuQt = unique_ptr<QMenu>{menuBar()->addMenu(tr("Help"))};
} closeApplicationQt = unique_ptr<QAction>{new QAction(new QObject(nullptr))};
void MainWindow::setupMainWidget() closeApplicationQt->setText("Exit Application");
{
mainWidgetQt = unique_ptr<QWidget>{new QWidget}; aboutApplicationQt = unique_ptr<QAction>{new QAction(new QObject(nullptr))};
aboutApplicationQt->setText("About");
windowComboBox = unique_ptr<QComboBox>{new QComboBox};
setupWindowLists(); fileMenuQt->addAction(closeApplicationQt.get());
helpMenuQt->addAction(aboutApplicationQt.get());
stackLayout = unique_ptr<QVBoxLayout>{new QVBoxLayout}; }
stackLayout->addWidget(windowComboBox.get()); void MainWindow::setupMainWidget()
{
uploadSongWidgetQt = unique_ptr<QWidget>{new QWidget}; mainWidgetQt = unique_ptr<QWidget>{new QWidget};
uploadSongWidgetQt->setLayout(mainLayoutQt.get());
windowComboBox = unique_ptr<QComboBox>{new QComboBox};
stackLayout->addWidget(uploadSongWidgetQt.get()); setupWindowLists();
mainWidgetQt->setLayout(stackLayout.get());
} stackLayout = unique_ptr<QVBoxLayout>{new QVBoxLayout};
void MainWindow::setupMainWindow() stackLayout->addWidget(windowComboBox.get());
{
configureWindowDimensions(); uploadSongWidgetQt = unique_ptr<QWidget>{new QWidget};
uploadSongWidgetQt->setLayout(mainLayoutQt.get());
mainLayoutQt = unique_ptr<QVBoxLayout>{new QVBoxLayout};
widgetStack = unique_ptr<QStackedWidget>{new QStackedWidget}; stackLayout->addWidget(uploadSongWidgetQt.get());
configureUploadSection(); mainWidgetQt->setLayout(stackLayout.get());
}
setupMainWidget(); void MainWindow::setupMainWindow()
{
widgetStack->addWidget(mainWidgetQt.get()); configureWindowDimensions();
MainDockWidgetQt = unique_ptr<QDockWidget>{new QDockWidget}; mainLayoutQt = unique_ptr<QVBoxLayout>{new QVBoxLayout};
MainDockWidgetQt.get()->setWindowTitle(tr("Music Manager")); widgetStack = unique_ptr<QStackedWidget>{new QStackedWidget};
MainDockWidgetQt->setWidget(widgetStack.get());
MainDockWidgetQt.get()->setFeatures(QDockWidget::NoDockWidgetFeatures); configureUploadSection();
setCentralWidget(MainDockWidgetQt.get()); setupMainWidget();
createMenus(); widgetStack->addWidget(mainWidgetQt.get());
configureWindowProperties(); MainDockWidgetQt = unique_ptr<QDockWidget>{new QDockWidget};
MainDockWidgetQt.get()->setWindowTitle(tr("Music Manager"));
connections(); MainDockWidgetQt->setWidget(widgetStack.get());
} MainDockWidgetQt.get()->setFeatures(QDockWidget::NoDockWidgetFeatures);
void MainWindow::setupWindowLists()
{ setCentralWidget(MainDockWidgetQt.get());
windowComboBox->addItem(tr("Upload song"));
windowComboBox->addItem(tr("Download song")); createMenus();
windowComboBox->addItem(tr("Display all songs"));
windowComboBox->addItem(tr("Display songs")); configureWindowProperties();
}
connections();
}
void MainWindow::exitApplication() void MainWindow::setupWindowLists()
{ {
exit(0); windowComboBox->addItem(tr("Upload song"));
} windowComboBox->addItem(tr("Download song"));
void MainWindow::displaySoftwareInformation() windowComboBox->addItem(tr("Display all songs"));
{ windowComboBox->addItem(tr("Display songs"));
aboutWindow->show(); }
}
void MainWindow::setCurrentIndex(int index)
{ void MainWindow::exitApplication()
cout<<"index "<<index<<endl; {
QString qText = windowComboBox->itemText(index); exit(0);
auto cnvert = Utilities::Conversions(qText); }
auto convertedStr = cnvert.convertQStringToString(); void MainWindow::displaySoftwareInformation()
cout<<"item text"<<endl; {
} aboutWindow->show();
void MainWindow::uploadSong() }
{ void MainWindow::setCurrentIndex(int index)
uploadSongQt->setEnabled(false); {
cout<<"index "<<index<<endl;
string url = urlQt->toPlainText().toUtf8().constData(); QString qText = windowComboBox->itemText(index);
string filePath = sourceFilePathQt->toPlainText().toUtf8().constData(); auto cnvert = Utilities::Conversions(qText);
cout<<"URL endpoint: "<<url<<endl; auto convertedStr = cnvert.convertQStringToString();
cout<<"Music file path: "<<filePath<<endl; cout<<"item text"<<endl;
UploadForm formData{url, filePath}; }
void MainWindow::uploadSong()
Upload upld{formData}; {
upld.uploadSong(); uploadSongQt->setEnabled(false);
uploadSongQt->setEnabled(true); string url = urlQt->toPlainText().toUtf8().constData();
} string filePath = sourceFilePathQt->toPlainText().toUtf8().constData();
cout<<"URL endpoint: "<<url<<endl;
cout<<"Music file path: "<<filePath<<endl;
UploadForm formData{url, filePath};
Upload upld{formData};
upld.uploadSong();
uploadSongQt->setEnabled(true);
}
#pragma endregion
} }
+17 -15
View File
@@ -1,24 +1,26 @@
#include"Utilities/Conversions.h" #include "Utilities/Conversions.h"
#include<iostream> #include <iostream>
using std::string; using std::string;
using std::unique_ptr; using std::unique_ptr;
namespace Utilities namespace Utilities
{ {
Conversions::Conversions()
{
initializeValues();
}
void Conversions::initializeValues() Conversions::Conversions()
{ {
} initializeValues();
template <typename T> }
void Conversions::printValue(T val)
{ void Conversions::initializeValues()
std::cout<<"going to print value"<<std::endl; {
std::cout<<val<<std::endl; }
} template <typename T>
void Conversions::printValue(T val)
{
std::cout<<"going to print value"<<std::endl;
std::cout<<val<<std::endl;
}
} }