From ee7016f5470161f3986f0575ded7dbd7dc33f570 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Tue, 15 Aug 2006 19:35:43 +0000 Subject: [PATCH] * Show "Hashing:" for torrents that are queued for hashing. * Allow different min/max peers setting for seeding. Patch by Josef Drexler. * Man page entry for "safe_sync" and "max/min_peers_seed". * The p,o,i,u keys are now bound so they change ElementMenu directly. * Bound ^P and ^N for moving up/down. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@758 e378c898-3ddf-0310-93e7-cc216c733640 --- doc/rtorrent.1.xml | 39 ++++++++++++++++++++-- doc/rtorrent.rc | 4 +++ src/core/download_factory.cc | 15 +++++++-- src/core/download_list.cc | 14 ++++++-- src/display/text_element_value.cc | 25 +++++++++----- src/display/text_element_value.h | 1 + src/display/utils.cc | 6 +++- src/option_handler_rules.cc | 2 ++ src/ui/download.cc | 14 ++++---- src/ui/element_download_list.cc | 4 +-- src/ui/element_file_list.cc | 5 +-- src/ui/element_menu.cc | 54 +++++++++++++++++-------------- src/ui/element_menu.h | 8 ++--- src/ui/element_peer_list.cc | 11 ++++--- src/ui/element_tracker_list.cc | 5 +-- 15 files changed, 145 insertions(+), 62 deletions(-) diff --git a/doc/rtorrent.1.xml b/doc/rtorrent.1.xml index fee2a2eb..46877c3c 100644 --- a/doc/rtorrent.1.xml +++ b/doc/rtorrent.1.xml @@ -445,6 +445,26 @@ Set the minimum number of peers to try to connect to in each download. + + max_peers_seed = value + + +Set the maximum number of peers to allow while seeding, or -1 (default) to use +max_peers. + + + + + + min_peers_seed = value + + +Set the minimum number of peers to try to connect to while seeding, or -1 (default) to use +min_peers. + + + + max_uploads = value @@ -757,7 +777,10 @@ Change the key-bindings. ADVANCED SETTINGS - This list contains settings users shouldn't need to touch. + +This list contains settings users shouldn't need to touch, some may +even cause crashes or similar if incorrectly set. + @@ -794,6 +817,16 @@ decent hash checking rate. + + safe_sync = yes|no + + +Always use MS_SYNC rather than MS_ASYNC when syncing chunks. This may +be nessesary in case of filesystem bugs like NFS in linux ~2.6.13. + + + + max_open_files = value @@ -924,7 +957,9 @@ Change the TOS of peer connections, by default set to AUTHORS - Jari "Rakshasa" Sundell jaris@ifi.uio.no + +Jari "Rakshasa" Sundell jaris@ifi.uio.no + diff --git a/doc/rtorrent.rc b/doc/rtorrent.rc index d3b4a0fe..8e860e64 100644 --- a/doc/rtorrent.rc +++ b/doc/rtorrent.rc @@ -6,6 +6,10 @@ #min_peers = 40 #max_peers = 100 +# Same as above but for seeding completed torrents (-1 = same as downloading) +#min_peers_seed = 10 +#max_peers_seed = 50 + # Maximum number of simultanious uploads per torrent. #max_uploads = 15 diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 64278614..2808eaa9 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -172,10 +172,21 @@ DownloadFactory::receive_success() { // Move to 'rtorrent'. download->variable()->set("connection_leech", m_variables.get("connection_leech")); download->variable()->set("connection_seed", m_variables.get("connection_seed")); - download->variable()->set("min_peers", control->variable()->get("min_peers")); - download->variable()->set("max_peers", control->variable()->get("max_peers")); download->variable()->set("max_uploads", control->variable()->get("max_uploads")); + if (download->variable()->get_value("complete") != 0) { + + if (control->variable()->get_value("min_peers_seed") >= 0) + download->variable()->set("min_peers", control->variable()->get("min_peers_seed")); + else + download->variable()->set("min_peers", control->variable()->get("min_peers")); + + if (control->variable()->get_value("max_peers_seed") >= 0) + download->variable()->set("max_peers", control->variable()->get("max_peers_seed")); + else + download->variable()->set("max_peers", control->variable()->get("max_peers")); + } + if (!control->variable()->get_value("use_udp_trackers")) download->enable_udp_trackers(false); diff --git a/src/core/download_list.cc b/src/core/download_list.cc index cf944561..69de898e 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -439,10 +439,12 @@ DownloadList::hash_done(Download* download) { case Download::variable_hashing_last: - if (download->is_done()) + if (download->is_done()) { confirm_finished(download); - else - download->set_message("Hash check on download completion found bad chunks."); + } else { + download->set_message("Hash check on download completion found bad chunks, consider using \"safe_sync\"."); + control->core()->push_log("Hash check on download completion found bad chunks, consider using \"safe_sync\"."); + } break; @@ -501,6 +503,12 @@ DownloadList::confirm_finished(Download* download) { download->set_connection_type(download->variable()->get_string("connection_seed")); download->set_priority(download->priority()); + if (download->variable_value("min_peers") == control->variable()->get_value("min_peers") && control->variable()->get_value("min_peers_seed") >= 0) + download->variable()->set("min_peers", control->variable()->get("min_peers_seed")); + + if (download->variable_value("max_peers") == control->variable()->get_value("max_peers") && control->variable()->get_value("max_peers_seed") >= 0) + download->variable()->set("max_peers", control->variable()->get("max_peers_seed")); + // Do this before the slots are called in case one of them closes // the download. if (!download->is_active() && control->variable()->get_value("session_on_completion") != 0) { diff --git a/src/display/text_element_value.cc b/src/display/text_element_value.cc index d06584e5..703ea991 100644 --- a/src/display/text_element_value.cc +++ b/src/display/text_element_value.cc @@ -72,6 +72,23 @@ TextElementValueBase::print(char* first, char* last, Canvas::attributes_list* at if (first == last) { // Do nothing, but ensure that the last attributes are set. + } else if (m_flags & flag_kb) { + // Just use a default width of 5 for now. + first += std::max(snprintf(first, last - first + 1, "%5.1f", (double)val / (1 << 10)), 0); + + } else if (m_flags & flag_mb) { + // Just use a default width of 8 for now. + first += std::max(snprintf(first, last - first + 1, "%8.1f", (double)val / (1 << 20)), 0); + + } else if (m_flags & flag_xb) { + + if (val < (int64_t(1) << 30)) + first += std::max(snprintf(first, last - first + 1, "%5.1f MB", (double)val / (int64_t(1) << 20)), 0); + else if (val < (int64_t(1) << 40)) + first += std::max(snprintf(first, last - first + 1, "%5.1f GB", (double)val / (int64_t(1) << 30)), 0); + else + first += std::max(snprintf(first, last - first + 1, "%5.1f TB", (double)val / (int64_t(1) << 40)), 0); + } else if (m_flags & flag_timer) { if (val == 0) first += std::max(snprintf(first, last - first + 1, "--:--:--"), 0); @@ -96,14 +113,6 @@ TextElementValueBase::print(char* first, char* last, Canvas::attributes_list* at first += std::max(snprintf(first, last - first + 1, "%2d:%02d:%02d", u->tm_hour, u->tm_min, u->tm_sec), 0); - } else if (m_flags & flag_kb) { - // Just use a default width of 5 for now. - first += std::max(snprintf(first, last - first + 1, "%5.1f", (double)val / (1 << 10)), 0); - - } else if (m_flags & flag_mb) { - // Just use a default width of 5 for now. - first += std::max(snprintf(first, last - first + 1, "%8.1f", (double)val / (1 << 20)), 0); - } else { first += std::max(snprintf(first, last - first + 1, "%lld", val), 0); } diff --git a/src/display/text_element_value.h b/src/display/text_element_value.h index b8fac13a..10e89584 100644 --- a/src/display/text_element_value.h +++ b/src/display/text_element_value.h @@ -53,6 +53,7 @@ public: static const int flag_kb = (1 << 3); static const int flag_mb = (1 << 4); + static const int flag_xb = (1 << 5); static const int flag_elapsed = (1 << 8); static const int flag_remaining = (1 << 9); diff --git a/src/display/utils.cc b/src/display/utils.cc index ca72aaf1..a3ff1154 100644 --- a/src/display/utils.cc +++ b/src/display/utils.cc @@ -170,7 +170,11 @@ print_download_info(char* first, char* last, core::Download* d) { char* print_download_status(char* first, char* last, core::Download* d) { - if (!d->is_active()) + if (d->is_active()) + ; + else if (d->variable_value("hashing") != 0) + first = print_buffer(first, last, "Hashing: "); + else if (!d->is_active()) first = print_buffer(first, last, "Inactive: "); if (d->is_hash_checking()) { diff --git a/src/option_handler_rules.cc b/src/option_handler_rules.cc index a4b9187d..abb36354 100644 --- a/src/option_handler_rules.cc +++ b/src/option_handler_rules.cc @@ -425,6 +425,8 @@ initialize_option_handler(Control* c) { variables->insert("min_peers", new utils::VariableValue(40)); variables->insert("max_peers", new utils::VariableValue(100)); + variables->insert("min_peers_seed", new utils::VariableValue(-1)); + variables->insert("max_peers_seed", new utils::VariableValue(-1)); variables->insert("max_uploads", new utils::VariableValue(15)); variables->insert("max_chunks_queued", new utils::VariableValue(0)); diff --git a/src/ui/download.cc b/src/ui/download.cc index d5c65743..976cedd4 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -115,7 +115,7 @@ Download::create_menu() { element->push_back("File list", sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_FILE_LIST), sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_FILE_LIST)); - element->push_back("Tracker kist", + element->push_back("Tracker list", sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRACKER_LIST), sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRACKER_LIST)); element->push_back("Chunks seen", @@ -125,7 +125,12 @@ Download::create_menu() { sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRANSFER_LIST), sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRANSFER_LIST)); - element->set_entry(0); + element->set_entry(0, false); + + m_bindings['p'] = sigc::bind(sigc::mem_fun(element, &ElementMenu::set_entry_trigger), 0); + m_bindings['o'] = sigc::bind(sigc::mem_fun(element, &ElementMenu::set_entry_trigger), 1); + m_bindings['i'] = sigc::bind(sigc::mem_fun(element, &ElementMenu::set_entry_trigger), 2); + m_bindings['u'] = sigc::bind(sigc::mem_fun(element, &ElementMenu::set_entry_trigger), 3); return element; } @@ -314,11 +319,6 @@ Download::bind_keys() { m_bindings['t'] = sigc::bind(sigc::mem_fun(m_download->tracker_list(), &torrent::TrackerList::manual_request), false); m_bindings['T'] = sigc::bind(sigc::mem_fun(m_download->tracker_list(), &torrent::TrackerList::manual_request), true); - - m_bindings['p'] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_PEER_LIST); - m_bindings['o'] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRACKER_LIST); - m_bindings['i'] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_CHUNKS_SEEN); - m_bindings['u'] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRANSFER_LIST); } } diff --git a/src/ui/element_download_list.cc b/src/ui/element_download_list.cc index ba00035d..1d1f7891 100644 --- a/src/ui/element_download_list.cc +++ b/src/ui/element_download_list.cc @@ -78,8 +78,8 @@ ElementDownloadList::ElementDownloadList() : m_bindings['6'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "incomplete"); m_bindings['7'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "hashing"); - m_bindings[KEY_UP] = sigc::mem_fun(*this, &ElementDownloadList::receive_prev); - m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &ElementDownloadList::receive_next); + m_bindings[KEY_UP] = m_bindings['P' - '@'] = sigc::mem_fun(*this, &ElementDownloadList::receive_prev); + m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = sigc::mem_fun(*this, &ElementDownloadList::receive_next); } void diff --git a/src/ui/element_file_list.cc b/src/ui/element_file_list.cc index 441fed35..a14c75fb 100644 --- a/src/ui/element_file_list.cc +++ b/src/ui/element_file_list.cc @@ -57,10 +57,11 @@ ElementFileList::ElementFileList(core::Download* d) : m_bindings[' '] = sigc::mem_fun(*this, &ElementFileList::receive_priority); m_bindings['*'] = sigc::mem_fun(*this, &ElementFileList::receive_change_all); - m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &ElementFileList::receive_next); - m_bindings[KEY_UP] = sigc::mem_fun(*this, &ElementFileList::receive_prev); m_bindings[KEY_NPAGE] = sigc::mem_fun(*this, &ElementFileList::receive_pagenext); m_bindings[KEY_PPAGE] = sigc::mem_fun(*this, &ElementFileList::receive_pageprev); + + m_bindings[KEY_DOWN] = m_bindings['P' - '@'] = sigc::mem_fun(*this, &ElementFileList::receive_next); + m_bindings[KEY_UP] = m_bindings['N' - '@'] = sigc::mem_fun(*this, &ElementFileList::receive_prev); } void diff --git a/src/ui/element_menu.cc b/src/ui/element_menu.cc index b43865a6..037e0de9 100644 --- a/src/ui/element_menu.cc +++ b/src/ui/element_menu.cc @@ -55,16 +55,35 @@ struct ElementMenuEntry { ElementMenu::slot_type m_slotSelect; }; +inline void +ElementMenu::focus_entry(size_type idx) { + if (idx >= size()) + return; + + if (m_focus) + base_type::operator[](idx)->m_element->set_attributes(display::Attributes::a_reverse); + else + base_type::operator[](idx)->m_element->set_attributes(display::Attributes::a_bold); +} + +inline void +ElementMenu::unfocus_entry(size_type idx) { + if (idx >= size()) + return; + + base_type::operator[](idx)->m_element->set_attributes(display::Attributes::a_normal); +} + ElementMenu::ElementMenu() : m_window(new WindowText(NULL, 2)), m_entry(entry_invalid) { // Move bindings into a function that defines default bindings. m_bindings[KEY_LEFT] = sigc::mem_fun(&m_slotExit, &slot_type::operator()); - - m_bindings[KEY_UP] = sigc::mem_fun(this, &ElementMenu::entry_prev); - m_bindings[KEY_DOWN] = sigc::mem_fun(this, &ElementMenu::entry_next); m_bindings[KEY_RIGHT] = sigc::mem_fun(this, &ElementMenu::entry_select); + + m_bindings[KEY_UP] = m_bindings['P' - '@'] = sigc::mem_fun(this, &ElementMenu::entry_prev); + m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = sigc::mem_fun(this, &ElementMenu::entry_next); } ElementMenu::~ElementMenu() { @@ -80,13 +99,12 @@ ElementMenu::activate(display::Frame* frame, bool focus) { control->input()->push_back(&m_bindings); m_focus = focus; + focus_entry(m_entry); m_frame = frame; m_frame->initialize_window(m_window); m_window->set_active(true); - - focus_entry(m_entry); } void @@ -158,35 +176,23 @@ ElementMenu::entry_select() { return; base_type::operator[](m_entry)->m_slotSelect(); - m_window->mark_dirty(); } void -ElementMenu::set_entry(size_type idx) { +ElementMenu::set_entry(size_type idx, bool triggerSlot) { + if (idx == m_entry) + return; + unfocus_entry(m_entry); m_entry = idx; focus_entry(m_entry); -} -inline void -ElementMenu::focus_entry(size_type idx) { - if (idx >= size()) - return; + if (triggerSlot) + base_type::operator[](m_entry)->m_slotFocus(); - if (m_focus) - base_type::operator[](idx)->m_element->set_attributes(display::Attributes::a_reverse); - else - base_type::operator[](idx)->m_element->set_attributes(display::Attributes::a_bold); -} - -inline void -ElementMenu::unfocus_entry(size_type idx) { - if (idx >= size()) - return; - - base_type::operator[](idx)->m_element->set_attributes(display::Attributes::a_normal); + m_window->mark_dirty(); } } diff --git a/src/ui/element_menu.h b/src/ui/element_menu.h index e97451ad..82f51892 100644 --- a/src/ui/element_menu.h +++ b/src/ui/element_menu.h @@ -91,12 +91,12 @@ public: void entry_select(); - // Does not trigger the callback. - void set_entry(size_type idx); + void set_entry(size_type idx, bool triggerSlot); + void set_entry_trigger(size_type idx) { set_entry(idx, true); } private: - inline void focus_entry(size_type idx); - inline void unfocus_entry(size_type idx); + void focus_entry(size_type idx); + void unfocus_entry(size_type idx); WindowText* m_window; diff --git a/src/ui/element_peer_list.cc b/src/ui/element_peer_list.cc index 392c737f..74ae99dc 100644 --- a/src/ui/element_peer_list.cc +++ b/src/ui/element_peer_list.cc @@ -72,10 +72,11 @@ ElementPeerList::ElementPeerList(core::Download* d) : m_bindings['k'] = sigc::mem_fun(this, &ElementPeerList::receive_disconnect_peer); m_bindings['*'] = sigc::mem_fun(this, &ElementPeerList::receive_snub_peer); - m_bindings[KEY_UP] = sigc::mem_fun(this, &ElementPeerList::receive_prev); - m_bindings[KEY_DOWN] = sigc::mem_fun(this, &ElementPeerList::receive_next); m_bindings[KEY_LEFT] = sigc::mem_fun(&m_slotExit, &slot_type::operator()); m_bindings[KEY_RIGHT] = sigc::bind(sigc::mem_fun(this, &ElementPeerList::activate_display), DISPLAY_INFO); + + m_bindings[KEY_UP] = m_bindings['P' - '@'] = sigc::mem_fun(this, &ElementPeerList::receive_prev); + m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = sigc::mem_fun(this, &ElementPeerList::receive_next); } ElementPeerList::~ElementPeerList() { @@ -113,11 +114,11 @@ ElementPeerList::create_info() { element->push_column("Snubbed:", display::text_element_branch(std::mem_fun(&torrent::Peer::is_snubbed), te_string("yes"), te_string("no"))); element->push_column("Done:", display::text_element_value_slot(rak::on(std::mem_fun(&torrent::Peer::bitfield), std::ptr_fun(&te_bitfield_percentage)))); element->push_column("Rate:", - display::text_element_value_slot(rak::on(std::mem_fun(&torrent::Peer::up_rate), std::mem_fun(&torrent::Rate::rate)), value_base::flag_kb), " / ", + display::text_element_value_slot(rak::on(std::mem_fun(&torrent::Peer::up_rate), std::mem_fun(&torrent::Rate::rate)), value_base::flag_kb), " KB / ", display::text_element_value_slot(rak::on(std::mem_fun(&torrent::Peer::down_rate), std::mem_fun(&torrent::Rate::rate)), value_base::flag_kb), " KB"); element->push_column("Total:", - display::text_element_value_slot(rak::on(std::mem_fun(&torrent::Peer::up_rate), std::mem_fun(&torrent::Rate::total)), value_base::flag_mb), " / ", - display::text_element_value_slot(rak::on(std::mem_fun(&torrent::Peer::down_rate), std::mem_fun(&torrent::Rate::total)), value_base::flag_mb), " MB"); + display::text_element_value_slot(rak::on(std::mem_fun(&torrent::Peer::up_rate), std::mem_fun(&torrent::Rate::total)), value_base::flag_xb), " / ", + display::text_element_value_slot(rak::on(std::mem_fun(&torrent::Peer::down_rate), std::mem_fun(&torrent::Rate::total)), value_base::flag_xb)); element->set_column_width(element->column_width() + 1); diff --git a/src/ui/element_tracker_list.cc b/src/ui/element_tracker_list.cc index 7c6e2f7c..d2def1c1 100644 --- a/src/ui/element_tracker_list.cc +++ b/src/ui/element_tracker_list.cc @@ -56,10 +56,11 @@ ElementTrackerList::ElementTrackerList(core::Download* d) : m_bindings[KEY_LEFT] = sigc::mem_fun(&m_slotExit, &slot_type::operator()); - m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &ElementTrackerList::receive_next); - m_bindings[KEY_UP] = sigc::mem_fun(*this, &ElementTrackerList::receive_prev); m_bindings[' '] = sigc::mem_fun(*this, &ElementTrackerList::receive_cycle_group); m_bindings['*'] = sigc::mem_fun(*this, &ElementTrackerList::receive_disable); + + m_bindings[KEY_DOWN] = m_bindings['P' - '@'] = sigc::mem_fun(*this, &ElementTrackerList::receive_next); + m_bindings[KEY_UP] = m_bindings['N' - '@'] = sigc::mem_fun(*this, &ElementTrackerList::receive_prev); } void