diff options
-rw-r--r-- | client-qt/udm-client-qt/client_session.cpp | 1 | ||||
-rw-r--r-- | client-qt/udm-client-qt/client_session.h | 1 | ||||
-rw-r--r-- | client-qt/udm-client-qt/downloads_model.cpp | 90 | ||||
-rw-r--r-- | client-qt/udm-client-qt/downloads_model.h | 5 | ||||
-rw-r--r-- | client-qt/udm-client-qt/udm_main.cpp | 21 | ||||
-rw-r--r-- | client-qt/udm-client-qt/udm_main.h | 4 | ||||
-rw-r--r-- | server/include/api_module_downloader.h | 14 | ||||
-rw-r--r-- | server/modules/downloaders/curl/main.cpp | 58 | ||||
-rw-r--r-- | server/modules/downloaders/curl/main.h | 7 |
9 files changed, 185 insertions, 16 deletions
diff --git a/client-qt/udm-client-qt/client_session.cpp b/client-qt/udm-client-qt/client_session.cpp index 9cb951c..885598b 100644 --- a/client-qt/udm-client-qt/client_session.cpp +++ b/client-qt/udm-client-qt/client_session.cpp @@ -309,6 +309,7 @@ client_session::~client_session() delete socket_; // boost::asio::io_service *s = &io_service_; // delete s; + emit client_disconnected(); emit terminate_thread(); } diff --git a/client-qt/udm-client-qt/client_session.h b/client-qt/udm-client-qt/client_session.h index 4b7cfb3..904e9f0 100644 --- a/client-qt/udm-client-qt/client_session.h +++ b/client-qt/udm-client-qt/client_session.h @@ -50,6 +50,7 @@ public: signals: void client_connected(bool success, QString error_text); //we are in threads, no links here void server_message_received(server_msg msg); //we are in threads, no links here + void client_disconnected(); void terminate_thread(); public slots: diff --git a/client-qt/udm-client-qt/downloads_model.cpp b/client-qt/udm-client-qt/downloads_model.cpp index 2dadc0f..567b5e5 100644 --- a/client-qt/udm-client-qt/downloads_model.cpp +++ b/client-qt/udm-client-qt/downloads_model.cpp @@ -21,47 +21,121 @@ #include "downloads_model.h" -downloads_model::downloads_model(QObject *parent) +downloads_model::downloads_model(std::vector<download> &downloads_, QObject */*parent*/) : downloads(downloads_) { } -int downloads_model::rowCount(const QModelIndex &parent) const +int downloads_model::rowCount(const QModelIndex &/*parent*/) const { - return 0; + return downloads.size(); } QVariant downloads_model::data(const QModelIndex &index, int role) const { if(!index.isValid()) return QVariant(); + if((unsigned)index.row() >= downloads.size()) + return QVariant(); + + + //TODO: support for dynamic columnt count + + if(role == Qt::DisplayRole) + { + switch(index.column()) + { + case 0: + return QString(" ") + QString::fromUtf8(downloads[index.row()].name().c_str()); + break; + //TODO: human readable size + case 1: + return (qint64) downloads[index.row()].size(); + break; + case 2: + return (qint64)downloads[index.row()].downloaded(); + break; + // + case 3: + return (qint64)((double)downloads[index.row()].downloaded() / (double)downloads[index.row()].size()) * 100.0; + break; + case 4: + return downloads[index.row()].module_name().c_str(); + break; + case 5: //TODO: + return QVariant(); + break; + case 6: //TODO: + return QVariant(); + break; + + + + } + } + return QVariant(); + } QVariant downloads_model::headerData(int section, Qt::Orientation orientation, int role) const { + //TODO: support for dynamic columnt count + if(role == Qt::DisplayRole) + { + if(orientation == Qt::Horizontal) + { + switch(section) + { + case 0: + return QString(tr("Name")); + break; + case 1: + return QString(tr("Size")); + break; + case 2: + return QString(tr("Downloaded")); + break; + case 3: + return QString(tr("Progress")); + break; + case 4: + return QString(tr("Module name")); + break; + case 5: + return QString(tr("Down Speed")); + break; + case 6: + return QString(tr("ETA")); + break; + } + } + } + return QVariant(); } -int downloads_model::columnCount ( const QModelIndex & parent) const +int downloads_model::columnCount ( const QModelIndex & /*parent*/) const { - return 1; + //TODO: support for dynamic columnt count + return 7; } -bool downloads_model::insertRows(int position, int rows, const QModelIndex &index) +bool downloads_model::insertRows(int position, int rows, const QModelIndex &/*index*/) { beginInsertRows(QModelIndex(), position, position+rows-1); endInsertRows(); return true; } -bool downloads_model::removeRows(int position, int rows, const QModelIndex &index) +bool downloads_model::removeRows(int position, int rows, const QModelIndex &/*index*/) { beginRemoveRows(QModelIndex(), position, position+rows-1); endRemoveRows(); return true; } -void downloads_model::sort ( int column, Qt::SortOrder order) +void downloads_model::sort ( int /*column*/, Qt::SortOrder /*order*/) { + //TODO: } diff --git a/client-qt/udm-client-qt/downloads_model.h b/client-qt/udm-client-qt/downloads_model.h index 5a27e90..fc7cfbc 100644 --- a/client-qt/udm-client-qt/downloads_model.h +++ b/client-qt/udm-client-qt/downloads_model.h @@ -24,12 +24,13 @@ #define DOWNLOADS_MODEL_H #include <QAbstractItemModel> +#include "../../protocol/udm.pb.h" class downloads_model : public QAbstractTableModel { Q_OBJECT public: - downloads_model(QObject *parent = 0); + downloads_model(std::vector<download> &downloads, QObject *parent = 0); int rowCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; @@ -42,6 +43,8 @@ public: signals: public slots: +private: + std::vector<download> &downloads; }; #endif // DOWNLOADS_MODEL_H diff --git a/client-qt/udm-client-qt/udm_main.cpp b/client-qt/udm-client-qt/udm_main.cpp index 91cfb10..bf58911 100644 --- a/client-qt/udm-client-qt/udm_main.cpp +++ b/client-qt/udm-client-qt/udm_main.cpp @@ -55,7 +55,7 @@ udm_main::udm_main(QWidget *parent) tbl_downloads = new QTableView; tbl_downloads->setShowGrid(false); - mdl_downloads = new downloads_model; + mdl_downloads = new downloads_model(downloads); tbl_downloads->setModel(mdl_downloads); tbl_downloads->setSelectionBehavior(QAbstractItemView::SelectRows); tbl_downloads->setSortingEnabled(true); @@ -135,10 +135,11 @@ void udm_main::client_pre_connect_init() session = new client_session(0, io_service_); //parent must be 0 here connect(session, SIGNAL(server_message_received(server_msg)), this, SLOT(server_message_received(server_msg))); connect(session, SIGNAL(client_connected(bool,QString)), this, SLOT(client_connected(bool,QString))); + connect(session, SIGNAL(client_disconnected()), this, SLOT(client_disconnected())); + connect(session, SIGNAL(terminate_thread()), thread_client_session, SLOT(quit())); } void udm_main::client_connect_finalize() { - connect(session, SIGNAL(terminate_thread()), thread_client_session, SLOT(quit())); session->moveToThread(thread_client_session); thread_client_session->start(); } @@ -201,17 +202,22 @@ void udm_main::server_message_received(server_msg msg) } break; case SERVER_MSG_TYPE::SERVER_CORE_INFO_REPLY: - { - } + server_info = msg.server_core_info_reply(); break; case SERVER_MSG_TYPE::SERVER_MODULES_REPLY: { + //TODO: create download info ui template for each module here + modules.clear(); //TODO: something better + for(auto i : msg.server_modules_reply()) + modules.push_back(i); } break; case SERVER_MSG_TYPE::SERVER_DOWNLOADS_LIST_REPLY: { - + downloads.clear(); //TODO: something better + for(auto i : msg.downloads()) + downloads.push_back(i.download()); } break; default: @@ -236,3 +242,8 @@ void udm_main::client_connected(bool success, QString error_text) msg.setText(success?"client connected with message:":"client connection error with error:" + error_text); msg.exec(); */ } + +void udm_main::client_disconnected() +{ + lbl_state->setText(tr("State") + ": " + tr("Disconnected")); +} diff --git a/client-qt/udm-client-qt/udm_main.h b/client-qt/udm-client-qt/udm_main.h index 23fe887..28d5440 100644 --- a/client-qt/udm-client-qt/udm_main.h +++ b/client-qt/udm-client-qt/udm_main.h @@ -58,6 +58,7 @@ public slots: void client_connect_ssl(QString &host, QString &password, int port, QString &ssl_ca, QString &ssl_crt, QString &ssl_key); void server_message_received(server_msg msg); void client_connected(bool success, QString error_text); + void client_disconnected(); signals: void connect_signal(QString host, QString password, int port); void connect_signal_ssl(QString host, QString password, int port, QString ssl_ca, QString ssl_crt, QString ssl_key); @@ -75,6 +76,9 @@ private: downloads_model *mdl_downloads; filters_model *mdl_filters; QSplitter *spl_hor, *spl_vert; + core_info server_info; + std::vector<download> downloads; + std::list<module_info> modules; }; #endif // UDM_MAIN_H diff --git a/server/include/api_module_downloader.h b/server/include/api_module_downloader.h index dbe0d14..dc31811 100644 --- a/server/include/api_module_downloader.h +++ b/server/include/api_module_downloader.h @@ -76,16 +76,18 @@ struct download_content_entry_s { //here is basic content entry description, thi struct download_s { - int id; - std::string name; //id generated via download_add or via session restore and it's unique for current session and current dowloader + int id; //id generated via download_add or via session restore and it's unique for current session and current dowloader + std::string name; int64_t size, downloaded, download_speed; //download size and size of downloaded data, also download speed all vars in bytes std::map<int, std::string> info_map; //any additional info provided by downloader module can be stored here std::list<download_content_entry_s> content; //download content can be set for download, structure described above + std::map<std::string, std::string> metadata; }; class module_downloader : public module_base { public: + //basic actions virtual int add_download(std::map<int, std::string> params) = 0; //add download, this function must return unique for current session and current downloader download id virtual bool stop_download(int download_id) = 0; //stop download by id received via add_download, return true on success, false otherwise virtual bool start_download(int download_id) = 0; //start download by id received via add_download, return true on success, false otherwise @@ -93,6 +95,14 @@ public: virtual bool execute_action_on_download(int download_id, int action_id) = 0; //execute module defined action on download, by id received via add_download virtual std::list<download_s> get_downloads(std::map<int, std::string> params = std::map<int, std::string>()) = 0; //this function must return list of downloads, additional options may be passed via params map virtual download_s get_download(int download_id, std::map<int, std::string> params = std::map<int, std::string>()) = 0; //same as above, except this one is for single download, not a complete list + //metadata manipulation (api for client specified metadata, unused by server itself, for example labels should be implemented using this api) + virtual bool metadata_set(int download_id, std::map<std::string, std::string> metadata) = 0; //replace download metadata with provided one + virtual bool metadata_update(int download_id, std::map<std::string, std::string> metadata) = 0; //updated matching metadata entries, create non existent + virtual bool metadata_drop(int download_id, std::string var = std::string()) = 0; //remove all metadata if no variable specified, otherwise delete specified variable + virtual std::map<std::string, std::string> metadata_get(int download_id) = 0; //get download metadata + virtual std::string metadata_get(int download_id, std::string var) = 0; //get value of specified metadata variable + + protected: downloader_module_info info; }; diff --git a/server/modules/downloaders/curl/main.cpp b/server/modules/downloaders/curl/main.cpp index b3a2f36..f3da19e 100644 --- a/server/modules/downloaders/curl/main.cpp +++ b/server/modules/downloaders/curl/main.cpp @@ -166,6 +166,64 @@ download_s downloader::get_download(int download_id, std::map<int, std::string> return d; } +std::string compute_var_name(int download_id, std::string setting_name) +{ + std::string var_name = "download_"; + char id_s[64]; + snprintf(id_s, 63, "%d", download_id); + var_name += id_s; + var_name += "_"; + var_name += setting_name; + return var_name; +} + +bool downloader::metadata_set(int download_id, std::map<std::string, std::string> metadata) +{ + downloads[download_id].metadata = metadata; + for(auto i : downloads[download_id].metadata) + api->metadata_set(this, compute_var_name(download_id, i.first), std::vector<char>(i.second.begin(), i.second.end())); + return true; +} + +bool downloader::metadata_update(int download_id, std::map<std::string, std::string> metadata) +{ + for(auto i : metadata) + downloads[download_id].metadata[i.first] = i.second; + for(auto i : downloads[download_id].metadata) + api->metadata_set(this, compute_var_name(download_id, i.first), std::vector<char>(i.second.begin(), i.second.end())); + return true; +} + +bool downloader::metadata_drop(int download_id, std::string var) +{ + if(!var.empty()) + { + downloads[download_id].metadata.erase(var); + api->metadata_remove(this, compute_var_name(download_id, var)); + } + else + { + for(auto i : downloads[download_id].metadata) + api->metadata_remove(this, compute_var_name(download_id, i.first)); + downloads[download_id].metadata.clear(); + } + return true; +} +std::map<std::string, std::string> downloader::metadata_get(int download_id) +{ + return downloads[download_id].metadata; +} + +std::string downloader::metadata_get(int download_id, std::string var) +{ + auto i = downloads[download_id].metadata.find(var); + if(i != downloads[download_id].metadata.end()) + return i->second; + return std::string(); +} + + + extern "C" module_downloader* udm_downloader_module_load() { return new downloader; diff --git a/server/modules/downloaders/curl/main.h b/server/modules/downloaders/curl/main.h index 4c4cbe9..f5e589b 100644 --- a/server/modules/downloaders/curl/main.h +++ b/server/modules/downloaders/curl/main.h @@ -48,6 +48,13 @@ public: bool execute_action_on_download(int download_id, int action_id); //execute module defined action on download, by id received via add_download std::list<download_s> get_downloads(std::map<int, std::string> params = std::map<int, std::string>()); //this function must return list of downloads, additional options may be passed via params map download_s get_download(int download_id, std::map<int, std::string> params = std::map<int, std::string>()); //same as above, except this one is for single download, not a complete list + //downloader metadata manipulations + bool metadata_set(int download_id, std::map<std::string, std::string> metadata); //replace download metadata with provided one + bool metadata_update(int download_id, std::map<std::string, std::string> metadata); //updated matching metadata entries, create non existent + bool metadata_drop(int download_id, std::string var = std::string()); //remove all metadata if no variable specified, otherwise delete specified variable + std::map<std::string, std::string> metadata_get(int download_id); //get download metadata + std::string metadata_get(int download_id, std::string var); //get value of specified metadata variable + private: void on_modules_loaded(); std::map<int, my_download> downloads; //map of id, download |