summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocol/udm.proto14
-rw-r--r--server/include/api_module_downloader.h5
-rw-r--r--server/modules/downloaders/curl/curl.cbp4
-rw-r--r--server/modules/downloaders/curl/include/curl_download.h30
-rw-r--r--server/modules/downloaders/curl/main.cpp37
-rw-r--r--server/modules/downloaders/curl/main.h10
-rw-r--r--server/modules/downloaders/curl/src/curl_download.cpp61
7 files changed, 150 insertions, 11 deletions
diff --git a/protocol/udm.proto b/protocol/udm.proto
index 15de0b7..2dd0ebf 100644
--- a/protocol/udm.proto
+++ b/protocol/udm.proto
@@ -35,12 +35,12 @@ enum MODULE_UI_ELEMENT_TYPE {
message module_download_ui_element_info {
optional MODULE_UI_ELEMENT_TYPE type = 1 [default = UI_EMPTY];
repeated module_download_ui_element_info children = 2;
- required string id = 3; //internal element id used to get element value (should be unique for every loaded module)
+ required int32 id = 3; //internal element id used to get element value (should be unique for every loaded module)
optional string name = 4 [default = "not set"]; //can be non unique
}
message module_download_menu_element_info {
- required string id = 1;
+ required int32 id = 1;
required string name = 2;
optional string description = 3;
optional bool data_required = 4 [default = false];
@@ -49,7 +49,7 @@ message module_download_menu_element_info {
message module_download_ui_element_data {
- required string ui_id = 1; //should be unique for every loaded module
+ required int32 ui_id = 1; //should be unique for every loaded module
required string data = 2;
}
@@ -66,7 +66,7 @@ message server_download_ui_data_reply {
message client_download_ui_data_request {
required string module_name = 1;
required string download_id = 2;
- repeated string ui_id = 3; //should be unique for for every loaded module
+ repeated int32 ui_id = 3; //should be unique for for every loaded module
}
@@ -84,7 +84,7 @@ message download_ui_subscription_info {
message download_ui_unsubscription_info {
- required string id = 1; //unsubscript from all updates for given id's
+ required int32 id = 1; //unsubscript from all updates for given id's
}
//ui subscriptions end
@@ -94,7 +94,7 @@ message download_ui_unsubscription_info {
//dowloads proto part begin
message client_download_request {
- required string id = 1;
+ required int32 id = 1;
optional bool with_content = 2 [default = false];
}
@@ -113,7 +113,7 @@ message download_content_entry {
message download {
- required string id = 1;
+ required int32 id = 1;
required string name = 2;
optional download_content_entry content = 3;
required int64 size = 4;
diff --git a/server/include/api_module_downloader.h b/server/include/api_module_downloader.h
index 7c68cad..872430d 100644
--- a/server/include/api_module_downloader.h
+++ b/server/include/api_module_downloader.h
@@ -75,8 +75,9 @@ struct download_content_entry_s { //here is basic content entry description, thi
struct download_s {
- std::string id, name; //id generated via download_add or via session restore and it's unique for current session and current dowloader
- int64_t size, downloaded; //download size and size of downloaded data
+ int id;
+ std::string name; //id generated via download_add or via session restore and it's unique for current session and current dowloader
+ int64_t size, downloaded, download_speed; //download size and size of downloaded data, also download speed all vars in bytes
std::map<std::string, 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
};
diff --git a/server/modules/downloaders/curl/curl.cbp b/server/modules/downloaders/curl/curl.cbp
index d61b038..b0971b5 100644
--- a/server/modules/downloaders/curl/curl.cbp
+++ b/server/modules/downloaders/curl/curl.cbp
@@ -15,6 +15,7 @@
<Option createStaticLib="1" />
<Compiler>
<Add option="-g" />
+ <Add directory="include" />
</Compiler>
</Target>
<Target title="Release">
@@ -26,6 +27,7 @@
<Option createStaticLib="1" />
<Compiler>
<Add option="-O2" />
+ <Add directory="include" />
</Compiler>
<Linker>
<Add option="-s" />
@@ -40,8 +42,10 @@
<Linker>
<Add library="boost_system" />
</Linker>
+ <Unit filename="include/curl_download.h" />
<Unit filename="main.cpp" />
<Unit filename="main.h" />
+ <Unit filename="src/curl_download.cpp" />
<Extensions>
<code_completion />
<debugger />
diff --git a/server/modules/downloaders/curl/include/curl_download.h b/server/modules/downloaders/curl/include/curl_download.h
new file mode 100644
index 0000000..1a43b29
--- /dev/null
+++ b/server/modules/downloaders/curl/include/curl_download.h
@@ -0,0 +1,30 @@
+#ifndef CURL_DOWNLOAD_H
+#define CURL_DOWNLOAD_H
+
+#include <api_module_downloader.h>
+#include <curl/curl.h>
+
+enum download_state {running, stopped};
+
+class curl_download
+{
+ public:
+ curl_download(std::map<std::string, std::string> params, core_api *a);
+ virtual ~curl_download();
+
+ void start();
+ void stop();
+ const bool get_cancel_state()
+ {
+ return cancel_transfer;
+ }
+ private:
+ void perform_internal();
+ download_s api_download;
+ CURL *easy_handle;
+ bool cancel_transfer;
+ download_state state;
+ std::string download_path;
+};
+
+#endif // CURL_DOWNLOAD_H
diff --git a/server/modules/downloaders/curl/main.cpp b/server/modules/downloaders/curl/main.cpp
index bd71104..fca69c5 100644
--- a/server/modules/downloaders/curl/main.cpp
+++ b/server/modules/downloaders/curl/main.cpp
@@ -22,6 +22,10 @@
#include "main.h"
#include <boost/bind.hpp>
+#include <curl/curl.h>
+
+#include "curl_download.h"
+
module_base::~module_base()
@@ -31,6 +35,8 @@ module_base::~module_base()
downloader::downloader()
{
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
+ ;//TODO: handle error
}
downloader::~downloader()
@@ -48,6 +54,15 @@ void downloader::load(core_api *a)
info.name = "curl";
info.description = "basic http/ftp downloader via libcurl, also example how to write downloader modules";
info.version = "0.0.0.1draft";
+ module_download_ui_element_info_s e;
+ e.id = "0";
+ e.name = "Url";
+ e.type = MODULE_UI_ELEMENT_TYPE_e::UI_STR;
+ info.download_creation_ui.push_back(e);
+ e.id = "1";
+ e.name = "Download path";
+ e.type = MODULE_UI_ELEMENT_TYPE_e::UI_STR;
+ info.download_creation_ui.push_back(e);
info.on_modules_loaded = boost::bind(&downloader::on_modules_loaded, this); //optional definition of function which is called after all modules loaded
}
@@ -64,8 +79,28 @@ void downloader::set_module_settings(const std::map<std::string, std::string> &s
int downloader::add_download(std::map<std::string, std::string> params)
{
+ curl_download *d = new curl_download(params, api);
+ my_download md;
+ std::string download_name;
+ {
+ auto p1 = params["0"].rfind("/");
+ if(p1 != std::string::npos)
+ md.name = params["0"].substr(p1);
+ }
+ md.curl_d = d;
+ int id = 0;
+ if(!downloads.empty())
+ {
+ id = downloads.size();
+
+ md.id = id;
+ }
+ else
+ md.id = 0;
+
+ downloads[id] = md;
//TODO:
- return 0;
+ return id;
}
bool downloader::stop_download(int download_id)
diff --git a/server/modules/downloaders/curl/main.h b/server/modules/downloaders/curl/main.h
index 16580ec..2fa2a66 100644
--- a/server/modules/downloaders/curl/main.h
+++ b/server/modules/downloaders/curl/main.h
@@ -24,6 +24,13 @@
#include <api_module_downloader.h>
+#include "curl_download.h"
+
+struct my_download : public download_s
+{
+ curl_download *curl_d;
+};
+
class downloader : public module_downloader
{
public:
@@ -45,7 +52,8 @@ private:
void on_modules_loaded();
downloader_module_info info;
core_api *api = nullptr;
- std::map<std::string, std::string> settings;
+ std::map<std::string, std::string> settings; //settings name, val
+ std::map<int, my_download> downloads; //map of id, download
};
diff --git a/server/modules/downloaders/curl/src/curl_download.cpp b/server/modules/downloaders/curl/src/curl_download.cpp
new file mode 100644
index 0000000..d474464
--- /dev/null
+++ b/server/modules/downloaders/curl/src/curl_download.cpp
@@ -0,0 +1,61 @@
+#include "curl_download.h"
+
+#include <boost/thread.hpp>
+
+
+size_t curl_w_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
+{
+ curl_download *d = (curl_download*)userdata;
+ if(d->get_cancel_state())
+ return -1; //cancel transfer
+ //TODO: implement pause
+ size_t size_ = size * nmemb;
+ if(size_)
+ {
+
+ }
+ return size_;
+}
+
+curl_download::curl_download(std::map<std::string, std::string> params, core_api *a) : cancel_transfer(false), state(stopped)
+{
+ //for now we use single transfer connection for url
+ //TODO: support multiple connections in parallel for multithreaded download
+ easy_handle = curl_easy_init();
+ if(!easy_handle)
+ ; //TODO: handle error
+
+ curl_easy_setopt(easy_handle, CURLOPT_URL, params["0"].c_str()); //Url as set in module_info
+ curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, curl_w_callback);
+ curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, this);
+ if(!params["0"].empty())
+ download_path = params["0"];
+ else
+ download_path = a->get_core_settings()["download_dir"];
+ //curl_easy_setopt(h, CURLOPT_DEFAULT_PROTOCOL, "http"); //require curl >= 7.45
+
+
+}
+
+void curl_download::start()
+{
+ boost::thread(boost::bind(&curl_download::perform_internal, this));
+ state = running;
+}
+
+void curl_download::stop()
+{
+ cancel_transfer = true;
+}
+
+
+void curl_download::perform_internal()
+{
+ curl_easy_perform(easy_handle);
+}
+
+curl_download::~curl_download()
+{
+ curl_easy_cleanup(easy_handle);
+
+}