mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-04 21:29:21 +00:00
* Cleanup of command handling.
* Added 'd.timestamp.finished' that is set when a downloading torrent completes. For torrents that only seed it remains '0'.
* Added 'elapsed.{less,greater}' for checking the time elapsed since a time is less/greater, and it also returns false in all cases where the time is '0'.
* Fixed a bug that would cause hash checking to block exessively in some cases.
git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1233 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+14
-6
@@ -31,13 +31,21 @@ gnuplot << EOF
|
||||
#
|
||||
# Choke groups:
|
||||
#
|
||||
# file.append = (cat,/foo/choke_group_stats.,(system.pid)),"timestamp",
|
||||
# "\"leech up unchoked\"","\"leech up queued\"","\"leech up rate\"","\"leech down unchoked\"","\"leech down queued\"","\"leech down rate\"","\"leech torrents\"",
|
||||
# "\"seed up unchoked\"","\"seed up queued\"","\"seed up rate\"","\"seed down unchoked\"","\"seed down queued\"","\"seed down rate\"","\"seed torrents\""
|
||||
# file.append = (cat,/foo/choke_group_stats.,(system.pid)),"timestamp",\
|
||||
# "\"default up unchoked\"","\"default up queued\"","\"default up rate\"",\
|
||||
# "\"default down unchoked\"","\"default down queued\"","\"default down rate\"","\"default torrents\"",\
|
||||
# "\"leech up unchoked\"","\"leech up queued\"","\"leech up rate\"",\
|
||||
# "\"leech down unchoked\"","\"leech down queued\"","\"leech down rate\"","\"leech torrents\"",\
|
||||
# "\"seed boost up unchoked\"","\"seed boost up queued\"","\"seed boost up rate\"",\
|
||||
# "\"seed boost down unchoked\"","\"seed boost down queued\"","\"seed boost down rate\"","\"seed boost torrents\"",\
|
||||
# "\"seed up unchoked\"","\"seed up queued\"","\"seed up rate\"",\
|
||||
# "\"seed down unchoked\"","\"seed down queued\"","\"seed down rate\"","\"seed torrents\""
|
||||
#
|
||||
# schedule = log_choke_group_stats,5,10,((file.append,((cat,/foo/choke_group_stats.,((system.pid)))),((system.time_seconds)),
|
||||
# ((choke_group.up.unchoked,0)),((choke_group.up.queued,0)),((choke_group.up.rate,0)),((choke_group.down.unchoked,0)),((choke_group.down.queued,0)),((choke_group.down.rate,0)),((choke_group.size,0)),
|
||||
# ((choke_group.up.unchoked,1)),((choke_group.up.queued,1)),((choke_group.up.rate,1)),((choke_group.down.unchoked,1)),((choke_group.down.queued,1)),((choke_group.down.rate,1)),((choke_group.size,1))))
|
||||
# schedule = log_choke_group_stats,5,10,((file.append,((cat,/foo/choke_group_stats.,((system.pid)))),((system.time_seconds)),\
|
||||
# ((choke_group.up.unchoked,0)),((choke_group.up.queued,0)),((choke_group.up.rate,0)),((choke_group.down.unchoked,0)),((choke_group.down.queued,0)),((choke_group.down.rate,0)),((choke_group.size,0)),\
|
||||
# ((choke_group.up.unchoked,1)),((choke_group.up.queued,1)),((choke_group.up.rate,1)),((choke_group.down.unchoked,1)),((choke_group.down.queued,1)),((choke_group.down.rate,1)),((choke_group.size,1)),\
|
||||
# ((choke_group.up.unchoked,2)),((choke_group.up.queued,2)),((choke_group.up.rate,2)),((choke_group.down.unchoked,2)),((choke_group.down.queued,2)),((choke_group.down.rate,2)),((choke_group.size,2)),\
|
||||
# ((choke_group.up.unchoked,3)),((choke_group.up.queued,3)),((choke_group.up.rate,3)),((choke_group.down.unchoked,3)),((choke_group.down.queued,3)),((choke_group.down.rate,3)),((choke_group.size,3)) ))
|
||||
#
|
||||
# Mincore stats:
|
||||
#
|
||||
|
||||
@@ -654,8 +654,10 @@ initialize_command_download() {
|
||||
|
||||
// 0 - stopped
|
||||
// 1 - started
|
||||
CMD2_DL_VAR_VALUE("d.state", "rtorrent", "state");
|
||||
CMD2_DL_VAR_VALUE("d.complete", "rtorrent", "complete");
|
||||
CMD2_DL_VAR_VALUE("d.state", "rtorrent", "state");
|
||||
CMD2_DL_VAR_VALUE("d.complete", "rtorrent", "complete");
|
||||
|
||||
CMD2_FUNC_SINGLE ("d.incomplete", "not=(d.complete)");
|
||||
|
||||
// 0 off
|
||||
// 1 scheduled, being controlled by a download scheduler. Includes a priority.
|
||||
@@ -684,6 +686,8 @@ initialize_command_download() {
|
||||
CMD2_DL_VAR_VALUE("d.state_counter", "rtorrent", "state_counter");
|
||||
CMD2_DL_VAR_VALUE_PUBLIC("d.ignore_commands", "rtorrent", "ignore_commands");
|
||||
|
||||
CMD2_DL_VAR_VALUE("d.timestamp.finished", "rtorrent", "timestamp.finished");
|
||||
|
||||
CMD2_DL ("d.connection_current", std::bind(&torrent::option_as_string, torrent::OPTION_CONNECTION_TYPE, CMD2_ON_DL(connection_type)));
|
||||
CMD2_DL_STRING("d.connection_current.set", std::bind(&apply_d_connection_type, std::placeholders::_1, std::placeholders::_2));
|
||||
|
||||
@@ -748,6 +752,7 @@ initialize_command_download() {
|
||||
CMD2_DL ("d.completed_chunks", CMD2_ON_FL(completed_chunks));
|
||||
CMD2_DL ("d.left_bytes", CMD2_ON_FL(left_bytes));
|
||||
|
||||
CMD2_DL_V ("d.tracker_announce", std::bind(&torrent::TrackerList::manual_request, CMD2_BIND_TL, false));
|
||||
CMD2_DL ("d.tracker_numwant", std::bind(&torrent::TrackerList::numwant, CMD2_BIND_TL));
|
||||
CMD2_DL_VALUE_V ("d.tracker_numwant.set", std::bind(&torrent::TrackerList::set_numwant, CMD2_BIND_TL, std::placeholders::_2));
|
||||
CMD2_DL ("d.tracker_focus", std::bind(&torrent::TrackerList::focus_index, CMD2_BIND_TL));
|
||||
|
||||
@@ -394,10 +394,15 @@ system_method_set_key(const torrent::Object::list_type& args) {
|
||||
const std::string& key = (itrArgs++)->as_string();
|
||||
const std::string& cmd_key = (itrArgs++)->as_string();
|
||||
|
||||
if (itrArgs != args.end())
|
||||
control->object_storage()->set_str_multi_key(key, cmd_key, system_method_generate_command(itrArgs, args.end()));
|
||||
else
|
||||
if (itrArgs == args.end()) {
|
||||
control->object_storage()->erase_str_multi_key(key, cmd_key);
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
if (itrArgs->is_dict_key())
|
||||
control->object_storage()->set_str_multi_key_obj(key.c_str(), cmd_key, *itrArgs);
|
||||
else
|
||||
control->object_storage()->set_str_multi_key(key, cmd_key, system_method_generate_command(itrArgs, args.end()));
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
@@ -404,6 +404,8 @@ apply_if(rpc::target_type target, const torrent::Object& rawArgs, int flags) {
|
||||
|
||||
if (flags & 0x1 && itr->is_string())
|
||||
conditional = &(tmp = rpc::parse_command(target, itr->as_string().c_str(), itr->as_string().c_str() + itr->as_string().size()).first);
|
||||
else if (flags & 0x1 && itr->is_dict_key())
|
||||
conditional = &(tmp = rpc::commands.call_command(itr->as_dict_key().c_str(), itr->as_dict_obj(), target));
|
||||
else
|
||||
conditional = &*itr;
|
||||
|
||||
@@ -437,6 +439,9 @@ apply_if(rpc::target_type target, const torrent::Object& rawArgs, int flags) {
|
||||
if (flags & 0x1 && itr->is_string()) {
|
||||
return rpc::parse_command(target, itr->as_string().c_str(), itr->as_string().c_str() + itr->as_string().size()).first;
|
||||
|
||||
} else if (flags & 0x1 && itr->is_dict_key()) {
|
||||
return rpc::commands.call_command(itr->as_dict_key().c_str(), itr->as_dict_obj(), target);
|
||||
|
||||
} else if (flags & 0x1 && itr->is_list()) {
|
||||
// Move this into a special function or something. Also, might be
|
||||
// nice to have a parse_command function that takes list
|
||||
@@ -512,6 +517,26 @@ cmd_view_set_not_visible(core::Download* download, const torrent::Object::string
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_elapsed_less(const torrent::Object::list_type& args) {
|
||||
if (args.size() != 2)
|
||||
throw torrent::input_error("Wrong argument count.");
|
||||
|
||||
int64_t start_time = rpc::convert_to_value(args.front());
|
||||
|
||||
return (int64_t)(start_time != 0 && rak::timer::current_seconds() - start_time < rpc::convert_to_value(args.back()));
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_elapsed_greater(const torrent::Object::list_type& args) {
|
||||
if (args.size() != 2)
|
||||
throw torrent::input_error("Wrong argument count.");
|
||||
|
||||
int64_t start_time = rpc::convert_to_value(args.front());
|
||||
|
||||
return (int64_t)(start_time != 0 && rak::timer::current_seconds() - start_time > rpc::convert_to_value(args.back()));
|
||||
}
|
||||
|
||||
void
|
||||
initialize_command_ui() {
|
||||
CMD2_VAR_STRING("keys.layout", "qwerty");
|
||||
@@ -573,4 +598,7 @@ initialize_command_ui() {
|
||||
CMD2_ANY_VALUE("convert.mb", std::bind(&apply_to_mb, std::placeholders::_2));
|
||||
CMD2_ANY_VALUE("convert.xb", std::bind(&apply_to_xb, std::placeholders::_2));
|
||||
CMD2_ANY_VALUE("convert.throttle", std::bind(&apply_to_throttle, std::placeholders::_2));
|
||||
|
||||
CMD2_ANY_LIST ("elapsed.less", std::bind(&apply_elapsed_less, std::placeholders::_2));
|
||||
CMD2_ANY_LIST ("elapsed.greater", std::bind(&apply_elapsed_greater, std::placeholders::_2));
|
||||
}
|
||||
|
||||
@@ -368,6 +368,8 @@ DownloadFactory::initialize_rtorrent(Download* download, torrent::Object* rtorre
|
||||
rtorrent->insert_preserve_copy("complete", (int64_t)0);
|
||||
rtorrent->insert_preserve_copy("hashing", (int64_t)Download::variable_hashing_stopped);
|
||||
|
||||
rtorrent->insert_preserve_copy("timestamp.finished", (int64_t)0);
|
||||
|
||||
rtorrent->insert_preserve_copy("tied_to_file", "");
|
||||
rtorrent->insert_key("loaded_file", m_isFile ? m_uri : std::string());
|
||||
|
||||
|
||||
@@ -533,8 +533,9 @@ DownloadList::hash_done(Download* download) {
|
||||
control->core()->push_log("Hash check on download completion found bad chunks, consider using \"safe_sync\".");
|
||||
rpc::commands.call_catch("event.download.hash_final_failed", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// TODO: Should we skip the 'hash_done' event here?
|
||||
return;
|
||||
|
||||
case Download::variable_hashing_stopped:
|
||||
default:
|
||||
|
||||
+3
-1
@@ -242,6 +242,8 @@ main(int argc, char** argv) {
|
||||
"method.set_key = event.download.erased, !_download_list, ui.unfocus_download=\n"
|
||||
"method.set_key = event.download.erased, ~_delete_tied, d.delete_tied=\n"
|
||||
|
||||
"method.set_key = event.download.finished, !_timestamp, ((d.timestamp.finished.set, ((system.time)) ))\n"
|
||||
|
||||
"method.insert.c_simple = group.insert_persistent_view,"
|
||||
"((view.add,((argument.0)))),((view.persistent,((argument.0)))),((group.insert,((argument.0)),((argument.0))))\n"
|
||||
|
||||
@@ -298,7 +300,7 @@ main(int argc, char** argv) {
|
||||
"view.add = hashing\n"
|
||||
"view.filter = hashing,((d.hashing))\n"
|
||||
"view.filter_on = hashing,event.download.hash_queued,event.download.hash_removed,"
|
||||
"event.download.hash_done,event.download.hash_failed,event.download.hash_final_failed\n"
|
||||
"event.download.hash_done,event.download.hash_failed,event.download.hash_final_failed,event.download.finished\n"
|
||||
// "view.sort_new = hashing,less=d.state_changed=\n"
|
||||
// "view.sort_current = hashing,less=d.state_changed=\n"
|
||||
|
||||
|
||||
@@ -205,7 +205,10 @@ object_storage::erase_multi_key(const torrent::raw_string& key, const std::strin
|
||||
}
|
||||
|
||||
void
|
||||
object_storage::set_multi_key(const torrent::raw_string& key, const std::string& cmd_key, const std::string& object) {
|
||||
object_storage::set_multi_key_obj(const torrent::raw_string& key, const std::string& cmd_key, const torrent::Object& object) {
|
||||
if (!object.is_string() && !object.is_dict_key())
|
||||
throw torrent::input_error("Object is wrong type.");
|
||||
|
||||
local_iterator itr = find_local(key);
|
||||
|
||||
if (itr == end(0) || (itr->second.flags & mask_type) != flag_multi_type)
|
||||
|
||||
@@ -150,11 +150,14 @@ public:
|
||||
// Multi-command function:
|
||||
bool has_multi_key(const torrent::raw_string& key, const std::string& cmd_key);
|
||||
void erase_multi_key(const torrent::raw_string& key, const std::string& cmd_key);
|
||||
void set_multi_key(const torrent::raw_string& key, const std::string& cmd_key, const std::string& object);
|
||||
void set_multi_key_obj(const torrent::raw_string& key, const std::string& cmd_key, const torrent::Object& object);
|
||||
|
||||
void set_multi_key(const torrent::raw_string& key, const std::string& cmd_key, const std::string& object) { set_multi_key_obj(key, cmd_key, object); }
|
||||
|
||||
bool has_str_multi_key(const std::string& key, const std::string& cmd_key);
|
||||
void erase_str_multi_key(const std::string& key, const std::string& cmd_key);
|
||||
void set_str_multi_key(const std::string& key, const std::string& cmd_key, const std::string& object);
|
||||
void set_str_multi_key_obj(const std::string& key, const std::string& cmd_key, const torrent::Object& object);
|
||||
|
||||
torrent::Object::list_type rlookup_list(const std::string& cmd_key);
|
||||
torrent::Object rlookup_obj_list(const std::string& cmd_key) { return torrent::Object::from_list(rlookup_list(cmd_key)); }
|
||||
@@ -241,7 +244,12 @@ object_storage::erase_str_multi_key(const std::string& key, const std::string& c
|
||||
|
||||
inline void
|
||||
object_storage::set_str_multi_key(const std::string& key, const std::string& cmd_key, const std::string& object) {
|
||||
return set_multi_key(torrent::raw_string::from_string(key), cmd_key, object);
|
||||
return set_multi_key_obj(torrent::raw_string::from_string(key), cmd_key, object);
|
||||
}
|
||||
|
||||
inline void
|
||||
object_storage::set_str_multi_key_obj(const std::string& key, const std::string& cmd_key, const torrent::Object& object) {
|
||||
return set_multi_key_obj(torrent::raw_string::from_string(key), cmd_key, object);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -295,10 +295,18 @@ command_function_call_object(const torrent::Object& cmd, target_type target, con
|
||||
}
|
||||
|
||||
} else {
|
||||
torrent::Object tmp_cmd = cmd;
|
||||
|
||||
rpc::parse_command_execute(target, &tmp_cmd);
|
||||
result = rpc::commands.call_command(tmp_cmd.as_dict_key().c_str(), tmp_cmd.as_dict_obj());
|
||||
torrent::Object tmp_command = cmd;
|
||||
|
||||
// Unquote the root function object so 'parse_command_execute'
|
||||
// doesn't end up calling it.
|
||||
//
|
||||
// TODO: Only call this if mask_function is set?
|
||||
uint32_t flags = tmp_command.flags() & torrent::Object::mask_function;
|
||||
tmp_command.unset_flags(torrent::Object::mask_function);
|
||||
tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function);
|
||||
|
||||
rpc::parse_command_execute(target, &tmp_command);
|
||||
rpc::commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(), target);
|
||||
}
|
||||
|
||||
rpc::command_base::pop_stack(&stack, last_stack);
|
||||
@@ -324,6 +332,23 @@ command_function_multi_call(const torrent::Object::map_type& cmd, target_type ta
|
||||
|
||||
try {
|
||||
for (torrent::Object::map_const_iterator itr = cmd.begin(), last = cmd.end(); itr != last; itr++) {
|
||||
if (itr->second.is_dict_key()) {
|
||||
// This can/should be optimized...
|
||||
torrent::Object tmp_command = itr->second;
|
||||
|
||||
// Unquote the root function object so 'parse_command_execute'
|
||||
// doesn't end up calling it.
|
||||
//
|
||||
// TODO: Only call this if mask_function is set?
|
||||
uint32_t flags = tmp_command.flags() & torrent::Object::mask_function;
|
||||
tmp_command.unset_flags(torrent::Object::mask_function);
|
||||
tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function);
|
||||
|
||||
rpc::parse_command_execute(target, &tmp_command);
|
||||
rpc::commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(), target);
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string& cmd_str = itr->second.as_string();
|
||||
parse_command_multiple(target, cmd_str.c_str(), cmd_str.c_str() + cmd_str.size());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user