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