diff --git a/src/command_download.cc b/src/command_download.cc index 2b470370..789cbd39 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -37,10 +37,15 @@ #include "config.h" #include +#include +#include +#include #include #include #include "core/download.h" +#include "core/manager.h" +#include "utils/command_slot.h" #include "utils/command_download_slot.h" #include "globals.h" @@ -72,6 +77,100 @@ retrieve_d_base_filename(core::Download* download) { return base.substr(split + 1); } +torrent::Object +apply_d_create_link(core::Download* download, const torrent::Object& rawArgs) { + const torrent::Object::list_type& args = rawArgs.as_list(); + + if (args.size() != 3) + throw torrent::input_error("Wrong argument count."); + + torrent::Object::list_type::const_iterator itr = args.begin(); + + const std::string& type = (itr++)->as_string(); + const std::string& prefix = (itr++)->as_string(); + const std::string& postfix = (itr++)->as_string(); + + if (type.empty()) + throw torrent::input_error("Invalid arguments."); + + std::string target; + std::string link; + + if (type == "base_path") { + target = download->get_string("base_path"); + link = rak::path_expand(prefix + download->get_string("base_path") + postfix); + + } else if (type == "base_filename") { + target = download->get_string("base_path"); + link = rak::path_expand(prefix + download->get_string("base_filename") + postfix); + + } else if (type == "tied") { + link = rak::path_expand(download->get_string("get_tied_to_file")); + + if (link.empty()) + return torrent::Object(); + + link = rak::path_expand(prefix + link + postfix); + target = download->get_string("base_path"); + + } else { + throw torrent::input_error("Unknown type argument."); + } + + if (symlink(target.c_str(), link.c_str()) == -1) +// control->core()->push_log("create_link failed: " + std::string(rak::error_number::current().c_str())); +// control->core()->push_log("create_link failed: " + std::string(rak::error_number::current().c_str()) + " to " + target); + ; // Disabled. + + return torrent::Object(); +} + +torrent::Object +apply_d_delete_link(core::Download* download, const torrent::Object& rawArgs) { + const torrent::Object::list_type& args = rawArgs.as_list(); + + if (args.size() != 3) + throw torrent::input_error("Wrong argument count."); + + torrent::Object::list_type::const_iterator itr = args.begin(); + + const std::string& type = (itr++)->as_string(); + const std::string& prefix = (itr++)->as_string(); + const std::string& postfix = (itr++)->as_string(); + + if (type.empty()) + throw torrent::input_error("Invalid arguments."); + + std::string link; + + if (type == "base_path") { + link = rak::path_expand(prefix + download->get_string("base_path") + postfix); + + } else if (type == "base_filename") { + link = rak::path_expand(prefix + download->get_string("base_filename") + postfix); + + } else if (type == "tied") { + link = rak::path_expand(download->get_string("get_tied_to_file")); + + if (link.empty()) + return torrent::Object(); + + link = rak::path_expand(prefix + link + postfix); + + } else { + throw torrent::input_error("Unknown type argument."); + } + + rak::file_stat fileStat; + rak::error_number::clear_global(); + + if (!fileStat.update_link(link) || !fileStat.is_link() || + unlink(link.c_str()) == -1) + ; // control->core()->push_log("delete_link failed: " + std::string(rak::error_number::current().c_str())); + + return torrent::Object(); +} + #define ADD_COMMAND_DOWNLOAD_SLOT(key, function, slot, parm, doc) \ commandDownloadSlotsItr->set_slot(slot); \ variables->insert(key, commandDownloadSlotsItr++, NULL, &utils::CommandDownloadSlot::function, utils::VariableMap::flag_dont_delete | utils::VariableMap::flag_public_xmlrpc, parm, doc); @@ -79,10 +178,43 @@ retrieve_d_base_filename(core::Download* download) { #define ADD_COMMAND_DOWNLOAD_VOID(key, slot) \ ADD_COMMAND_DOWNLOAD_SLOT(key, call_unknown, utils::object_d_fn(slot), "i:", "") +#define ADD_COMMAND_DOWNLOAD_LIST(key, slot) \ + ADD_COMMAND_DOWNLOAD_SLOT(key, call_list, slot, "i:", "") + +#define ADD_COMMAND_DOWNLOAD_VARIABLE_VALUE(key, firstKey, secondKey) \ + ADD_COMMAND_DOWNLOAD_SLOT("get_" key, call_unknown, utils::get_variable_d_fn(firstKey, secondKey), "i:", ""); \ + ADD_COMMAND_DOWNLOAD_SLOT("set_" key, call_value, utils::set_variable_d_fn(firstKey, secondKey), "i:i", ""); + +#define ADD_COMMAND_DOWNLOAD_VARIABLE_STRING(key, firstKey, secondKey) \ + ADD_COMMAND_DOWNLOAD_SLOT("get_" key, call_unknown, utils::get_variable_d_fn(firstKey, secondKey), "i:", ""); \ + ADD_COMMAND_DOWNLOAD_SLOT("set_" key, call_string, utils::set_variable_d_fn(firstKey, secondKey), "i:s", ""); + void initialize_command_download() { utils::VariableMap* variables = control->download_variables(); ADD_COMMAND_DOWNLOAD_VOID("base_path", &retrieve_d_base_path); ADD_COMMAND_DOWNLOAD_VOID("base_filename", &retrieve_d_base_filename); + + ADD_COMMAND_DOWNLOAD_LIST("create_link", rak::ptr_fn(&apply_d_create_link)); + ADD_COMMAND_DOWNLOAD_LIST("delete_link", rak::ptr_fn(&apply_d_delete_link)); + + ADD_COMMAND_STRING_UN("print", rak::make_mem_fun(control->core(), &core::Manager::push_log)); + + // 0 - stopped + // 1 - started + ADD_COMMAND_DOWNLOAD_VARIABLE_VALUE("state", "rtorrent", "state"); + ADD_COMMAND_DOWNLOAD_VARIABLE_VALUE("complete", "rtorrent", "complete"); + + // 0 - Not hashing + // 1 - Normal hashing + // 2 - Download finished, hashing + ADD_COMMAND_DOWNLOAD_VARIABLE_VALUE("hashing", "rtorrent", "hashing"); + ADD_COMMAND_DOWNLOAD_VARIABLE_STRING("tied_to_file", "rtorrent", "tied_to_file"); + + // The "state_changed" variable is required to be a valid unix time + // value, it indicates the last time the torrent changed its state, + // resume/pause. + ADD_COMMAND_DOWNLOAD_VARIABLE_VALUE("state_changed", "rtorrent", "state_changed"); + ADD_COMMAND_DOWNLOAD_VARIABLE_VALUE("ignore_commands", "rtorrent", "ignore_commands"); } diff --git a/src/command_events.cc b/src/command_events.cc index ec5ffe90..df1e378d 100644 --- a/src/command_events.cc +++ b/src/command_events.cc @@ -102,7 +102,7 @@ apply_stop_on_ratio(const torrent::Object& rawArgs) { if ((totalUpload >= minUpload && totalUpload * 100 >= totalDone * minRatio) || (maxRatio > 0 && totalUpload * 100 > totalDone * maxRatio)) { downloadList->stop_try(*itr); - (*itr)->set("ignore_commands", (int64_t)1); + (*itr)->set("set_ignore_commands", (int64_t)1); } ++itr; @@ -114,11 +114,11 @@ apply_stop_on_ratio(const torrent::Object& rawArgs) { torrent::Object apply_start_tied() { for (core::DownloadList::iterator itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ++itr) { - if ((*itr)->get_value("state") == 1) + if ((*itr)->get_value("get_state") == 1) continue; rak::file_stat fs; - const std::string& tiedToFile = (*itr)->get_string("tied_to_file"); + const std::string& tiedToFile = (*itr)->get_string("get_tied_to_file"); if (!tiedToFile.empty() && fs.update(rak::path_expand(tiedToFile))) control->core()->download_list()->start_try(*itr); @@ -130,11 +130,11 @@ apply_start_tied() { torrent::Object apply_stop_untied() { for (core::DownloadList::iterator itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ++itr) { - if ((*itr)->get_value("state") == 0) + if ((*itr)->get_value("get_state") == 0) continue; rak::file_stat fs; - const std::string& tiedToFile = (*itr)->get_string("tied_to_file"); + const std::string& tiedToFile = (*itr)->get_string("get_tied_to_file"); if (!tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile))) control->core()->download_list()->stop_try(*itr); @@ -147,7 +147,7 @@ torrent::Object apply_close_untied() { for (core::DownloadList::iterator itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ++itr) { rak::file_stat fs; - const std::string& tiedToFile = (*itr)->get_string("tied_to_file"); + const std::string& tiedToFile = (*itr)->get_string("get_tied_to_file"); if (!tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile)) && control->core()->download_list()->stop_try(*itr)) control->core()->download_list()->close(*itr); @@ -160,7 +160,7 @@ torrent::Object apply_remove_untied() { for (core::DownloadList::iterator itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ) { rak::file_stat fs; - const std::string& tiedToFile = (*itr)->get_string("tied_to_file"); + const std::string& tiedToFile = (*itr)->get_string("get_tied_to_file"); if (!tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile)) && control->core()->download_list()->stop_try(*itr)) itr = control->core()->download_list()->erase(itr); diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 0b6848eb..d8e56895 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -182,7 +182,7 @@ DownloadFactory::receive_success() { download->set("max_peers", control->variable()->call_command_void("get_max_peers")); download->set("tracker_numwant", control->variable()->call_command_void("get_tracker_numwant")); - if (download->get_value("complete") != 0) { + if (download->get_value("get_complete") != 0) { if (control->variable()->call_command_value("get_min_peers_seed") >= 0) download->set("min_peers", control->variable()->call_command_void("get_min_peers_seed")); @@ -211,7 +211,7 @@ DownloadFactory::receive_success() { download->set("directory", rtorrent->get_key("directory")); if (!m_session && m_variables["tied_to_file"].as_value()) - download->set("tied_to_file", m_uri); + download->set("set_tied_to_file", m_uri); torrent::Object& resumeObject = root->has_key_map("libtorrent_resume") ? root->get_key("libtorrent_resume") @@ -236,8 +236,8 @@ DownloadFactory::receive_success() { if (m_session) { // This torrent was queued for hashing or hashing when the session // file was saved. Or it was in a started state. - if (download->get_value("hashing") != Download::variable_hashing_stopped || - download->get_value("state") != 0) + if (download->get_value("get_hashing") != Download::variable_hashing_stopped || + download->get_value("get_state") != 0) m_manager->download_list()->resume(download); } else { diff --git a/src/core/download_list.cc b/src/core/download_list.cc index 62e87f61..9f5498f6 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -242,7 +242,7 @@ DownloadList::close_throw(Download* download) { download->download()->close(); - if (!download->is_hash_failed() && download->get_value("hashing") != Download::variable_hashing_stopped) + if (!download->is_hash_failed() && download->get_value("get_hashing") != Download::variable_hashing_stopped) throw torrent::internal_error("DownloadList::close_throw(...) called but we're going into a hashing loop."); std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download)); @@ -256,7 +256,7 @@ DownloadList::start_normal(Download* download) { // Clear hash failed as we're doing a manual start and want to try // hashing again. download->set_hash_failed(false); - download->set("state", (int64_t)1); + download->set("set_state", (int64_t)1); resume(download); } @@ -268,12 +268,12 @@ DownloadList::start_try(Download* download) { // Also don't start if the state is one of those that indicate we // were manually stopped? - if (download->is_hash_failed() || download->get_value("ignore_commands") != 0) + if (download->is_hash_failed() || download->get_value("get_ignore_commands") != 0) return false; // Don't clear the hash failed as this function is used by scripts, // etc. - download->set("state", (int64_t)1); + download->set("set_state", (int64_t)1); resume(download); return true; @@ -283,7 +283,7 @@ void DownloadList::stop_normal(Download* download) { check_contains(download); - download->set("state", (int64_t)0); + download->set("set_state", (int64_t)0); pause(download); } @@ -292,10 +292,10 @@ bool DownloadList::stop_try(Download* download) { check_contains(download); - if (download->get_value("ignore_commands") != 0) + if (download->get_value("get_ignore_commands") != 0) return false; - download->set("state", (int64_t)0); + download->set("set_state", (int64_t)0); pause(download); return true; @@ -321,8 +321,8 @@ DownloadList::resume(Download* download) { if (download->is_hash_failed()) return; - if (download->get_value("hashing") == Download::variable_hashing_stopped) - download->set("hashing", Download::variable_hashing_initial); + if (download->get_value("get_hashing") == Download::variable_hashing_stopped) + download->set("set_hashing", Download::variable_hashing_initial); std::for_each(slot_map_hash_queued().begin(), slot_map_hash_queued().end(), download_list_call(download)); return; @@ -331,7 +331,7 @@ DownloadList::resume(Download* download) { // This will never actually do anything due to the above hash check. // open_throw(download); - download->set("state_changed", cachedTime.seconds()); + download->set("set_state_changed", cachedTime.seconds()); if (download->is_done()) { download->set_connection_type(download->get_string("connection_seed")); @@ -365,9 +365,9 @@ DownloadList::pause(Download* download) { // Always clear hashing on pause. When a hashing request is added, // it should have cleared the hash resume data. - if (download->get_value("hashing") != Download::variable_hashing_stopped) { + if (download->get_value("get_hashing") != Download::variable_hashing_stopped) { download->download()->hash_stop(); - download->set_value("hashing", Download::variable_hashing_stopped); + download->set_value("set_hashing", Download::variable_hashing_stopped); std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download)); } @@ -380,7 +380,7 @@ DownloadList::pause(Download* download) { std::for_each(slot_map_stop().begin(), slot_map_stop().end(), download_list_call(download)); - download->set("state_changed", cachedTime.seconds()); + download->set("set_state_changed", cachedTime.seconds()); // Save the state after all the slots, etc have been called so we // include the modifications they may make. @@ -397,7 +397,7 @@ DownloadList::check_hash(Download* download) { try { - if (download->get_value("hashing") != Download::variable_hashing_stopped) + if (download->get_value("get_hashing") != Download::variable_hashing_stopped) return; hash_queue(download, Download::variable_hashing_rehash); @@ -430,8 +430,8 @@ DownloadList::hash_done(Download* download) { // confirm all the data, avoiding large BW usage on f.ex. the // ReiserFS bug with >4GB files. - int64_t hashing = download->get_value("hashing"); - download->set_value("hashing", Download::variable_hashing_stopped); + int64_t hashing = download->get_value("get_hashing"); + download->set_value("set_hashing", Download::variable_hashing_stopped); switch (hashing) { case Download::variable_hashing_initial: @@ -440,17 +440,17 @@ DownloadList::hash_done(Download* download) { // If the download was previously completed but the files were // f.ex deleted, then we clear the state and complete. - if (download->get_value("complete") && !download->is_done()) { - download->set("state", (int64_t)0); + if (download->get_value("get_complete") && !download->is_done()) { + download->set("set_state", (int64_t)0); download->set_message("Download registered as completed, but hash check returned unfinished chunks."); } // Save resume data so we update time-stamps and priorities if // they were invalid/changed while loading/hashing. - download->set("complete", (int64_t)download->is_done()); + download->set("set_complete", (int64_t)download->is_done()); torrent::resume_save_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume")); - if (download->get_value("state") == 1) + if (download->get_value("get_state") == 1) resume(download); break; @@ -480,14 +480,14 @@ void DownloadList::hash_queue(Download* download, int type) { check_contains(download); - if (download->get_value("hashing") != Download::variable_hashing_stopped) + if (download->get_value("get_hashing") != Download::variable_hashing_stopped) throw torrent::internal_error("DownloadList::hash_queue(...) hashing already queued."); close_throw(download); torrent::resume_clear_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume")); download->set_hash_failed(false); - download->set_value("hashing", type); + download->set_value("set_hashing", type); if (download->is_open()) throw torrent::internal_error("DownloadList::hash_clear(...) download still open."); @@ -516,7 +516,7 @@ void DownloadList::confirm_finished(Download* download) { check_contains(download); - download->set("complete", (int64_t)1); + download->set("set_complete", (int64_t)1); download->set_connection_type(download->get_string("connection_seed")); download->set_priority(download->priority()); @@ -540,7 +540,7 @@ DownloadList::confirm_finished(Download* download) { std::for_each(slot_map_finished().begin(), slot_map_finished().end(), download_list_call(download)); - if (!download->is_active() && download->get_value("state") == 1) + if (!download->is_active() && download->get_value("get_state") == 1) resume(download); } diff --git a/src/core/manager.cc b/src/core/manager.cc index 6f1981aa..66db7a7e 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -168,7 +168,7 @@ Manager::handshake_log(const sockaddr* sa, int msg, int err, const torrent::Hash // Hmm... find some better place for all this. void Manager::delete_tied(Download* download) { - const std::string& tie = download->get_string("tied_to_file"); + const std::string& tie = download->get_string("get_tied_to_file"); // This should be configurable, need to wait for the variable // thingie to be implemented. @@ -178,7 +178,7 @@ Manager::delete_tied(Download* download) { if (::unlink(rak::path_expand(tie).c_str()) == -1) push_log("Could not unlink tied file: " + std::string(rak::error_number::current().c_str())); - download->set("tied_to_file", std::string()); + download->set("set_tied_to_file", std::string()); } Manager::Manager() : @@ -482,7 +482,7 @@ Manager::try_create_download_expand(const std::string& uri, bool start, bool pri if (tied) for (std::vector::iterator itr = paths.begin(); itr != paths.end(); ) - if (std::find_if(m_downloadList->begin(), m_downloadList->end(), rak::equal(*itr, rak::bind2nd(std::mem_fun(&Download::get_string), "tied_to_file"))) + if (std::find_if(m_downloadList->begin(), m_downloadList->end(), rak::equal(*itr, rak::bind2nd(std::mem_fun(&Download::get_string), "get_tied_to_file"))) != m_downloadList->end()) itr = paths.erase(itr); else @@ -514,7 +514,7 @@ Manager::receive_hashing_changed() { continue; bool tryQuick = - (*itr)->get_value("hashing") == Download::variable_hashing_initial && + (*itr)->get_value("get_hashing") == Download::variable_hashing_initial && (*itr)->download()->file_list()->bitfield()->empty(); if (!tryQuick && foundHashing) @@ -537,7 +537,7 @@ Manager::receive_hashing_changed() { (*itr)->download()->hash_stop(); if (foundHashing) { - (*itr)->set_value("hashing", Download::variable_hashing_rehash); + (*itr)->set_value("set_hashing", Download::variable_hashing_rehash); continue; } } @@ -548,7 +548,7 @@ Manager::receive_hashing_changed() { } catch (torrent::local_error& e) { if (tryQuick) { // Make sure we don't repeat the quick hashing. - (*itr)->set_value("hashing", Download::variable_hashing_rehash); + (*itr)->set_value("set_hashing", Download::variable_hashing_rehash); } else { (*itr)->set_hash_failed(true); diff --git a/src/core/view_manager.cc b/src/core/view_manager.cc index 410d93b2..0012a31b 100644 --- a/src/core/view_manager.cc +++ b/src/core/view_manager.cc @@ -134,19 +134,19 @@ ViewManager::ViewManager(DownloadList* dl) : m_sort["name"] = new ViewSortName(); m_sort["name_reverse"] = new ViewSortReverse(new ViewSortName()); - m_sort["stopped"] = new ViewSortVariableValue("state"); - m_sort["started"] = new ViewSortVariableValue("state", true); - m_sort["complete"] = new ViewSortVariableValue("complete"); - m_sort["incomplete"] = new ViewSortVariableValue("complete", true); + m_sort["stopped"] = new ViewSortVariableValue("get_state"); + m_sort["started"] = new ViewSortVariableValue("get_state", true); + m_sort["complete"] = new ViewSortVariableValue("get_complete"); + m_sort["incomplete"] = new ViewSortVariableValue("get_complete", true); - m_sort["state_changed"] = new ViewSortVariableValue("state_changed"); - m_sort["state_changed_reverse"] = new ViewSortVariableValue("state_changed", true); + m_sort["state_changed"] = new ViewSortVariableValue("get_state_changed"); + m_sort["state_changed_reverse"] = new ViewSortVariableValue("get_state_changed", true); - m_filter["started"] = new ViewFilterVariableValue("state", 1); - m_filter["stopped"] = new ViewFilterVariableValue("state", 0); - m_filter["complete"] = new ViewFilterVariableValue("complete", 0, true); - m_filter["incomplete"] = new ViewFilterVariableValue("complete", 0); - m_filter["hashing"] = new ViewFilterVariableValue("hashing", 0, true); + m_filter["started"] = new ViewFilterVariableValue("get_state", 1); + m_filter["stopped"] = new ViewFilterVariableValue("get_state", 0); + m_filter["complete"] = new ViewFilterVariableValue("get_complete", 0, true); + m_filter["incomplete"] = new ViewFilterVariableValue("get_complete", 0); + m_filter["hashing"] = new ViewFilterVariableValue("get_hashing", 0, true); } void diff --git a/src/display/utils.cc b/src/display/utils.cc index 66d7bae9..aa39b524 100644 --- a/src/display/utils.cc +++ b/src/display/utils.cc @@ -159,8 +159,8 @@ print_download_info(char* first, char* last, core::Download* d) { } first = print_buffer(first, last, " [%c%c R: %3.2f", - d->get_string("tied_to_file").empty() ? ' ' : 'T', - d->get_value("ignore_commands") == 0 ? ' ' : 'I', + d->get_string("get_tied_to_file").empty() ? ' ' : 'T', + d->get_value("get_ignore_commands") == 0 ? ' ' : 'I', d->download()->bytes_done() > 0 ? (double)(100 * d->download()->up_rate()->total() / d->download()->bytes_done()) / 100 : 0.0); if (d->priority() != 2) @@ -178,7 +178,7 @@ char* print_download_status(char* first, char* last, core::Download* d) { if (d->is_active()) ; - else if (d->get_value("hashing") != 0) + else if (d->get_value("get_hashing") != 0) first = print_buffer(first, last, "Hashing: "); else if (!d->is_active()) first = print_buffer(first, last, "Inactive: "); diff --git a/src/option_handler_rules.cc b/src/option_handler_rules.cc index 0d4093df..85c8d93f 100644 --- a/src/option_handler_rules.cc +++ b/src/option_handler_rules.cc @@ -105,92 +105,6 @@ var_d2_get_value(Target target, GetFunc getFunc) { return new utils::VariableDownloadValueSlot(rak::ftor_fn1(rak::on(rak::on(std::mem_fun(&core::Download::download), std::mem_fun(target)), std::mem_fun(getFunc))), NULL); } -void -apply_d_create_link(core::Download* download, const torrent::Object::list_type& args) { - if (args.size() != 3) - throw torrent::input_error("Wrong argument count."); - - torrent::Object::list_type::const_iterator itr = args.begin(); - - const std::string& type = (itr++)->as_string(); - const std::string& prefix = (itr++)->as_string(); - const std::string& postfix = (itr++)->as_string(); - - if (type.empty()) - throw torrent::input_error("Invalid arguments."); - - std::string target; - std::string link; - - if (type == "base_path") { - target = download->get_string("base_path"); - link = rak::path_expand(prefix + download->get_string("base_path") + postfix); - - } else if (type == "base_filename") { - target = download->get_string("base_path"); - link = rak::path_expand(prefix + download->get_string("base_filename") + postfix); - - } else if (type == "tied") { - link = rak::path_expand(download->get_string("tied_to_file")); - - if (link.empty()) - return; - - link = rak::path_expand(prefix + link + postfix); - target = download->get_string("base_path"); - - } else { - throw torrent::input_error("Unknown type argument."); - } - - if (symlink(target.c_str(), link.c_str()) == -1) -// control->core()->push_log("create_link failed: " + std::string(rak::error_number::current().c_str())); -// control->core()->push_log("create_link failed: " + std::string(rak::error_number::current().c_str()) + " to " + target); - ; // Disabled. -} - -void -apply_d_delete_link(core::Download* download, const torrent::Object::list_type& args) { - if (args.size() != 3) - throw torrent::input_error("Wrong argument count."); - - torrent::Object::list_type::const_iterator itr = args.begin(); - - const std::string& type = (itr++)->as_string(); - const std::string& prefix = (itr++)->as_string(); - const std::string& postfix = (itr++)->as_string(); - - if (type.empty()) - throw torrent::input_error("Invalid arguments."); - - std::string link; - - if (type == "base_path") { - link = rak::path_expand(prefix + download->get_string("base_path") + postfix); - - } else if (type == "base_filename") { - link = rak::path_expand(prefix + download->get_string("base_filename") + postfix); - - } else if (type == "tied") { - link = rak::path_expand(download->get_string("tied_to_file")); - - if (link.empty()) - return; - - link = rak::path_expand(prefix + link + postfix); - - } else { - throw torrent::input_error("Unknown type argument."); - } - - rak::file_stat fileStat; - rak::error_number::clear_global(); - - if (!fileStat.update_link(link) || !fileStat.is_link() || - unlink(link.c_str()) == -1) - ; // control->core()->push_log("delete_link failed: " + std::string(rak::error_number::current().c_str())); -} - void initialize_download_variables() { utils::VariableMap* variables = control->download_variables(); @@ -201,22 +115,6 @@ initialize_download_variables() { variables->insert("connection_leech", new utils::VariableAny(core::Download::connection_type_to_string(torrent::Download::CONNECTION_LEECH))); variables->insert("connection_seed", new utils::VariableAny(core::Download::connection_type_to_string(torrent::Download::CONNECTION_SEED))); - // 0 - stopped - // 1 - started - variables->insert("state", new utils::VariableObject("rtorrent", "state", torrent::Object::TYPE_VALUE)); - variables->insert("complete", new utils::VariableObject("rtorrent", "complete", torrent::Object::TYPE_VALUE)); - - // 0 - Not hashing - // 1 - Normal hashing - // 2 - Download finished, hashing - variables->insert("hashing", new utils::VariableObject("rtorrent", "hashing", torrent::Object::TYPE_VALUE)); - variables->insert("tied_to_file", new utils::VariableObject("rtorrent", "tied_to_file", torrent::Object::TYPE_STRING)); - - // The "state_changed" variable is required to be a valid unix time - // value, it indicates the last time the torrent changed its state, - // resume/pause. - variables->insert("state_changed", new utils::VariableObject("rtorrent", "state_changed", torrent::Object::TYPE_VALUE)); - variables->insert("directory", new utils::VariableDownloadStringSlot(rak::ftor_fn1(rak::on(std::mem_fun(&core::Download::file_list), std::mem_fun(&torrent::FileList::root_dir))), rak::ftor_fn2(std::mem_fun(&core::Download::set_root_directory)))); @@ -241,10 +139,5 @@ initialize_download_variables() { variables->insert("priority", new utils::VariableDownloadValueSlot(rak::ftor_fn1(std::mem_fun(&core::Download::priority)), rak::ftor_fn2(std::mem_fun(&core::Download::set_priority)))); variables->insert("tracker_numwant", var_d_value(&core::Download::tracker_list, &torrent::TrackerList::numwant, &torrent::TrackerList::set_numwant)); - variables->insert("ignore_commands", new utils::VariableObject("rtorrent", "ignore_commands", torrent::Object::TYPE_VALUE)); - // Hmm... do we need dupicates? - variables->insert("print", new utils::VariableStringSlot(NULL, rak::mem_fn(control->core(), &core::Manager::push_log))); - variables->insert("create_link", new utils::VariableDownloadListSlot(rak::ptr_fn(&apply_d_create_link))); - variables->insert("delete_link", new utils::VariableDownloadListSlot(rak::ptr_fn(&apply_d_delete_link))); } diff --git a/src/ui/download.cc b/src/ui/download.cc index 8648a487..f1f0db43 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -154,13 +154,13 @@ Download::create_info() { element->push_back(""); element->push_column("Directory:", te_string(&torrent::FileList::root_dir)); - element->push_column("Tied to file:", te_variable_string("tied_to_file")); + element->push_column("Tied to file:", te_variable_string("get_tied_to_file")); element->push_back(""); element->push_column("Chunks:", te_value(&torrent::FileList::completed_chunks), " / ", te_value(&torrent::FileList::size_chunks), " * ", te_value(&torrent::FileList::chunk_size)); element->push_column("Priority:", te_variable_value("priority")); - element->push_column("State changed:", te_variable_value("state_changed", value_base::flag_timer | value_base::flag_elapsed)); + element->push_column("State changed:", te_variable_value("get_state_changed", value_base::flag_timer | value_base::flag_elapsed)); element->push_back(""); element->push_column("Memory usage:", te_value(&torrent::ChunkManager::memory_usage, value_base::flag_mb), " MB"); diff --git a/src/ui/element_download_list.cc b/src/ui/element_download_list.cc index c9a66446..69da5921 100644 --- a/src/ui/element_download_list.cc +++ b/src/ui/element_download_list.cc @@ -151,7 +151,7 @@ ElementDownloadList::receive_stop_download() { if (m_view->focus() == m_view->end_visible()) return; - if ((*m_view->focus())->get_value("state") == 1) + if ((*m_view->focus())->get_value("get_state") == 1) control->core()->download_list()->stop_normal(*m_view->focus()); else control->core()->download_list()->erase(*m_view->focus()); @@ -166,7 +166,7 @@ ElementDownloadList::receive_close_download() { core::Download* download = *m_view->focus(); - download->set("ignore_commands", (int64_t)1); + download->set("set_ignore_commands", (int64_t)1); control->core()->download_list()->stop_normal(download); control->core()->download_list()->close(download); @@ -205,11 +205,11 @@ ElementDownloadList::receive_ignore_ratio() { if (m_view->focus() == m_view->end_visible()) return; - if ((*m_view->focus())->get_value("ignore_commands") != 0) { - (*m_view->focus())->set("ignore_commands", (int64_t)0); + if ((*m_view->focus())->get_value("get_ignore_commands") != 0) { + (*m_view->focus())->set("set_ignore_commands", (int64_t)0); control->core()->push_log("Torrent set to heed commands."); } else { - (*m_view->focus())->set("ignore_commands", (int64_t)1); + (*m_view->focus())->set("set_ignore_commands", (int64_t)1); control->core()->push_log("Torrent set to ignore commands."); } } @@ -219,7 +219,7 @@ ElementDownloadList::receive_clear_tied() { if (m_view->focus() == m_view->end_visible()) return; - const std::string& tiedFile = (*m_view->focus())->get_string("tied_to_file"); + const std::string& tiedFile = (*m_view->focus())->get_string("get_tied_to_file"); if (!tiedFile.empty()) { // Move this into core? diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am index a84032f6..594de484 100644 --- a/src/utils/Makefile.am +++ b/src/utils/Makefile.am @@ -3,10 +3,10 @@ noinst_LIBRARIES = libsub_utils.a libsub_utils_a_SOURCES = \ command_slot.cc \ command_slot.h \ - command_download_slot.cc \ - command_download_slot.h \ command_variable.cc \ command_variable.h \ + command_download_slot.cc \ + command_download_slot.h \ directory.cc \ directory.h \ list_focus.h \ diff --git a/src/utils/command_download_slot.cc b/src/utils/command_download_slot.cc index c1483a75..b42ff9e7 100644 --- a/src/utils/command_download_slot.cc +++ b/src/utils/command_download_slot.cc @@ -36,6 +36,7 @@ #include "config.h" +#include "core/download.h" #include "utils/parse.h" #include "command_download_slot.h" @@ -140,4 +141,22 @@ CommandDownloadSlot::call_string(Variable* rawVariable, core::Download* download // return variable->m_variable; // } +torrent::Object +set_variable_d_fn_t::operator () (core::Download* download, const torrent::Object& arg1) { + if (m_firstKey == NULL) + download->bencode()->get_key(m_secondKey) = arg1; + else + download->bencode()->get_key(m_firstKey).get_key(m_secondKey) = arg1; + + return torrent::Object(); +} + +torrent::Object +get_variable_d_fn_t::operator () (core::Download* download, const torrent::Object& arg1) { + if (m_firstKey == NULL) + return download->bencode()->get_key(m_secondKey); + else + return download->bencode()->get_key(m_firstKey).get_key(m_secondKey); +} + } diff --git a/src/utils/command_download_slot.h b/src/utils/command_download_slot.h index 1edf4bef..48319437 100644 --- a/src/utils/command_download_slot.h +++ b/src/utils/command_download_slot.h @@ -171,6 +171,33 @@ object_d_fn(Return (*func)(core::Download*)) { // template object_value_fn1_t* object_value_fn(Func func) { return new object_value_fn1_t(func); } // template object_string_fn1_t* object_string_fn(Func func) { return new object_string_fn1_t(func); } +class set_variable_d_fn_t : public rak::function_base2 { +public: + set_variable_d_fn_t(const char* firstKey, const char* secondKey) : m_firstKey(firstKey), m_secondKey(secondKey) {} + + virtual torrent::Object operator () (core::Download* download, const torrent::Object& arg1); + +private: + const char* m_firstKey; + const char* m_secondKey; +}; + +class get_variable_d_fn_t : public rak::function_base2 { +public: + get_variable_d_fn_t(const char* firstKey, const char* secondKey) : m_firstKey(firstKey), m_secondKey(secondKey) {} + + virtual torrent::Object operator () (core::Download* download, const torrent::Object& arg1); + +private: + const char* m_firstKey; + const char* m_secondKey; +}; + +inline set_variable_d_fn_t* +set_variable_d_fn(const char* firstKey, const char* secondKey) { return new set_variable_d_fn_t(firstKey, secondKey); } +inline get_variable_d_fn_t* +get_variable_d_fn(const char* firstKey, const char* secondKey) { return new get_variable_d_fn_t(firstKey, secondKey); } + } #endif diff --git a/src/utils/command_variable.cc b/src/utils/command_variable.cc index bbb229f4..339ac9e1 100644 --- a/src/utils/command_variable.cc +++ b/src/utils/command_variable.cc @@ -40,9 +40,6 @@ namespace utils { -extern CommandVariable commandVariables[10]; -extern CommandVariable* commandVariablesItr; - const torrent::Object CommandVariable::set_bool(Variable* rawVariable, const torrent::Object& rawArgs) { CommandVariable* variable = static_cast(rawVariable);