summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2015-09-10 00:15:07 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2015-09-10 00:15:07 +0300
commitccffc685c412183b56f822438da5cc8a575d757e (patch)
tree4ff9b3abb4ac1d94941ff5aa5aee9ee4cbe74a3e
parentb5af51e358073145cdf66470cc890d98547a6dac (diff)
client-qt:
handle disconnect basic downloads model (still draft with unimplemented basic features like dynamic columns count, dynamic columns will be implemented next) basic handler for download list (in theory it's already working now, but untested) basic modules info handler (just store data in memory for now, all basic features still unimplemented, download info ui templates generation will be implemented next here) basic core info handler (just store data in memory for now, core settings and core info ui will be implemented next here.) server: api: added client metadata manipulation api for downloader modules added metadata map to download structure in downloader modules curl_downloader: implemented new api's
-rw-r--r--client-qt/udm-client-qt/client_session.cpp1
-rw-r--r--client-qt/udm-client-qt/client_session.h1
-rw-r--r--client-qt/udm-client-qt/downloads_model.cpp90
-rw-r--r--client-qt/udm-client-qt/downloads_model.h5
-rw-r--r--client-qt/udm-client-qt/udm_main.cpp21
-rw-r--r--client-qt/udm-client-qt/udm_main.h4
-rw-r--r--server/include/api_module_downloader.h14
-rw-r--r--server/modules/downloaders/curl/main.cpp58
-rw-r--r--server/modules/downloaders/curl/main.h7
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