From 52bf80d7043c774de15d029edc11dc1d598995dd Mon Sep 17 00:00:00 2001 From: rakshasa Date: Fri, 7 Jul 2006 22:19:20 +0000 Subject: [PATCH] * 'I' key set the download to ignore the start/stop_try commands. * Added options for timeout_sync/safe_sync and max_chunks_queued. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@739 e378c898-3ddf-0310-93e7-cc216c733640 --- src/core/download.cc | 11 +++-- src/core/download.h | 5 +- src/core/download_factory.cc | 13 ++++- src/core/download_list.cc | 22 +++++++-- src/core/download_list.h | 11 ++++- src/display/utils.cc | 11 +++-- src/option_handler_rules.cc | 95 +++++++++++++++--------------------- src/ui/download_list.cc | 15 +++--- 8 files changed, 102 insertions(+), 81 deletions(-) diff --git a/src/core/download.cc b/src/core/download.cc index 4e3f40de..cc5b8cd1 100644 --- a/src/core/download.cc +++ b/src/core/download.cc @@ -94,9 +94,14 @@ Download::Download(download_type d) : m_variables.insert("min_peers", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::peers_min), rak::mem_fn(&m_download, &download_type::set_peers_min))); m_variables.insert("max_peers", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::peers_max), rak::mem_fn(&m_download, &download_type::set_peers_max))); m_variables.insert("max_uploads", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::uploads_max), rak::mem_fn(&m_download, &download_type::set_uploads_max))); + m_variables.insert("max_chunks_queued", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::max_chunks_queued), rak::mem_fn(&m_download, &download_type::set_max_chunks_queued))); + + m_variables.insert("timeout_sync", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::timeout_sync), rak::mem_fn(&m_download, &download_type::set_timeout_sync))); + m_variables.insert("timeout_safe_sync", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::timeout_safe_sync), rak::mem_fn(&m_download, &download_type::set_timeout_safe_sync))); + m_variables.insert("priority", new utils::VariableValueSlot(rak::mem_fn(this, &Download::priority), rak::mem_fn(this, &Download::set_priority))); - m_variables.insert("ignore_ratio", new utils::VariableObject(bencode(), "rtorrent", "ignore_ratio", torrent::Object::TYPE_VALUE)); + m_variables.insert("ignore_commands", new utils::VariableObject(bencode(), "rtorrent", "ignore_commands", torrent::Object::TYPE_VALUE)); } Download::~Download() { @@ -117,9 +122,9 @@ Download::enable_udp_trackers(bool state) { for (int i = 0, last = tl.size(); i < last; ++i) if (tl.get(i).tracker_type() == torrent::Tracker::TRACKER_UDP) if (state) - tl.get(i).enable(); + tl.get(i).enable(); else - tl.get(i).disable(); + tl.get(i).disable(); } uint32_t diff --git a/src/core/download.h b/src/core/download.h index 3088890f..2d90333a 100644 --- a/src/core/download.h +++ b/src/core/download.h @@ -78,8 +78,9 @@ public: bool is_hash_failed() const { return m_hashFailed; } void set_hash_failed(bool v) { m_hashFailed = v; } - variable_map_type* variable() { return &m_variables; } - std::string variable_string(const std::string& key) { return m_variables.get_string(key); } + variable_map_type* variable() { return &m_variables; } + int64_t variable_value(const std::string& key) const { return m_variables.get_value(key); } + const std::string& variable_string(const std::string& key) const { return m_variables.get_string(key); } download_type* download() { return &m_download; } const download_type* download() const { return &m_download; } diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 972d1b6a..62460286 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -176,6 +176,15 @@ DownloadFactory::receive_success() { download->variable()->set("max_peers", control->variable()->get("max_peers")); download->variable()->set("max_uploads", control->variable()->get("max_uploads")); + if (!control->variable()->get_value("timeout_sync") != 0) + download->variable()->set("timeout_sync", control->variable()->get("timeout_sync")); + + if (!control->variable()->get_value("timeout_safe_sync") != 0) + download->variable()->set("timeout_safe_sync", control->variable()->get("timeout_safe_sync")); + + if (!control->variable()->get_value("max_chunks_queued") != 0) + download->variable()->set("max_chunks_queued", control->variable()->get("max_chunks_queued")); + if (!control->variable()->get_value("use_udp_trackers")) download->enable_udp_trackers(false); @@ -277,8 +286,8 @@ DownloadFactory::initialize_rtorrent(Download* download, torrent::Object* rtorre if (rtorrent->has_key_value("chunks_done")) download->download()->set_chunks_done(std::min(rtorrent->get_key_value("chunks_done"), download->download()->chunks_total())); - if (!rtorrent->has_key_value("ignore_ratio")) - rtorrent->insert_key("ignore_ratio", (int64_t)0); + if (!rtorrent->has_key_value("ignore_commands")) + rtorrent->insert_key("ignore_commands", (int64_t)0); } } diff --git a/src/core/download_list.cc b/src/core/download_list.cc index 11eb8f82..137eb2c8 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -241,25 +241,26 @@ DownloadList::start_normal(Download* download) { resume(download); } -void +bool DownloadList::start_try(Download* download) { check_contains(download); // Also don't start if the state is one of those that indicate we // were manually stopped? - if (download->is_hash_failed()) - return; + if (download->is_hash_failed() || download->variable()->get_value("ignore_commands") != 0) + return false; // Don't clear the hash failed as this function is used by scripts, // etc. download->variable()->set("state", (int64_t)1); resume(download); + return true; } void -DownloadList::stop(Download* download) { +DownloadList::stop_normal(Download* download) { check_contains(download); download->variable()->set("state", (int64_t)0); @@ -267,6 +268,19 @@ DownloadList::stop(Download* download) { pause(download); } +bool +DownloadList::stop_try(Download* download) { + check_contains(download); + + if (download->variable()->get_value("ignore_commands") != 0) + return false; + + download->variable()->set("state", (int64_t)0); + + pause(download); + return true; +} + void DownloadList::resume(Download* download) { check_contains(download); diff --git a/src/core/download_list.h b/src/core/download_list.h index d0662abb..6fc1eb18 100644 --- a/src/core/download_list.h +++ b/src/core/download_list.h @@ -72,6 +72,8 @@ public: using base_type::empty; using base_type::size; + DownloadList() { } + void clear(); void session_save(); @@ -93,8 +95,10 @@ public: void close_throw(Download* d); void start_normal(Download* d); - void start_try(Download* d); - void stop(Download* d); + bool start_try(Download* d); + + void stop_normal(Download* d); + bool stop_try(Download* d); void resume(Download* d); void pause(Download* d); @@ -168,6 +172,9 @@ public: static void erase_key(slot_map& sm, const std::string& key) { sm.erase(key); } private: + DownloadList(const DownloadList&); + void operator = (const DownloadList&); + void hash_done(Download* d); void hash_queue(Download* d, int type); diff --git a/src/display/utils.cc b/src/display/utils.cc index 536065fa..ca72aaf1 100644 --- a/src/display/utils.cc +++ b/src/display/utils.cc @@ -152,12 +152,15 @@ print_download_info(char* first, char* last, core::Download* d) { first = print_buffer(first, last, " "); } - if (d->download()->bytes_done() > 0) - first = print_buffer(first, last, " R: %3.2f", - (double)(100 * d->download()->up_rate()->total() / d->download()->bytes_done()) / 100); + first = print_buffer(first, last, " [%c%c R: %3.2f", + d->variable()->get_string("tied_to_file").empty() ? ' ' : 'T', + d->variable()->get_value("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) - first = print_buffer(first, last, " [%s]", core::Download::priority_to_string(d->priority())); + first = print_buffer(first, last, " %s]", core::Download::priority_to_string(d->priority())); + else + first = print_buffer(first, last, "]"); if (first > last) throw torrent::client_error("print_download_info(...) wrote past end of the buffer."); diff --git a/src/option_handler_rules.cc b/src/option_handler_rules.cc index e50c256f..051402eb 100644 --- a/src/option_handler_rules.cc +++ b/src/option_handler_rules.cc @@ -118,74 +118,54 @@ apply_load_start_verbose(Control* m, const std::string& arg) { } void -apply_start_tied(Control* m, const std::string& arg) { - std::vector paths; - paths.reserve(256); +apply_start_tied(Control* m) { + for (core::DownloadList::iterator itr = m->core()->download_list()->begin(); itr != m->core()->download_list()->end(); ++itr) { + if ((*itr)->variable_value("state") == 1) + continue; - core::path_expand(&paths, arg); + rak::file_stat fs; + const std::string& tiedToFile = (*itr)->variable_string("tied_to_file"); - for (std::vector::iterator itr = paths.begin(); itr != paths.end(); ++itr) { - core::DownloadList::iterator dItr = std::find_if(m->core()->download_list()->begin(), m->core()->download_list()->end(), - rak::equal(*itr, rak::bind2nd(std::mem_fun(&core::Download::variable_string), "tied_to_file"))); - - if (dItr != m->core()->download_list()->end()) - m->core()->download_list()->start_try(*dItr); + if (!tiedToFile.empty() && fs.update(rak::path_expand(tiedToFile))) + m->core()->download_list()->start_try(*itr); } } void apply_stop_untied(Control* m) { - core::Manager::DListItr itr = m->core()->download_list()->begin(); + for (core::DownloadList::iterator itr = m->core()->download_list()->begin(); itr != m->core()->download_list()->end(); ++itr) { + if ((*itr)->variable_value("state") == 0) + continue; - while ((itr = std::find_if(itr, m->core()->download_list()->end(), rak::on(rak::bind2nd(std::mem_fun(&core::Download::variable_string), "tied_to_file"), - std::not1(std::mem_fun_ref(&std::string::empty))))) - != m->core()->download_list()->end()) { rak::file_stat fs; + const std::string& tiedToFile = (*itr)->variable_string("tied_to_file"); - if (!fs.update(rak::path_expand((*itr)->variable_string("tied_to_file")))) { -// (*itr)->variable()->set("tied_to_file", std::string()); - m->core()->download_list()->stop(*itr); - } - - ++itr; + if (!tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile))) + m->core()->download_list()->stop_try(*itr); } } void apply_close_untied(Control* m) { - core::Manager::DListItr itr = m->core()->download_list()->begin(); - - while ((itr = std::find_if(itr, m->core()->download_list()->end(), rak::on(rak::bind2nd(std::mem_fun(&core::Download::variable_string), "tied_to_file"), - std::not1(std::mem_fun_ref(&std::string::empty))))) - != m->core()->download_list()->end()) { + for (core::DownloadList::iterator itr = m->core()->download_list()->begin(); itr != m->core()->download_list()->end(); ++itr) { rak::file_stat fs; + const std::string& tiedToFile = (*itr)->variable_string("tied_to_file"); - if (!fs.update(rak::path_expand((*itr)->variable_string("tied_to_file")))) { -// (*itr)->variable()->set("tied_to_file", std::string()); + if (!tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile)) && m->core()->download_list()->stop_try(*itr)) m->core()->download_list()->close(*itr); - } - - ++itr; } } void apply_remove_untied(Control* m) { - core::Manager::DListItr itr = m->core()->download_list()->begin(); - - while ((itr = std::find_if(itr, m->core()->download_list()->end(), rak::on(rak::bind2nd(std::mem_fun(&core::Download::variable_string), "tied_to_file"), - std::not1(std::mem_fun_ref(&std::string::empty))))) - != m->core()->download_list()->end()) { + for (core::DownloadList::iterator itr = m->core()->download_list()->begin(); itr != m->core()->download_list()->end(); ) { rak::file_stat fs; + const std::string& tiedToFile = (*itr)->variable_string("tied_to_file"); - if (!fs.update(rak::path_expand((*itr)->variable_string("tied_to_file")))) { -// (*itr)->variable()->set("tied_to_file", std::string()); - m->core()->download_list()->stop(*itr); + if (!tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile)) && m->core()->download_list()->stop_try(*itr)) itr = m->core()->download_list()->erase(itr); - - } else { + else ++itr; - } } } @@ -193,8 +173,7 @@ void apply_close_low_diskspace(Control* m, int64_t arg) { core::Manager::DListItr itr = m->core()->download_list()->begin(); - while ((itr = std::find_if(itr, m->core()->download_list()->end(), rak::equal(true, std::mem_fun(&core::Download::is_downloading)))) - != m->core()->download_list()->end()) { + while ((itr = std::find_if(itr, m->core()->download_list()->end(), std::mem_fun(&core::Download::is_downloading))) != m->core()->download_list()->end()) { rak::fs_stat stat; std::string path = (*itr)->file_list()->root_dir() + (*itr)->file_list()->get(0).path()->as_string(); @@ -203,6 +182,8 @@ apply_close_low_diskspace(Control* m, int64_t arg) { } else if (stat.bytes_avail() < arg) { m->core()->download_list()->close(*itr); + + (*itr)->set_hash_failed(true); (*itr)->set_message(std::string("Low diskspace")); } @@ -212,32 +193,28 @@ apply_close_low_diskspace(Control* m, int64_t arg) { void apply_stop_on_ratio(Control* m, const std::string& arg) { - int64_t min_Ratio = 0; // first argument: minimum ratio to reach - int64_t min_Upload = 0; // second argument: minimum upload amount to reach [optional] - int64_t max_Ratio = 0; // third argument: maximum ratio to reach [optional] + int64_t minRatio = 0; // first argument: minimum ratio to reach + int64_t minUpload = 0; // second argument: minimum upload amount to reach [optional] + int64_t maxRatio = 0; // third argument: maximum ratio to reach [optional] rak::split_iterator_t sitr = rak::split_iterator(arg, ','); - utils::Variable::string_to_value_unit(rak::trim(*sitr).c_str(), &min_Ratio, 0, 1); + utils::Variable::string_to_value_unit(rak::trim(*sitr).c_str(), &minRatio, 0, 1); if (++sitr != rak::split_iterator(arg)) - utils::Variable::string_to_value_unit(rak::trim(*sitr).c_str(), &min_Upload, 0, 1); + utils::Variable::string_to_value_unit(rak::trim(*sitr).c_str(), &minUpload, 0, 1); if (++sitr != rak::split_iterator(arg)) - utils::Variable::string_to_value_unit(rak::trim(*sitr).c_str(), &max_Ratio, 0, 1); + utils::Variable::string_to_value_unit(rak::trim(*sitr).c_str(), &maxRatio, 0, 1); core::Manager::DListItr itr = m->core()->download_list()->begin(); - while ((itr = std::find_if(itr, m->core()->download_list()->end(), rak::equal(true, std::mem_fun(&core::Download::is_seeding)))) - != m->core()->download_list()->end()) { + while ((itr = std::find_if(itr, m->core()->download_list()->end(), std::mem_fun(&core::Download::is_seeding))) != m->core()->download_list()->end()) { int64_t totalUpload = (*itr)->download()->up_rate()->total(); int64_t totalDone = (*itr)->download()->bytes_done(); - if ((totalUpload >= min_Upload && totalUpload * 100 >= totalDone * min_Ratio) || - (max_Ratio > 0 && totalUpload * 100 > totalDone * max_Ratio)) { - if ((*itr)->variable()->get_value("ignore_ratio") == 0) - m->core()->download_list()->stop(*itr); - } + if ((totalUpload >= minUpload && totalUpload * 100 >= totalDone * minRatio) || (maxRatio > 0 && totalUpload * 100 > totalDone * maxRatio)) + m->core()->download_list()->stop_try(*itr); ++itr; } @@ -446,6 +423,10 @@ initialize_option_handler(Control* c) { variables->insert("min_peers", new utils::VariableValue(40)); variables->insert("max_peers", new utils::VariableValue(100)); variables->insert("max_uploads", new utils::VariableValue(15)); + variables->insert("max_chunks_queued", new utils::VariableValue(0)); + + variables->insert("timeout_sync", new utils::VariableValue(0)); + variables->insert("timeout_safe_sync", new utils::VariableValue(0)); variables->insert("download_rate", new utils::VariableValueSlot(rak::ptr_fn(&torrent::down_throttle), rak::mem_fn(control->ui(), &ui::Root::set_down_throttle_i64), 0, (1 << 10))); @@ -496,7 +477,7 @@ initialize_option_handler(Control* c) { variables->insert("load_start", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_load_start, c))); variables->insert("load_start_verbose", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_load_start_verbose, c))); - variables->insert("start_tied", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_start_tied, c))); + variables->insert("start_tied", new utils::VariableVoidSlot(rak::bind_ptr_fn(&apply_start_tied, c))); variables->insert("stop_untied", new utils::VariableVoidSlot(rak::bind_ptr_fn(&apply_stop_untied, c))); variables->insert("close_untied", new utils::VariableVoidSlot(rak::bind_ptr_fn(&apply_close_untied, c))); variables->insert("remove_untied", new utils::VariableVoidSlot(rak::bind_ptr_fn(&apply_remove_untied, c))); diff --git a/src/ui/download_list.cc b/src/ui/download_list.cc index ceced36a..598e4faf 100644 --- a/src/ui/download_list.cc +++ b/src/ui/download_list.cc @@ -210,7 +210,7 @@ DownloadList::receive_stop_download() { return; if ((*m_view->focus())->variable()->get_value("state") == 1) - m_control->core()->download_list()->stop(*m_view->focus()); + m_control->core()->download_list()->stop_normal(*m_view->focus()); else m_control->core()->download_list()->erase(*m_view->focus()); @@ -222,6 +222,7 @@ DownloadList::receive_close_download() { if (m_view->focus() == m_view->end_visible()) return; + m_control->core()->download_list()->stop_normal(*m_view->focus()); m_control->core()->download_list()->close(*m_view->focus()); m_view->set_last_changed(); } @@ -287,12 +288,12 @@ DownloadList::receive_ignore_ratio() { if (m_view->focus() == m_view->end_visible()) return; - if ((*m_view->focus())->variable()->get_value("ignore_ratio") > 0) { - (*m_view->focus())->variable()->set("ignore_ratio", (int64_t)0); - m_control->core()->push_log("Torrent set to stop when reaching upload ratio."); + if ((*m_view->focus())->variable()->get_value("ignore_commands") != 0) { + (*m_view->focus())->variable()->set("ignore_commands", (int64_t)0); + m_control->core()->push_log("Torrent set to heed commands."); } else { - (*m_view->focus())->variable()->set("ignore_ratio", (int64_t)1); - m_control->core()->push_log("Torrent set to no longer stop when reaching upload ratio."); + (*m_view->focus())->variable()->set("ignore_commands", (int64_t)1); + m_control->core()->push_log("Torrent set to ignore commands"); } } @@ -356,7 +357,7 @@ DownloadList::receive_exit_input(Input type) { case INPUT_CHANGE_DIRECTORY: if (m_view->focus() == m_view->end_visible()) - throw torrent::input_error("No download in focus to change root directory."); + throw torrent::input_error("No download in focus to change root directory."); (*m_view->focus())->variable()->set("directory", rak::trim(m_windowTextInput->get_input()->str())); m_control->core()->push_log("New root dir \"" + (*m_view->focus())->variable()->get_string("directory") + "\" for torrent.");