mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-08 15:19:20 +00:00
* Optimized view filtering and sorting.
git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1213 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+34
-27
@@ -27,11 +27,11 @@ gnuplot << EOF
|
|||||||
# 4) throttle.global_down.rate
|
# 4) throttle.global_down.rate
|
||||||
# 5) throttle.global_down.total
|
# 5) throttle.global_down.total
|
||||||
#
|
#
|
||||||
# 9) pieces.memory.current
|
# 6) pieces.memory.current
|
||||||
# 10) pieces.memory.sync_queue
|
# 7) pieces.memory.sync_queue
|
||||||
# 11) pieces.memory.block_count
|
# 8) pieces.memory.block_count
|
||||||
# 12) pieces.stats.total_size
|
# 9) pieces.stats.total_size
|
||||||
# 13) pieces.hash.queue_size
|
# 10) pieces.hash.queue_size
|
||||||
#
|
#
|
||||||
# schedule = log_bandwidth_stats,5,10,((execute,log_rtorrent.sh,((cat,/foo/bandwidth_stats.,((system.pid)))),((system.time_seconds)),((throttle.global_up.rate)),((throttle.global_up.total)),((throttle.global_down.rate)),((throttle.global_down.total)),((pieces.memory.current)),((pieces.memory.sync_queue)),((pieces.memory.block_count)),((pieces.stats.total_size)),((pieces.hash.queue_size))))
|
# schedule = log_bandwidth_stats,5,10,((execute,log_rtorrent.sh,((cat,/foo/bandwidth_stats.,((system.pid)))),((system.time_seconds)),((throttle.global_up.rate)),((throttle.global_up.total)),((throttle.global_down.rate)),((throttle.global_down.total)),((pieces.memory.current)),((pieces.memory.sync_queue)),((pieces.memory.block_count)),((pieces.stats.total_size)),((pieces.hash.queue_size))))
|
||||||
#
|
#
|
||||||
@@ -52,57 +52,64 @@ set terminal png size 1024,600
|
|||||||
set xdata time
|
set xdata time
|
||||||
set timefmt "%s"
|
set timefmt "%s"
|
||||||
set format x "%H:%M"
|
set format x "%H:%M"
|
||||||
set format y "%.0s %cb"
|
|
||||||
set format y2 "%.0f"
|
set format y2 "%.0f"
|
||||||
set y2tics
|
set y2tics
|
||||||
set autoscale xfix
|
set autoscale xfix
|
||||||
|
|
||||||
grab(x)=(x<min)?min=x:(x>max)?max=x:0;
|
grab(x)=(x<min)?min=x:(x>max)?max=x:0;
|
||||||
#div100(x)=(x/100)
|
|
||||||
divrak(v)=(v>0)?-v:0;
|
set output "output_$1_sockets.png"
|
||||||
|
plot "peer_stats.$1" using 1:7 smooth bezier with lines lw 4 title 'active',\
|
||||||
|
"peer_stats.$1" using 1:5 smooth bezier with lines lw 4 title 'leeching',\
|
||||||
|
"peer_stats.$1" using 1:6 smooth bezier with lines lw 4 title 'seeding',\
|
||||||
|
"<awk '{x=1000; if (\$4 < 1000) x=\$4; print \$1,x}' peer_stats.$1" using 1:2 smooth bezier with lines lw 2 title 'open sockets' axis x1y2,\
|
||||||
|
"peer_stats.$1" using 1:2 smooth bezier with lines lw 2 title 'upload unchoked' axis x1y2,\
|
||||||
|
"peer_stats.$1" using 1:3 smooth bezier with lines lw 2 title 'download unchoked' axis x1y2
|
||||||
|
|
||||||
|
# "peer_stats.$1" using 1:4 smooth bezier with lines lw 2 title 'open sockets' axis x1y2,\
|
||||||
|
|
||||||
|
set format y "%.0s %cb"
|
||||||
|
|
||||||
set output "output_$1_bandwidth.png"
|
set output "output_$1_bandwidth.png"
|
||||||
plot "bandwidth_stats.$1" using 1:2 smooth bezier with lines lw 4 title 'Upload rate',\
|
plot "bandwidth_stats.$1" using 1:2 smooth bezier with lines lw 4 title 'Upload rate',\
|
||||||
"bandwidth_stats.$1" using 1:4 smooth bezier with lines lw 4 title 'Download rate',\
|
"bandwidth_stats.$1" using 1:4 smooth bezier with lines lw 4 title 'Download rate',\
|
||||||
"bandwidth_stats.$1" using 1:6 smooth bezier with lines lw 2 title 'Upload unchoked' axis x1y2,\
|
"peer_stats.$1" using 1:2 smooth bezier with lines lw 2 title 'Upload unchoked' axis x1y2,\
|
||||||
"bandwidth_stats.$1" using 1:7 smooth bezier with lines lw 2 title 'Download unchoked' axis x1y2
|
"peer_stats.$1" using 1:3 smooth bezier with lines lw 2 title 'Download unchoked' axis x1y2
|
||||||
|
|
||||||
set output "output_$1_memory.png"
|
set output "output_$1_memory.png"
|
||||||
plot "bandwidth_stats.$1" using 1:9 smooth bezier with lines lw 4 title 'Memory usage' axis x1y1,\
|
plot "bandwidth_stats.$1" using 1:6 smooth bezier with lines lw 4 title 'Memory usage' axis x1y1,\
|
||||||
"bandwidth_stats.$1" using 1:6 smooth bezier with lines lw 2 title 'Upload unchoked' axis x1y2,\
|
"peer_stats.$1" using 1:2 smooth bezier with lines lw 2 title 'Upload unchoked' axis x1y2,\
|
||||||
"bandwidth_stats.$1" using 1:7 smooth bezier with lines lw 2 title 'Download unchoked' axis x1y2
|
"peer_stats.$1" using 1:3 smooth bezier with lines lw 2 title 'Download unchoked' axis x1y2
|
||||||
|
|
||||||
#set yrange [0:3900000000.0]
|
#set yrange [0:3900000000.0]
|
||||||
#set y2range [0:2000]
|
#set y2range [0:2000]
|
||||||
|
|
||||||
set output "output_$1_pieces.png"
|
set output "output_$1_pieces.png"
|
||||||
plot "bandwidth_stats.$1" using 1:9 smooth bezier with lines lw 4 title 'Memory usage' axis x1y1,\
|
plot "bandwidth_stats.$1" using 1:6 smooth bezier with lines lw 4 title 'Memory usage' axis x1y1,\
|
||||||
"bandwidth_stats.$1" using 1:10 smooth bezier with lines lw 4 title 'Sync queue Memory' axis x1y1,\
|
"bandwidth_stats.$1" using 1:7 smooth bezier with lines lw 4 title 'Sync queue Memory' axis x1y1,\
|
||||||
"<awk '{x=\$12*10; print \$1,x}' mincore_stats.$1" using 1:2 smooth bezier with lines lw 4 title 'Alloc /100s' axis x1y1,\
|
"<awk '{x=\$12*10; print \$1,x}' mincore_stats.$1" using 1:2 smooth bezier with lines lw 4 title 'Alloc /100s' axis x1y1,\
|
||||||
"<awk '{x=\$13*10; print \$1,x}' mincore_stats.$1" using 1:2 smooth bezier with lines lw 4 title 'Dealloc /100s' axis x1y1,\
|
"<awk '{x=\$13*10; print \$1,x}' mincore_stats.$1" using 1:2 smooth bezier with lines lw 4 title 'Dealloc /100s' axis x1y1,\
|
||||||
"mincore_stats.$1" using 1:7 smooth bezier with lines lw 2 title 'Sync success /10s' axis x1y2,\
|
"mincore_stats.$1" using 1:7 smooth bezier with lines lw 2 title 'Sync success /10s' axis x1y2,\
|
||||||
"mincore_stats.$1" using 1:8 smooth bezier with lines lw 2 title 'Sync failed /10s' axis x1y2,\
|
"mincore_stats.$1" using 1:8 smooth bezier with lines lw 2 title 'Sync failed /10s' axis x1y2,\
|
||||||
"mincore_stats.$1" using 1:11 smooth bezier with lines lw 2 title 'Alloc failed /10s' axis x1y2,\
|
"mincore_stats.$1" using 1:11 smooth bezier with lines lw 2 title 'Alloc failed /10s' axis x1y2,\
|
||||||
"<awk '{x=\$11/10; print \$1,x}' bandwidth_stats.$1" using 1:2 smooth bezier with lines lw 2 title 'Block count /10' axis x1y2,\
|
"<awk '{x=\$8/10; print \$1,x}' bandwidth_stats.$1" using 1:2 smooth bezier with lines lw 2 title 'Block count /10' axis x1y2,\
|
||||||
"bandwidth_stats.$1" using 1:13 smooth bezier with lines lw 2 title 'Hash queue count' axis x1y2
|
"bandwidth_stats.$1" using 1:10 smooth bezier with lines lw 2 title 'Hash queue count' axis x1y2
|
||||||
# "<awk '{x=\$13/10; print \$1,x}' bandwidth_stats.$1" using 1:2 smooth bezier with lines lw 2 title 'Hash queue count /10' axis x1y2
|
|
||||||
|
|
||||||
|
|
||||||
#set yrange [*:*]
|
#set yrange [*:*]
|
||||||
#set y2range [*:*]
|
#set y2range [*:*]
|
||||||
|
|
||||||
set format y2 "%.0s %cb"
|
set format y2 "%.0s %cb"
|
||||||
set output "output_$1_torrents.png"
|
set output "output_$1_torrents.png"
|
||||||
plot "bandwidth_stats.$1" using 1:9 smooth bezier with lines lw 4 title 'Memory usage' axis x1y1,\
|
plot "bandwidth_stats.$1" using 1:6 smooth bezier with lines lw 4 title 'Memory usage' axis x1y1,\
|
||||||
"bandwidth_stats.$1" using 1:12 smooth bezier with lines lw 2 title 'Pieces total size' axis x1y2
|
"bandwidth_stats.$1" using 1:9 smooth bezier with lines lw 2 title 'Pieces total size' axis x1y2
|
||||||
|
|
||||||
set format y "%.0f"
|
set format y "%.0f"
|
||||||
|
|
||||||
set output "output_$1_incore.png"
|
set output "output_$1_incore.png"
|
||||||
plot "bandwidth_stats.$1" using 1:(0) smooth bezier with lines title '',\
|
plot "bandwidth_stats.$1" using 1:(0) smooth bezier with lines title '',\
|
||||||
"mincore_stats.$1" using 1:2 smooth bezier with lines lw 2 title 'Incore cont.' axis x1y1,\
|
"mincore_stats.$1" using 1:2 smooth bezier with lines lw 2 title 'Incore cont. /10s' axis x1y1,\
|
||||||
"mincore_stats.$1" using 1:3 smooth bezier with lines lw 4 title 'Incore new' axis x1y2,\
|
"mincore_stats.$1" using 1:3 smooth bezier with lines lw 4 title 'Incore new /10s' axis x1y2,\
|
||||||
"mincore_stats.$1" using 1:4 smooth bezier with lines lw 2 title 'Not incore cont.' axis x1y1,\
|
"mincore_stats.$1" using 1:4 smooth bezier with lines lw 2 title 'Not incore cont. /10s' axis x1y1,\
|
||||||
"mincore_stats.$1" using 1:5 smooth bezier with lines lw 4 title 'Not incore new' axis x1y2
|
"mincore_stats.$1" using 1:5 smooth bezier with lines lw 4 title 'Not incore new /10s' axis x1y2
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
+54
-16
@@ -53,7 +53,8 @@
|
|||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "command_helpers.h"
|
#include "command_helpers.h"
|
||||||
|
|
||||||
typedef void (core::ViewManager::*view_cfilter_slot)(const std::string&, const std::string&);
|
typedef void (core::ViewManager::*view_cfilter_slot)(const std::string&, const torrent::Object&);
|
||||||
|
typedef void (core::ViewManager::*view_event_slot)(const std::string&, const std::string&);
|
||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
apply_view_filter_on(const torrent::Object::list_type& args) {
|
apply_view_filter_on(const torrent::Object::list_type& args) {
|
||||||
@@ -82,6 +83,21 @@ apply_view_cfilter(view_cfilter_slot viewFilterSlot, const torrent::Object::list
|
|||||||
|
|
||||||
const std::string& name = args.front().as_string();
|
const std::string& name = args.front().as_string();
|
||||||
|
|
||||||
|
if (name.empty())
|
||||||
|
throw torrent::input_error("First argument must be a string.");
|
||||||
|
|
||||||
|
(control->view_manager()->*viewFilterSlot)(name, args.back());
|
||||||
|
|
||||||
|
return torrent::Object();
|
||||||
|
}
|
||||||
|
|
||||||
|
torrent::Object
|
||||||
|
apply_view_event(view_event_slot viewFilterSlot, const torrent::Object::list_type& args) {
|
||||||
|
if (args.size() != 2)
|
||||||
|
throw torrent::input_error("Too few arguments.");
|
||||||
|
|
||||||
|
const std::string& name = args.front().as_string();
|
||||||
|
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
throw torrent::input_error("First argument must be a string.");
|
throw torrent::input_error("First argument must be a string.");
|
||||||
|
|
||||||
@@ -156,7 +172,7 @@ apply_cat(rpc::target_type target, const torrent::Object& rawArgs) {
|
|||||||
|
|
||||||
// Move these boolean operators to a new file.
|
// Move these boolean operators to a new file.
|
||||||
|
|
||||||
bool
|
inline bool
|
||||||
as_boolean(const torrent::Object& rawArgs) {
|
as_boolean(const torrent::Object& rawArgs) {
|
||||||
switch (rawArgs.type()) {
|
switch (rawArgs.type()) {
|
||||||
case torrent::Object::TYPE_VALUE: return rawArgs.as_value();
|
case torrent::Object::TYPE_VALUE: return rawArgs.as_value();
|
||||||
@@ -169,6 +185,11 @@ as_boolean(const torrent::Object& rawArgs) {
|
|||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
apply_not(rpc::target_type target, const torrent::Object& rawArgs) {
|
apply_not(rpc::target_type target, const torrent::Object& rawArgs) {
|
||||||
|
if (rawArgs.is_dict_key())
|
||||||
|
return (int64_t)!as_boolean(rpc::commands.call_command(rawArgs.as_dict_key().c_str(),
|
||||||
|
rawArgs.as_dict_obj(),
|
||||||
|
target));
|
||||||
|
|
||||||
return (int64_t)!as_boolean(rawArgs);
|
return (int64_t)!as_boolean(rawArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,8 +204,14 @@ apply_and(rpc::target_type target, const torrent::Object& rawArgs) {
|
|||||||
return as_boolean(rawArgs);
|
return as_boolean(rawArgs);
|
||||||
|
|
||||||
for (torrent::Object::list_const_iterator itr = rawArgs.as_list().begin(), last = rawArgs.as_list().end(); itr != last; itr++)
|
for (torrent::Object::list_const_iterator itr = rawArgs.as_list().begin(), last = rawArgs.as_list().end(); itr != last; itr++)
|
||||||
if (!as_boolean(rpc::parse_command_single(target, itr->as_string())))
|
if (itr->is_dict_key()) {
|
||||||
return (int64_t)false;
|
if (!as_boolean(rpc::commands.call_command(itr->as_dict_key().c_str(), itr->as_dict_obj(), target)))
|
||||||
|
return (int64_t)false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (!as_boolean(rpc::parse_command_single(target, itr->as_string())))
|
||||||
|
return (int64_t)false;
|
||||||
|
}
|
||||||
|
|
||||||
return (int64_t)true;
|
return (int64_t)true;
|
||||||
}
|
}
|
||||||
@@ -195,8 +222,14 @@ apply_or(rpc::target_type target, const torrent::Object& rawArgs) {
|
|||||||
return as_boolean(rawArgs);
|
return as_boolean(rawArgs);
|
||||||
|
|
||||||
for (torrent::Object::list_const_iterator itr = rawArgs.as_list().begin(), last = rawArgs.as_list().end(); itr != last; itr++)
|
for (torrent::Object::list_const_iterator itr = rawArgs.as_list().begin(), last = rawArgs.as_list().end(); itr != last; itr++)
|
||||||
if (as_boolean(rpc::parse_command_single(target, itr->as_string())))
|
if (itr->is_dict_key()) {
|
||||||
return (int64_t)true;
|
if (as_boolean(rpc::commands.call_command(itr->as_dict_key().c_str(), itr->as_dict_obj(), target)))
|
||||||
|
return (int64_t)true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (as_boolean(rpc::parse_command_single(target, itr->as_string())))
|
||||||
|
return (int64_t)true;
|
||||||
|
}
|
||||||
|
|
||||||
return (int64_t)false;
|
return (int64_t)false;
|
||||||
}
|
}
|
||||||
@@ -215,13 +248,18 @@ apply_cmp(rpc::target_type target, const torrent::Object::list_type& args) {
|
|||||||
torrent::Object result1;
|
torrent::Object result1;
|
||||||
torrent::Object result2;
|
torrent::Object result2;
|
||||||
|
|
||||||
if (rpc::is_target_pair(target)) {
|
rpc::target_type target1 = rpc::is_target_pair(target) ? rpc::get_target_left(target) : target;
|
||||||
result1 = rpc::parse_command_single(rpc::get_target_left(target), args.front().as_string());
|
rpc::target_type target2 = rpc::is_target_pair(target) ? rpc::get_target_right(target) : target;
|
||||||
result2 = rpc::parse_command_single(rpc::get_target_right(target), args.back().as_string());
|
|
||||||
} else {
|
if (args.front().is_dict_key())
|
||||||
result1 = rpc::parse_command_single(target, args.front().as_string());
|
result1 = rpc::commands.call_command(args.front().as_dict_key().c_str(), args.front().as_dict_obj(), target1);
|
||||||
result2 = rpc::parse_command_single(target, args.back().as_string());
|
else
|
||||||
}
|
result1 = rpc::parse_command_single(target1, args.front().as_string());
|
||||||
|
|
||||||
|
if (args.back().is_dict_key())
|
||||||
|
result2 = rpc::commands.call_command(args.back().as_dict_key().c_str(), args.back().as_dict_obj(), target2);
|
||||||
|
else
|
||||||
|
result2 = rpc::parse_command_single(target2, args.back().as_string());
|
||||||
|
|
||||||
if (result1.type() != result2.type())
|
if (result1.type() != result2.type())
|
||||||
throw torrent::input_error("Type mismatch.");
|
throw torrent::input_error("Type mismatch.");
|
||||||
@@ -410,7 +448,7 @@ torrent::Object
|
|||||||
cmd_view_persistent(const torrent::Object::string_type& args) {
|
cmd_view_persistent(const torrent::Object::string_type& args) {
|
||||||
core::View* view = *control->view_manager()->find_throw(args);
|
core::View* view = *control->view_manager()->find_throw(args);
|
||||||
|
|
||||||
if (!view->get_filter().empty() || !view->get_event_added().empty() || !view->get_event_removed().empty())
|
if (!view->get_filter().is_empty() || !view->get_event_added().empty() || !view->get_event_removed().empty())
|
||||||
throw torrent::input_error("Cannot set modified views as persitent.");
|
throw torrent::input_error("Cannot set modified views as persitent.");
|
||||||
|
|
||||||
view->set_filter("d.views.has=" + args);
|
view->set_filter("d.views.has=" + args);
|
||||||
@@ -471,8 +509,8 @@ initialize_command_ui() {
|
|||||||
CMD2_ANY_LIST("view.sort_new", std::bind(&apply_view_cfilter, &core::ViewManager::set_sort_new, std::placeholders::_2));
|
CMD2_ANY_LIST("view.sort_new", std::bind(&apply_view_cfilter, &core::ViewManager::set_sort_new, std::placeholders::_2));
|
||||||
CMD2_ANY_LIST("view.sort_current", std::bind(&apply_view_cfilter, &core::ViewManager::set_sort_current, std::placeholders::_2));
|
CMD2_ANY_LIST("view.sort_current", std::bind(&apply_view_cfilter, &core::ViewManager::set_sort_current, std::placeholders::_2));
|
||||||
|
|
||||||
CMD2_ANY_LIST("view.event_added", std::bind(&apply_view_cfilter, &core::ViewManager::set_event_added, std::placeholders::_2));
|
CMD2_ANY_LIST("view.event_added", std::bind(&apply_view_event, &core::ViewManager::set_event_added, std::placeholders::_2));
|
||||||
CMD2_ANY_LIST("view.event_removed", std::bind(&apply_view_cfilter, &core::ViewManager::set_event_removed, std::placeholders::_2));
|
CMD2_ANY_LIST("view.event_removed", std::bind(&apply_view_event, &core::ViewManager::set_event_removed, std::placeholders::_2));
|
||||||
|
|
||||||
// Cleanup and add . to view.
|
// Cleanup and add . to view.
|
||||||
|
|
||||||
|
|||||||
+39
-8
@@ -55,14 +55,28 @@ namespace core {
|
|||||||
|
|
||||||
// Also add focus thingie here?
|
// Also add focus thingie here?
|
||||||
struct view_downloads_compare : std::binary_function<Download*, Download*, bool> {
|
struct view_downloads_compare : std::binary_function<Download*, Download*, bool> {
|
||||||
view_downloads_compare(const std::string& cmd) : m_command(cmd) {}
|
view_downloads_compare(const torrent::Object& cmd) : m_command(cmd) {}
|
||||||
|
|
||||||
bool operator () (Download* d1, Download* d2) const {
|
bool operator () (Download* d1, Download* d2) const {
|
||||||
try {
|
try {
|
||||||
if (m_command.empty())
|
if (m_command.is_empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return rpc::parse_command_single(rpc::make_target_pair(d1, d2), m_command).as_value();
|
if (!m_command.is_dict_key())
|
||||||
|
return rpc::parse_command_single(rpc::make_target_pair(d1, d2), m_command.as_string()).as_value();
|
||||||
|
|
||||||
|
// torrent::Object tmp_command = m_command;
|
||||||
|
|
||||||
|
// 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(rpc::make_target_pair(d1, d2), &tmp_command);
|
||||||
|
// return rpc::commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(),
|
||||||
|
// rpc::make_target_pair(d1, d2)).as_value();
|
||||||
|
|
||||||
|
return rpc::commands.call_command(m_command.as_dict_key().c_str(), m_command.as_dict_obj(),
|
||||||
|
rpc::make_target_pair(d1, d2)).as_value();
|
||||||
|
|
||||||
} catch (torrent::input_error& e) {
|
} catch (torrent::input_error& e) {
|
||||||
control->core()->push_log(e.what());
|
control->core()->push_log(e.what());
|
||||||
@@ -71,18 +85,35 @@ struct view_downloads_compare : std::binary_function<Download*, Download*, bool>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& m_command;
|
const torrent::Object& m_command;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct view_downloads_filter : std::unary_function<Download*, bool> {
|
struct view_downloads_filter : std::unary_function<Download*, bool> {
|
||||||
view_downloads_filter(const std::string& cmd) : m_command(cmd) {}
|
view_downloads_filter(const torrent::Object& cmd) : m_command(cmd) {}
|
||||||
|
|
||||||
bool operator () (Download* d1) const {
|
bool operator () (Download* d1) const {
|
||||||
if (m_command.empty())
|
if (m_command.is_empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
torrent::Object result = rpc::parse_command_single(rpc::make_target(d1), m_command);
|
torrent::Object result;
|
||||||
|
|
||||||
|
if (m_command.is_dict_key()) {
|
||||||
|
// torrent::Object tmp_command = m_command;
|
||||||
|
|
||||||
|
// 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(rpc::make_target(d1), &tmp_command);
|
||||||
|
// result = rpc::commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(),
|
||||||
|
// rpc::make_target(d1));
|
||||||
|
|
||||||
|
result = rpc::commands.call_command(m_command.as_dict_key().c_str(), m_command.as_dict_obj(), rpc::make_target(d1));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result = rpc::parse_command_single(rpc::make_target(d1), m_command.as_string());
|
||||||
|
}
|
||||||
|
|
||||||
switch (result.type()) {
|
switch (result.type()) {
|
||||||
// case torrent::Object::TYPE_RAW_BENCODE: return !result.as_raw_bencode().empty();
|
// case torrent::Object::TYPE_RAW_BENCODE: return !result.as_raw_bencode().empty();
|
||||||
@@ -104,7 +135,7 @@ struct view_downloads_filter : std::unary_function<Download*, bool> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& m_command;
|
const torrent::Object& m_command;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
|||||||
+8
-7
@@ -54,6 +54,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <rak/timer.h>
|
#include <rak/timer.h>
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
|
#include <torrent/object.h>
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
@@ -115,15 +116,15 @@ public:
|
|||||||
|
|
||||||
void sort();
|
void sort();
|
||||||
|
|
||||||
void set_sort_new(const std::string& s) { m_sortNew = s; }
|
void set_sort_new(const torrent::Object& s) { m_sortNew = s; }
|
||||||
void set_sort_current(const std::string& s) { m_sortCurrent = s; }
|
void set_sort_current(const torrent::Object& s) { m_sortCurrent = s; }
|
||||||
|
|
||||||
// Need to explicity trigger filtering.
|
// Need to explicity trigger filtering.
|
||||||
void filter();
|
void filter();
|
||||||
void filter_download(core::Download* download);
|
void filter_download(core::Download* download);
|
||||||
|
|
||||||
const std::string& get_filter() const { return m_filter; }
|
const torrent::Object& get_filter() const { return m_filter; }
|
||||||
void set_filter(const std::string& s) { m_filter = s; }
|
void set_filter(const torrent::Object& s) { m_filter = s; }
|
||||||
void set_filter_on_event(const std::string& event);
|
void set_filter_on_event(const std::string& event);
|
||||||
|
|
||||||
void clear_filter_on();
|
void clear_filter_on();
|
||||||
@@ -167,10 +168,10 @@ private:
|
|||||||
size_type m_focus;
|
size_type m_focus;
|
||||||
|
|
||||||
// These should be replaced by a faster non-string command type.
|
// These should be replaced by a faster non-string command type.
|
||||||
std::string m_sortNew;
|
torrent::Object m_sortNew;
|
||||||
std::string m_sortCurrent;
|
torrent::Object m_sortCurrent;
|
||||||
|
|
||||||
std::string m_filter;
|
torrent::Object m_filter;
|
||||||
event_list_type m_events;
|
event_list_type m_events;
|
||||||
|
|
||||||
std::string m_eventAdded;
|
std::string m_eventAdded;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ ViewManager::sort(const std::string& name, uint32_t timeout) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ViewManager::set_filter(const std::string& name, const std::string& cmd) {
|
ViewManager::set_filter(const std::string& name, const torrent::Object& cmd) {
|
||||||
iterator viewItr = find_throw(name);
|
iterator viewItr = find_throw(name);
|
||||||
|
|
||||||
(*viewItr)->set_filter(cmd);
|
(*viewItr)->set_filter(cmd);
|
||||||
|
|||||||
@@ -88,10 +88,10 @@ public:
|
|||||||
void sort(const std::string& name, uint32_t timeout = 0);
|
void sort(const std::string& name, uint32_t timeout = 0);
|
||||||
|
|
||||||
// These could be moved to where the command is implemented.
|
// These could be moved to where the command is implemented.
|
||||||
void set_sort_new(const std::string& name, const std::string& cmd) { (*find_throw(name))->set_sort_new(cmd); }
|
void set_sort_new(const std::string& name, const torrent::Object& cmd) { (*find_throw(name))->set_sort_new(cmd); }
|
||||||
void set_sort_current(const std::string& name, const std::string& cmd) { (*find_throw(name))->set_sort_current(cmd); }
|
void set_sort_current(const std::string& name, const torrent::Object& cmd) { (*find_throw(name))->set_sort_current(cmd); }
|
||||||
|
|
||||||
void set_filter(const std::string& name, const std::string& cmd);
|
void set_filter(const std::string& name, const torrent::Object& cmd);
|
||||||
void set_filter_on(const std::string& name, const filter_args& args);
|
void set_filter_on(const std::string& name, const filter_args& args);
|
||||||
|
|
||||||
void set_event_added(const std::string& name, const std::string& cmd) { (*find_throw(name))->set_event_added(cmd); }
|
void set_event_added(const std::string& name, const std::string& cmd) { (*find_throw(name))->set_event_added(cmd); }
|
||||||
|
|||||||
+20
-20
@@ -260,54 +260,54 @@ main(int argc, char** argv) {
|
|||||||
"view.add = default\n"
|
"view.add = default\n"
|
||||||
|
|
||||||
"view.add = name\n"
|
"view.add = name\n"
|
||||||
"view.sort_new = name,less=d.name=\n"
|
"view.sort_new = name,((less,((d.name))))\n"
|
||||||
"view.sort_current = name,less=d.name=\n"
|
"view.sort_current = name,((less,((d.name))))\n"
|
||||||
|
|
||||||
"view.add = active\n"
|
"view.add = active\n"
|
||||||
"view.filter = active,false=\n"
|
"view.filter = active,((false))\n"
|
||||||
|
|
||||||
"view.add = started\n"
|
"view.add = started\n"
|
||||||
"view.filter = started,false=\n"
|
"view.filter = started,((false))\n"
|
||||||
"view.event_added = started,\"view.set_not_visible=stopped ;d.state.set=1 ;scheduler.simple.added=\"\n"
|
"view.event_added = started,\"view.set_not_visible=stopped ;d.state.set=1 ;scheduler.simple.added=\"\n"
|
||||||
"view.event_removed = started,\"view.set_visible=stopped ;scheduler.simple.removed=\"\n"
|
"view.event_removed = started,\"view.set_visible=stopped ;scheduler.simple.removed=\"\n"
|
||||||
|
|
||||||
"view.add = stopped\n"
|
"view.add = stopped\n"
|
||||||
"view.filter = stopped,false=\n"
|
"view.filter = stopped,((false))\n"
|
||||||
"view.event_added = stopped,\"view.set_not_visible=started ;d.state.set=0\"\n"
|
"view.event_added = stopped,\"view.set_not_visible=started ;d.state.set=0\"\n"
|
||||||
"view.event_removed = stopped,view.set_visible=started\n"
|
"view.event_removed = stopped,view.set_visible=started\n"
|
||||||
|
|
||||||
"view.add = complete\n"
|
"view.add = complete\n"
|
||||||
"view.filter = complete,d.complete=\n"
|
"view.filter = complete,((d.complete))\n"
|
||||||
"view.filter_on = complete,event.download.hash_done,event.download.hash_failed,event.download.hash_final_failed,event.download.finished\n"
|
"view.filter_on = complete,event.download.hash_done,event.download.hash_failed,event.download.hash_final_failed,event.download.finished\n"
|
||||||
"view.sort_new = complete,less=d.state_changed=\n"
|
// "view.sort_new = complete,((less,((d.state_changed))))\n"
|
||||||
"view.sort_current = complete,less=d.state_changed=\n"
|
// "view.sort_current = complete,((less,((d.state_changed))))\n"
|
||||||
|
|
||||||
"view.add = incomplete\n"
|
"view.add = incomplete\n"
|
||||||
"view.filter = incomplete,not=$d.complete=\n"
|
"view.filter = incomplete,((not,((d.complete))))\n"
|
||||||
"view.filter_on = incomplete,event.download.hash_done,event.download.hash_failed,"
|
"view.filter_on = incomplete,event.download.hash_done,event.download.hash_failed,"
|
||||||
"event.download.hash_final_failed,event.download.finished\n"
|
"event.download.hash_final_failed,event.download.finished\n"
|
||||||
"view.sort_new = incomplete,less=d.state_changed=\n"
|
// "view.sort_new = incomplete,((less,((d.state_changed))))\n"
|
||||||
"view.sort_current = incomplete,less=d.state_changed=\n"
|
// "view.sort_current = incomplete,((less,((d.state_changed))))\n"
|
||||||
|
|
||||||
// The hashing view does not include stopped torrents.
|
// The hashing view does not include stopped torrents.
|
||||||
"view.add = hashing\n"
|
"view.add = hashing\n"
|
||||||
"view.filter = hashing,d.hashing=\n"
|
"view.filter = hashing,((d.hashing))\n"
|
||||||
"view.filter_on = hashing,event.download.hash_queued,event.download.hash_removed,"
|
"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\n"
|
||||||
// "view.sort_new = hashing,less=d.state_changed=\n"
|
// "view.sort_new = hashing,less=d.state_changed=\n"
|
||||||
// "view.sort_current = hashing,less=d.state_changed=\n"
|
// "view.sort_current = hashing,less=d.state_changed=\n"
|
||||||
|
|
||||||
"view.add = seeding\n"
|
"view.add = seeding\n"
|
||||||
"view.filter = seeding,\"and=d.state=,d.complete=\"\n"
|
"view.filter = seeding,((and,((d.state)),((d.complete))))\n"
|
||||||
"view.filter_on = seeding,event.download.resumed,event.download.paused,event.download.finished\n"
|
"view.filter_on = seeding,event.download.resumed,event.download.paused,event.download.finished\n"
|
||||||
"view.sort_new = seeding,less=d.state_changed=\n"
|
// "view.sort_new = seeding,((less,((d.state_changed))))\n"
|
||||||
"view.sort_current = seeding,less=d.state_changed=\n"
|
// "view.sort_current = seeding,((less,((d.state_changed))))\n"
|
||||||
|
|
||||||
"view.add = leeching\n"
|
"view.add = leeching\n"
|
||||||
"view.filter = leeching,\"and=d.state=,not=$d.complete=\"\n"
|
"view.filter = leeching,((and,((d.state)),((not,((d.complete))))))\n"
|
||||||
"view.filter_on = leeching,event.download.resumed,event.download.paused,event.download.finished\n"
|
"view.filter_on = leeching,event.download.resumed,event.download.paused,event.download.finished\n"
|
||||||
"view.sort_new = leeching,less=d.state_changed=\n"
|
// "view.sort_new = leeching,((less,((d.state_changed))))\n"
|
||||||
"view.sort_current = leeching,less=d.state_changed=\n"
|
// "view.sort_current = leeching,((less,((d.state_changed))))\n"
|
||||||
|
|
||||||
"schedule2 = view.main,10,10,((view.sort,main,20))\n"
|
"schedule2 = view.main,10,10,((view.sort,main,20))\n"
|
||||||
"schedule2 = view.name,10,10,((view.sort,name,20))\n"
|
"schedule2 = view.name,10,10,((view.sort,name,20))\n"
|
||||||
|
|||||||
@@ -106,6 +106,8 @@ CommandScheduler::call_item(value_type item) {
|
|||||||
|
|
||||||
// Unquote the root function object so 'parse_command_execute'
|
// Unquote the root function object so 'parse_command_execute'
|
||||||
// doesn't end up calling it.
|
// 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;
|
uint32_t flags = tmp_command.flags() & torrent::Object::mask_function;
|
||||||
tmp_command.unset_flags(torrent::Object::mask_function);
|
tmp_command.unset_flags(torrent::Object::mask_function);
|
||||||
tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function);
|
tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function);
|
||||||
|
|||||||
+19
-17
@@ -67,32 +67,34 @@ parse_string(const char* first, const char* last, std::string* dest, bool (*deli
|
|||||||
if (first == last)
|
if (first == last)
|
||||||
return first;
|
return first;
|
||||||
|
|
||||||
bool quoted = parse_is_quote(*first);
|
if (parse_is_quote(*first)) {
|
||||||
|
|
||||||
if (quoted)
|
|
||||||
first++;
|
first++;
|
||||||
|
|
||||||
while (first != last) {
|
while (first != last) {
|
||||||
if (quoted) {
|
|
||||||
if (parse_is_quote(*first))
|
if (parse_is_quote(*first))
|
||||||
return ++first;
|
return ++first;
|
||||||
|
|
||||||
} else {
|
if (parse_is_escape(*first) && ++first == last)
|
||||||
if (delim(*first))
|
throw torrent::input_error("Escape character at end of input.");
|
||||||
return first;
|
|
||||||
|
dest->push_back(*first++);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_is_escape(*first) && ++first == last)
|
|
||||||
throw torrent::input_error("Escape character at end of input.");
|
|
||||||
|
|
||||||
dest->push_back(*first);
|
|
||||||
first++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quoted)
|
|
||||||
throw torrent::input_error("Missing closing quote.");
|
throw torrent::input_error("Missing closing quote.");
|
||||||
|
|
||||||
return first;
|
} else {
|
||||||
|
while (first != last) {
|
||||||
|
if (delim(*first))
|
||||||
|
return first;
|
||||||
|
|
||||||
|
if (parse_is_escape(*first) && ++first == last)
|
||||||
|
throw torrent::input_error("Escape character at end of input.");
|
||||||
|
|
||||||
|
dest->push_back(*first++);
|
||||||
|
}
|
||||||
|
|
||||||
|
return first;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+19
-15
@@ -112,6 +112,21 @@ parse_command_execute(target_type target, torrent::Object* object) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use a static length buffer for dest.
|
||||||
|
inline const char*
|
||||||
|
parse_command_name(const char* first, const char* last, char* dest_first, char* dest_last) {
|
||||||
|
if (first == last || !std::isalpha(*first))
|
||||||
|
throw torrent::input_error("Invalid start of command name.");
|
||||||
|
|
||||||
|
last = first + std::min(std::distance(first, last), std::distance(dest_first, dest_last) - 1);
|
||||||
|
|
||||||
|
while (first != last && (std::isalnum(*first) || *first == '_' || *first == '.'))
|
||||||
|
*dest_first++ = *first++;
|
||||||
|
|
||||||
|
*dest_first = '\0';
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
// Set 'download' to NULL to call the generic functions, thus reusing
|
// Set 'download' to NULL to call the generic functions, thus reusing
|
||||||
// the code below for both cases.
|
// the code below for both cases.
|
||||||
parse_command_type
|
parse_command_type
|
||||||
@@ -121,8 +136,9 @@ parse_command(target_type target, const char* first, const char* last) {
|
|||||||
if (first == last || *first == '#')
|
if (first == last || *first == '#')
|
||||||
return std::make_pair(torrent::Object(), first);
|
return std::make_pair(torrent::Object(), first);
|
||||||
|
|
||||||
std::string key;
|
char key[128];
|
||||||
first = parse_command_name(first, last, &key);
|
|
||||||
|
first = parse_command_name(first, last, key, key + 128);
|
||||||
first = std::find_if(first, last, std::not1(command_map_is_space()));
|
first = std::find_if(first, last, std::not1(command_map_is_space()));
|
||||||
|
|
||||||
if (first == last || *first != '=')
|
if (first == last || *first != '=')
|
||||||
@@ -147,7 +163,7 @@ parse_command(target_type target, const char* first, const char* last) {
|
|||||||
// following command.
|
// following command.
|
||||||
parse_command_execute(target, &args);
|
parse_command_execute(target, &args);
|
||||||
|
|
||||||
return std::make_pair(commands.call_command(key.c_str(), args, target), first);
|
return std::make_pair(commands.call_command(key, args, target), first);
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
@@ -223,18 +239,6 @@ parse_command_file(const std::string& path) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a static length buffer for dest.
|
|
||||||
const char*
|
|
||||||
parse_command_name(const char* first, const char* last, std::string* dest) {
|
|
||||||
if (first == last || !std::isalpha(*first))
|
|
||||||
throw torrent::input_error("Invalid start of name.");
|
|
||||||
|
|
||||||
for ( ; first != last && (std::isalnum(*first) || *first == '_' || *first == '.'); ++first)
|
|
||||||
dest->push_back(*first);
|
|
||||||
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user