* Added groups and started reworking the ratio handling.

git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1078 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2008-11-09 16:20:57 +00:00
parent 5166253190
commit 66a2af991a
3 changed files with 72 additions and 50 deletions
+13 -5
View File
@@ -67,7 +67,7 @@ create_new_key(const std::string& key, const char postfix[postfix_size]) {
}
// system.method.insert <generic> {name, "simple|private|const", ...}
// system.method.insert <generic> {name, "list|private|const"}
// system.method.insert <generic> {name, "multi|private|const"}
// system.method.insert <generic> {name, "value|private|const"}
// system.method.insert <generic> {name, "value|private|const", value}
// system.method.insert <generic> {name, "bool|private|const"}
@@ -100,7 +100,7 @@ system_method_insert(__UNUSED rpc::target_type target, const torrent::Object& ra
if (options.find("const") != std::string::npos)
flags &= ~rpc::CommandMap::flag_modifiable;
if (options.find("list") != std::string::npos) {
if (options.find("multi") != std::string::npos) {
// Later, make it possible to add functions here.
rpc::Command* command = new rpc::CommandFunctionList();
rpc::Command::any_slot slot = &rpc::CommandFunctionList::call;
@@ -115,7 +115,8 @@ system_method_insert(__UNUSED rpc::target_type target, const torrent::Object& ra
} else if (options.find("value") != std::string::npos ||
options.find("bool") != std::string::npos ||
options.find("string") != std::string::npos) {
options.find("string") != std::string::npos ||
options.find("list") != std::string::npos) {
rpc::CommandVariable *command;
rpc::Command::cleaned_slot getSlot;
rpc::Command::cleaned_slot setSlot;
@@ -128,10 +129,15 @@ system_method_insert(__UNUSED rpc::target_type target, const torrent::Object& ra
command = new rpc::CommandVariable(int64_t());
getSlot = &rpc::CommandVariable::get_bool;
setSlot = &rpc::CommandVariable::set_bool;
} else {
} else if (options.find("string") != std::string::npos) {
command = new rpc::CommandVariable(std::string());
getSlot = &rpc::CommandVariable::get_string;
setSlot = &rpc::CommandVariable::set_string;
} else {
// command = new rpc::CommandVariable(torrent::Object::create_list());
// getSlot = &rpc::CommandVariable::get_string;
// setSlot = &rpc::CommandVariable::set_string;
throw torrent::input_error("No support for 'list' variable type.");
}
// Only allow deletion after adding a flag that ensures we search
@@ -140,7 +146,9 @@ system_method_insert(__UNUSED rpc::target_type target, const torrent::Object& ra
flags &= ~rpc::CommandMap::flag_modifiable;
rpc::commands.insert_type(create_new_key<0>(rawKey, ""), command, getSlot, flags, NULL, NULL);
rpc::commands.insert_type(create_new_key<5>(rawKey, ".set"), command, setSlot, flags | rpc::CommandMap::flag_dont_delete, NULL, NULL);
if (options.find("static") == std::string::npos)
rpc::commands.insert_type(create_new_key<5>(rawKey, ".set"), command, setSlot, flags | rpc::CommandMap::flag_dont_delete, NULL, NULL);
if (++itrArgs != args.end())
(*setSlot)(command, NULL, *itrArgs);
+30 -33
View File
@@ -93,54 +93,52 @@ apply_on_state_change(const char* name, const torrent::Object& rawArgs) {
}
torrent::Object
apply_on_ratio(int action, const torrent::Object& rawArgs) {
const torrent::Object::list_type& args = rawArgs.as_list();
apply_on_ratio(const torrent::Object& rawArgs) {
const std::string& groupName = rawArgs.as_string();
if (args.empty())
throw torrent::input_error("Too few arguments.");
char buffer[32 + groupName.size()];
sprintf(buffer, "group.%s.view", groupName.c_str());
torrent::Object::list_const_iterator argItr = args.begin();
core::ViewManager::iterator viewItr = control->view_manager()->find(rpc::commands.call(buffer, rpc::make_target()).as_string());
if (viewItr == control->view_manager()->end())
throw torrent::input_error("Could not find view.");
char* bufferStart = buffer + sprintf(buffer, "group.%s.ratio.", groupName.c_str());
// first argument: minimum ratio to reach
// second argument: minimum upload amount to reach [optional]
// third argument: maximum ratio to reach [optional]
int64_t minRatio = rpc::convert_to_value(*argItr++);
int64_t minUpload = argItr != args.end() ? rpc::convert_to_value(*argItr++) : 0;
int64_t maxRatio = argItr != args.end() ? rpc::convert_to_value(*argItr++) : 0;
std::strcpy(bufferStart, "min");
int64_t minRatio = rpc::commands.call(buffer, rpc::make_target()).as_value();
std::strcpy(bufferStart, "max");
int64_t maxRatio = rpc::commands.call(buffer, rpc::make_target()).as_value();
std::strcpy(bufferStart, "upload");
int64_t minUpload = rpc::commands.call(buffer, rpc::make_target()).as_value();
core::DownloadList* downloadList = control->core()->download_list();
std::vector<core::Download*> downloads;
for (core::Manager::DListItr itr = downloadList->begin();
(itr = std::find_if(itr, downloadList->end(), std::mem_fun(&core::Download::is_seeding))) != downloadList->end(); ) {
core::Download* current = *itr++;
if (rpc::call_command_value("d.get_ignore_commands", rpc::make_target(current)) != 0)
for (core::View::iterator itr = (*viewItr)->begin_visible(), last = (*viewItr)->end_visible(); itr != last; itr++) {
if (rpc::call_command_value("d.get_ignore_commands", rpc::make_target(*itr)) != 0)
continue;
int64_t totalDone = current->download()->bytes_done();
int64_t totalUpload = current->download()->up_rate()->total();
rpc::parse_command_single(rpc::make_target(*itr), "print={Checked ratio of download.}");
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))
continue;
bool success = true;
downloads.push_back(*itr);
}
switch (action) {
// case core::DownloadList::SLOTS_CLOSE: success = downloadList->close_try(current); break;
// case core::DownloadList::SLOTS_STOP: success = downloadList->stop_try(current); break;
case core::DownloadList::D_SLOTS_CLOSE: rpc::parse_command_single(rpc::make_target(current), "d.try_close="); break;
case core::DownloadList::D_SLOTS_STOP: rpc::parse_command_single(rpc::make_target(current), "d.try_stop="); break;
default: success = false; break;
}
std::strcpy(bufferStart, "command");
if (!success)
continue;
rpc::call_command("d.set_ignore_commands", (int64_t)1, rpc::make_target(current));
for (torrent::Object::list_const_iterator itr2 = argItr; itr2 != args.end(); itr2++)
rpc::parse_command_object(rpc::make_target(current), *itr2);
for (std::vector<core::Download*>::iterator itr = downloads.begin(), last = downloads.end(); itr != last; itr++) {
rpc::commands.call("print", rpc::make_target(*itr), "Calling ratio command.");
rpc::commands.call_catch(buffer, rpc::make_target(*itr), torrent::Object(), "Ratio reached, but command failed: ");
}
return torrent::Object();
@@ -369,8 +367,7 @@ initialize_command_events() {
ADD_COMMAND_LIST("on_hash_removed", rak::bind_ptr_fn(&apply_on_state_change, "event.download.hash_removed"));
ADD_COMMAND_LIST("on_finished", rak::bind_ptr_fn(&apply_on_state_change, "event.download.finished"));
ADD_COMMAND_LIST("stop_on_ratio", rak::bind_ptr_fn(&apply_on_ratio, (int)core::DownloadList::D_SLOTS_STOP));
ADD_COMMAND_LIST("close_on_ratio", rak::bind_ptr_fn(&apply_on_ratio, (int)core::DownloadList::D_SLOTS_CLOSE));
ADD_COMMAND_STRING("on_ratio", rak::ptr_fn(&apply_on_ratio));
ADD_COMMAND_VOID("start_tied", &apply_start_tied);
ADD_COMMAND_VOID("stop_untied", &apply_stop_untied);
+29 -12
View File
@@ -181,19 +181,19 @@ main(int argc, char** argv) {
"system.method.insert = test.method.simple,simple,\"print=simple_test_,$argument.0=\"\n"
"system.method.insert = event.download.inserted,list\n"
"system.method.insert = event.download.inserted_new,list\n"
"system.method.insert = event.download.inserted_session,list\n"
"system.method.insert = event.download.erased,list\n"
"system.method.insert = event.download.opened,list\n"
"system.method.insert = event.download.closed,list\n"
"system.method.insert = event.download.resumed,list\n"
"system.method.insert = event.download.paused,list\n"
"system.method.insert = event.download.inserted,multi\n"
"system.method.insert = event.download.inserted_new,multi\n"
"system.method.insert = event.download.inserted_session,multi\n"
"system.method.insert = event.download.erased,multi\n"
"system.method.insert = event.download.opened,multi\n"
"system.method.insert = event.download.closed,multi\n"
"system.method.insert = event.download.resumed,multi\n"
"system.method.insert = event.download.paused,multi\n"
"system.method.insert = event.download.finished,list\n"
"system.method.insert = event.download.hash_done,list\n"
"system.method.insert = event.download.hash_removed,list\n"
"system.method.insert = event.download.hash_queued,list\n"
"system.method.insert = event.download.finished,multi\n"
"system.method.insert = event.download.hash_done,multi\n"
"system.method.insert = event.download.hash_removed,multi\n"
"system.method.insert = event.download.hash_queued,multi\n"
"system.method.set_key = event.download.inserted, 1_connect_logs, d.initialize_logs=\n"
"system.method.set_key = event.download.inserted_new, 1_prepare, \"branch=d.get_state=,view.set_visible=started,view.set_visible=stopped ;d.save_session=\"\n"
@@ -202,6 +202,23 @@ main(int argc, char** argv) {
"system.method.set_key = event.download.erased, 0_download_list, ui.unfocus_download=\n"
"system.method.set_key = event.download.erased, 9_delete_tied, d.delete_tied=\n"
// Allow setting 'group.view' as constant, so that we can't
// modify the value. And look into the possibility of making
// 'const' use non-heap memory, as we know they can't be
// erased.
// TODO: Remember to ensure it doesn't get restarted by watch
// dir, etc. Set ignore commands, or something.
"system.method.insert = group.seeding.view,string|static|const,seeding\n"
"system.method.insert = group.seeding.ratio.enable ,simple,\"schedule=group.seeding.ratio,5,60,on_ratio=seeding\"\n"
"system.method.insert = group.seeding.ratio.disable,simple,\"schedule_remove=group.seeding.ratio\"\n"
"system.method.insert = group.seeding.ratio.command,simple|static,\"d.try_close= ;d.set_ignore_commands=1\"\n"
"system.method.insert = group.seeding.ratio.min,value,200\n"
"system.method.insert = group.seeding.ratio.max,value,300\n"
"system.method.insert = group.seeding.ratio.upload,value,20M\n"
"set_name = \"$cat=$system.hostname=,:,$system.pid=\"\n"
// Currently not doing any sorting on main.