/* Copyright © 2015-2016 Gluzskiy Alexandr (sss) This file is part of Unknown Download Manager (UDM). UDM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. UDM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with UDM. If not, see . */ #include "main.h" #include #include #include #include "curl_download.h" downloader::downloader() { if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { //TODO: handle error } } downloader::~downloader() { //TODO: stop downloads //TODO: deinit curl //save runtime state on exit } 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; } void downloader::on_modules_loaded() { //TODO: load downloads, metadata, e.t.c. auto setting_list = api->metadata_setting_list(this); setting_list.sort(); { int id = -1; std::map params; std::string name, download_path; for(auto i : setting_list) { std::string::size_type p = i.find("_", strlen("download_")); std::string id_str = i.substr(strlen("download_"), p - strlen("download_")); int new_id = atoi(id_str.c_str()); if(id == -1) id = new_id; if(id != new_id) { //TODO: something better add_download(params); params.clear(); name.clear(); download_path.clear(); } if(i.find("_download_path") != std::string::npos) { std::vector v; if(!api->metadata_get(this, i, v)) { //TODO: handle error } download_path.assign(v.begin(), v.end()); } if(i.find("_name") != std::string::npos) { std::vector v; if(!api->metadata_get(this, i, v)) { //TODO: handle error } name.assign(v.begin(), v.end()); } std::string::size_type pos2 = i.find("_param_"); if(pos2 != std::string::npos) { std::string id_str2 = i.substr(pos2 + strlen("_param_")); int param_id = atoi(id_str2.c_str()); std::vector v; if(!api->metadata_get(this, i, v)) { //TODO: handle error } params[param_id] = std::string(v.begin(), v.end()); } } } } void downloader::load(core_api *a) { 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 } const module_info_base &downloader::get_module_info() { return info; } void downloader::set_module_settings(const std::map &settings) { this->settings = settings; } int downloader::add_download(std::map params) { if(params.find(0) == params.end()) //missed required parameter return -1; curl_download *d = new curl_download(params, api, this); // std::string download_name; { auto p1 = params[0].rfind("/"); if(p1 != std::string::npos) d->name = params[0].substr(p1+1); else d->name = params[0]; } int id = 0; if(!downloads.empty()) { id = downloads.size(); d->id = id; } else d->id = 0; downloads[id] = d; //store metadata { if(!api->metadata_set(this, compute_var_name(id, "name"), std::vector(d->name.begin(), d->name.end()))) { //TODO: handle error } if(!api->metadata_set(this, compute_var_name(id, "download_path"), std::vector(d->get_download_path().begin(), d->get_download_path().end()))) { //TODO: handle error } //store params for(auto i : params) { char num_[32]; snprintf(num_, 31, "%d", i.first); if(!api->metadata_set(this, compute_var_name(id, std::string("param_") + num_), std::vector(i.second.begin(), i.second.end()))) { //TODO: handle error } } } //TODO: return id; } bool downloader::stop_download(int download_id) { //TODO: bool status = downloads[download_id]->stop(); if(!status) { //TODO: handle error return false; } return true; } bool downloader::start_download(int download_id) { //TODO: bool status = downloads[download_id]->start(); if(!status) { //TODO: handle error return false; } return true; } bool downloader::delete_download(int download_id, bool delete_data) { bool status = downloads[download_id]->delete_download(); if(!status) { //TODO: handle errror return false; } else { delete downloads[download_id]; downloads.erase(download_id); //metadata cleanup { //TODO: handle errors if(api->metadata_remove(this, compute_var_name(download_id, "name"))) { if(api->metadata_remove(this, compute_var_name(download_id, "download_path"))) { char param_name[16]; for(int i = 0;; i++) { snprintf(param_name, 15, "param_%d", i); if(!api->metadata_remove(this, compute_var_name(download_id, param_name))) break; } } } } } //TODO: return true; } bool downloader::execute_action_on_download(int download_id, int action_id) { //TODO: return true; } std::list downloader::get_downloads(std::map params) { std::list l; for(auto i : downloads) l.push_back(*(i.second)); //TODO: fill aditional data fields return l; } download_s downloader::get_download(int download_id, std::map params) { download_s d = *downloads[download_id]; //TODO: fill additional data fields return d; } bool downloader::metadata_set(int download_id, std::map 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(i.second.begin(), i.second.end())); return true; } bool downloader::metadata_update(int download_id, std::map 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(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); return 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 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; }