diff --git a/application/main.cpp b/application/main.cpp index a76e1d6..b41b5c4 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -1,49 +1,52 @@ -#include "gui/mainwindow.h" -#include "gui/settings.h" +#include "cli/mainfeatures.h" +#include "gui/initiate.h" #if defined(GUI_QTWIDGETS) || defined(GUI_QTQUICK) # include #else # include #endif -#include -#if defined(GUI_QTWIDGETS) -# include -#elif defined(GUI_QTQUICK) -# include -#endif +#include + +#include #include +#include "main.h" + using namespace std; +using namespace std::placeholders; using namespace ApplicationUtilities; int main(int argc, char *argv[]) { + // setup argument parser ArgumentParser parser; QT_CONFIG_ARGUMENTS qtConfigArgs; HelpArgument helpArg(parser); - parser.setMainArguments({&qtConfigArgs.qtWidgetsGuiArg(), &helpArg}); - parser.parseArgs(argc, argv); + Argument noConfirmArg("no-confirm", "n", "start downloading without confirmation"); + noConfirmArg.setCombinable(true); + Argument downloadArg("download", "d", "downloads the specified data"); + downloadArg.setValueNames({"URL1", "URL2", "URL3"}); + downloadArg.setRequiredValueCount(-1); + downloadArg.setDenotesOperation(true); + downloadArg.setSecondaryArguments({&noConfirmArg}); + downloadArg.setCallback(bind(Cli::download, argc, argv, _1, cref(noConfirmArg))); + parser.setMainArguments({&qtConfigArgs.qtWidgetsGuiArg(), &downloadArg, &helpArg}); + // parse arguments + try { + parser.parseArgs(argc, argv); + } catch (Failure &ex) { + cout << "Unable to parse arguments. " << ex.what() << "\nSee --help for available commands." << endl; + } + // set meta info for application + QCoreApplication::setOrganizationName(QStringLiteral("Martchus")); + QCoreApplication::setOrganizationDomain(QStringLiteral("http://martchus.netai.net/")); + QCoreApplication::setApplicationName(QStringLiteral("Video Downloader")); + QCoreApplication::setApplicationVersion(QStringLiteral("1.0.7")); if(qtConfigArgs.areQtGuiArgsPresent()) { -#ifdef GUI_QTWIDGETS - QGuiApplication::setOrganizationName(QStringLiteral("Martchus")); - QGuiApplication::setOrganizationDomain(QStringLiteral("http://martchus.netai.net/")); - QGuiApplication::setApplicationName(QStringLiteral("Video Downloader")); - QGuiApplication::setApplicationVersion(QStringLiteral("1.0.7")); - QApplication a(argc, argv); - QtUtilitiesResources::init(); - Theme::setup(); - QtGui::restoreSettings(); - QtGui::MainWindow w; - w.show(); - int r = a.exec(); - QtGui::saveSettings(); - return r; -#else - cout << "Application has not been build with Qt widgets GUI support." << endl; -#endif + return QtGui::runWidgetsGui(argc, argv); } return 0; } diff --git a/application/main.h b/application/main.h new file mode 100644 index 0000000..9e38ded --- /dev/null +++ b/application/main.h @@ -0,0 +1,6 @@ +#ifndef MAIN_H +#define MAIN_H + +int main(int argc, char *argv[]); + +#endif // MAIN_H diff --git a/cli/clidownloadinteraction.cpp b/cli/clidownloadinteraction.cpp new file mode 100644 index 0000000..4d2b9ea --- /dev/null +++ b/cli/clidownloadinteraction.cpp @@ -0,0 +1,79 @@ +#include "clidownloadinteraction.h" + +#include "network/download.h" +#include "network/permissionstatus.h" + +#include + +#include + +using namespace std; +using namespace Network; +using namespace ApplicationUtilities; + +namespace Cli { + +CliDownloadInteraction::CliDownloadInteraction(QObject *parent) : + QObject(parent) +{} + +void CliDownloadInteraction::connectDownload(Download *download) +{ + connect(download, &Download::outputDeviceRequired, this, static_cast(&CliDownloadInteraction::downloadRequiresOutputDevice), Qt::QueuedConnection); + connect(download, &Download::overwriteingPermissionRequired, this, &CliDownloadInteraction::downloadRequriesOverwritePermission, Qt::QueuedConnection); + connect(download, &Download::appendingPermissionRequired, this, &CliDownloadInteraction::downloadRequriesAppendingPermission, Qt::QueuedConnection); + connect(download, &Download::redirectionPermissonRequired, this, &CliDownloadInteraction::downloadRequiresRedirectionPermission, Qt::QueuedConnection); + connect(download, &Download::authenticationRequired, this, &CliDownloadInteraction::downloadRequiresAuthentication, Qt::QueuedConnection); + connect(download, &Download::sslErrors, this, &CliDownloadInteraction::downloadHasSslErrors, Qt::QueuedConnection); +} + +void CliDownloadInteraction::disconnectDownload(Download *download) +{ + download->disconnect(this); +} + +void CliDownloadInteraction::downloadRequiresOutputDevice(Download *download, size_t optionIndex) +{ + downloadRequiresOutputDevice(download, optionIndex, false); +} + +void CliDownloadInteraction::downloadRequiresOutputDevice(Download *download, size_t optionIndex, bool forceFileDialog) +{ + // TODO +} + +void CliDownloadInteraction::downloadRequriesOverwritePermission(Download *download, size_t optionIndex, const QString &file) +{ + // TODO +} + +void CliDownloadInteraction::downloadRequriesAppendingPermission(Download *download, size_t optionIndex, const QString &file, quint64 offset, quint64 fileSize) +{ + // TODO +} + +void CliDownloadInteraction::downloadRequiresRedirectionPermission(Download *download, size_t optionIndex) +{ + // TODO +} + +void CliDownloadInteraction::downloadRequiresAuthentication(Download *download, size_t optionIndex, const QString &realm) +{ + // TODO +} + +void CliDownloadInteraction::downloadHasSslErrors(Download *download, size_t optionIndex, const QList &sslErrors) +{ + // TODO + const string downloadName = (download->downloadUrl().isEmpty() ? download->id() : download->downloadUrl().toString()).toStdString(); + cout << "The download \"" << downloadName << "\" has SSL errors:" << endl; + foreach(const QSslError &error, sslErrors) { + cout << "- " << error.errorString().toStdString() << ":" << endl; + cout << " " << error.certificate().toText().toStdString() << endl; + } + if(confirmPrompt("Do you want to ignore the SSL errors for this download?")) { + // TODO + } +} + +} diff --git a/cli/clidownloadinteraction.h b/cli/clidownloadinteraction.h new file mode 100644 index 0000000..7b42ce8 --- /dev/null +++ b/cli/clidownloadinteraction.h @@ -0,0 +1,40 @@ +#ifndef CLI_DOWNLOADINTERACTION_H +#define CLI_DOWNLOADINTERACTION_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +namespace Network { +class Download; +} + +namespace Cli { + +class CliDownloadInteraction : public QObject +{ + Q_OBJECT +public: + explicit CliDownloadInteraction(QObject *parent = nullptr); + +public slots: + void connectDownload(Network::Download *download); + void disconnectDownload(Network::Download *download); + +private slots: + void downloadRequiresOutputDevice(Network::Download *download, size_t optionIndex); + void downloadRequiresOutputDevice(Network::Download *download, size_t optionIndex, bool forceFileDialog); + void downloadRequriesOverwritePermission(Network::Download *download, size_t optionIndex, const QString &file); + void downloadRequriesAppendingPermission(Network::Download *download, size_t optionIndex, const QString &file, quint64 offset, quint64 fileSize); + void downloadRequiresRedirectionPermission(Network::Download *download, size_t optionIndex); + void downloadRequiresAuthentication(Network::Download *download, size_t optionIndex, const QString &realm); + void downloadHasSslErrors(Network::Download *download, size_t optionIndex, const QList &sslErrors); + +}; + +} + +#endif // CLI_DOWNLOADINTERACTION_H diff --git a/cli/mainfeatures.cpp b/cli/mainfeatures.cpp new file mode 100644 index 0000000..05302a8 --- /dev/null +++ b/cli/mainfeatures.cpp @@ -0,0 +1,11 @@ +#include "mainfeatures.h" + +namespace Cli { + +mainfeatures::mainfeatures() +{ + +} + +} // namespace Cli + diff --git a/cli/mainfeatures.h b/cli/mainfeatures.h new file mode 100644 index 0000000..961bd60 --- /dev/null +++ b/cli/mainfeatures.h @@ -0,0 +1,20 @@ +#ifndef CLI_MAINFEATURES_H +#define CLI_MAINFEATURES_H + +#include +#include + +namespace ApplicationUtilities { + +typedef std::vector StringVector; +class Argument; + +} + +namespace Cli { + +void download(int argc, char *argv[], const ApplicationUtilities::StringVector ¶meterValues, const ApplicationUtilities::Argument &noConfirmArg); + +} + +#endif // CLI_MAINFEATURES_H diff --git a/general.pri b/general.pri index 9156999..9f790b4 100644 --- a/general.pri +++ b/general.pri @@ -12,7 +12,17 @@ unix { QMAKE_LFLAGS += "-Wl,--rpath=./" } # prefix -targetprefix = . +targetprefix = $$(TARGET_PREFIX) +equals(targetprefix, "") { + win32 { + targetprefix = ../../.. + } else { + targetprefix = ../.. + } +} +message("Using target prefix \"$${targetprefix}\".") +# print install root +message("Using install root \"$$(INSTALL_ROOT)\".") # target CONFIG(debug, debug|release) { TARGET = $$targetprefix/$${projectname}d diff --git a/gui/downloadinteraction.h b/gui/downloadinteraction.h index 62ef129..ce17003 100644 --- a/gui/downloadinteraction.h +++ b/gui/downloadinteraction.h @@ -7,7 +7,6 @@ QT_BEGIN_NAMESPACE class QWidget; class QString; -//class QSslError; QT_END_NAMESPACE namespace Network { diff --git a/gui/initiate.cpp b/gui/initiate.cpp new file mode 100644 index 0000000..e39e7e5 --- /dev/null +++ b/gui/initiate.cpp @@ -0,0 +1,35 @@ +#include "initiate.h" +#include "settings.h" +#include "mainwindow.h" + +#include + +#if defined(GUI_QTWIDGETS) +# include +#elif defined(GUI_QTQUICK) +# include +#endif + +using namespace std; + +namespace QtGui { + +int runWidgetsGui(int argc, char *argv[]) +{ +#ifdef GUI_QTWIDGETS + QApplication a(argc, argv); + QtUtilitiesResources::init(); + Theme::setup(); + QtGui::restoreSettings(); + QtGui::MainWindow w; + w.show(); + int r = a.exec(); + QtGui::saveSettings(); + return r; +#else + cout << "Application has not been build with Qt widgets GUI support." << endl; + return 0; +#endif +} + +} diff --git a/gui/initiate.h b/gui/initiate.h new file mode 100644 index 0000000..fedee3e --- /dev/null +++ b/gui/initiate.h @@ -0,0 +1,10 @@ +#ifndef QTGUI_INIT_H +#define QTGUI_INIT_H + +namespace QtGui { + +int runWidgetsGui(int argc, char *argv[]); + +} + +#endif // QTGUI_INIT_H diff --git a/network/httpdownload.cpp b/network/httpdownload.cpp index 72b204f..f64e0f8 100644 --- a/network/httpdownload.cpp +++ b/network/httpdownload.cpp @@ -137,7 +137,7 @@ void HttpDownload::checkStatusAndClear(size_t optionIndex) reportDownloadInterrupted(optionIndex); reply->deleteLater(); m_replies.removeAll(reply); - } else if((error == QNetworkReply::AuthenticationRequiredError)) { + } else if(error == QNetworkReply::AuthenticationRequiredError) { // authentication is required reportAuthenticationRequired(optionIndex, m_realm); reply->deleteLater(); diff --git a/videodownloader.pro b/videodownloader.pro index 4936e17..8597bed 100644 --- a/videodownloader.pro +++ b/videodownloader.pro @@ -1,4 +1,5 @@ projectname = videodownloader +VERSION = 1.0.7 # include ../../common.pri when building as part of a subdirs project; otherwise include general.pri !include(../../common.pri) { @@ -51,7 +52,10 @@ SOURCES += application/main.cpp \ itemdelegates/progressbaritemdelegate.cpp \ gui/downloadinteraction.cpp \ gui/settings.cpp \ - network/optiondata.cpp + network/optiondata.cpp \ + gui/initiate.cpp \ + cli/mainfeatures.cpp \ + cli/clidownloadinteraction.cpp HEADERS += application/main.h \ network/bitsharedownload.h \ @@ -83,7 +87,11 @@ HEADERS += application/main.h \ gui/settings.h \ network/authenticationcredentials.h \ network/permissionstatus.h \ - network/optiondata.h + network/optiondata.h \ + application/main.h \ + gui/initiate.h \ + cli/mainfeatures.h \ + cli/clidownloadinteraction.h testdownload { SOURCES += network/testdownload.cpp @@ -127,14 +135,14 @@ INCLUDEPATH += ../ target.path = $$(INSTALL_ROOT)/bin INSTALLS += target icon.path = $$(INSTALL_ROOT)/share/icons/hicolor/scalable/apps/ -icon.files = ./resources/icons/hicolor/scalable/apps/$${projectname}.svg +icon.files = $${PWD}/resources/icons/hicolor/scalable/apps/$${projectname}.svg INSTALLS += icon menu.path = $$(INSTALL_ROOT)/share/applications/ -menu.files = ./resources/desktop/applications/$${projectname}.desktop +menu.files = $${PWD}/resources/desktop/applications/$${projectname}.desktop INSTALLS += menu translations.path = $$(INSTALL_ROOT)/share/$${projectname}/translations/ -translations.files = ./translations/*.qm +translations.files = $${PWD}/translations/*.qm INSTALLS += translations json.path = $$(INSTALL_ROOT)/share/$${projectname}/json/ -json.files = ./resources/json/groovesharkauthenticationinfo.json +json.files = $${PWD}/resources/json/groovesharkauthenticationinfo.json INSTALLS += json