#include "config.h" #include <torrent/runtime/memory_manager.h>#include <torrent/utils/log.h> #include "command_helpers.h"#include "control.h"#include "core/download.h"#include "core/manager.h"#include "rpc/parse_commands.h"#include "rpc/lua.h"#include "rpc/scgi.h"#include "session/session_manager.h" typedef torrent::ChunkManager CM_t;typedef torrent::FileManager FM_t; torrent::Objectapply_pieces_stats_total_size() { uint64_t size = 0; for (const auto& d : *control->core()->download_list()) if (d->is_active()) size += d->file_list()->size_bytes(); return size;} inline torrent::Object::list_const_iteratorpost_increment(torrent::Object::list_const_iterator& itr, const torrent::Object::list_const_iterator& last) { if (itr == last) throw torrent::input_error("Invalid number of arguments."); return itr++;} inline const std::string&check_name(const std::string& str) { auto itr = std::find_if(str.begin(), str.end(), [](char c) { return !std::isalnum(c, std::locale::classic()) && c != '_'; }); if (itr != str.end()) throw torrent::input_error("Invalid characters found in name."); return str;} torrent::Objectgroup_insert(const torrent::Object::list_type& args) { torrent::Object::list_const_iterator itr = args.begin(); torrent::Object::list_const_iterator last = args.end(); const std::string& name = check_name(post_increment(itr, last)->as_string()); const std::string& view = check_name(post_increment(itr, last)->as_string()); rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.enable", "simple", "schedule=group." + name + ".ratio,5,60,on_ratio=" + name)); rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.disable", "simple", "schedule.remove=group." + name + ".ratio")); rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.command", "simple", "d.try_close= ;d.ignore_commands.set=1")); rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".view", "string", view)); rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.min", "value", (int64_t)200)); rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.max", "value", (int64_t)300)); rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.upload", "value", (int64_t)20 << 20)); rpc::rpc.mark_safe("group." + name + ".view"); rpc::rpc.mark_safe("group." + name + ".view.set"); rpc::rpc.mark_safe("group." + name + ".ratio.min"); rpc::rpc.mark_safe("group." + name + ".ratio.min.set"); rpc::rpc.mark_safe("group." + name + ".ratio.max"); rpc::rpc.mark_safe("group." + name + ".ratio.max.set"); rpc::rpc.mark_safe("group." + name + ".ratio.upload"); rpc::rpc.mark_safe("group." + name + ".ratio.upload.set"); return name;} voidinitialize_command_local() { core::DownloadList* dList = control->core()->download_list(); CMD_ANY ("pieces.sync.always_safe", [](auto, auto) { return torrent::runtime::memory_manager()->safe_sync(); }); CMD_ANY_VALUE_V ("pieces.sync.always_safe.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_safe_sync(value); }); CMD_ANY ("pieces.sync.safe_free_diskspace", [](auto, auto) { return torrent::runtime::memory_manager()->sync_safe_free_diskspace(); }); CMD_ANY ("pieces.sync.timeout", [](auto, auto) { return torrent::runtime::memory_manager()->timeout_sync().count(); }); CMD_ANY_VALUE_V ("pieces.sync.timeout.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_timeout_sync(value); }); CMD_ANY ("pieces.sync.timeout_safe", [](auto, auto) { return 0; }); CMD_ANY_VALUE_V ("pieces.sync.timeout_safe.set", [](auto, auto) { lt_log_print(torrent::LOG_WARN, "pieces.sync.timeout_safe.set is no longer supported and does nothing."); }); CMD_ANY ("pieces.sync.queue_size", [](auto, auto) { return torrent::runtime::memory_manager()->sync_queue_block_count(); }); CMD_ANY ("pieces.preload.type", [](auto, auto) { return torrent::runtime::memory_manager()->preload_type(); }); CMD_ANY_VALUE_V ("pieces.preload.type.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_type(value); }); CMD_ANY ("pieces.preload.min_size", [](auto, auto) { return torrent::runtime::memory_manager()->preload_min_size(); }); CMD_ANY_VALUE_V ("pieces.preload.min_size.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_min_size(value); }); CMD_ANY ("pieces.preload.min_rate", [](auto, auto) { return torrent::runtime::memory_manager()->preload_required_rate(); }); CMD_ANY_VALUE_V ("pieces.preload.min_rate.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_required_rate(value); }); CMD_ANY ("pieces.stats_preloaded", [](auto, auto) { return torrent::runtime::memory_manager()->stats_preloaded(); }); CMD_ANY ("pieces.stats_not_preloaded", [](auto, auto) { return torrent::runtime::memory_manager()->stats_not_preloaded(); }); CMD_ANY ("pieces.stats.total_size", std::bind(&apply_pieces_stats_total_size)); CMD_ANY ("pieces.memory.current", [](auto, auto) { return torrent::runtime::memory_manager()->memory_usage(); }); CMD_ANY ("pieces.memory.sync_queue", [](auto, auto) { return torrent::runtime::memory_manager()->sync_queue_memory_usage(); }); CMD_ANY ("pieces.memory.block_count", [](auto, auto) { return torrent::runtime::memory_manager()->memory_block_count(); }); CMD_ANY ("pieces.memory.max", [](auto, auto) { return torrent::runtime::memory_manager()->max_memory_usage(); }); CMD_ANY_VALUE_V ("pieces.memory.max.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_max_memory_usage(value); }); CMD_ANY ("pieces.hash.queue_size", std::bind(&torrent::main_thread::hash_queue_size)); CMD_VAR_BOOL ("pieces.hash.on_completion", true); CMD_VAR_STRING ("directory.default", "./"); CMD_ANY ("directory.default.realpath.or_empty", [](auto, auto) { return resolve_path(rpc::call_command_string("directory.default")); }); CMD_ANY ("directory.default.realpath.or_throw", [](auto, auto) { return resolve_path_or_throw(rpc::call_command_string("directory.default")); }); CMD_VAR_STRING ("session.name", ""); CMD_ANY ("session.path", [](auto, auto) { return session_thread::manager()->path(); }); CMD_ANY ("session.path.realpath.or_empty", [](auto, auto) { return resolve_path(session_thread::manager()->path()); }); CMD_ANY ("session.path.realpath.or_throw", [](auto, auto) { return resolve_path_or_throw(session_thread::manager()->path()); }); CMD_ANY_STRING_V("session.path.set", [](auto, auto& str) { return session_thread::manager()->set_path(str); }); CMD_ANY ("session.use_lock", [](auto, auto) { return session_thread::manager()->use_lock(); }); CMD_ANY_VALUE_V ("session.use_lock.set", [](auto, auto& value) { return session_thread::manager()->set_use_lock(value); }); CMD_VAR_BOOL ("session.on_completion", true); CMD_ANY_V ("session.save", [dList](auto, auto) { return dList->session_save(); }); CMD_ANY ("magnet.path", [](auto, auto) { return control->core()->magnet_path(); }); CMD_ANY_STRING_V("magnet.path.set", [](auto, auto& str) { return control->core()->set_magnet_path(str); }); #ifdef HAVE_LUA rpc::LuaEngine* lua_engine = control->lua_engine(); CMD_ANY ("lua.execute", std::bind(&rpc::execute_lua, lua_engine, std::placeholders::_1, std::placeholders::_2, 0)); CMD_ANY ("lua.execute.str", std::bind(&rpc::execute_lua, lua_engine, std::placeholders::_1, std::placeholders::_2, rpc::LuaEngine::flag_string));#endif #define CMD_EXECUTE(key, flags) \ CMD_ANY(key, std::bind(&rpc::ExecFile::execute_object, &rpc::execFile, std::placeholders::_2, flags)); CMD_EXECUTE ("execute", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw); CMD_EXECUTE ("execute.throw", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw); CMD_EXECUTE ("execute.throw.bg", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw | rpc::ExecFile::flag_background); CMD_EXECUTE ("execute.nothrow", rpc::ExecFile::flag_expand_tilde); CMD_EXECUTE ("execute.nothrow.bg", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_background); CMD_EXECUTE ("execute.raw", rpc::ExecFile::flag_throw); CMD_EXECUTE ("execute.raw.bg", rpc::ExecFile::flag_throw | rpc::ExecFile::flag_background); CMD_EXECUTE ("execute.raw_nothrow", 0); CMD_EXECUTE ("execute.raw_nothrow.bg", rpc::ExecFile::flag_background); CMD_EXECUTE ("execute.capture", rpc::ExecFile::flag_throw | rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture); CMD_EXECUTE ("execute.capture_nothrow", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture); // TODO: Convert to new command types: *rpc::command_base::argument(0) = "placeholder.0"; *rpc::command_base::argument(1) = "placeholder.1"; *rpc::command_base::argument(2) = "placeholder.2"; *rpc::command_base::argument(3) = "placeholder.3"; CMD_ANY_P("argument.0", std::bind(&rpc::command_base::argument_ref, 0)); CMD_ANY_P("argument.1", std::bind(&rpc::command_base::argument_ref, 1)); CMD_ANY_P("argument.2", std::bind(&rpc::command_base::argument_ref, 2)); CMD_ANY_P("argument.3", std::bind(&rpc::command_base::argument_ref, 3)); CMD_ANY_LIST ("group.insert", std::bind(&group_insert, std::placeholders::_2)); rpc::rpc.mark_safe("directory.default"); rpc::rpc.mark_safe("session.path"); rpc::rpc.mark_safe("session.path.realpath.or_empty"); rpc::rpc.mark_safe("session.path.realpath.or_throw"); rpc::rpc.mark_safe("directory.default.realpath.or_empty"); rpc::rpc.mark_safe("directory.default.realpath.or_throw"); rpc::rpc.mark_safe("session.use_lock"); rpc::rpc.mark_safe("session.on_completion"); rpc::rpc.mark_safe("pieces.sync.always_safe"); rpc::rpc.mark_safe("pieces.sync.timeout"); rpc::rpc.mark_safe("pieces.sync.timeout_safe"); rpc::rpc.mark_safe("pieces.preload.type"); rpc::rpc.mark_safe("pieces.preload.min_size"); rpc::rpc.mark_safe("pieces.preload.min_rate"); rpc::rpc.mark_safe("pieces.memory.max"); rpc::rpc.mark_safe("pieces.hash.on_completion");}
#include "config.h"
#include <torrent/runtime/memory_manager.h>
#include <torrent/utils/log.h>
#include "command_helpers.h"
#include "control.h"
#include "core/download.h"
#include "core/manager.h"
#include "rpc/parse_commands.h"
#include "rpc/lua.h"
#include "rpc/scgi.h"
#include "session/session_manager.h"
typedef torrent::ChunkManager CM_t;
typedef torrent::FileManager FM_t;
torrent::Object
apply_pieces_stats_total_size() {
uint64_t size = 0;
for (const auto& d : *control->core()->download_list())
if (d->is_active())
size += d->file_list()->size_bytes();
return size;
}
inline torrent::Object::list_const_iterator
post_increment(torrent::Object::list_const_iterator& itr, const torrent::Object::list_const_iterator& last) {
if (itr == last)
throw torrent::input_error("Invalid number of arguments.");
return itr++;
}
inline const std::string&
check_name(const std::string& str) {
auto itr = std::find_if(str.begin(), str.end(), [](char c) {
return !std::isalnum(c, std::locale::classic()) && c != '_';
});
if (itr != str.end())
throw torrent::input_error("Invalid characters found in name.");
return str;
}
torrent::Object
group_insert(const torrent::Object::list_type& args) {
torrent::Object::list_const_iterator itr = args.begin();
torrent::Object::list_const_iterator last = args.end();
const std::string& name = check_name(post_increment(itr, last)->as_string());
const std::string& view = check_name(post_increment(itr, last)->as_string());
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.enable", "simple",
"schedule=group." + name + ".ratio,5,60,on_ratio=" + name));
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.disable", "simple",
"schedule.remove=group." + name + ".ratio"));
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.command", "simple",
"d.try_close= ;d.ignore_commands.set=1"));
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".view", "string", view));
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.min", "value", (int64_t)200));
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.max", "value", (int64_t)300));
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.upload", "value", (int64_t)20 << 20));
rpc::rpc.mark_safe("group." + name + ".view");
rpc::rpc.mark_safe("group." + name + ".view.set");
rpc::rpc.mark_safe("group." + name + ".ratio.min");
rpc::rpc.mark_safe("group." + name + ".ratio.min.set");
rpc::rpc.mark_safe("group." + name + ".ratio.max");
rpc::rpc.mark_safe("group." + name + ".ratio.max.set");
rpc::rpc.mark_safe("group." + name + ".ratio.upload");
rpc::rpc.mark_safe("group." + name + ".ratio.upload.set");
return name;
}
void
initialize_command_local() {
core::DownloadList* dList = control->core()->download_list();
CMD_ANY ("pieces.sync.always_safe", [](auto, auto) { return torrent::runtime::memory_manager()->safe_sync(); });
CMD_ANY_VALUE_V ("pieces.sync.always_safe.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_safe_sync(value); });
CMD_ANY ("pieces.sync.safe_free_diskspace", [](auto, auto) { return torrent::runtime::memory_manager()->sync_safe_free_diskspace(); });
CMD_ANY ("pieces.sync.timeout", [](auto, auto) { return torrent::runtime::memory_manager()->timeout_sync().count(); });
CMD_ANY_VALUE_V ("pieces.sync.timeout.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_timeout_sync(value); });
CMD_ANY ("pieces.sync.timeout_safe", [](auto, auto) { return 0; });
CMD_ANY_VALUE_V ("pieces.sync.timeout_safe.set", [](auto, auto) {
lt_log_print(torrent::LOG_WARN, "pieces.sync.timeout_safe.set is no longer supported and does nothing.");
});
CMD_ANY ("pieces.sync.queue_size", [](auto, auto) { return torrent::runtime::memory_manager()->sync_queue_block_count(); });
CMD_ANY ("pieces.preload.type", [](auto, auto) { return torrent::runtime::memory_manager()->preload_type(); });
CMD_ANY_VALUE_V ("pieces.preload.type.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_type(value); });
CMD_ANY ("pieces.preload.min_size", [](auto, auto) { return torrent::runtime::memory_manager()->preload_min_size(); });
CMD_ANY_VALUE_V ("pieces.preload.min_size.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_min_size(value); });
CMD_ANY ("pieces.preload.min_rate", [](auto, auto) { return torrent::runtime::memory_manager()->preload_required_rate(); });
CMD_ANY_VALUE_V ("pieces.preload.min_rate.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_required_rate(value); });
CMD_ANY ("pieces.stats_preloaded", [](auto, auto) { return torrent::runtime::memory_manager()->stats_preloaded(); });
CMD_ANY ("pieces.stats_not_preloaded", [](auto, auto) { return torrent::runtime::memory_manager()->stats_not_preloaded(); });
CMD_ANY ("pieces.stats.total_size", std::bind(&apply_pieces_stats_total_size));
CMD_ANY ("pieces.memory.current", [](auto, auto) { return torrent::runtime::memory_manager()->memory_usage(); });
CMD_ANY ("pieces.memory.sync_queue", [](auto, auto) { return torrent::runtime::memory_manager()->sync_queue_memory_usage(); });
CMD_ANY ("pieces.memory.block_count", [](auto, auto) { return torrent::runtime::memory_manager()->memory_block_count(); });
CMD_ANY ("pieces.memory.max", [](auto, auto) { return torrent::runtime::memory_manager()->max_memory_usage(); });
CMD_ANY_VALUE_V ("pieces.memory.max.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_max_memory_usage(value); });
CMD_ANY ("pieces.hash.queue_size", std::bind(&torrent::main_thread::hash_queue_size));
CMD_VAR_BOOL ("pieces.hash.on_completion", true);
CMD_VAR_STRING ("directory.default", "./");
CMD_ANY ("directory.default.realpath.or_empty", [](auto, auto) { return resolve_path(rpc::call_command_string("directory.default")); });
CMD_ANY ("directory.default.realpath.or_throw", [](auto, auto) { return resolve_path_or_throw(rpc::call_command_string("directory.default")); });
CMD_VAR_STRING ("session.name", "");
CMD_ANY ("session.path", [](auto, auto) { return session_thread::manager()->path(); });
CMD_ANY ("session.path.realpath.or_empty", [](auto, auto) { return resolve_path(session_thread::manager()->path()); });
CMD_ANY ("session.path.realpath.or_throw", [](auto, auto) { return resolve_path_or_throw(session_thread::manager()->path()); });
CMD_ANY_STRING_V("session.path.set", [](auto, auto& str) { return session_thread::manager()->set_path(str); });
CMD_ANY ("session.use_lock", [](auto, auto) { return session_thread::manager()->use_lock(); });
CMD_ANY_VALUE_V ("session.use_lock.set", [](auto, auto& value) { return session_thread::manager()->set_use_lock(value); });
CMD_VAR_BOOL ("session.on_completion", true);
CMD_ANY_V ("session.save", [dList](auto, auto) { return dList->session_save(); });
CMD_ANY ("magnet.path", [](auto, auto) { return control->core()->magnet_path(); });
CMD_ANY_STRING_V("magnet.path.set", [](auto, auto& str) { return control->core()->set_magnet_path(str); });
#ifdef HAVE_LUA
rpc::LuaEngine* lua_engine = control->lua_engine();
CMD_ANY ("lua.execute", std::bind(&rpc::execute_lua, lua_engine, std::placeholders::_1, std::placeholders::_2, 0));
CMD_ANY ("lua.execute.str", std::bind(&rpc::execute_lua, lua_engine, std::placeholders::_1, std::placeholders::_2, rpc::LuaEngine::flag_string));
#endif
#define CMD_EXECUTE(key, flags) \
CMD_ANY(key, std::bind(&rpc::ExecFile::execute_object, &rpc::execFile, std::placeholders::_2, flags));
CMD_EXECUTE ("execute", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw);
CMD_EXECUTE ("execute.throw", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw);
CMD_EXECUTE ("execute.throw.bg", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw | rpc::ExecFile::flag_background);
CMD_EXECUTE ("execute.nothrow", rpc::ExecFile::flag_expand_tilde);
CMD_EXECUTE ("execute.nothrow.bg", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_background);
CMD_EXECUTE ("execute.raw", rpc::ExecFile::flag_throw);
CMD_EXECUTE ("execute.raw.bg", rpc::ExecFile::flag_throw | rpc::ExecFile::flag_background);
CMD_EXECUTE ("execute.raw_nothrow", 0);
CMD_EXECUTE ("execute.raw_nothrow.bg", rpc::ExecFile::flag_background);
CMD_EXECUTE ("execute.capture", rpc::ExecFile::flag_throw | rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture);
CMD_EXECUTE ("execute.capture_nothrow", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture);
// TODO: Convert to new command types:
*rpc::command_base::argument(0) = "placeholder.0";
*rpc::command_base::argument(1) = "placeholder.1";
*rpc::command_base::argument(2) = "placeholder.2";
*rpc::command_base::argument(3) = "placeholder.3";
CMD_ANY_P("argument.0", std::bind(&rpc::command_base::argument_ref, 0));
CMD_ANY_P("argument.1", std::bind(&rpc::command_base::argument_ref, 1));
CMD_ANY_P("argument.2", std::bind(&rpc::command_base::argument_ref, 2));
CMD_ANY_P("argument.3", std::bind(&rpc::command_base::argument_ref, 3));
CMD_ANY_LIST ("group.insert", std::bind(&group_insert, std::placeholders::_2));
rpc::rpc.mark_safe("directory.default");
rpc::rpc.mark_safe("session.path");
rpc::rpc.mark_safe("session.path.realpath.or_empty");
rpc::rpc.mark_safe("session.path.realpath.or_throw");
rpc::rpc.mark_safe("directory.default.realpath.or_empty");
rpc::rpc.mark_safe("directory.default.realpath.or_throw");
rpc::rpc.mark_safe("session.use_lock");
rpc::rpc.mark_safe("session.on_completion");
rpc::rpc.mark_safe("pieces.sync.always_safe");
rpc::rpc.mark_safe("pieces.sync.timeout");
rpc::rpc.mark_safe("pieces.sync.timeout_safe");
rpc::rpc.mark_safe("pieces.preload.type");
rpc::rpc.mark_safe("pieces.preload.min_size");
rpc::rpc.mark_safe("pieces.preload.min_rate");
rpc::rpc.mark_safe("pieces.memory.max");
rpc::rpc.mark_safe("pieces.hash.on_completion");
}