/*
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;
}