/*
Copyright © 2015 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 "modules_handler.h"
#include "main.h"
#include "utilities.h"
#include
#include
#include
#include
#include
#include "config.h"
extern runtime_config_s runtime_config;
extern core_api *module_api;
void modules_handler::load_metadata_modules(const std::string &path)
{
if(boost::filesystem::exists(path) && boost::filesystem::is_directory(path))
{
for(boost::filesystem::directory_iterator i(path), end = boost::filesystem::directory_iterator(); i != end; ++i)
{
void *lib = dlopen(i->path().generic_string().c_str(), RTLD_LAZY |RTLD_GLOBAL);
if(!lib)
{
printf("failed to open library \"%s\" with error: %s\n", i->path().c_str(), dlerror());
continue;
}
void *fptr = dlsym(lib, "udm_metadata_module_load");
if(!fptr)
{
printf("failed to find symbol \"udm_metadata_module_load\" in library %s with error %s\n", i->path().c_str(), dlerror());
dlclose(lib);
continue;
}
module_metadata_storage *(*f)(void);
f = (module_metadata_storage *(*)(void))fptr;
//TODO: aditional sanity checks
module_metadata_storage *m = f();
m->load(module_api);
sync_module_settings(m);
metadata_modules.push_back(m);
}
}
}
void modules_handler::load_downloader_modules(const std::string &path)
{
if(boost::filesystem::exists(path) && boost::filesystem::is_directory(path))
{
for(boost::filesystem::directory_iterator i(path), end = boost::filesystem::directory_iterator(); i != end; ++i)
{
void *lib = dlopen(i->path().generic_string().c_str(), RTLD_LAZY |RTLD_GLOBAL);
if(!lib)
{
printf("failed to open library \"%s\" with error: %s\n", i->path().c_str(), dlerror());
continue;
}
void *fptr = dlsym(lib, "udm_downloader_module_load");
if(!fptr)
{
printf("failed to find symbol \"udm_downloader_module_load\" in library %s with error %s\n", i->path().c_str(), dlerror());
dlclose(lib);
continue;
}
module_downloader *(*f)(void);
f = (module_downloader *(*)(void))fptr;
//TODO: aditional sanity checks
module_downloader *m = f();
m->load(module_api);
sync_module_settings(m);
downloader_modules.push_back(m);
}
}
}
std::string modules_handler::get_self_path()
{
//TODO: dynamic buffer
char buf[1024];
readlink("/proc/self/exe", buf, 1023);
std::string s (buf);
return s;
}
std::string modules_handler::list_modules()
{
std::string buf;
buf += "Installed metadata modules:\n";
buf += list_modules_single_type_internal(metadata_modules);
buf += "\nInstalled downloader modules:\n";
buf += list_modules_single_type_internal(downloader_modules);
return buf;
}
std::string modules_handler::list_modules_single_type_internal(const std::list &modules)
{
std::string buf;
for(auto i : modules)
{
//TODO: additional info for each module type
buf += "\tName: ";
buf += i->get_module_info().name;
buf += "\n\tDescription: " + i->get_module_info().description;
buf += "\n\tVersion: " + i->get_module_info().version;
if(runtime_config.settings.verbosity >= 1)
{
buf += "\n\tAvailable options:";
for(auto i1 : i->get_module_info().default_settings)
{
buf += "\n\t\t";
buf += i1.first;
buf += " = ";
buf += i1.second.value;
}
}
buf += "\n\n";
}
return buf;
}
void modules_handler::sync_module_settings(module_base *m)
{
//update config file with available modules settings
for(auto i : m->get_module_info().default_settings)
{
std::string setting = "modules." + m->get_module_info().name + "." + i.first;
std::string current_val = runtime_config.config_file.get(setting, "not set");
if(current_val == "not set")
runtime_config.config_file.put(setting, i.second.value);
}
}
modules_handler::modules_handler()
{
self_path = get_self_path();
}
void modules_handler::load_modules()
{
boost::filesystem::path p(self_path);
std::string self_dir = p.parent_path().generic_string();
load_metadata_modules(self_dir + "/modules/metadata");
load_metadata_modules(replace_home_var("~/.share/udm/modules/metadata"));
load_metadata_modules("/usr/lib/udm/modules/metadata");
load_downloader_modules(self_dir + "/modules/downloaders");
load_downloader_modules(replace_home_var("~/.share/udm/modules/downloaders"));
load_downloader_modules("/usr/lib/udm/modules/downloaders");
load_modules_settings();
}
void modules_handler::on_modules_loaded()
{
for(auto i : metadata_modules)
{
if(!i->get_module_info().on_modules_loaded.empty())
i->get_module_info().on_modules_loaded();
}
for(auto i : downloader_modules)
{
if(!i->get_module_info().on_modules_loaded.empty())
i->get_module_info().on_modules_loaded();
}
}
void modules_handler::sync_downloads(std::map &downloads)
{
int id = downloads.size();
for(auto i : downloader_modules)
{
module_downloader *d = static_cast(i);
for(auto it : d->get_downloads())
{
downloads[id].module_name = d->get_module_info().name;
downloads[id].module_id = it.id;
id++;
}
}
}
void modules_handler::load_modules_settings()
{
for(auto i : metadata_modules)
i->set_module_settings(module_api->get_module_settings(i));
for(auto i : downloader_modules)
i->set_module_settings(module_api->get_module_settings(i));
}
std::list &modules_handler::get_metadata_modules()
{
return metadata_modules;
}
std::list &modules_handler::get_downloader_modules()
{
return downloader_modules;
}
modules_handler::~modules_handler()
{
//dtor
}