From 465625692fc4cd2abc2194378e9a98790dc8d28f Mon Sep 17 00:00:00 2001 From: rakshasa Date: Fri, 20 Jul 2007 23:54:31 +0000 Subject: [PATCH] * Allow a list of commands to be called on a newly created download before it is started. * The "load_*" commands now allow a list of commands to be appended. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@941 e378c898-3ddf-0310-93e7-cc216c733640 --- src/command_events.cc | 30 ++++++++++++++++++++++-------- src/core/download_factory.cc | 2 ++ src/core/download_factory.h | 3 +++ src/core/manager.cc | 17 +++++++++-------- src/core/manager.h | 11 +++++++++-- src/rpc/parse_commands.h | 2 +- src/ui/download_list.cc | 5 +++-- 7 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/command_events.cc b/src/command_events.cc index 4261793d..a04a8bff 100644 --- a/src/command_events.cc +++ b/src/command_events.cc @@ -197,10 +197,24 @@ apply_schedule(const torrent::Object& rawArgs) { return torrent::Object(); } -void apply_load(const std::string& arg) { control->core()->try_create_download_expand(arg, false, false, true); } -void apply_load_verbose(const std::string& arg) { control->core()->try_create_download_expand(arg, false, true, true); } -void apply_load_start(const std::string& arg) { control->core()->try_create_download_expand(arg, true, false, true); } -void apply_load_start_verbose(const std::string& arg) { control->core()->try_create_download_expand(arg, true, true, true); } +torrent::Object +apply_load(int flags, const torrent::Object& rawArgs) { + const torrent::Object::list_type& args = rawArgs.as_list(); + torrent::Object::list_type::const_iterator argsItr = args.begin(); + + if (argsItr == args.end()) + throw torrent::input_error("Too few arguments."); + + const std::string& filename = argsItr->as_string(); + core::Manager::command_list_type commands; + + while (++argsItr != args.end()) + commands.push_back(argsItr->as_string()); + + control->core()->try_create_download_expand(filename, flags, commands); + + return torrent::Object(); +} void apply_import(const std::string& path) { if (!rpc::parse_command_file(path)) throw torrent::input_error("Could not open option file: " + path); } void apply_try_import(const std::string& path) { if (!rpc::parse_command_file(path)) control->core()->push_log_std("Could not read resource file: " + path); } @@ -317,10 +331,10 @@ initialize_command_events() { ADD_COMMAND_STRING_UN("import", std::ptr_fun(&apply_import)); ADD_COMMAND_STRING_UN("try_import", std::ptr_fun(&apply_try_import)); - ADD_COMMAND_STRING_UN("load", std::ptr_fun(&apply_load)); - ADD_COMMAND_STRING_UN("load_verbose", std::ptr_fun(&apply_load_verbose)); - ADD_COMMAND_STRING_UN("load_start", std::ptr_fun(&apply_load_start)); - ADD_COMMAND_STRING_UN("load_start_verbose", std::ptr_fun(&apply_load_start_verbose)); + ADD_COMMAND_LIST("load", rak::bind_ptr_fn(&apply_load, core::Manager::create_quiet | core::Manager::create_tied)); + ADD_COMMAND_LIST("load_verbose", rak::bind_ptr_fn(&apply_load, core::Manager::create_tied)); + ADD_COMMAND_LIST("load_start", rak::bind_ptr_fn(&apply_load, core::Manager::create_quiet | core::Manager::create_tied | core::Manager::create_start)); + ADD_COMMAND_LIST("load_start_verbose", rak::bind_ptr_fn(&apply_load, core::Manager::create_tied | core::Manager::create_start)); ADD_COMMAND_VALUE_UN("close_low_diskspace", std::ptr_fun(&apply_close_low_diskspace)); diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 93d82a52..4bcdafc8 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -230,6 +230,8 @@ DownloadFactory::receive_success() { return; } + std::for_each(m_commands.begin(), m_commands.end(), rak::bind1st(std::ptr_fun(&rpc::parse_command_d_multiple_std), download)); + // When a download scheduler is implemented, this is handled by the // above insertion into download list. if (m_session) { diff --git a/src/core/download_factory.h b/src/core/download_factory.h index b8e1a6cb..60a21eaa 100644 --- a/src/core/download_factory.h +++ b/src/core/download_factory.h @@ -55,6 +55,7 @@ class Manager; class DownloadFactory { public: typedef sigc::slot Slot; + typedef std::vector command_list_type; // Do not destroy this object while it is in a HttpQueue. DownloadFactory(const std::string& uri, Manager* m); @@ -66,6 +67,7 @@ public: void load(); void commit(); + command_list_type& commands() { return m_commands; } torrent::Object::map_type& variables() { return m_variables; } bool get_session() const { return m_session; } @@ -99,6 +101,7 @@ private: bool m_start; bool m_printLog; + command_list_type m_commands; torrent::Object::map_type m_variables; Slot m_slotFinished; diff --git a/src/core/manager.cc b/src/core/manager.cc index 442c1c76..826abf8e 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -395,14 +395,15 @@ Manager::receive_http_failed(std::string msg) { } void -Manager::try_create_download(const std::string& uri, bool start, bool printLog, bool tied) { +Manager::try_create_download(const std::string& uri, int flags, const command_list_type& commands) { // Adding download. DownloadFactory* f = new DownloadFactory(uri, this); - f->variables()["tied_to_file"] = (int64_t)tied; + f->variables()["tied_to_file"] = (int64_t)(bool)(flags & create_tied); + f->commands().insert(f->commands().end(), commands.begin(), commands.end()); - f->set_start(start); - f->set_print_log(printLog); + f->set_start(flags & create_start); + f->set_print_log(!(flags & create_quiet)); f->slot_finished(sigc::bind(sigc::ptr_fun(&rak::call_delete_func), f)); f->load(); f->commit(); @@ -463,13 +464,13 @@ manager_equal_tied(const std::string& path, Download* download) { } void -Manager::try_create_download_expand(const std::string& uri, bool start, bool printLog, bool tied) { +Manager::try_create_download_expand(const std::string& uri, int flags, command_list_type commands) { std::vector paths; paths.reserve(256); path_expand(&paths, uri); - if (tied) + if (flags & create_tied) for (std::vector::iterator itr = paths.begin(); itr != paths.end(); ) if (std::find_if(m_downloadList->begin(), m_downloadList->end(), rak::bind1st(std::ptr_fun(&manager_equal_tied), *itr)) != m_downloadList->end()) @@ -479,10 +480,10 @@ Manager::try_create_download_expand(const std::string& uri, bool start, bool pri if (!paths.empty()) for (std::vector::iterator itr = paths.begin(); itr != paths.end(); ++itr) - try_create_download(*itr, start, printLog, tied); + try_create_download(*itr, flags, commands); else - try_create_download(uri, start, printLog, tied); + try_create_download(uri, flags, commands); } // DownloadList's hashing related functions don't actually start the diff --git a/src/core/manager.h b/src/core/manager.h index 51f1326a..0c5cefdb 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -38,6 +38,7 @@ #define RTORRENT_CORE_MANAGER_H #include +#include #include "download_list.h" #include "poll_manager.h" @@ -98,9 +99,15 @@ public: void handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash); + static const int create_start = 0x1; + static const int create_tied = 0x2; + static const int create_quiet = 0x4; + + typedef std::vector command_list_type; + // Temporary, find a better place for this. - void try_create_download(const std::string& uri, bool start, bool printLog = true, bool tied = false); - void try_create_download_expand(const std::string& uri, bool start, bool printLog = true, bool tied = false); + void try_create_download(const std::string& uri, int flags, const command_list_type& commands); + void try_create_download_expand(const std::string& uri, int flags, command_list_type commands = command_list_type()); private: void create_http(const std::string& uri); diff --git a/src/rpc/parse_commands.h b/src/rpc/parse_commands.h index 588fe121..221f37d1 100644 --- a/src/rpc/parse_commands.h +++ b/src/rpc/parse_commands.h @@ -65,7 +65,7 @@ inline torrent::Object parse_command_d_single(core::Download* download, const ch void parse_command_multiple(core::Download* download, const char* first, const char* last); void parse_command_d_multiple(core::Download* download, const char* first); -inline void parse_command_d_multiple_std(core::Download* download, const std::string& cmd) { parse_command_d_multiple(download, cmd.c_str()); } +inline void parse_command_d_multiple_std(core::Download* download, const std::string& cmd) { parse_command_multiple(download, cmd.c_str(), cmd.c_str() + cmd.size()); } inline void parse_command_multiple(const char* first) { parse_command_d_multiple(NULL, first); } bool parse_command_file(const std::string& path); diff --git a/src/ui/download_list.cc b/src/ui/download_list.cc index 9c315e90..abe2222a 100644 --- a/src/ui/download_list.cc +++ b/src/ui/download_list.cc @@ -278,9 +278,10 @@ DownloadList::receive_exit_input(Input type) { case INPUT_LOAD_DEFAULT: case INPUT_LOAD_MODIFIED: - if (!input->str().empty()) - control->core()->try_create_download_expand(input->str(), type == INPUT_LOAD_DEFAULT); + if (input->str().empty()) + break; + control->core()->try_create_download_expand(input->str(), type == INPUT_LOAD_DEFAULT ? core::Manager::create_start : 0); break; case INPUT_CHANGE_DIRECTORY: