diff --git a/src/command_events.cc b/src/command_events.cc index 5d776f1d..79654eaa 100644 --- a/src/command_events.cc +++ b/src/command_events.cc @@ -39,12 +39,15 @@ #include #include #include +#include #include #include +#include #include "core/download.h" #include "core/download_list.h" #include "core/manager.h" +#include "core/view_manager.h" #include "rpc/command_slot.h" #include "rpc/command_variable.h" #include "rpc/parse.h" @@ -162,10 +165,15 @@ apply_remove_untied() { rak::file_stat fs; const std::string& tiedToFile = rpc::call_command_d_string("get_d_tied_to_file", *itr); - if (!tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile)) && control->core()->download_list()->stop_try(*itr)) + if (!tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile))) { + // Need to clear tied_to_file so it doesn't try to delete it. + rpc::call_command_d("set_d_tied_to_file", *itr, std::string()); + itr = control->core()->download_list()->erase(itr); - else + + } else { ++itr; + } } return torrent::Object(); @@ -213,6 +221,34 @@ apply_close_low_diskspace(int64_t arg) { } } +torrent::Object +apply_download_list(const torrent::Object& rawArgs) { + const torrent::Object::list_type& args = rawArgs.as_list(); + torrent::Object::list_type::const_iterator argsItr = args.begin(); + + core::ViewManager* viewManager = control->view_manager(); + core::ViewManager::iterator viewItr; + + if (argsItr != args.end()) + viewItr = viewManager->find((argsItr++)->as_string()); + else + viewItr = viewManager->find("main"); + + if (viewItr == viewManager->end()) + throw torrent::input_error("Could not find view."); + + torrent::Object result(torrent::Object::TYPE_LIST); + torrent::Object::list_type& resultList = result.as_list(); + + for (core::View::const_iterator itr = (*viewItr)->begin_visible(), last = (*viewItr)->end_visible(); itr != last; itr++) { + const torrent::HashString* hashString = &(*itr)->download()->info_hash(); + + resultList.push_back(rak::transform_hex(hashString->begin(), hashString->end())); + } + + return result; +} + void initialize_command_events() { core::DownloadList* downloadList = control->core()->download_list(); @@ -252,4 +288,6 @@ initialize_command_events() { ADD_COMMAND_STRING_UN("load_start_verbose", std::ptr_fun(&apply_load_start_verbose)); ADD_COMMAND_VALUE_UN("close_low_diskspace", std::ptr_fun(&apply_close_low_diskspace)); + + ADD_COMMAND_LIST("download_list", rak::ptr_fn(&apply_download_list)); } diff --git a/src/core/download_list.cc b/src/core/download_list.cc index e5a285ea..95b539c3 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -145,8 +145,6 @@ DownloadList::insert(Download* download) { void DownloadList::erase(Download* download) { - check_contains(download); - erase(std::find(begin(), end(), download)); } diff --git a/src/rpc/xmlrpc.cc b/src/rpc/xmlrpc.cc index 67622485..15c926aa 100644 --- a/src/rpc/xmlrpc.cc +++ b/src/rpc/xmlrpc.cc @@ -115,6 +115,33 @@ xmlrpc_to_object(xmlrpc_env* env, xmlrpc_value* value) { } } +xmlrpc_value* +object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) { + xmlrpc_value* result; + xmlrpc_int32 tmpInt; + + switch (object.type()) { + case torrent::Object::TYPE_VALUE: + tmpInt = object.as_value(); + return xmlrpc_build_value(env, "i", tmpInt); + + case torrent::Object::TYPE_STRING: + return xmlrpc_string_new(env, object.as_string().c_str()); + + case torrent::Object::TYPE_LIST: + result = xmlrpc_array_new(env); + + for (torrent::Object::list_type::const_iterator itr = object.as_list().begin(), last = object.as_list().end(); itr != last; itr++) + xmlrpc_array_append_item(env, result, object_to_xmlrpc(env, *itr)); + + return result; + + default: + tmpInt = 0; + return xmlrpc_build_value(env, "i", tmpInt); + } +} + xmlrpc_value* XmlRpc::call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) { torrent::Object object = xmlrpc_to_object(env, args); @@ -123,27 +150,7 @@ XmlRpc::call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) return NULL; try { - const torrent::Object& resultObject = XmlRpc::m_slotCall((const char*)voidServerInfo, object); - - xmlrpc_value* result; - xmlrpc_int32 tmpInt; - - switch (resultObject.type()) { - case torrent::Object::TYPE_VALUE: - tmpInt = resultObject.as_value(); - result = xmlrpc_build_value(env, "i", tmpInt); - break; - - case torrent::Object::TYPE_STRING: - result = xmlrpc_string_new(env, resultObject.as_string().c_str()); - break; - - default: - tmpInt = 1; - result = xmlrpc_build_value(env, "i", tmpInt); - } - - return result; + return object_to_xmlrpc(env, XmlRpc::m_slotCall((const char*)voidServerInfo, object)); } catch (torrent::local_error& e) { xmlrpc_env_set_fault(env, XMLRPC_PARSE_ERROR, e.what());