From 804eb769a00db378f85fa2b260e96379d7577df8 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 6 Sep 2007 22:39:43 +0000 Subject: [PATCH] * Added "close_on_ratio". * Allow commands to be appended to "{stop,close}_on_ratio". git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@976 e378c898-3ddf-0310-93e7-cc216c733640 --- src/command_events.cc | 61 ++++++++++++++++++++++++--------------- src/core/download_list.cc | 16 ++++++++++ src/core/download_list.h | 1 + src/rpc/command_slot.h | 5 ++++ src/rpc/parse_commands.cc | 5 ++++ src/rpc/parse_commands.h | 3 ++ 6 files changed, 67 insertions(+), 24 deletions(-) diff --git a/src/command_events.cc b/src/command_events.cc index 3ab9c909..cbb87f45 100644 --- a/src/command_events.cc +++ b/src/command_events.cc @@ -79,7 +79,7 @@ apply_on_state_change(core::DownloadList::slot_map* slotMap, const torrent::Obje } torrent::Object -apply_stop_on_ratio(const torrent::Object& rawArgs) { +apply_on_ratio(int action, const torrent::Object& rawArgs) { const torrent::Object::list_type& args = rawArgs.as_list(); if (args.empty()) @@ -95,20 +95,32 @@ apply_stop_on_ratio(const torrent::Object& rawArgs) { int64_t maxRatio = argItr != args.end() ? rpc::convert_to_value(*argItr++) : 0; core::DownloadList* downloadList = control->core()->download_list(); - core::Manager::DListItr itr = downloadList->begin(); - while ((itr = std::find_if(itr, downloadList->end(), std::mem_fun(&core::Download::is_seeding))) - != downloadList->end()) { + for (core::Manager::DListItr itr = downloadList->begin(); + (itr = std::find_if(itr, downloadList->end(), std::mem_fun(&core::Download::is_seeding))) != downloadList->end(); + itr++) { int64_t totalDone = (*itr)->download()->bytes_done(); int64_t totalUpload = (*itr)->download()->up_rate()->total(); - if ((totalUpload >= minUpload && totalUpload * 100 >= totalDone * minRatio) || - (maxRatio > 0 && totalUpload * 100 > totalDone * maxRatio)) { - downloadList->stop_try(*itr); - rpc::call_command("d.set_ignore_commands", (int64_t)1, rpc::make_target(*itr)); + if (!(totalUpload >= minUpload && totalUpload * 100 >= totalDone * minRatio) && + !(maxRatio > 0 && totalUpload * 100 > totalDone * maxRatio)) + continue; + + bool success; + + switch (action) { + case core::DownloadList::SLOTS_CLOSE: success = downloadList->close_try(*itr); break; + case core::DownloadList::SLOTS_STOP: success = downloadList->stop_try(*itr); break; + default: success = false; break; } - ++itr; + if (!success) + continue; + + rpc::call_command("d.set_ignore_commands", (int64_t)1, rpc::make_target(*itr)); + + while (argItr != args.end()) + rpc::parse_command_object(rpc::make_target(*itr), *(argItr++)); } return torrent::Object(); @@ -322,23 +334,24 @@ initialize_command_events() { ADD_VARIABLE_BOOL("session_lock", true); ADD_VARIABLE_BOOL("session_on_completion", true); - ADD_COMMAND_SLOT_PRIVATE("on_insert", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_insert())); - ADD_COMMAND_SLOT_PRIVATE("on_erase", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_erase())); - ADD_COMMAND_SLOT_PRIVATE("on_open", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_open())); - ADD_COMMAND_SLOT_PRIVATE("on_close", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_close())); - ADD_COMMAND_SLOT_PRIVATE("on_start", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_start())); - ADD_COMMAND_SLOT_PRIVATE("on_stop", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_stop())); - ADD_COMMAND_SLOT_PRIVATE("on_hash_queued", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_hash_queued())); - ADD_COMMAND_SLOT_PRIVATE("on_hash_removed", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_hash_removed())); - ADD_COMMAND_SLOT_PRIVATE("on_hash_done", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_hash_done())); - ADD_COMMAND_SLOT_PRIVATE("on_finished", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_finished())); + ADD_COMMAND_LIST("on_insert", rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_insert())); + ADD_COMMAND_LIST("on_erase", rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_erase())); + ADD_COMMAND_LIST("on_open", rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_open())); + ADD_COMMAND_LIST("on_close", rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_close())); + ADD_COMMAND_LIST("on_start", rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_start())); + ADD_COMMAND_LIST("on_stop", rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_stop())); + ADD_COMMAND_LIST("on_hash_queued", rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_hash_queued())); + ADD_COMMAND_LIST("on_hash_removed", rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_hash_removed())); + ADD_COMMAND_LIST("on_hash_done", rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_hash_done())); + ADD_COMMAND_LIST("on_finished", rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_finished())); - ADD_COMMAND_SLOT_PRIVATE("stop_on_ratio", call_list, rak::ptr_fn(&apply_stop_on_ratio)); + ADD_COMMAND_LIST("stop_on_ratio", rak::bind_ptr_fn(&apply_on_ratio, (int)core::DownloadList::SLOTS_STOP)); + ADD_COMMAND_LIST("close_on_ratio", rak::bind_ptr_fn(&apply_on_ratio, (int)core::DownloadList::SLOTS_CLOSE)); - ADD_COMMAND_SLOT_PRIVATE("start_tied", call_string, rpc::object_fn(&apply_start_tied)); - ADD_COMMAND_SLOT_PRIVATE("stop_untied", call_string, rpc::object_fn(&apply_stop_untied)); - ADD_COMMAND_SLOT_PRIVATE("close_untied", call_string, rpc::object_fn(&apply_close_untied)); - ADD_COMMAND_SLOT_PRIVATE("remove_untied", call_string, rpc::object_fn(&apply_remove_untied)); + ADD_COMMAND_VOID("start_tied", &apply_start_tied); + ADD_COMMAND_VOID("stop_untied", &apply_stop_untied); + ADD_COMMAND_VOID("close_untied", &apply_close_untied); + ADD_COMMAND_VOID("remove_untied", &apply_remove_untied); ADD_COMMAND_LIST("schedule", rak::ptr_fn(&apply_schedule)); ADD_COMMAND_STRING_UN("schedule_remove", rak::make_mem_fun(control->command_scheduler(), &rpc::CommandScheduler::erase_str)); diff --git a/src/core/download_list.cc b/src/core/download_list.cc index b2490a2a..68b97e21 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -234,6 +234,22 @@ DownloadList::close(Download* download) { } } +bool +DownloadList::close_try(Download* download) { + try { + if (rpc::call_command_value("d.get_ignore_commands", rpc::make_target(download)) != 0) + return false; + + rpc::call_command("d.set_state", (int64_t)0, rpc::make_target(download)); + close_throw(download); + return true; + + } catch (torrent::local_error& e) { + control->core()->push_log(e.what()); + return false; + } +} + void DownloadList::close_directly(Download* download) { if (download->download()->is_active()) { diff --git a/src/core/download_list.h b/src/core/download_list.h index ee45ad7a..0b1ce404 100644 --- a/src/core/download_list.h +++ b/src/core/download_list.h @@ -101,6 +101,7 @@ public: void open_throw(Download* d); void close(Download* d); + bool close_try(Download* d); void close_directly(Download* d); void close_quick(Download* d); void close_throw(Download* d); diff --git a/src/rpc/command_slot.h b/src/rpc/command_slot.h index b057062c..5a36115d 100644 --- a/src/rpc/command_slot.h +++ b/src/rpc/command_slot.h @@ -259,6 +259,11 @@ object_fn(Return (*func)(Target)) { return new object_void_fn_t object_void_fn_t* object_fn(Return (*func)()) { return new object_void_fn_t(func); } +template object_void_fn_t* +object_void_fn(Return (*func)(Target)) { return new object_void_fn_t(func); } +template object_void_fn_t* +object_void_fn(Return (*func)()) { return new object_void_fn_t(func); } + template object_void_fn_t* object_void_fn(Func func) { return new object_void_fn_t(func); } template object_void_fn_t* object_void_fn(Func func) { return new object_void_fn_t(func); } template object_value_fn_t* object_value_fn(Func func) { return new object_value_fn_t(func); } diff --git a/src/rpc/parse_commands.cc b/src/rpc/parse_commands.cc index cc42d412..12873a11 100644 --- a/src/rpc/parse_commands.cc +++ b/src/rpc/parse_commands.cc @@ -149,6 +149,11 @@ parse_command_multiple(target_type target, const char* first, const char* last) } } +parse_command_type +parse_command_object(target_type target, const torrent::Object& object) { + return parse_command(target, object.as_string().c_str(), object.as_string().c_str() + object.as_string().size()); +} + bool parse_command_file(const std::string& path) { std::fstream file(rak::path_expand(path).c_str(), std::ios::in); diff --git a/src/rpc/parse_commands.h b/src/rpc/parse_commands.h index dff12eb1..062b6519 100644 --- a/src/rpc/parse_commands.h +++ b/src/rpc/parse_commands.h @@ -62,6 +62,9 @@ typedef std::pair parse_command_type; parse_command_type parse_command(target_type target, const char* first, const char* last); void parse_command_multiple(target_type target, const char* first, const char* last); +// Make this take care of lists too. +parse_command_type parse_command_object(target_type target, const torrent::Object& object); + inline void parse_command_single(target_type target, const char* first) { parse_command(target, first, first + std::strlen(first)); } inline void parse_command_multiple(target_type target, const char* first) { parse_command_multiple(target, first, first + std::strlen(first)); }