From 3d166de17505bb098d1f021f72c2be9b57ec0735 Mon Sep 17 00:00:00 2001 From: Henrik Jonsson Date: Thu, 4 Sep 2014 12:50:47 +0200 Subject: [PATCH 01/46] Also mentions that ^o changes destination dir in -help output, like http://libtorrent.rakshasa.no/rtorrent/rtorrent.1.html does --- src/main.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cc b/src/main.cc index 5f4e2c33..caa606dc 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1017,6 +1017,7 @@ print_help() { std::cout << " ^s Start torrent" << std::endl; std::cout << " ^d Stop torrent or delete a stopped torrent" << std::endl; std::cout << " ^r Manually initiate hash checking" << std::endl; + std::cout << " ^o Change the destination directory of the download. The torrent must be closed." << std::endl; std::cout << " ^q Initiate shutdown or skip shutdown process" << std::endl; std::cout << " a,s,d,z,x,c Adjust upload throttle" << std::endl; std::cout << " A,S,D,Z,X,C Adjust download throttle" << std::endl; From b5bff0cb9c835bc49c78630d47a1bdc88d44d915 Mon Sep 17 00:00:00 2001 From: Henrik Jonsson Date: Thu, 4 Sep 2014 12:50:47 +0200 Subject: [PATCH 02/46] Also mentions that ^o changes destination dir in -help output, like http://libtorrent.rakshasa.no/rtorrent/rtorrent.1.html does --- src/main.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cc b/src/main.cc index 5f4e2c33..caa606dc 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1017,6 +1017,7 @@ print_help() { std::cout << " ^s Start torrent" << std::endl; std::cout << " ^d Stop torrent or delete a stopped torrent" << std::endl; std::cout << " ^r Manually initiate hash checking" << std::endl; + std::cout << " ^o Change the destination directory of the download. The torrent must be closed." << std::endl; std::cout << " ^q Initiate shutdown or skip shutdown process" << std::endl; std::cout << " a,s,d,z,x,c Adjust upload throttle" << std::endl; std::cout << " A,S,D,Z,X,C Adjust download throttle" << std::endl; From 3cf9cffe68dbbe7a6a6db485fb1b87213798e764 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Tue, 4 Nov 2014 19:48:55 +0900 Subject: [PATCH 03/46] Moved logging commands to a separate file. --- src/Makefile.am | 1 + src/command_helpers.cc | 2 + src/command_local.cc | 96 ------------------------- src/command_logging.cc | 155 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 158 insertions(+), 96 deletions(-) create mode 100644 src/command_logging.cc diff --git a/src/Makefile.am b/src/Makefile.am index e0808137..16ead459 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,7 @@ libsub_root_a_SOURCES = \ command_helpers.h \ command_groups.cc \ command_local.cc \ + command_logging.cc \ command_network.cc \ command_peer.cc \ command_throttle.cc \ diff --git a/src/command_helpers.cc b/src/command_helpers.cc index 59892f13..54c0b35e 100644 --- a/src/command_helpers.cc +++ b/src/command_helpers.cc @@ -49,6 +49,7 @@ void initialize_command_file(); void initialize_command_ip(); void initialize_command_peer(); void initialize_command_local(); +void initialize_command_logging(); void initialize_command_network(); void initialize_command_groups(); void initialize_command_throttle(); @@ -63,6 +64,7 @@ initialize_commands() { initialize_command_network(); initialize_command_groups(); initialize_command_local(); + initialize_command_logging(); initialize_command_ui(); initialize_command_download(); initialize_command_file(); diff --git a/src/command_local.cc b/src/command_local.cc index ea7822c1..5275747a 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -48,7 +48,6 @@ #include #include #include -#include #include #include "core/download.h" @@ -79,42 +78,6 @@ apply_pieces_stats_total_size() { return size; } -torrent::Object -apply_log(const torrent::Object::string_type& arg, int logType) { - if (rpc::execFile.log_fd() != -1) { - switch (logType) { - case 0: ::close(rpc::execFile.log_fd()); rpc::execFile.set_log_fd(-1); break; - case 1: -// if (control->scgi()) { -// ::close(control->scgi()->log_fd()); -// control->scgi()->set_log_fd(-1); -// } - break; - default: break; - } - } - - if (!arg.empty()) { - int logFd = open(rak::path_expand(arg).c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644); - - if (logFd < 0) - throw torrent::input_error("Could not open execute log file."); - - switch (logType) { - case 0: rpc::execFile.set_log_fd(logFd); break; -// case 1: if (control->scgi()) control->scgi()->set_log_fd(logFd); break; - default: break; - } - - control->core()->push_log("Opened log file."); - - } else { - control->core()->push_log("Closed log file."); - } - - return torrent::Object(); -} - torrent::Object system_hostname() { char buffer[1024]; @@ -212,27 +175,6 @@ group_insert(const torrent::Object::list_type& args) { return name; } -torrent::Object -log_vmmap_dump(const std::string& str) { - core::DownloadList* d_list = control->core()->download_list(); - std::vector all_mappings; - - for (core::DownloadList::iterator itr = d_list->begin(), last = d_list->end(); itr != last; itr++) { - std::vector tmp_mappings = torrent::chunk_list_mapping((*itr)->download()); - - all_mappings.insert(all_mappings.end(), tmp_mappings.begin(), tmp_mappings.end()); - } - - FILE* log_file = fopen(str.c_str(), "w"); - - for (std::vector::iterator itr = all_mappings.begin(), last = all_mappings.end(); itr != last; itr++) { - fprintf(log_file, "%8p-%8p [%5llxk]\n", itr->ptr, (char*)itr->ptr + itr->length, (long long unsigned int)(itr->length / 1024)); - } - - fclose(log_file); - return torrent::Object(); -} - static const int file_print_use_space = 0x1; static const int file_print_delim_space = 0x2; @@ -277,36 +219,6 @@ cmd_file_append(const torrent::Object::list_type& args) { return torrent::Object(); } -torrent::Object -apply_log_open_file(const torrent::Object::list_type& args) { - if (args.size() != 2) - throw torrent::input_error("Invalid number of arguments."); - - torrent::log_open_file_output(args.front().as_string().c_str(), - rak::path_expand(args.back().as_string()).c_str()); - return torrent::Object(); -} - -torrent::Object -apply_log_open_gz_file(const torrent::Object::list_type& args) { - if (args.size() != 2) - throw torrent::input_error("Invalid number of arguments."); - - torrent::log_open_gz_file_output(args.front().as_string().c_str(), - rak::path_expand(args.back().as_string()).c_str()); - return torrent::Object(); -} - -torrent::Object -apply_log_add_output(const torrent::Object::list_type& args) { - if (args.size() != 2) - throw torrent::input_error("Invalid number of arguments."); - - torrent::log_add_group_output(torrent::option_find_string(torrent::OPTION_LOG_GROUP, args.front().as_string().c_str()), - args.back().as_string().c_str()); - return torrent::Object(); -} - void initialize_command_local() { torrent::ChunkManager* chunkManager = torrent::chunk_manager(); @@ -401,14 +313,6 @@ initialize_command_local() { CMD2_EXECUTE ("execute.capture", rpc::ExecFile::flag_throw | rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture); CMD2_EXECUTE ("execute.capture_nothrow", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture); - CMD2_ANY_LIST ("log.open_file", std::bind(&apply_log_open_file, std::placeholders::_2)); - CMD2_ANY_LIST ("log.open_gz_file", std::bind(&apply_log_open_gz_file, std::placeholders::_2)); - CMD2_ANY_LIST ("log.add_output", std::bind(&apply_log_add_output, std::placeholders::_2)); - - CMD2_ANY_STRING ("log.execute", std::bind(&apply_log, std::placeholders::_2, 0)); - CMD2_ANY_STRING ("log.vmmap.dump", std::bind(&log_vmmap_dump, std::placeholders::_2)); - CMD2_ANY_STRING_V("log.xmlrpc", std::bind(&ThreadWorker::set_xmlrpc_log, worker_thread, std::placeholders::_2)); - CMD2_ANY_LIST ("file.append", std::bind(&cmd_file_append, std::placeholders::_2)); // TODO: Convert to new command types: diff --git a/src/command_logging.cc b/src/command_logging.cc new file mode 100644 index 00000000..e84d1264 --- /dev/null +++ b/src/command_logging.cc @@ -0,0 +1,155 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2011, Jari Sundell +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations +// including the two. +// +// You must obey the GNU General Public License in all respects for +// all of the code used other than OpenSSL. If you modify file(s) +// with this exception, you may extend this exception to your version +// of the file(s), but you are not obligated to do so. If you do not +// wish to do so, delete this exception statement from your version. +// If you delete this exception statement from all source files in the +// program, then also delete it here. +// +// Contact: Jari Sundell +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "core/download.h" +#include "core/download_list.h" +#include "core/manager.h" +#include "rak/path.h" +#include "rpc/parse_commands.h" + +#include "globals.h" +#include "control.h" +#include "command_helpers.h" + +torrent::Object +apply_log_open_file(const torrent::Object::list_type& args) { + if (args.size() != 2) + throw torrent::input_error("Invalid number of arguments."); + + torrent::log_open_file_output(args.front().as_string().c_str(), + rak::path_expand(args.back().as_string()).c_str()); + return torrent::Object(); +} + +torrent::Object +apply_log_open_gz_file(const torrent::Object::list_type& args) { + if (args.size() != 2) + throw torrent::input_error("Invalid number of arguments."); + + torrent::log_open_gz_file_output(args.front().as_string().c_str(), + rak::path_expand(args.back().as_string()).c_str()); + return torrent::Object(); +} + +torrent::Object +apply_log_add_output(const torrent::Object::list_type& args) { + if (args.size() != 2) + throw torrent::input_error("Invalid number of arguments."); + + torrent::log_add_group_output(torrent::option_find_string(torrent::OPTION_LOG_GROUP, args.front().as_string().c_str()), + args.back().as_string().c_str()); + return torrent::Object(); +} + +// TODO: Deprecated. +torrent::Object +apply_log(const torrent::Object::string_type& arg, int logType) { + if (rpc::execFile.log_fd() != -1) { + switch (logType) { + case 0: ::close(rpc::execFile.log_fd()); rpc::execFile.set_log_fd(-1); break; + case 1: +// if (control->scgi()) { +// ::close(control->scgi()->log_fd()); +// control->scgi()->set_log_fd(-1); +// } + break; + default: break; + } + } + + if (!arg.empty()) { + int logFd = open(rak::path_expand(arg).c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644); + + if (logFd < 0) + throw torrent::input_error("Could not open execute log file."); + + switch (logType) { + case 0: rpc::execFile.set_log_fd(logFd); break; +// case 1: if (control->scgi()) control->scgi()->set_log_fd(logFd); break; + default: break; + } + + control->core()->push_log("Opened log file."); + + } else { + control->core()->push_log("Closed log file."); + } + + return torrent::Object(); +} + +torrent::Object +log_vmmap_dump(const std::string& str) { + core::DownloadList* d_list = control->core()->download_list(); + std::vector all_mappings; + + for (core::DownloadList::iterator itr = d_list->begin(), last = d_list->end(); itr != last; itr++) { + std::vector tmp_mappings = torrent::chunk_list_mapping((*itr)->download()); + + all_mappings.insert(all_mappings.end(), tmp_mappings.begin(), tmp_mappings.end()); + } + + FILE* log_file = fopen(str.c_str(), "w"); + + for (std::vector::iterator itr = all_mappings.begin(), last = all_mappings.end(); itr != last; itr++) { + fprintf(log_file, "%8p-%8p [%5llxk]\n", itr->ptr, (char*)itr->ptr + itr->length, (long long unsigned int)(itr->length / 1024)); + } + + fclose(log_file); + return torrent::Object(); +} + +void +initialize_command_logging() { + // CMD2_ANY_LIST ("log.open", std::bind(&apply_log_open, std::placeholders::_2)); + CMD2_ANY_LIST ("log.open_file", std::bind(&apply_log_open_file, std::placeholders::_2)); + CMD2_ANY_LIST ("log.open_gz_file", std::bind(&apply_log_open_gz_file, std::placeholders::_2)); + CMD2_ANY_LIST ("log.add_output", std::bind(&apply_log_add_output, std::placeholders::_2)); + + CMD2_ANY_STRING ("log.execute", std::bind(&apply_log, std::placeholders::_2, 0)); + CMD2_ANY_STRING ("log.vmmap.dump", std::bind(&log_vmmap_dump, std::placeholders::_2)); + CMD2_ANY_STRING_V("log.xmlrpc", std::bind(&ThreadWorker::set_xmlrpc_log, worker_thread, std::placeholders::_2)); +} From e3cc2c601dd90bf300f19e7e4977e3b6ad1d965d Mon Sep 17 00:00:00 2001 From: rakshasa Date: Tue, 4 Nov 2014 22:46:35 +0900 Subject: [PATCH 04/46] Use a generic function for logging and allow output groups to be appended. log.open_file = "instrumentation_memory.log", "/foo/instrumentation_memory.log", "instrumentation_memory", ... --- src/command_logging.cc | 44 +++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/command_logging.cc b/src/command_logging.cc index e84d1264..b1896f2f 100644 --- a/src/command_logging.cc +++ b/src/command_logging.cc @@ -54,23 +54,28 @@ #include "control.h" #include "command_helpers.h" -torrent::Object -apply_log_open_file(const torrent::Object::list_type& args) { - if (args.size() != 2) - throw torrent::input_error("Invalid number of arguments."); - - torrent::log_open_file_output(args.front().as_string().c_str(), - rak::path_expand(args.back().as_string()).c_str()); - return torrent::Object(); -} +static const int log_flag_use_gz = 0x1; torrent::Object -apply_log_open_gz_file(const torrent::Object::list_type& args) { - if (args.size() != 2) +apply_log_open_generic(int output_flags, const torrent::Object::list_type& args) { + if (args.size() < 2) throw torrent::input_error("Invalid number of arguments."); - torrent::log_open_gz_file_output(args.front().as_string().c_str(), - rak::path_expand(args.back().as_string()).c_str()); + torrent::Object::list_const_iterator itr = args.begin(); + + std::string output_id = (itr++)->as_string(); + std::string file_name = rak::path_expand((itr++)->as_string()); + + if ((output_flags & log_flag_use_gz)) + torrent::log_open_gz_file_output(output_id.c_str(), file_name.c_str()); + else + torrent::log_open_file_output(output_id.c_str(), file_name.c_str()); + + while (itr != args.end()) { + int log_group = torrent::option_find_string(torrent::OPTION_LOG_GROUP, (itr++)->as_string().c_str()); + torrent::log_add_group_output(log_group, output_id.c_str()); + } + return torrent::Object(); } @@ -79,8 +84,11 @@ apply_log_add_output(const torrent::Object::list_type& args) { if (args.size() != 2) throw torrent::input_error("Invalid number of arguments."); - torrent::log_add_group_output(torrent::option_find_string(torrent::OPTION_LOG_GROUP, args.front().as_string().c_str()), - args.back().as_string().c_str()); + int log_group = torrent::option_find_string(torrent::OPTION_LOG_GROUP, args.front().as_string().c_str()); + std::string output_id = args.back().as_string().c_str(); + + torrent::log_add_group_output(log_group, output_id.c_str()); + return torrent::Object(); } @@ -144,9 +152,9 @@ log_vmmap_dump(const std::string& str) { void initialize_command_logging() { - // CMD2_ANY_LIST ("log.open", std::bind(&apply_log_open, std::placeholders::_2)); - CMD2_ANY_LIST ("log.open_file", std::bind(&apply_log_open_file, std::placeholders::_2)); - CMD2_ANY_LIST ("log.open_gz_file", std::bind(&apply_log_open_gz_file, std::placeholders::_2)); + CMD2_ANY_LIST ("log.open_file", std::bind(&apply_log_open_generic, 0, std::placeholders::_2)); + CMD2_ANY_LIST ("log.open_gz_file", std::bind(&apply_log_open_generic, log_flag_use_gz, std::placeholders::_2)); + CMD2_ANY_LIST ("log.add_output", std::bind(&apply_log_add_output, std::placeholders::_2)); CMD2_ANY_STRING ("log.execute", std::bind(&apply_log, std::placeholders::_2, 0)); From 7343e33a6a0d279179b304a380bf011f1c8be64a Mon Sep 17 00:00:00 2001 From: rakshasa Date: Tue, 4 Nov 2014 23:34:51 +0900 Subject: [PATCH 05/46] Added 'log.open_file_pid' and 'log.open_gz_file_pid' commands that appends the pid automatically. --- src/command_local.cc | 2 +- src/command_logging.cc | 34 +++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/command_local.cc b/src/command_local.cc index 5275747a..11ce6f10 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -238,7 +238,7 @@ initialize_command_local() { CMD2_VAR_STRING ("system.file.split_suffix", ".part"); CMD2_ANY ("system.file_status_cache.size", std::bind(&utils::FileStatusCache::size, - (utils::FileStatusCache::base_type*)control->core()->file_status_cache())); + (utils::FileStatusCache::base_type*)control->core()->file_status_cache())); CMD2_ANY_V ("system.file_status_cache.prune", std::bind(&utils::FileStatusCache::prune, control->core()->file_status_cache())); CMD2_VAR_BOOL ("file.prioritize_toc", 0); diff --git a/src/command_logging.cc b/src/command_logging.cc index b1896f2f..77648831 100644 --- a/src/command_logging.cc +++ b/src/command_logging.cc @@ -55,9 +55,16 @@ #include "command_helpers.h" static const int log_flag_use_gz = 0x1; +static const int log_flag_append_pid = 0x2; + +void +log_add_group_output_str(const char* group_name, const char* output_id) { + int log_group = torrent::option_find_string(torrent::OPTION_LOG_GROUP, group_name); + torrent::log_add_group_output(log_group, output_id); +} torrent::Object -apply_log_open_generic(int output_flags, const torrent::Object::list_type& args) { +apply_log_open(int output_flags, const torrent::Object::list_type& args) { if (args.size() < 2) throw torrent::input_error("Invalid number of arguments."); @@ -66,15 +73,20 @@ apply_log_open_generic(int output_flags, const torrent::Object::list_type& args) std::string output_id = (itr++)->as_string(); std::string file_name = rak::path_expand((itr++)->as_string()); + if ((output_flags & log_flag_append_pid)) { + char buffer[32]; + snprintf(buffer, 32, ".%li", (long)getpid()); + + file_name += buffer; + } + if ((output_flags & log_flag_use_gz)) torrent::log_open_gz_file_output(output_id.c_str(), file_name.c_str()); else torrent::log_open_file_output(output_id.c_str(), file_name.c_str()); - while (itr != args.end()) { - int log_group = torrent::option_find_string(torrent::OPTION_LOG_GROUP, (itr++)->as_string().c_str()); - torrent::log_add_group_output(log_group, output_id.c_str()); - } + while (itr != args.end()) + log_add_group_output_str((itr++)->as_string().c_str(), output_id.c_str()); return torrent::Object(); } @@ -84,10 +96,8 @@ apply_log_add_output(const torrent::Object::list_type& args) { if (args.size() != 2) throw torrent::input_error("Invalid number of arguments."); - int log_group = torrent::option_find_string(torrent::OPTION_LOG_GROUP, args.front().as_string().c_str()); - std::string output_id = args.back().as_string().c_str(); - - torrent::log_add_group_output(log_group, output_id.c_str()); + log_add_group_output_str(args.front().as_string().c_str(), + args.back().as_string().c_str()); return torrent::Object(); } @@ -152,8 +162,10 @@ log_vmmap_dump(const std::string& str) { void initialize_command_logging() { - CMD2_ANY_LIST ("log.open_file", std::bind(&apply_log_open_generic, 0, std::placeholders::_2)); - CMD2_ANY_LIST ("log.open_gz_file", std::bind(&apply_log_open_generic, log_flag_use_gz, std::placeholders::_2)); + CMD2_ANY_LIST ("log.open_file", std::bind(&apply_log_open, 0, std::placeholders::_2)); + CMD2_ANY_LIST ("log.open_gz_file", std::bind(&apply_log_open, log_flag_use_gz, std::placeholders::_2)); + CMD2_ANY_LIST ("log.open_file_pid", std::bind(&apply_log_open, log_flag_append_pid, std::placeholders::_2)); + CMD2_ANY_LIST ("log.open_gz_file_pid", std::bind(&apply_log_open, log_flag_append_pid | log_flag_use_gz, std::placeholders::_2)); CMD2_ANY_LIST ("log.add_output", std::bind(&apply_log_add_output, std::placeholders::_2)); From b5f2cfe3937a554ad51ebc18cb777c6510e3d4d0 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Sun, 9 Nov 2014 23:12:46 +0900 Subject: [PATCH 06/46] Renamed mincore instrumentation plotter. --- .../{mincore.sh => instrumentation_mincore.sh} | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) rename doc/plot/{mincore.sh => instrumentation_mincore.sh} (65%) diff --git a/doc/plot/mincore.sh b/doc/plot/instrumentation_mincore.sh similarity index 65% rename from doc/plot/mincore.sh rename to doc/plot/instrumentation_mincore.sh index 3dfaa630..37971a93 100755 --- a/doc/plot/mincore.sh +++ b/doc/plot/instrumentation_mincore.sh @@ -1,7 +1,7 @@ #/bin/bash gnuplot << EOF -set terminal png size 1024,768 enhanced +set terminal png size 1024 * 1, 768 enhanced set xdata time set timefmt "%s" set format x "%H:%M" @@ -14,17 +14,17 @@ set format y2 "%.0f" set output "output_$1_incore_sync.png" plot \ - "instrumentation_mincore.log.$1" using 1:6 title 'success' smooth sbezier with lines lw 4 axis x1y1,\ - "instrumentation_mincore.log.$1" using 1:7 title 'failed' smooth sbezier with lines lw 4 axis x1y1,\ - "instrumentation_mincore.log.$1" using 1:8 title 'not synced' smooth sbezier with lines lw 4 axis x1y2,\ - "instrumentation_mincore.log.$1" using 1:9 title 'not deallocated' smooth sbezier with lines lw 4 axis x1y2 + "instrumentation_mincore.log.$1" using 1:6 title 'success' with lines lw 4 axis x1y1,\ + "instrumentation_mincore.log.$1" using 1:7 title 'failed' with lines lw 4 axis x1y1,\ + "instrumentation_mincore.log.$1" using 1:8 title 'not synced' with lines lw 4 axis x1y2,\ + "instrumentation_mincore.log.$1" using 1:9 title 'not deallocated' with lines lw 4 axis x1y2 set format y "%.0g" set output "output_$1_incore_alloc.png" plot \ - "instrumentation_mincore.log.$1" using 1:12 title 'allocations' smooth sbezier with lines lw 2 axis x1y1,\ - "instrumentation_mincore.log.$1" using 1:13 title 'deallocations' smooth sbezier with lines lw 4 axis x1y1,\ - "instrumentation_mincore.log.$1" using 1:10 title 'alloc failed' smooth sbezier with lines lw 2 axis x1y2 + "instrumentation_mincore.log.$1" using 1:12 title 'allocations' with lines lw 2 axis x1y1,\ + "instrumentation_mincore.log.$1" using 1:13 title 'deallocations' with lines lw 4 axis x1y1,\ + "instrumentation_mincore.log.$1" using 1:10 title 'alloc failed' with lines lw 2 axis x1y2 EOF From 0d1dc8a3310e88d0619a7b8d9203a2f071374554 Mon Sep 17 00:00:00 2001 From: Lauri Tirkkonen Date: Sat, 3 Jan 2015 16:20:57 +0200 Subject: [PATCH 07/46] don't depend on dirent DT_DIR --- src/input/path_input.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/input/path_input.cc b/src/input/path_input.cc index fa8afdaa..caf1e17b 100644 --- a/src/input/path_input.cc +++ b/src/input/path_input.cc @@ -75,7 +75,11 @@ PathInput::pressed(int key) { struct _transform_filename { void operator () (utils::directory_entry& entry) { +#ifdef __sun__ + if (entry.d_type & S_IFDIR) +#else if (entry.d_type == DT_DIR) +#endif entry.d_name += '/'; } }; From 1a728fc68352423b577477760182d97266712778 Mon Sep 17 00:00:00 2001 From: mynamewastaken Date: Tue, 10 Mar 2015 20:33:47 -0500 Subject: [PATCH 08/46] Partially update outdated documentation --- doc/rtorrent.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rtorrent.rc b/doc/rtorrent.rc index 3680b85b..f58ef4b3 100644 --- a/doc/rtorrent.rc +++ b/doc/rtorrent.rc @@ -27,7 +27,7 @@ # Watch a directory for new torrents, and stop those that have been # deleted. -#schedule = watch_directory,5,5,load_start=./watch/*.torrent +#schedule = watch_directory,5,5,load.start=./watch/*.torrent #schedule = untied_directory,5,5,stop_untied= # Close torrents when diskspace is low. From eb5443bbadcb24d7efcc3c7109d408a1ff9b5ddc Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 4 May 2015 19:21:25 -0400 Subject: [PATCH 09/46] Add load.raw_start_verbose Fixes #289. --- src/command_events.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/command_events.cc b/src/command_events.cc index 0bf0314e..0b40af7c 100644 --- a/src/command_events.cc +++ b/src/command_events.cc @@ -353,6 +353,7 @@ initialize_command_events() { CMD2_ANY_LIST ("load.raw_verbose", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_raw_data)); CMD2_ANY_LIST ("load.raw_start", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_quiet | core::Manager::create_start | core::Manager::create_raw_data)); + CMD2_ANY_LIST ("load.raw_start_verbose", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_start | core::Manager::create_raw_data)); CMD2_ANY_VALUE ("close_low_diskspace", std::bind(&apply_close_low_diskspace, std::placeholders::_2)); From 1c47bf61623be7ca8e5b0147679d888922dc2ad0 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Tue, 23 Jun 2015 14:14:27 +0200 Subject: [PATCH 10/46] add support for the XDG base dir spec for rtorrent.rc --- src/main.cc | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main.cc b/src/main.cc index d3622774..b898e758 100644 --- a/src/main.cc +++ b/src/main.cc @@ -831,9 +831,25 @@ main(int argc, char** argv) { int firstArg = parse_options(control, argc, argv); if (OptionParser::has_flag('n', argc, argv)) { - lt_log_print(torrent::LOG_WARN, "Ignoring ~/.rtorrent.rc."); + lt_log_print(torrent::LOG_WARN, "Ignoring rtorrent.rc."); } else { - rpc::parse_command_single(rpc::make_target(), "try_import = ~/.rtorrent.rc"); + char* config_dir = std::getenv("XDG_CONFIG_HOME"); + char* home_dir = std::getenv("HOME"); + bool absolute_path = false; + + if(config_dir && config_dir[0] == '/') { + absolute_path = true; + } + + if(access((std::string(config_dir) + "/rtorrent/rtorrent.rc").c_str(), F_OK ) != -1 && absolute_path) { + rpc::parse_command_single(rpc::make_target(), "try_import = " + std::string(config_dir) + "/rtorrent/rtorrent.rc"); + } + else if(access((std::string(home_dir) +"/.config/rtorrent/rtorrent.rc").c_str(), F_OK ) != -1) { + rpc::parse_command_single(rpc::make_target(), "try_import = ~/.config/rtorrent/rtorrent.rc"); + } + else { + rpc::parse_command_single(rpc::make_target(), "try_import = ~/.rtorrent.rc"); + } } control->initialize(); @@ -1004,7 +1020,7 @@ print_help() { std::cout << "Usage: rtorrent [OPTIONS]... [FILE]... [URL]..." << std::endl; std::cout << " -D Enable deprecated commands" << std::endl; std::cout << " -h Display this very helpful text" << std::endl; - std::cout << " -n Don't try to load ~/.rtorrent.rc on startup" << std::endl; + std::cout << " -n Don't try to load rtorrent.rc on startup" << std::endl; std::cout << " -b Bind the listening socket to this IP" << std::endl; std::cout << " -i Change the IP that is sent to the tracker" << std::endl; std::cout << " -p - Set port range for incoming connections" << std::endl; From 9ba4d1d92efd25158e5d4501191c0229c24c5fe0 Mon Sep 17 00:00:00 2001 From: Justin Lecher Date: Wed, 29 Jul 2015 09:32:37 +0200 Subject: [PATCH 11/46] Try use pkg-config to detect ncurses libraries Modern ncurses version provide a pkg-config interface, so let's try to use it first. This also helps when ncurses provides functions inside libtinfo.so and thus needs to be linked against it as well. Signed-off-by: Justin Lecher --- configure.ac | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 72015453..46cc5e08 100644 --- a/configure.ac +++ b/configure.ac @@ -30,15 +30,21 @@ TORRENT_WITHOUT_STATVFS TORRENT_WITHOUT_STATFS AX_PTHREAD([], AC_MSG_ERROR([requires pthread])) -AX_WITH_CURSES - -if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then - AC_MSG_ERROR([requires either NcursesW or Ncurses library]) -fi +PKG_CHECK_MODULES([CURSES],[ncursesw],[ + AC_DEFINE(HAVE_NCURSESW_CURSES_H, 1) + ], + [PKG_CHECK_MODULES([CURSES],[ncurses],[ + AC_DEFINE(HAVE_NCURSES_H, 1) + ], + [AX_WITH_CURSES + if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then + AC_MSG_ERROR([requires either NcursesW or Ncurses library]) + fi]) + ]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS" CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS" -LIBS="$PTHREAD_LIBS $CURSES_LIB $LIBS" +LIBS="$PTHREAD_LIBS $CURSES_LIB $CURSES_LIBS $LIBS" PKG_CHECK_MODULES([libcurl], libcurl >= 7.15.4, CXXFLAGS="$CXXFLAGS $libcurl_CFLAGS"; From 62cb5a4605c0664bc522e0e0da9c72f09cf643a9 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Tue, 8 Sep 2015 05:12:40 +0900 Subject: [PATCH 12/46] Bumped master to 0.9.6. --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 72015453..10bcda90 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ -AC_INIT(rtorrent, 0.9.4, sundell.software@gmail.com) +AC_INIT(rtorrent, 0.9.6, sundell.software@gmail.com) -AC_DEFINE(API_VERSION, 8, api version) +AC_DEFINE(API_VERSION, 9, api version) AM_INIT_AUTOMAKE AC_CONFIG_HEADERS(config.h) @@ -44,7 +44,7 @@ PKG_CHECK_MODULES([libcurl], libcurl >= 7.15.4, CXXFLAGS="$CXXFLAGS $libcurl_CFLAGS"; LIBS="$LIBS $libcurl_LIBS") -PKG_CHECK_MODULES([libtorrent], libtorrent >= 0.13.4, +PKG_CHECK_MODULES([libtorrent], libtorrent >= 0.13.6, CXXFLAGS="$CXXFLAGS $libtorrent_CFLAGS"; LIBS="$LIBS $libtorrent_LIBS") From 06db5776ae4420f87d8b88a3531471fd8bd961c1 Mon Sep 17 00:00:00 2001 From: Micdu70 Date: Thu, 5 Nov 2015 18:41:27 +0100 Subject: [PATCH 13/46] Save downloaded stat of each torrent --- src/core/download_factory.cc | 3 +++ src/core/download_store.cc | 1 + 2 files changed, 4 insertions(+) diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 6105a27d..f19a4812 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -418,6 +418,9 @@ DownloadFactory::initialize_rtorrent(Download* download, torrent::Object* rtorre if (rtorrent->has_key_value("total_uploaded")) download->info()->mutable_up_rate()->set_total(rtorrent->get_key_value("total_uploaded")); + if (rtorrent->has_key_value("total_downloaded")) + download->info()->mutable_dl_rate()->set_total(rtorrent->get_key_value("total_downloaded")); + if (rtorrent->has_key_value("chunks_done") && rtorrent->has_key_value("chunks_wanted")) download->download()->set_chunks_done(rtorrent->get_key_value("chunks_done"), rtorrent->get_key_value("chunks_wanted")); diff --git a/src/core/download_store.cc b/src/core/download_store.cc index 4364c1d4..a85dca96 100644 --- a/src/core/download_store.cc +++ b/src/core/download_store.cc @@ -140,6 +140,7 @@ DownloadStore::save(Download* d, int flags) { rtorrent_base->insert_key("chunks_done", d->download()->file_list()->completed_chunks()); rtorrent_base->insert_key("chunks_wanted", d->download()->data()->wanted_chunks()); rtorrent_base->insert_key("total_uploaded", d->info()->up_rate()->total()); + rtorrent_base->insert_key("total_downloaded", d->info()->dl_rate()->total()); // Don't save for completed torrents when we've cleared the uncertain_pieces. torrent::resume_save_progress(*d->download(), *resume_base); From e1cc736f1114a6ecb7595bced652158b8dfc6363 Mon Sep 17 00:00:00 2001 From: Samantha Baldwin Date: Sat, 19 Dec 2015 01:28:14 -0500 Subject: [PATCH 14/46] change *dl_rate() to *down_rate() --- src/core/download_factory.cc | 2 +- src/core/download_store.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index f19a4812..b1bdd64b 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -419,7 +419,7 @@ DownloadFactory::initialize_rtorrent(Download* download, torrent::Object* rtorre download->info()->mutable_up_rate()->set_total(rtorrent->get_key_value("total_uploaded")); if (rtorrent->has_key_value("total_downloaded")) - download->info()->mutable_dl_rate()->set_total(rtorrent->get_key_value("total_downloaded")); + download->info()->mutable_down_rate()->set_total(rtorrent->get_key_value("total_downloaded")); if (rtorrent->has_key_value("chunks_done") && rtorrent->has_key_value("chunks_wanted")) download->download()->set_chunks_done(rtorrent->get_key_value("chunks_done"), rtorrent->get_key_value("chunks_wanted")); diff --git a/src/core/download_store.cc b/src/core/download_store.cc index a85dca96..536dba10 100644 --- a/src/core/download_store.cc +++ b/src/core/download_store.cc @@ -140,7 +140,7 @@ DownloadStore::save(Download* d, int flags) { rtorrent_base->insert_key("chunks_done", d->download()->file_list()->completed_chunks()); rtorrent_base->insert_key("chunks_wanted", d->download()->data()->wanted_chunks()); rtorrent_base->insert_key("total_uploaded", d->info()->up_rate()->total()); - rtorrent_base->insert_key("total_downloaded", d->info()->dl_rate()->total()); + rtorrent_base->insert_key("total_downloaded", d->info()->down_rate()->total()); // Don't save for completed torrents when we've cleared the uncertain_pieces. torrent::resume_save_progress(*d->download(), *resume_base); From 33601ddc0c1f190366839382bac638cb4e65862d Mon Sep 17 00:00:00 2001 From: Karl-Philipp Richter Date: Mon, 25 Jan 2016 08:33:00 +0100 Subject: [PATCH 15/46] added checkout URL to action-if-not-found of PKG_CHECK_MODULES for libtorrent, fixed #377 --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 10bcda90..a121c06e 100644 --- a/configure.ac +++ b/configure.ac @@ -46,7 +46,8 @@ PKG_CHECK_MODULES([libcurl], libcurl >= 7.15.4, PKG_CHECK_MODULES([libtorrent], libtorrent >= 0.13.6, CXXFLAGS="$CXXFLAGS $libtorrent_CFLAGS"; - LIBS="$LIBS $libtorrent_LIBS") + LIBS="$LIBS $libtorrent_LIBS", + [AC_MSG_ERROR([libtorrent >= 0.13.6 not found. Install from https://github.com/rakshasa/libtorrent.git])]) AC_LANG_PUSH(C++) TORRENT_WITH_XMLRPC_C From 1f5e4d37d5229b63963bb66e76c07ec3e359ecba Mon Sep 17 00:00:00 2001 From: pyroscope Date: Sat, 5 Mar 2016 03:12:35 +0100 Subject: [PATCH 16/46] added system.env=NAME command --- src/command_local.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/command_local.cc b/src/command_local.cc index 11ce6f10..67545870 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -78,6 +78,15 @@ apply_pieces_stats_total_size() { return size; } +torrent::Object +system_env(const torrent::Object::string_type& arg) { + if (arg.empty()) + throw torrent::input_error("system.env: Missing variable name."); + + char* val = getenv(arg.c_str()); + return std::string(val ? val : ""); +} + torrent::Object system_hostname() { char buffer[1024]; @@ -249,6 +258,8 @@ initialize_command_local() { CMD2_ANY ("system.files.closed_counter", std::bind(&FM_t::files_closed_counter, fileManager)); CMD2_ANY ("system.files.failed_counter", std::bind(&FM_t::files_failed_counter, fileManager)); + CMD2_ANY_STRING ("system.env", std::bind(&system_env, std::placeholders::_2)); + CMD2_ANY ("system.time", std::bind(&rak::timer::seconds, &cachedTime)); CMD2_ANY ("system.time_seconds", std::bind(&rak::timer::current_seconds)); CMD2_ANY ("system.time_usec", std::bind(&rak::timer::current_usec)); From 30d8379391ad4cb3097d57aa56a488d061e68662 Mon Sep 17 00:00:00 2001 From: pyroscope Date: Tue, 8 Mar 2016 13:25:04 +0100 Subject: [PATCH 17/46] added ui.current_view command --- src/command_ui.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/command_ui.cc b/src/command_ui.cc index 8540964a..bc9124dc 100644 --- a/src/command_ui.cc +++ b/src/command_ui.cc @@ -466,6 +466,11 @@ cmd_ui_set_view(const torrent::Object::string_type& args) { return torrent::Object(); } +torrent::Object +cmd_ui_current_view() { + return control->ui()->download_list()->current_view()->name(); +} + torrent::Object cmd_ui_unfocus_download(core::Download* download) { control->ui()->download_list()->unfocus_download(download); @@ -547,6 +552,7 @@ initialize_command_ui() { // Commands that affect the default rtorrent UI. CMD2_DL ("ui.unfocus_download", std::bind(&cmd_ui_unfocus_download, std::placeholders::_1)); + CMD2_ANY ("ui.current_view", std::bind(&cmd_ui_current_view)); CMD2_ANY_STRING("ui.current_view.set", std::bind(&cmd_ui_set_view, std::placeholders::_2)); // Move. From 4fb036f87d71f24b4bb18d9f91ac2f5b4f6535f5 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 10 Mar 2016 04:03:56 +0900 Subject: [PATCH 18/46] Revert "Merge pull request #317 from jlec/tinfo" This reverts commit b19cf8b4ff799b4c92f85501114d9d6bbc0ddb42, reversing changes made to 83d7dc896424f1dbc3618d1c88b10b2d70c52afa. --- configure.ac | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 1f3b0573..10bcda90 100644 --- a/configure.ac +++ b/configure.ac @@ -30,21 +30,15 @@ TORRENT_WITHOUT_STATVFS TORRENT_WITHOUT_STATFS AX_PTHREAD([], AC_MSG_ERROR([requires pthread])) -PKG_CHECK_MODULES([CURSES],[ncursesw],[ - AC_DEFINE(HAVE_NCURSESW_CURSES_H, 1) - ], - [PKG_CHECK_MODULES([CURSES],[ncurses],[ - AC_DEFINE(HAVE_NCURSES_H, 1) - ], - [AX_WITH_CURSES - if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then - AC_MSG_ERROR([requires either NcursesW or Ncurses library]) - fi]) - ]) +AX_WITH_CURSES + +if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then + AC_MSG_ERROR([requires either NcursesW or Ncurses library]) +fi CFLAGS="$CFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS" CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS" -LIBS="$PTHREAD_LIBS $CURSES_LIB $CURSES_LIBS $LIBS" +LIBS="$PTHREAD_LIBS $CURSES_LIB $LIBS" PKG_CHECK_MODULES([libcurl], libcurl >= 7.15.4, CXXFLAGS="$CXXFLAGS $libcurl_CFLAGS"; From a92da121d750eac62c1ed0e8c98e76a7d2a72f1d Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 10 Mar 2016 04:21:24 +0900 Subject: [PATCH 19/46] Cleaned up XDG_CONFIG_HOME patch. --- src/main.cc | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main.cc b/src/main.cc index b898e758..bfc34ff6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -835,19 +835,13 @@ main(int argc, char** argv) { } else { char* config_dir = std::getenv("XDG_CONFIG_HOME"); char* home_dir = std::getenv("HOME"); - bool absolute_path = false; - if(config_dir && config_dir[0] == '/') { - absolute_path = true; - } - - if(access((std::string(config_dir) + "/rtorrent/rtorrent.rc").c_str(), F_OK ) != -1 && absolute_path) { + if (config_dir != NULL && config_dir[0] == '/' && + access((std::string(config_dir) + "/rtorrent/rtorrent.rc").c_str(), F_OK) != -1) { rpc::parse_command_single(rpc::make_target(), "try_import = " + std::string(config_dir) + "/rtorrent/rtorrent.rc"); - } - else if(access((std::string(home_dir) +"/.config/rtorrent/rtorrent.rc").c_str(), F_OK ) != -1) { + } else if (home_dir != NULL && access((std::string(home_dir) + "/.config/rtorrent/rtorrent.rc").c_str(), F_OK) != -1) { rpc::parse_command_single(rpc::make_target(), "try_import = ~/.config/rtorrent/rtorrent.rc"); - } - else { + } else { rpc::parse_command_single(rpc::make_target(), "try_import = ~/.rtorrent.rc"); } } From 4ba24af463a1bf1f860cdebfaf33b30587bfc40e Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 10 Mar 2016 08:27:27 +0900 Subject: [PATCH 20/46] Adding travis file for testing. --- .travis | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .travis diff --git a/.travis b/.travis new file mode 100644 index 00000000..65ac7dce --- /dev/null +++ b/.travis @@ -0,0 +1,16 @@ +language: cpp +compiler: + - gcc + - clang + +before_install: + - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test + - sudo apt-get update -qq + - sudo apt-get build-dep rtorrent libtorrent-dev +# prevent `macro `AM_PATH_CPPUNIT' not found in library` in `autogen.sh` + - sudo apt-get install libcppunit-dev gcc-4.7 g++-4.7 +# `autogen.sh` doesn't call `configure` + - export CC=gcc-4.7 && export CXX=g++-4.7 + - git clone https://github.com/rakshasa/libtorrent.git && cd libtorrent && ./autogen.sh && configure && make -j24 && sudo make install && cd .. + +script: ./autogen.sh && ./configure && make -j24 && make -j24 check && sudo make install From 3edeb364bc7bfd3536e2b98dcc0f546aa2e249d2 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 10 Mar 2016 08:47:14 +0900 Subject: [PATCH 21/46] Fix a stray 'simple' method.insert check. --- src/command_dynamic.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/command_dynamic.cc b/src/command_dynamic.cc index ed6cedcf..91eb3c46 100644 --- a/src/command_dynamic.cc +++ b/src/command_dynamic.cc @@ -247,6 +247,10 @@ system_method_insert(const torrent::Object::list_type& args) { const std::string& options = itrArgs->as_string(); + // TODO: Replace find with a method that does '|' separated search + // for all valid options, and then cross-checks that unmixable ones + // aren't in there. Use a bitfield. + if (options.find("private") != std::string::npos) flags &= ~rpc::CommandMap::flag_public_xmlrpc; if (options.find("const") != std::string::npos) @@ -289,8 +293,7 @@ system_method_insert(const torrent::Object::list_type& args) { } else if (options.find("value") != std::string::npos || options.find("bool") != std::string::npos || options.find("string") != std::string::npos || - options.find("list") != std::string::npos || - options.find("simple") != std::string::npos) { + options.find("list") != std::string::npos) { torrent::Object::list_type new_args; new_args.push_back(rawKey); From adf4a32097b51a5d63a8c0e27c5d2480ea99b189 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 10 Mar 2016 08:50:43 +0900 Subject: [PATCH 22/46] Fixed name. --- .travis => .travis.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .travis => .travis.yml (100%) diff --git a/.travis b/.travis.yml similarity index 100% rename from .travis rename to .travis.yml From 0510e4db9d6413402505dd5a91179929d6a55c71 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 10 Mar 2016 08:59:33 +0900 Subject: [PATCH 23/46] Don't run 'make check' in travis as it has linker issues. --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 65ac7dce..89ff2805 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,5 @@ before_install: - export CC=gcc-4.7 && export CXX=g++-4.7 - git clone https://github.com/rakshasa/libtorrent.git && cd libtorrent && ./autogen.sh && configure && make -j24 && sudo make install && cd .. -script: ./autogen.sh && ./configure && make -j24 && make -j24 check && sudo make install +# Figure out how to fix the issue running 'make check'. +script: ./autogen.sh && ./configure && make -j24 && make -j24 && sudo make install From 3e7f9d8b4fc1a3f6a63b4d1434b74bad7608544a Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 10 Mar 2016 09:24:08 +0900 Subject: [PATCH 24/46] Removed make check. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 89ff2805..c17ea6e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,4 @@ before_install: - git clone https://github.com/rakshasa/libtorrent.git && cd libtorrent && ./autogen.sh && configure && make -j24 && sudo make install && cd .. # Figure out how to fix the issue running 'make check'. -script: ./autogen.sh && ./configure && make -j24 && make -j24 && sudo make install +script: ./autogen.sh && ./configure && make -j12 && sudo make install From 629e421d675cae7c75295b8a5f5bcb2b691ed242 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 10 Mar 2016 09:37:58 +0900 Subject: [PATCH 25/46] Updated travis file to properly select gcc-4.7. --- .travis.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c17ea6e4..454b9298 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,14 @@ before_install: - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test - sudo apt-get update -qq - sudo apt-get build-dep rtorrent libtorrent-dev + +if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.7; fi +if [ "$CXX" = "g++" ]; then export CXX="g++-4.7" CC="gcc-4.7"; fi + # prevent `macro `AM_PATH_CPPUNIT' not found in library` in `autogen.sh` - - sudo apt-get install libcppunit-dev gcc-4.7 g++-4.7 -# `autogen.sh` doesn't call `configure` - - export CC=gcc-4.7 && export CXX=g++-4.7 - - git clone https://github.com/rakshasa/libtorrent.git && cd libtorrent && ./autogen.sh && configure && make -j24 && sudo make install && cd .. + - sudo apt-get install libcppunit-dev + + - git clone https://github.com/rakshasa/libtorrent.git && cd libtorrent && ./autogen.sh && configure && make -j12 && sudo make install && cd .. # Figure out how to fix the issue running 'make check'. script: ./autogen.sh && ./configure && make -j12 && sudo make install From 944d3041931ed5edd16a794807c45c302de0cd87 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 10 Mar 2016 09:41:16 +0900 Subject: [PATCH 26/46] Fixed travis config file. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 454b9298..e2c5df1b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,8 +8,8 @@ before_install: - sudo apt-get update -qq - sudo apt-get build-dep rtorrent libtorrent-dev -if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.7; fi -if [ "$CXX" = "g++" ]; then export CXX="g++-4.7" CC="gcc-4.7"; fi + - if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.7; fi + - if [ "$CXX" = "g++" ]; then export CXX="g++-4.7" CC="gcc-4.7"; fi # prevent `macro `AM_PATH_CPPUNIT' not found in library` in `autogen.sh` - sudo apt-get install libcppunit-dev From b68d4c2db9ca68c2dbc5a32fd5a60a0e34c2579e Mon Sep 17 00:00:00 2001 From: yate Date: Sun, 15 May 2016 22:58:16 -0400 Subject: [PATCH 27/46] use whatever unit necessary in peer list info --- src/ui/element_peer_list.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/element_peer_list.cc b/src/ui/element_peer_list.cc index a8c2fc8d..8e3ff09d 100644 --- a/src/ui/element_peer_list.cc +++ b/src/ui/element_peer_list.cc @@ -118,8 +118,8 @@ ElementPeerList::create_info() { element->push_back(""); element->push_column("Snubbed:", te_command("if=$p.is_snubbed=,yes,no")); element->push_column("Done:", te_command("p.completed_percent=")); - element->push_column("Rate:", te_command("cat=$convert.kb=$p.up_rate=,\\ KB\\ ,$convert.kb=$p.down_rate=,\\ KB")); - element->push_column("Total:", te_command("cat=$convert.kb=$p.up_total=,\\ KB\\ ,$convert.kb=$p.down_total=,\\ KB")); + element->push_column("Rate:", te_command("cat=$convert.xb=$p.up_rate=,\\ ,$convert.xb=$p.down_rate=")); + element->push_column("Total:", te_command("cat=$convert.xb=$p.up_total=,\\ ,$convert.xb=$p.down_total=")); element->set_column_width(element->column_width() + 1); element->set_error_handler(new display::TextElementCString("No peer selected.")); From 0797d636fbde0a13e839923361fc2945b3a9f3f9 Mon Sep 17 00:00:00 2001 From: jmdevince Date: Wed, 15 Jun 2016 09:46:33 -0400 Subject: [PATCH 28/46] Show non-preloaded pieces stats --- src/ui/download.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/download.cc b/src/ui/download.cc index 5f5d2102..6058fe77 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -194,7 +194,7 @@ Download::create_info() { element->push_column("Upload:", te_command("cat=$convert.kb=$d.up.rate=,\" KB / \",$convert.xb=$d.up.total=")); element->push_column("Download:", te_command("cat=$convert.kb=$d.down.rate=,\" KB / \",$convert.xb=$d.down.total=")); element->push_column("Skipped:", te_command("cat=$convert.kb=$d.skip.rate=,\" KB / \",$convert.xb=$d.skip.total=")); - element->push_column("Preload:", te_command("cat=$pieces.preload.type=,\" / \",$pieces.stats_preloaded=,\" / \",$pieces.stats_preloaded=")); + element->push_column("Preload:", te_command("cat=$pieces.preload.type=,\" / \",$pieces.stats_preloaded=,\" / \",$pieces.stats_not_preloaded=")); element->set_column_width(element->column_width() + 1); From c01709fa27de80def528ba77a12f8895b9ce9624 Mon Sep 17 00:00:00 2001 From: zp Date: Sun, 19 Jun 2016 02:06:30 -0500 Subject: [PATCH 29/46] Allow rtorrent to run as a daemon, slightly modified version of the PR provided by sallyswiss --- src/command_local.cc | 2 + src/control.cc | 8 +++- src/display/canvas.cc | 88 +++++++++++++++++++++++++------------------ src/display/canvas.h | 71 ++++++++++++++++++---------------- 4 files changed, 99 insertions(+), 70 deletions(-) diff --git a/src/command_local.cc b/src/command_local.cc index 67545870..ccd87945 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -265,6 +265,8 @@ initialize_command_local() { CMD2_ANY ("system.time_usec", std::bind(&rak::timer::current_usec)); CMD2_ANY_VALUE_V ("system.umask.set", std::bind(&umask, std::placeholders::_2)); + + CMD2_VAR_BOOL ("system.use_daemon", false); CMD2_ANY ("system.cwd", std::bind(&system_get_cwd)); CMD2_ANY_STRING ("system.cwd.set", std::bind(&system_set_cwd, std::placeholders::_2)); diff --git a/src/control.cc b/src/control.cc index fc1b61b6..ed033102 100644 --- a/src/control.cc +++ b/src/control.cc @@ -118,7 +118,9 @@ Control::initialize() { m_ui->init(this); - m_inputStdin->insert(torrent::main_thread()->poll()); + if(!display::Canvas::daemon()) { + m_inputStdin->insert(torrent::main_thread()->poll()); + } } void @@ -128,7 +130,9 @@ Control::cleanup() { priority_queue_erase(&taskScheduler, &m_taskShutdown); - m_inputStdin->remove(torrent::main_thread()->poll()); + if(!display::Canvas::daemon()) { + m_inputStdin->remove(torrent::main_thread()->poll()); + } m_core->download_store()->disable(); diff --git a/src/display/canvas.cc b/src/display/canvas.cc index 31db4ad4..ea2eb73b 100644 --- a/src/display/canvas.cc +++ b/src/display/canvas.cc @@ -41,54 +41,63 @@ #include #include +#include "rpc/parse_commands.h" + #include "canvas.h" namespace display { bool Canvas::m_isInitialized = false; +bool Canvas::m_isDaemon = false; -Canvas::Canvas(int x, int y, int width, int height) : - m_window(newwin(height, width, y, x)) { +Canvas::Canvas(int x, int y, int width, int height) { + if (!m_isDaemon) { + m_window = newwin(height, width, y, x); - if (m_window == NULL) - throw torrent::internal_error("Could not allocate ncurses canvas."); + if (m_window == NULL) + throw torrent::internal_error("Could not allocate ncurses canvas."); + } } void Canvas::resize(int x, int y, int w, int h) { - wresize(m_window, h, w); - mvwin(m_window, y, x); + if (!m_isDaemon) { + wresize(m_window, h, w); + mvwin(m_window, y, x); + } } void Canvas::print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes) { - move(x, y); + if (!m_isDaemon) { + move(x, y); - attr_t org_attr; - short org_pair; - wattr_get(m_window, &org_attr, &org_pair, NULL); + attr_t org_attr; + short org_pair; + wattr_get(m_window, &org_attr, &org_pair, NULL); - attributes_list::const_iterator attrItr = attributes->begin(); - wattr_set(m_window, Attributes::a_normal, Attributes::color_default, NULL); + attributes_list::const_iterator attrItr = attributes->begin(); + wattr_set(m_window, Attributes::a_normal, Attributes::color_default, NULL); - while (first != last) { - const char* next = last; + while (first != last) { + const char* next = last; - if (attrItr != attributes->end()) { - next = attrItr->position(); + if (attrItr != attributes->end()) { + next = attrItr->position(); - if (first >= next) { - wattr_set(m_window, attrItr->attributes(), attrItr->colors(), NULL); - ++attrItr; + if (first >= next) { + wattr_set(m_window, attrItr->attributes(), attrItr->colors(), NULL); + ++attrItr; + } } + + print("%.*s", next - first, first); + first = next; } - print("%.*s", next - first, first); - first = next; + // Reset the color. + wattr_set(m_window, org_attr, org_pair, NULL); } - - // Reset the color. - wattr_set(m_window, org_attr, org_pair, NULL); } void @@ -96,14 +105,18 @@ Canvas::initialize() { if (m_isInitialized) return; + m_isDaemon = rpc::call_command_value("system.use_daemon"); + m_isInitialized = true; - initscr(); - raw(); - noecho(); - nodelay(stdscr, TRUE); - keypad(stdscr, TRUE); - curs_set(0); + if (!m_isDaemon) { + initscr(); + raw(); + noecho(); + nodelay(stdscr, TRUE); + keypad(stdscr, TRUE); + curs_set(0); + } } void @@ -113,18 +126,21 @@ Canvas::cleanup() { m_isInitialized = false; - noraw(); - endwin(); + if (!m_isDaemon) { + noraw(); + endwin(); + } } std::pair Canvas::term_size() { struct winsize ws; - if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0) - return std::pair(ws.ws_col, ws.ws_row); - else - return std::pair(80, 24); + if (!m_isDaemon) { + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0) + return std::pair(ws.ws_col, ws.ws_row); + } + return std::pair(80, 24); } } diff --git a/src/display/canvas.h b/src/display/canvas.h index 7023cada..50da0fd8 100644 --- a/src/display/canvas.h +++ b/src/display/canvas.h @@ -49,37 +49,37 @@ public: typedef std::vector attributes_list; Canvas(int x = 0, int y = 0, int width = 0, int height = 0); - ~Canvas() { delwin(m_window); } + ~Canvas() { if (!m_isDaemon) { delwin(m_window); } } - void refresh() { wnoutrefresh(m_window); } - static void refresh_std() { wnoutrefresh(stdscr); } - void redraw() { redrawwin(m_window); } - static void redraw_std() { redrawwin(stdscr); } + void refresh() { if (!m_isDaemon) { wnoutrefresh(m_window); } } + static void refresh_std() { if (!m_isDaemon) { wnoutrefresh(stdscr); } } + void redraw() { if (!m_isDaemon) { redrawwin(m_window); } } + static void redraw_std() { if (!m_isDaemon) { redrawwin(stdscr); } } - void resize(int w, int h) { wresize(m_window, h, w); } + void resize(int w, int h) { if (!m_isDaemon) { wresize(m_window, h, w); } } void resize(int x, int y, int w, int h); - static void resize_term(int x, int y) { resizeterm(y, x); } - static void resize_term(std::pair dim) { resizeterm(dim.second, dim.first); } + static void resize_term(int x, int y) { if (!m_isDaemon) { resizeterm(y, x); } } + static void resize_term(std::pair dim) { if (!m_isDaemon) { resizeterm(dim.second, dim.first); } } - unsigned int get_x() { int x, __UNUSED y; getyx(m_window, y, x); return x; } - unsigned int get_y() { int x, y; getyx(m_window, y, x); return y; } + unsigned int get_x() { int x, __UNUSED y; if (!m_isDaemon) { getyx(m_window, y, x); } else { x=1; } return x; } + unsigned int get_y() { int x, y; if (!m_isDaemon) { getyx(m_window, y, x); } else { y=1; } return y; } - unsigned int width() { int x, __UNUSED y; getmaxyx(m_window, y, x); return x; } - unsigned int height() { int x, y; getmaxyx(m_window, y, x); return y; } + unsigned int width() { int x, __UNUSED y; if (!m_isDaemon) { getmaxyx(m_window, y, x); } else { x=80; } return x; } + unsigned int height() { int x, y; if (!m_isDaemon) { getmaxyx(m_window, y, x); } else { y=24; } return y; } - void move(unsigned int x, unsigned int y) { wmove(m_window, y, x); } + void move(unsigned int x, unsigned int y) { if (!m_isDaemon) { wmove(m_window, y, x); } } - chtype get_background() { return getbkgd(m_window); } - void set_background(chtype c) { return wbkgdset(m_window, c); } + chtype get_background() { chtype bg=0; if (!m_isDaemon) { bg=getbkgd(m_window); } return bg; } + void set_background(chtype c) { if (!m_isDaemon) { return wbkgdset(m_window, c); } } - void erase() { werase(m_window); } - static void erase_std() { werase(stdscr); } + void erase() { if (!m_isDaemon) { werase(m_window); } } + static void erase_std() { if (!m_isDaemon) { werase(stdscr); } } void print_border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, - chtype bl, chtype br) { wborder(m_window, ls, rs, ts, bs, tl, tr, bl, br); } + chtype bl, chtype br) { if (!m_isDaemon) { wborder(m_window, ls, rs, ts, bs, tl, tr, bl, br); } } // The format string is non-const, but that will not be a problem // since the string shall always be a C string choosen at @@ -90,29 +90,32 @@ public: void print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes); - void print_char(const chtype ch) { waddch(m_window, ch); } - void print_char(unsigned int x, unsigned int y, const chtype ch) { mvwaddch(m_window, y, x, ch); } + void print_char(const chtype ch) { if (!m_isDaemon) { waddch(m_window, ch); } } + void print_char(unsigned int x, unsigned int y, const chtype ch) { if (!m_isDaemon) { mvwaddch(m_window, y, x, ch); } } - void set_attr(unsigned int x, unsigned int y, unsigned int n, int attr, int color) { mvwchgat(m_window, y, x, n, attr, color, NULL); } + void set_attr(unsigned int x, unsigned int y, unsigned int n, int attr, int color) { if (!m_isDaemon) { mvwchgat(m_window, y, x, n, attr, color, NULL); } } - void set_default_attributes(int attr) { (void)wattrset(m_window, attr); } + void set_default_attributes(int attr) { if (!m_isDaemon) { (void)wattrset(m_window, attr); } } // Initialize stdscr. static void initialize(); static void cleanup(); - static int get_screen_width() { int x, __UNUSED y; getmaxyx(stdscr, y, x); return x; } - static int get_screen_height() { int x, y; getmaxyx(stdscr, y, x); return y; } + static int get_screen_width() { int x, __UNUSED y; if (!m_isDaemon) { getmaxyx(stdscr, y, x); } else { x=80; } return x; } + static int get_screen_height() { int x, y; if (!m_isDaemon) { getmaxyx(stdscr, y, x); } else { y=24;} return y; } static std::pair term_size(); - static void do_update() { doupdate(); } + static void do_update() { if (!m_isDaemon) { doupdate(); } } + + static bool daemon() { return m_isDaemon; } private: Canvas(const Canvas&); void operator = (const Canvas&); static bool m_isInitialized; + static bool m_isDaemon; WINDOW* m_window; }; @@ -121,19 +124,23 @@ inline void Canvas::print(const char* str, ...) { va_list arglist; - va_start(arglist, str); - vw_printw(m_window, const_cast(str), arglist); - va_end(arglist); + if (!m_isDaemon) { + va_start(arglist, str); + vw_printw(m_window, const_cast(str), arglist); + va_end(arglist); + } } inline void Canvas::print(unsigned int x, unsigned int y, const char* str, ...) { va_list arglist; - va_start(arglist, str); - wmove(m_window, y, x); - vw_printw(m_window, const_cast(str), arglist); - va_end(arglist); + if (!m_isDaemon) { + va_start(arglist, str); + wmove(m_window, y, x); + vw_printw(m_window, const_cast(str), arglist); + va_end(arglist); + } } } From 7ea572967600a196a16e6c98768c6b57d7716682 Mon Sep 17 00:00:00 2001 From: zp Date: Sun, 19 Jun 2016 07:04:23 -0500 Subject: [PATCH 30/46] trim modified files --- src/command_local.cc | 16 ++++++++-------- src/control.cc | 6 +++--- src/display/canvas.cc | 8 ++++---- src/display/canvas.h | 6 +++--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/command_local.cc b/src/command_local.cc index ccd87945..beeead5a 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -5,12 +5,12 @@ // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -135,7 +135,7 @@ check_name(const std::string& str) { throw torrent::input_error("Non-alphanumeric characters found."); return str; -} +} torrent::Object group_insert(const torrent::Object::list_type& args) { @@ -158,7 +158,7 @@ group_insert(const torrent::Object::list_type& args) { if (rpc::call_command_value("method.use_intermediate") == 1) { // Deprecated in 0.7.0: - + CMD2_REDIRECT_GENERIC_STR("group." + name + ".view", "group2." + name + ".view"); CMD2_REDIRECT_GENERIC_STR("group." + name + ".view.set", "group2." + name + ".view.set"); CMD2_REDIRECT_GENERIC_STR("group." + name + ".ratio.min", "group2." + name + ".ratio.min"); @@ -170,7 +170,7 @@ group_insert(const torrent::Object::list_type& args) { } if (rpc::call_command_value("method.use_intermediate") == 2) { // Deprecated in 0.7.0: - + CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".view", "group2." + name + ".view"); CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".view.set", "group2." + name + ".view.set"); CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".ratio.min", "group2." + name + ".ratio.min"); @@ -215,9 +215,9 @@ torrent::Object cmd_file_append(const torrent::Object::list_type& args) { if (args.empty()) throw torrent::input_error("Invalid number of arguments."); - + FILE* output = fopen(args.front().as_string().c_str(), "a"); - + if (output == NULL) throw torrent::input_error("Could not append to file '" + args.front().as_string() + "': " + rak::error_number::current().c_str()); @@ -265,7 +265,7 @@ initialize_command_local() { CMD2_ANY ("system.time_usec", std::bind(&rak::timer::current_usec)); CMD2_ANY_VALUE_V ("system.umask.set", std::bind(&umask, std::placeholders::_2)); - + CMD2_VAR_BOOL ("system.use_daemon", false); CMD2_ANY ("system.cwd", std::bind(&system_get_cwd)); diff --git a/src/control.cc b/src/control.cc index ed033102..8e28da0d 100644 --- a/src/control.cc +++ b/src/control.cc @@ -5,12 +5,12 @@ // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -138,7 +138,7 @@ Control::cleanup() { m_ui->cleanup(); m_core->cleanup(); - + display::Canvas::erase_std(); display::Canvas::refresh_std(); display::Canvas::do_update(); diff --git a/src/display/canvas.cc b/src/display/canvas.cc index ea2eb73b..02bdc193 100644 --- a/src/display/canvas.cc +++ b/src/display/canvas.cc @@ -5,12 +5,12 @@ // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -104,7 +104,7 @@ void Canvas::initialize() { if (m_isInitialized) return; - + m_isDaemon = rpc::call_command_value("system.use_daemon"); m_isInitialized = true; @@ -123,7 +123,7 @@ void Canvas::cleanup() { if (!m_isInitialized) return; - + m_isInitialized = false; if (!m_isDaemon) { diff --git a/src/display/canvas.h b/src/display/canvas.h index 50da0fd8..b324d81a 100644 --- a/src/display/canvas.h +++ b/src/display/canvas.h @@ -5,12 +5,12 @@ // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -107,7 +107,7 @@ public: static std::pair term_size(); static void do_update() { if (!m_isDaemon) { doupdate(); } } - + static bool daemon() { return m_isDaemon; } private: From efc9097d62cd93e2d139d6d321b5a71d1b169502 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Mon, 27 Jun 2016 01:46:54 +0900 Subject: [PATCH 31/46] Renamed system.use_daemon to system.daemon. --- src/command_local.cc | 2 +- src/display/canvas.cc | 2 +- src/main.cc | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/command_local.cc b/src/command_local.cc index beeead5a..9236f9bb 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -266,7 +266,7 @@ initialize_command_local() { CMD2_ANY_VALUE_V ("system.umask.set", std::bind(&umask, std::placeholders::_2)); - CMD2_VAR_BOOL ("system.use_daemon", false); + CMD2_VAR_BOOL ("system.daemon", false); CMD2_ANY ("system.cwd", std::bind(&system_get_cwd)); CMD2_ANY_STRING ("system.cwd.set", std::bind(&system_set_cwd, std::placeholders::_2)); diff --git a/src/display/canvas.cc b/src/display/canvas.cc index 02bdc193..fc24bbc3 100644 --- a/src/display/canvas.cc +++ b/src/display/canvas.cc @@ -105,7 +105,7 @@ Canvas::initialize() { if (m_isInitialized) return; - m_isDaemon = rpc::call_command_value("system.use_daemon"); + m_isDaemon = rpc::call_command_value("system.daemon"); m_isInitialized = true; diff --git a/src/main.cc b/src/main.cc index bfc34ff6..2bd73815 100644 --- a/src/main.cc +++ b/src/main.cc @@ -190,8 +190,10 @@ main(int argc, char** argv) { control = new Control; - srandom(cachedTime.usec() ^ (getpid() << 16) ^ getppid()); - srand48(cachedTime.usec() ^ (getpid() << 16) ^ getppid()); + unsigned int random_seed = cachedTime.seconds() ^ cachedTime.usec() ^ (getpid() << 16) ^ getppid(); + + srandom(random_seed); + srand48(random_seed); SignalHandler::set_ignore(SIGPIPE); SignalHandler::set_handler(SIGINT, std::bind(&Control::receive_normal_shutdown, control)); From a8c67b4aab1dd95bc2e06f0f1105f74efe86b8aa Mon Sep 17 00:00:00 2001 From: chros Date: Wed, 6 Jul 2016 23:15:04 +0100 Subject: [PATCH 32/46] Fix scheduled sorting/filtering bug on started and stopped views in rtorrent (See #3) --- src/core/view.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/view.cc b/src/core/view.cc index c57c0f0e..842fdbbf 100644 --- a/src/core/view.cc +++ b/src/core/view.cc @@ -257,6 +257,10 @@ View::sort() { void View::filter() { + // Do NOT allow filter STARTED and STOPPED views: they are special + if (m_name == "started" || m_name == "stopped") + return; + // Parition the list in two steps so we know which elements changed. iterator splitVisible = std::stable_partition(begin_visible(), end_visible(), view_downloads_filter(m_filter)); iterator splitFiltered = std::stable_partition(begin_filtered(), end_filtered(), view_downloads_filter(m_filter)); From 3f698b3b3992039ec8dfeb8575d5180e7b95036a Mon Sep 17 00:00:00 2001 From: Speeddymon Date: Sat, 9 Jul 2016 13:59:08 -0500 Subject: [PATCH 33/46] Update example rtorrent.rc to 0.9 format --- doc/rtorrent.rc | 52 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/doc/rtorrent.rc b/doc/rtorrent.rc index f58ef4b3..9c70d424 100644 --- a/doc/rtorrent.rc +++ b/doc/rtorrent.rc @@ -3,61 +3,61 @@ # uncomment the options you wish to enable. # Maximum and minimum number of peers to connect to per torrent. -#min_peers = 40 -#max_peers = 100 +#throttle.min_peers.normal.set = 40 +#throttle.max_peers.normal.set = 100 # Same as above but for seeding completed torrents (-1 = same as downloading) -#min_peers_seed = 10 -#max_peers_seed = 50 +#throttle.min_peers.seed.set = 10 +#throttle.max_peers.seed.set = 50 # Maximum number of simultanious uploads per torrent. -#max_uploads = 15 +#throttle.max_uploads.set = 15 # Global upload and download rate in KiB. "0" for unlimited. -#download_rate = 0 -#upload_rate = 0 +#throttle.global_down.max_rate.set_kb = 0 +#throttle.global_up.max_rate.set_kb = 0 # Default directory to save the downloaded torrents. -#directory = ./ +#directory.default.set = ./ # Default session directory. Make sure you don't run multiple instance # of rtorrent using the same session directory. Perhaps using a # relative path? -#session = ./session +#session.path.set = ./session # Watch a directory for new torrents, and stop those that have been # deleted. -#schedule = watch_directory,5,5,load.start=./watch/*.torrent -#schedule = untied_directory,5,5,stop_untied= +#schedule2 = watch_directory,5,5,load.start=./watch/*.torrent +#schedule2 = untied_directory,5,5,stop_untied= # Close torrents when diskspace is low. -#schedule = low_diskspace,5,60,close_low_diskspace=100M +#schedule2 = low_diskspace,5,60,close_low_diskspace=100M # The ip address reported to the tracker. -#ip = 127.0.0.1 -#ip = rakshasa.no +#network.local_address.set = 127.0.0.1 +#network.local_address.set = rakshasa.no # The ip address the listening socket and outgoing connections is # bound to. -#bind = 127.0.0.1 -#bind = rakshasa.no +#network.bind_address.set = 127.0.0.1 +#network.bind_address.set = rakshasa.no # Port range to use for listening. -#port_range = 6890-6999 +#network.port_range.set = 6890-6999 # Start opening ports at a random position within the port range. -#port_random = no +#network.port_random.set = no # Check hash for finished torrents. Might be usefull until the bug is # fixed that causes lack of diskspace not to be properly reported. -#check_hash = no +#pieces.hash.on_completion.set = no # Set whether the client should try to connect to UDP trackers. -#use_udp_trackers = yes +#trackers.use_udp.set = yes # Alternative calls to bind and ip that should handle dynamic ip's. -#schedule = ip_tick,0,1800,ip=rakshasa -#schedule = bind_tick,0,1800,bind=rakshasa +#schedule2 = ip_tick,0,1800,ip=rakshasa +#schedule2 = bind_tick,0,1800,bind=rakshasa # Encryption options, set to none (default) or any combination of the following: # allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext @@ -66,19 +66,19 @@ # outgoing connections but retries with encryption if they fail, preferring # plaintext to RC4 encryption after the encrypted handshake # -# encryption = allow_incoming,enable_retry,prefer_plaintext +# protocol.encryption.set = allow_incoming,enable_retry,prefer_plaintext # Enable DHT support for trackerless torrents or when all trackers are down. # May be set to "disable" (completely disable DHT), "off" (do not start DHT), # "auto" (start and stop DHT as needed), or "on" (start DHT immediately). # The default is "off". For DHT to work, a session directory must be defined. # -# dht = auto +# dht.mode.set = auto # UDP port to use for DHT. # -# dht_port = 6881 +# dht.port.set = 6881 # Enable peer exchange (for torrents not marked private) # -# peer_exchange = yes +# protocol.pex.set = yes From f24154e7727b11848070ebe28f1963ad4bfd1e95 Mon Sep 17 00:00:00 2001 From: Speeddymon Date: Sat, 9 Jul 2016 14:02:31 -0500 Subject: [PATCH 34/46] Fix travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e2c5df1b..9641c06e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ before_install: # prevent `macro `AM_PATH_CPPUNIT' not found in library` in `autogen.sh` - sudo apt-get install libcppunit-dev - - git clone https://github.com/rakshasa/libtorrent.git && cd libtorrent && ./autogen.sh && configure && make -j12 && sudo make install && cd .. + - git clone https://github.com/rakshasa/libtorrent.git && cd libtorrent && ./autogen.sh && ./configure && make -j12 && sudo make install && cd .. # Figure out how to fix the issue running 'make check'. script: ./autogen.sh && ./configure && make -j12 && sudo make install From 8385957b0684d5bd7d36b958f1d698eb411d4d55 Mon Sep 17 00:00:00 2001 From: netpok Date: Fri, 15 Jul 2016 11:52:33 +0200 Subject: [PATCH 35/46] Fix warning message of deprecated commands --- src/main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cc b/src/main.cc index 2bd73815..c66247d0 100644 --- a/src/main.cc +++ b/src/main.cc @@ -233,7 +233,7 @@ main(int argc, char** argv) { if (OptionParser::has_flag('D', argc, argv)) { rpc::call_command_set_value("method.use_deprecated.set", true); - lt_log_print(torrent::LOG_WARN, "Disabled deprecated commands."); + lt_log_print(torrent::LOG_WARN, "Enabled deprecated commands."); } if (OptionParser::has_flag('I', argc, argv)) { From 8140c3fe07489b88dfdb571c4dd64314597dfe46 Mon Sep 17 00:00:00 2001 From: chros Date: Thu, 21 Jul 2016 18:50:42 +0100 Subject: [PATCH 36/46] Expose meta property of downloads (See #5) --- src/command_download.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/command_download.cc b/src/command_download.cc index 5a1b2ed3..40cc5dea 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -683,6 +683,7 @@ initialize_command_download() { CMD2_DL ("d.is_pex_active", CMD2_ON_INFO(is_pex_active)); CMD2_DL ("d.is_partially_done", CMD2_ON_DATA(is_partially_done)); CMD2_DL ("d.is_not_partially_done", CMD2_ON_DATA(is_not_partially_done)); + CMD2_DL ("d.is_meta", CMD2_ON_INFO(is_meta_download)); CMD2_DL_V ("d.resume", std::bind(&core::DownloadList::resume_default, control->core()->download_list(), std::placeholders::_1)); CMD2_DL_V ("d.pause", std::bind(&core::DownloadList::pause_default, control->core()->download_list(), std::placeholders::_1)); From d111594d2031545e45ffd5b14b819b61c562dc2c Mon Sep 17 00:00:00 2001 From: rakshasa Date: Wed, 3 Aug 2016 23:01:28 +0900 Subject: [PATCH 37/46] Added merzlya's torrent status display changes. --- doc/rtorrent.rc | 25 ++++++- src/command_ui.cc | 2 + src/display/utils.cc | 104 ++++++++++++++++++++++++++++ src/display/utils.h | 1 + src/display/window_download_list.cc | 35 +++++++--- src/main.cc | 5 ++ src/ui/element_download_list.cc | 6 ++ src/ui/element_download_list.h | 2 + 8 files changed, 166 insertions(+), 14 deletions(-) diff --git a/doc/rtorrent.rc b/doc/rtorrent.rc index 9c70d424..78186a79 100644 --- a/doc/rtorrent.rc +++ b/doc/rtorrent.rc @@ -3,59 +3,74 @@ # uncomment the options you wish to enable. # Maximum and minimum number of peers to connect to per torrent. +# #throttle.min_peers.normal.set = 40 #throttle.max_peers.normal.set = 100 # Same as above but for seeding completed torrents (-1 = same as downloading) +# #throttle.min_peers.seed.set = 10 #throttle.max_peers.seed.set = 50 # Maximum number of simultanious uploads per torrent. +# #throttle.max_uploads.set = 15 # Global upload and download rate in KiB. "0" for unlimited. +# #throttle.global_down.max_rate.set_kb = 0 #throttle.global_up.max_rate.set_kb = 0 # Default directory to save the downloaded torrents. +# #directory.default.set = ./ # Default session directory. Make sure you don't run multiple instance # of rtorrent using the same session directory. Perhaps using a # relative path? +# #session.path.set = ./session # Watch a directory for new torrents, and stop those that have been # deleted. +# #schedule2 = watch_directory,5,5,load.start=./watch/*.torrent #schedule2 = untied_directory,5,5,stop_untied= # Close torrents when diskspace is low. +# #schedule2 = low_diskspace,5,60,close_low_diskspace=100M # The ip address reported to the tracker. +# #network.local_address.set = 127.0.0.1 #network.local_address.set = rakshasa.no # The ip address the listening socket and outgoing connections is # bound to. +# #network.bind_address.set = 127.0.0.1 #network.bind_address.set = rakshasa.no # Port range to use for listening. +# #network.port_range.set = 6890-6999 # Start opening ports at a random position within the port range. +# #network.port_random.set = no # Check hash for finished torrents. Might be usefull until the bug is # fixed that causes lack of diskspace not to be properly reported. +# #pieces.hash.on_completion.set = no # Set whether the client should try to connect to UDP trackers. +# #trackers.use_udp.set = yes # Alternative calls to bind and ip that should handle dynamic ip's. +# #schedule2 = ip_tick,0,1800,ip=rakshasa #schedule2 = bind_tick,0,1800,bind=rakshasa @@ -76,9 +91,13 @@ # dht.mode.set = auto # UDP port to use for DHT. -# -# dht.port.set = 6881 +# +#dht.port.set = 6881 # Enable peer exchange (for torrents not marked private) # -# protocol.pex.set = yes +#protocol.pex.set = yes + +# Set downlad list layout style (default - 0, compact - 1) +# +#download_list_layout = 1 diff --git a/src/command_ui.cc b/src/command_ui.cc index bc9124dc..88a2f873 100644 --- a/src/command_ui.cc +++ b/src/command_ui.cc @@ -523,6 +523,8 @@ void initialize_command_ui() { CMD2_VAR_STRING("keys.layout", "qwerty"); + CMD2_VAR_VALUE("download.list.layout", 0); + CMD2_ANY_STRING("view.add", object_convert_void(std::bind(&core::ViewManager::insert_throw, control->view_manager(), std::placeholders::_2))); CMD2_ANY_L ("view.list", std::bind(&apply_view_list)); diff --git a/src/display/utils.cc b/src/display/utils.cc index 2ab4c1a7..640a7226 100644 --- a/src/display/utils.cc +++ b/src/display/utils.cc @@ -182,6 +182,110 @@ print_download_info(char* first, char* last, core::Download* d) { return first; } +char* +print_download_info2(char* first, char* last, core::Download* d) { + //Name + std::string name = "Name"; + if(d) name = d->info()->name(); + name.resize(64,' '); + first = print_buffer(first, last, " %s", name.c_str()); + + //Status + first = print_buffer(first, last, "|"); + if (!d) + first = print_buffer(first, last, " Status "); + else if (!d->download()->info()->is_open()) + first = print_buffer(first, last, " CLOSED "); + else if (!d->download()->info()->is_active()) + first = print_buffer(first, last, " OPEN "); + else + first = print_buffer(first, last, " "); + + //Downloaded + first = print_buffer(first, last, "|"); + if (!d) + first = print_buffer(first, last, " Downloaded "); + else + first = print_buffer(first, last, " %7.1f MB ", (double)d->download()->bytes_done() / (double)(1 << 20)); + + //Size + first = print_buffer(first, last, "|"); + if (!d) + first = print_buffer(first, last, " Size "); + else + first = print_buffer(first, last, " %7.1f MB ", (double)d->download()->file_list()->size_bytes() / (double)(1 << 20)); + + //Done + first = print_buffer(first, last, "|"); + if (!d) + first = print_buffer(first, last, " Done "); + else if (d->is_done()) + first = print_buffer(first, last, " 100%% "); + else if (d->is_open()) + first = print_buffer(first, last, " %2u%% ",(d->download()->file_list()->completed_chunks() * 100) / d->download()->file_list()->size_chunks()); + else + first = print_buffer(first, last, " "); + + //Rate Up + first = print_buffer(first, last, "|"); + if (!d) + first = print_buffer(first, last, " Up Rate "); + else + first = print_buffer(first, last, " %6.1f KB ", (double)d->info()->up_rate()->rate() / (1 << 10)); + + //Rate Down + first = print_buffer(first, last, "|"); + if (!d) + first = print_buffer(first, last, " Down Rate "); + else + first = print_buffer(first, last, " %6.1f KB ", (double)d->info()->down_rate()->rate() / (1 << 10)); + + //Uploaded + first = print_buffer(first, last, "|"); + if (!d) + first = print_buffer(first, last, " Uploaded "); + else + first = print_buffer(first, last, " %7.1f MB ", (double)d->info()->up_rate()->total() / (1 << 20)); + + //ETA + first = print_buffer(first, last, "| "); + if (!d) + first = print_buffer(first, last, " ETA "); + else if (d->download()->info()->is_active() && !d->is_done()) + first = print_download_time_left(first, last, d); + else + first = print_buffer(first, last, " "); + + //Ratio + first = print_buffer(first, last, " |"); + if (!d) + first = print_buffer(first, last, " Ratio"); + else + first = print_buffer(first, last, " %4.2f ", (double)rpc::call_command_value("d.ratio", rpc::make_target(d)) / 1000.0); + + //Misc + first = print_buffer(first, last, "|"); + if (!d) { + first = print_buffer(first, last, " Misc "); + } else { + first = print_buffer(first, last, " %c%c", + rpc::call_command_string("d.tied_to_file", rpc::make_target(d)).empty() ? ' ' : 'T', + rpc::call_command_value("d.ignore_commands", rpc::make_target(d)) == 0 ? ' ' : 'I', + (double)rpc::call_command_value("d.ratio", rpc::make_target(d)) / 1000.0); + + if (d->priority() != 2) + first = print_buffer(first, last, " %s", rpc::call_command_string("d.priority_str", rpc::make_target(d)).c_str()); + + if (!d->bencode()->get_key("rtorrent").get_key_string("throttle_name").empty()) + first = print_buffer(first, last , " %s", rpc::call_command_string("d.throttle_name", rpc::make_target(d)).c_str()); + } + + if (first > last) + throw torrent::internal_error("print_download_info(...) wrote past end of the buffer."); + + return first; +} + char* print_download_status(char* first, char* last, core::Download* d) { if (d->is_active()) diff --git a/src/display/utils.h b/src/display/utils.h index 7f75425c..ccb392d1 100644 --- a/src/display/utils.h +++ b/src/display/utils.h @@ -67,6 +67,7 @@ char* print_ddmmyyyy(char* first, char* last, time_t t); char* print_download_title(char* first, char* last, core::Download* d); char* print_download_info(char* first, char* last, core::Download* d); +char* print_download_info2(char* first, char* last, core::Download* d); char* print_download_status(char* first, char* last, core::Download* d); char* print_download_time_left(char* first, char* last, core::Download* d); char* print_download_percentage_done(char* first, char* last, core::Download* d); diff --git a/src/display/window_download_list.cc b/src/display/window_download_list.cc index 138ea8c9..b490c557 100644 --- a/src/display/window_download_list.cc +++ b/src/display/window_download_list.cc @@ -40,6 +40,7 @@ #include "core/download.h" #include "core/view.h" +#include "rpc/parse_commands.h" #include "canvas.h" #include "globals.h" @@ -73,6 +74,8 @@ WindowDownloadList::set_view(core::View* l) { void WindowDownloadList::redraw() { + const int layout = rpc::call_command_value("download.list.layout"); + m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds()); m_canvas->erase(); @@ -90,7 +93,7 @@ WindowDownloadList::redraw() { Range range = rak::advance_bidirectional(m_view->begin_visible(), m_view->focus() != m_view->end_visible() ? m_view->focus() : m_view->begin_visible(), m_view->end_visible(), - m_canvas->height() / 3); + m_canvas->height()/(layout ? 1 : 3)); // Make sure we properly fill out the last lines so it looks like // there are more torrents, yet don't hide it if we got the last one @@ -99,20 +102,30 @@ WindowDownloadList::redraw() { ++range.second; int pos = 1; + char buffer[m_canvas->width() + 1]; + char* last = buffer + m_canvas->width() - 2 + 1; + + if(layout) { + print_download_info2(buffer, last, NULL); + m_canvas->set_default_attributes(A_BOLD); + m_canvas->print(0, pos++, " %s", buffer); + } while (range.first != range.second) { - char buffer[m_canvas->width() + 1]; - char* last = buffer + m_canvas->width() - 2 + 1; + if(layout) { + print_download_info2(buffer, last, *range.first); + m_canvas->set_default_attributes(range.first == m_view->focus() ? A_REVERSE : A_NORMAL); + m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); + } else { + print_download_title(buffer, last, *range.first); + m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); - print_download_title(buffer, last, *range.first); - m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); - - print_download_info(buffer, last, *range.first); - m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); - - print_download_status(buffer, last, *range.first); - m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); + print_download_info(buffer, last, *range.first); + m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); + print_download_status(buffer, last, *range.first); + m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); + } ++range.first; } } diff --git a/src/main.cc b/src/main.cc index c66247d0..2735dc84 100644 --- a/src/main.cc +++ b/src/main.cc @@ -416,6 +416,11 @@ main(int argc, char** argv) { CMD2_REDIRECT_GENERIC("to_xb", "convert.xb"); CMD2_REDIRECT_GENERIC("to_throttle", "convert.throttle"); + // TODO: Rename to something with 'ui.fooobar.....' and put + // together with the other ui options. In fact, add redirect for + // that other new ui option. + CMD2_REDIRECT ("download_list_layout", "download.list.layout.set"); + // Deprecated commands. Don't use these anymore. if (rpc::call_command_value("method.use_intermediate") == 1) { diff --git a/src/ui/element_download_list.cc b/src/ui/element_download_list.cc index bc40e7e2..5a782751 100644 --- a/src/ui/element_download_list.cc +++ b/src/ui/element_download_list.cc @@ -99,6 +99,8 @@ ElementDownloadList::ElementDownloadList() : m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::bind(&ElementDownloadList::receive_prev, this); m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::bind(&ElementDownloadList::receive_next, this); + + m_bindings['L'] = std::bind(&ElementDownloadList::toggle_layout, this); } void @@ -221,4 +223,8 @@ ElementDownloadList::receive_change_view(const std::string& name) { set_view(*itr); } +void +ElementDownloadList::toggle_layout() { + rpc::call_command("download.list.layout.set", (rpc::call_command_value("download.list.layout") + 1)%2); +} } diff --git a/src/ui/element_download_list.h b/src/ui/element_download_list.h index 20185b50..5bf4f08f 100644 --- a/src/ui/element_download_list.h +++ b/src/ui/element_download_list.h @@ -77,6 +77,8 @@ public: void receive_change_view(const std::string& name); + void toggle_layout(); + private: WDownloadList* m_window; core::View* m_view; From 2c60226bd2f4a366fb4de63d9cb38db01df94616 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Wed, 3 Aug 2016 23:57:02 +0900 Subject: [PATCH 38/46] Cleaned up compact display. --- doc/rtorrent.rc | 4 +- src/command_ui.cc | 5 +- src/display/utils.cc | 170 +++++++++-------------- src/display/utils.h | 7 +- src/display/window_download_list.cc | 48 ++++--- src/display/window_download_statusbar.cc | 2 +- src/main.cc | 5 +- 7 files changed, 108 insertions(+), 133 deletions(-) diff --git a/doc/rtorrent.rc b/doc/rtorrent.rc index 78186a79..9c940ebe 100644 --- a/doc/rtorrent.rc +++ b/doc/rtorrent.rc @@ -98,6 +98,6 @@ # #protocol.pex.set = yes -# Set downlad list layout style (default - 0, compact - 1) +# Set downlad list layout style. ("full", "compact") # -#download_list_layout = 1 +#torrent_list_layout = "full" diff --git a/src/command_ui.cc b/src/command_ui.cc index 88a2f873..69ee2f54 100644 --- a/src/command_ui.cc +++ b/src/command_ui.cc @@ -523,8 +523,6 @@ void initialize_command_ui() { CMD2_VAR_STRING("keys.layout", "qwerty"); - CMD2_VAR_VALUE("download.list.layout", 0); - CMD2_ANY_STRING("view.add", object_convert_void(std::bind(&core::ViewManager::insert_throw, control->view_manager(), std::placeholders::_2))); CMD2_ANY_L ("view.list", std::bind(&apply_view_list)); @@ -557,6 +555,9 @@ initialize_command_ui() { CMD2_ANY ("ui.current_view", std::bind(&cmd_ui_current_view)); CMD2_ANY_STRING("ui.current_view.set", std::bind(&cmd_ui_set_view, std::placeholders::_2)); + // TODO: Add 'option_string' for rtorrent-specific options. + CMD2_VAR_STRING("ui.torrent_list.layout", "full"); + // Move. CMD2_ANY("print", &apply_print); CMD2_ANY("cat", &apply_cat); diff --git a/src/display/utils.cc b/src/display/utils.cc index 640a7226..93011e82 100644 --- a/src/display/utils.cc +++ b/src/display/utils.cc @@ -133,7 +133,7 @@ print_download_title(char* first, char* last, core::Download* d) { } char* -print_download_info(char* first, char* last, core::Download* d) { +print_download_info_full(char* first, char* last, core::Download* d) { if (!d->download()->info()->is_open()) first = print_buffer(first, last, "[CLOSED] "); else if (!d->download()->info()->is_active()) @@ -177,111 +177,7 @@ print_download_info(char* first, char* last, core::Download* d) { first = print_buffer(first, last , "]"); if (first > last) - throw torrent::internal_error("print_download_info(...) wrote past end of the buffer."); - - return first; -} - -char* -print_download_info2(char* first, char* last, core::Download* d) { - //Name - std::string name = "Name"; - if(d) name = d->info()->name(); - name.resize(64,' '); - first = print_buffer(first, last, " %s", name.c_str()); - - //Status - first = print_buffer(first, last, "|"); - if (!d) - first = print_buffer(first, last, " Status "); - else if (!d->download()->info()->is_open()) - first = print_buffer(first, last, " CLOSED "); - else if (!d->download()->info()->is_active()) - first = print_buffer(first, last, " OPEN "); - else - first = print_buffer(first, last, " "); - - //Downloaded - first = print_buffer(first, last, "|"); - if (!d) - first = print_buffer(first, last, " Downloaded "); - else - first = print_buffer(first, last, " %7.1f MB ", (double)d->download()->bytes_done() / (double)(1 << 20)); - - //Size - first = print_buffer(first, last, "|"); - if (!d) - first = print_buffer(first, last, " Size "); - else - first = print_buffer(first, last, " %7.1f MB ", (double)d->download()->file_list()->size_bytes() / (double)(1 << 20)); - - //Done - first = print_buffer(first, last, "|"); - if (!d) - first = print_buffer(first, last, " Done "); - else if (d->is_done()) - first = print_buffer(first, last, " 100%% "); - else if (d->is_open()) - first = print_buffer(first, last, " %2u%% ",(d->download()->file_list()->completed_chunks() * 100) / d->download()->file_list()->size_chunks()); - else - first = print_buffer(first, last, " "); - - //Rate Up - first = print_buffer(first, last, "|"); - if (!d) - first = print_buffer(first, last, " Up Rate "); - else - first = print_buffer(first, last, " %6.1f KB ", (double)d->info()->up_rate()->rate() / (1 << 10)); - - //Rate Down - first = print_buffer(first, last, "|"); - if (!d) - first = print_buffer(first, last, " Down Rate "); - else - first = print_buffer(first, last, " %6.1f KB ", (double)d->info()->down_rate()->rate() / (1 << 10)); - - //Uploaded - first = print_buffer(first, last, "|"); - if (!d) - first = print_buffer(first, last, " Uploaded "); - else - first = print_buffer(first, last, " %7.1f MB ", (double)d->info()->up_rate()->total() / (1 << 20)); - - //ETA - first = print_buffer(first, last, "| "); - if (!d) - first = print_buffer(first, last, " ETA "); - else if (d->download()->info()->is_active() && !d->is_done()) - first = print_download_time_left(first, last, d); - else - first = print_buffer(first, last, " "); - - //Ratio - first = print_buffer(first, last, " |"); - if (!d) - first = print_buffer(first, last, " Ratio"); - else - first = print_buffer(first, last, " %4.2f ", (double)rpc::call_command_value("d.ratio", rpc::make_target(d)) / 1000.0); - - //Misc - first = print_buffer(first, last, "|"); - if (!d) { - first = print_buffer(first, last, " Misc "); - } else { - first = print_buffer(first, last, " %c%c", - rpc::call_command_string("d.tied_to_file", rpc::make_target(d)).empty() ? ' ' : 'T', - rpc::call_command_value("d.ignore_commands", rpc::make_target(d)) == 0 ? ' ' : 'I', - (double)rpc::call_command_value("d.ratio", rpc::make_target(d)) / 1000.0); - - if (d->priority() != 2) - first = print_buffer(first, last, " %s", rpc::call_command_string("d.priority_str", rpc::make_target(d)).c_str()); - - if (!d->bencode()->get_key("rtorrent").get_key_string("throttle_name").empty()) - first = print_buffer(first, last , " %s", rpc::call_command_string("d.throttle_name", rpc::make_target(d)).c_str()); - } - - if (first > last) - throw torrent::internal_error("print_download_info(...) wrote past end of the buffer."); + throw torrent::internal_error("print_download_info_full(...) wrote past end of the buffer."); return first; } @@ -322,6 +218,68 @@ print_download_status(char* first, char* last, core::Download* d) { return first; } +char* +print_download_column_compact(char* first, char* last) { + first = print_buffer(first, last, " %-64.64s", "Name"); + first = print_buffer(first, last, "| Status | Downloaded | Size | Done | Up Rate | Down Rate | Uploaded | ETA | Ratio| Misc "); + + if (first > last) + throw torrent::internal_error("print_download_column_compact(...) wrote past end of the buffer."); + + return first; +} + +char* +print_download_info_compact(char* first, char* last, core::Download* d) { + first = print_buffer(first, last, " %-64.64s", d->info()->name().c_str()); + first = print_buffer(first, last, "|"); + + if (!d->download()->info()->is_open()) + first = print_buffer(first, last, " CLOSED "); + else if (!d->download()->info()->is_active()) + first = print_buffer(first, last, " OPEN "); + else + first = print_buffer(first, last, " "); + + first = print_buffer(first, last, "| %7.1f MB ", (double)d->download()->bytes_done() / (double)(1 << 20)); + first = print_buffer(first, last, "| %7.1f MB ", (double)d->download()->file_list()->size_bytes() / (double)(1 << 20)); + first = print_buffer(first, last, "|"); + + if (d->is_done()) + first = print_buffer(first, last, " 100%% "); + else if (d->is_open()) + first = print_buffer(first, last, " %2u%% ",(d->download()->file_list()->completed_chunks() * 100) / d->download()->file_list()->size_chunks()); + else + first = print_buffer(first, last, " "); + + first = print_buffer(first, last, "| %6.1f KB ", (double)d->info()->up_rate()->rate() / (1 << 10)); + first = print_buffer(first, last, "| %6.1f KB ", (double)d->info()->down_rate()->rate() / (1 << 10)); + first = print_buffer(first, last, "| %7.1f MB ", (double)d->info()->up_rate()->total() / (1 << 20)); + first = print_buffer(first, last, "| "); + + if (d->download()->info()->is_active() && !d->is_done()) + first = print_download_time_left(first, last, d); + else + first = print_buffer(first, last, " "); + + first = print_buffer(first, last, "| %4.2f ", (double)rpc::call_command_value("d.ratio", rpc::make_target(d)) / 1000.0); + first = print_buffer(first, last, "| %c%c", + rpc::call_command_string("d.tied_to_file", rpc::make_target(d)).empty() ? ' ' : 'T', + rpc::call_command_value("d.ignore_commands", rpc::make_target(d)) == 0 ? ' ' : 'I', + (double)rpc::call_command_value("d.ratio", rpc::make_target(d)) / 1000.0); + + if (d->priority() != 2) + first = print_buffer(first, last, " %s", rpc::call_command_string("d.priority_str", rpc::make_target(d)).c_str()); + + if (!d->bencode()->get_key("rtorrent").get_key_string("throttle_name").empty()) + first = print_buffer(first, last , " %s", rpc::call_command_string("d.throttle_name", rpc::make_target(d)).c_str()); + + if (first > last) + throw torrent::internal_error("print_download_info_compact(...) wrote past end of the buffer."); + + return first; +} + char* print_download_time_left(char* first, char* last, core::Download* d) { uint32_t rate = d->info()->down_rate()->rate(); diff --git a/src/display/utils.h b/src/display/utils.h index ccb392d1..eb2daf8e 100644 --- a/src/display/utils.h +++ b/src/display/utils.h @@ -66,9 +66,12 @@ char* print_ddhhmm(char* first, char* last, time_t t); char* print_ddmmyyyy(char* first, char* last, time_t t); char* print_download_title(char* first, char* last, core::Download* d); -char* print_download_info(char* first, char* last, core::Download* d); -char* print_download_info2(char* first, char* last, core::Download* d); +char* print_download_info_full(char* first, char* last, core::Download* d); char* print_download_status(char* first, char* last, core::Download* d); + +char* print_download_column_compact(char* first, char* last); +char* print_download_info_compact(char* first, char* last, core::Download* d); + char* print_download_time_left(char* first, char* last, core::Download* d); char* print_download_percentage_done(char* first, char* last, core::Download* d); diff --git a/src/display/window_download_list.cc b/src/display/window_download_list.cc index b490c557..74911555 100644 --- a/src/display/window_download_list.cc +++ b/src/display/window_download_list.cc @@ -74,8 +74,6 @@ WindowDownloadList::set_view(core::View* l) { void WindowDownloadList::redraw() { - const int layout = rpc::call_command_value("download.list.layout"); - m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds()); m_canvas->erase(); @@ -88,12 +86,24 @@ WindowDownloadList::redraw() { if (m_view->empty_visible() || m_canvas->width() < 5 || m_canvas->height() < 2) return; + int layout_height; + const std::string layout_name = rpc::call_command_string("ui.torrent_list.layout"); + + if (layout_name == "full") { + layout_height = 3; + } else if (layout_name == "compact") { + layout_height = 1; + } else { + m_canvas->print(0, 0, "INVALID ui.torrent_list.layout '%s'", layout_name.c_str()); + return; + } + typedef std::pair Range; Range range = rak::advance_bidirectional(m_view->begin_visible(), m_view->focus() != m_view->end_visible() ? m_view->focus() : m_view->begin_visible(), m_view->end_visible(), - m_canvas->height()/(layout ? 1 : 3)); + m_canvas->height() / layout_height); // Make sure we properly fill out the last lines so it looks like // there are more torrents, yet don't hide it if we got the last one @@ -105,29 +115,35 @@ WindowDownloadList::redraw() { char buffer[m_canvas->width() + 1]; char* last = buffer + m_canvas->width() - 2 + 1; - if(layout) { - print_download_info2(buffer, last, NULL); + // Add a proper 'column info' method. + if (layout_name == "compact") { + print_download_column_compact(buffer, last); + m_canvas->set_default_attributes(A_BOLD); m_canvas->print(0, pos++, " %s", buffer); } - while (range.first != range.second) { - if(layout) { - print_download_info2(buffer, last, *range.first); - m_canvas->set_default_attributes(range.first == m_view->focus() ? A_REVERSE : A_NORMAL); - m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); - } else { + if (layout_name == "full") { + while (range.first != range.second) { print_download_title(buffer, last, *range.first); m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); - - print_download_info(buffer, last, *range.first); + print_download_info_full(buffer, last, *range.first); m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); - print_download_status(buffer, last, *range.first); m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); + + range.first++; } - ++range.first; - } + + } else { + while (range.first != range.second) { + print_download_info_compact(buffer, last, *range.first); + m_canvas->set_default_attributes(range.first == m_view->focus() ? A_REVERSE : A_NORMAL); + m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); + + range.first++; + } + } } } diff --git a/src/display/window_download_statusbar.cc b/src/display/window_download_statusbar.cc index bbf0379f..284b8b54 100644 --- a/src/display/window_download_statusbar.cc +++ b/src/display/window_download_statusbar.cc @@ -66,7 +66,7 @@ WindowDownloadStatusbar::redraw() { char buffer[m_canvas->width()]; char* last = buffer + m_canvas->width() - 2; - print_download_info(buffer, last, m_download); + print_download_info_full(buffer, last, m_download); m_canvas->print(0, 0, "%s", buffer); snprintf(buffer, last - buffer, "Peers: %i(%i) Min/Max: %i/%i Slots: U:%i/%i D:%i/%i U/I/C/A: %i/%i/%i/%i Unchoked: %u/%u Failed: %i", diff --git a/src/main.cc b/src/main.cc index 2735dc84..58d31a23 100644 --- a/src/main.cc +++ b/src/main.cc @@ -416,10 +416,7 @@ main(int argc, char** argv) { CMD2_REDIRECT_GENERIC("to_xb", "convert.xb"); CMD2_REDIRECT_GENERIC("to_throttle", "convert.throttle"); - // TODO: Rename to something with 'ui.fooobar.....' and put - // together with the other ui options. In fact, add redirect for - // that other new ui option. - CMD2_REDIRECT ("download_list_layout", "download.list.layout.set"); + CMD2_REDIRECT ("torrent_list_layout", "ui.torrent_list.layout.set"); // Deprecated commands. Don't use these anymore. From 66619840d89d1c093cd24567aea970a1ca0ebafe Mon Sep 17 00:00:00 2001 From: rakshasa Date: Sat, 6 Aug 2016 03:02:14 +0900 Subject: [PATCH 39/46] Increased max file size to 512GB. --- src/command_local.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command_local.cc b/src/command_local.cc index 9236f9bb..741b3000 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -242,7 +242,7 @@ initialize_command_local() { CMD2_VAR_C_STRING("system.client_version", PACKAGE_VERSION); CMD2_VAR_C_STRING("system.library_version", torrent::version()); CMD2_VAR_VALUE ("system.file.allocate", 0); - CMD2_VAR_VALUE ("system.file.max_size", (int64_t)128 << 30); + CMD2_VAR_VALUE ("system.file.max_size", (int64_t)512 << 30); CMD2_VAR_VALUE ("system.file.split_size", -1); CMD2_VAR_STRING ("system.file.split_suffix", ".part"); From 51c5190eb1b630c1066fbb555d894a26ae0dd95f Mon Sep 17 00:00:00 2001 From: rakshasa Date: Sat, 6 Aug 2016 05:24:43 +0900 Subject: [PATCH 40/46] Removed commands that were deprecated in version 0.7.0. --- src/main.cc | 393 ---------------------------------------------------- 1 file changed, 393 deletions(-) diff --git a/src/main.cc b/src/main.cc index 58d31a23..687e57c8 100644 --- a/src/main.cc +++ b/src/main.cc @@ -436,399 +436,6 @@ main(int argc, char** argv) { #if LT_SLIM_VERSION != 1 if (rpc::call_command_value("method.use_deprecated")) { - // Deprecated in 0.7.0: - - CMD2_REDIRECT_GENERIC("system.method.insert", "method.insert"); - CMD2_REDIRECT_GENERIC("system.method.erase", "method.erase"); - CMD2_REDIRECT_GENERIC("system.method.get", "method.get"); - CMD2_REDIRECT_GENERIC("system.method.set", "method.set"); - CMD2_REDIRECT_GENERIC("system.method.list_keys", "method.list_keys"); - CMD2_REDIRECT_GENERIC("system.method.has_key", "method.has_key"); - CMD2_REDIRECT_GENERIC("system.method.set_key", "method.set_key"); - - CMD2_REDIRECT ("get_directory", "directory.default"); - CMD2_REDIRECT_GENERIC("set_directory", "directory.default.set"); - - CMD2_REDIRECT ("get_session", "session.path"); - CMD2_REDIRECT_GENERIC("set_session", "session.path.set"); - - CMD2_REDIRECT ("session_save", "session.save"); - - CMD2_REDIRECT ("get_name", "session.name"); - CMD2_REDIRECT_GENERIC("set_name", "session.name.set"); - - CMD2_REDIRECT ("system.file_allocate", "system.file.allocate"); - CMD2_REDIRECT ("system.file_allocate.set", "system.file.allocate.set"); - CMD2_REDIRECT ("get_max_file_size", "system.file.max_size"); - CMD2_REDIRECT_GENERIC("set_max_file_size", "system.file.max_size.set"); - CMD2_REDIRECT ("get_split_file_size", "system.file.split_size"); - CMD2_REDIRECT_GENERIC("set_split_file_size", "system.file.split_size.set"); - CMD2_REDIRECT ("get_split_suffix", "system.file.split_suffix"); - CMD2_REDIRECT_GENERIC("set_split_suffix", "system.file.split_suffix.set"); - - CMD2_REDIRECT ("get_timeout_sync", "pieces.sync.timeout"); - CMD2_REDIRECT_GENERIC("set_timeout_sync", "pieces.sync.timeout.set"); - CMD2_REDIRECT ("get_timeout_safe_sync", "pieces.sync.timeout_safe"); - CMD2_REDIRECT_GENERIC("set_timeout_safe_sync", "pieces.sync.timeout_safe.set"); - - CMD2_REDIRECT_GENERIC("get_preload_type", "pieces.preload.type"); - CMD2_REDIRECT_GENERIC("get_preload_min_size", "pieces.preload.min_size"); - CMD2_REDIRECT_GENERIC("get_preload_required_rate", "pieces.preload.min_rate"); - CMD2_REDIRECT_GENERIC("set_preload_type", "pieces.preload.type.set"); - CMD2_REDIRECT_GENERIC("set_preload_min_size", "pieces.preload.min_size.set"); - CMD2_REDIRECT_GENERIC("set_preload_required_rate", "pieces.preload.min_rate.set"); - CMD2_REDIRECT_GENERIC("get_stats_preloaded", "pieces.stats_preloaded"); - CMD2_REDIRECT_GENERIC("get_stats_not_preloaded", "pieces.stats_not_preloaded"); - - CMD2_REDIRECT_GENERIC("get_safe_sync", "pieces.sync.always_safe"); - CMD2_REDIRECT_GENERIC("set_safe_sync", "pieces.sync.always_safe.set"); - - CMD2_REDIRECT ("get_memory_usage", "pieces.memory.current"); - CMD2_REDIRECT_GENERIC("get_max_memory_usage", "pieces.memory.max"); - CMD2_REDIRECT_GENERIC("set_max_memory_usage", "pieces.memory.max.set"); - - CMD2_REDIRECT_GENERIC("load", "load.normal"); - CMD2_REDIRECT_GENERIC("load_verbose", "load.verbose"); - CMD2_REDIRECT_GENERIC("load_start", "load.start"); - CMD2_REDIRECT_GENERIC("load_start_verbose", "load.start_verbose"); - - CMD2_REDIRECT_GENERIC("load_raw", "load.raw"); - CMD2_REDIRECT_GENERIC("load_raw_start", "load.raw_start"); - CMD2_REDIRECT_GENERIC("load_raw_verbose", "load.raw_verbose"); - - CMD2_REDIRECT_GENERIC("get_connection_leech", "protocol.connection.leech"); - CMD2_REDIRECT_GENERIC("get_connection_seed", "protocol.connection.seed"); - CMD2_REDIRECT_GENERIC("set_connection_leech", "protocol.connection.leech.set"); - CMD2_REDIRECT_GENERIC("set_connection_seed", "protocol.connection.seed.set"); - - // - // Throttle: - // - - CMD2_REDIRECT_GENERIC("throttle_up", "throttle.up"); - CMD2_REDIRECT_GENERIC("throttle_down", "throttle.down"); - CMD2_REDIRECT_GENERIC("throttle_ip", "throttle.ip"); - - CMD2_REDIRECT_GENERIC("get_throttle_up_max", "throttle.up.max"); - CMD2_REDIRECT_GENERIC("get_throttle_up_rate", "throttle.up.rate"); - CMD2_REDIRECT_GENERIC("get_throttle_down_max", "throttle.down.max"); - CMD2_REDIRECT_GENERIC("get_throttle_down_rate", "throttle.down.rate"); - - CMD2_REDIRECT_GENERIC("set_min_peers", "throttle.min_peers.normal.set"); - CMD2_REDIRECT_GENERIC("set_max_peers", "throttle.max_peers.normal.set"); - CMD2_REDIRECT_GENERIC("set_min_peers_seed", "throttle.min_peers.seed.set"); - CMD2_REDIRECT_GENERIC("set_max_peers_seed", "throttle.max_peers.seed.set"); - - CMD2_REDIRECT_GENERIC("set_max_uploads", "throttle.max_uploads.set"); - - CMD2_REDIRECT_GENERIC("set_max_uploads_div", "throttle.max_uploads.div.set"); - CMD2_REDIRECT_GENERIC("set_max_uploads_global", "throttle.max_uploads.global.set"); - CMD2_REDIRECT_GENERIC("set_max_downloads_div", "throttle.max_downloads.div.set"); - CMD2_REDIRECT_GENERIC("set_max_downloads_global", "throttle.max_downloads.global.set"); - - CMD2_REDIRECT ("get_min_peers", "throttle.min_peers.normal"); - CMD2_REDIRECT ("get_max_peers", "throttle.max_peers.normal"); - CMD2_REDIRECT ("get_min_peers_seed", "throttle.min_peers.seed"); - CMD2_REDIRECT ("get_max_peers_seed", "throttle.max_peers.seed"); - - CMD2_REDIRECT ("get_max_uploads", "throttle.max_uploads"); - - CMD2_REDIRECT ("get_max_uploads_div", "throttle.max_uploads.div"); - CMD2_REDIRECT ("get_max_uploads_global", "throttle.max_uploads.global"); - CMD2_REDIRECT ("get_max_downloads_div", "throttle.max_downloads.div"); - CMD2_REDIRECT ("get_max_downloads_global", "throttle.max_downloads.global"); - - CMD2_REDIRECT ("get_up_rate", "throttle.global_up.rate"); - CMD2_REDIRECT ("get_up_total", "throttle.global_up.total"); - CMD2_REDIRECT ("get_upload_rate", "throttle.global_up.max_rate"); - CMD2_REDIRECT_GENERIC("set_upload_rate", "throttle.global_up.max_rate.set"); - CMD2_REDIRECT ("get_down_rate", "throttle.global_down.rate"); - CMD2_REDIRECT ("get_down_total", "throttle.global_down.total"); - CMD2_REDIRECT ("get_download_rate", "throttle.global_down.max_rate"); - CMD2_REDIRECT_GENERIC("set_download_rate", "throttle.global_down.max_rate.set"); - - // - // Network: - // - - CMD2_REDIRECT ("get_send_buffer_size", "network.send_buffer.size"); - CMD2_REDIRECT_GENERIC("set_send_buffer_size", "network.send_buffer.size.set"); - CMD2_REDIRECT ("get_receive_buffer_size", "network.receive_buffer.size"); - CMD2_REDIRECT_GENERIC("set_receive_buffer_size", "network.receive_buffer.size.set"); - - CMD2_REDIRECT_GENERIC("set_bind", "network.bind_address.set"); - CMD2_REDIRECT ("get_bind", "network.bind_address"); - - CMD2_REDIRECT_GENERIC("set_ip", "network.local_address.set"); - CMD2_REDIRECT ("get_ip", "network.local_address"); - - CMD2_REDIRECT ("get_port_range", "network.port_range"); - CMD2_REDIRECT_GENERIC("set_port_range", "network.port_range.set"); - - CMD2_REDIRECT ("get_port_random", "network.port_random"); - CMD2_REDIRECT_GENERIC("set_port_random", "network.port_random.set"); - - CMD2_REDIRECT ("port_open", "network.port_open.set"); - CMD2_REDIRECT ("get_port_open", "network.port_open"); - CMD2_REDIRECT_GENERIC("set_port_open", "network.port_open.set"); - - CMD2_REDIRECT_GENERIC("set_proxy_address", "network.proxy_address.set"); - CMD2_REDIRECT ("get_proxy_address", "network.proxy_address"); - - CMD2_REDIRECT_GENERIC("set_scgi_dont_route", "network.scgi.dont_route.set"); - CMD2_REDIRECT ("get_scgi_dont_route", "network.scgi.dont_route"); - - CMD2_REDIRECT ("get_max_open_sockets", "network.max_open_sockets"); - - CMD2_REDIRECT ("get_max_open_files", "network.max_open_files"); - CMD2_REDIRECT_GENERIC("set_max_open_files", "network.max_open_files.set"); - - // - // XMLRPC stuff: - // - - CMD2_REDIRECT_GENERIC("xmlrpc_dialect", "network.xmlrpc.dialect.set"); - CMD2_REDIRECT_GENERIC("set_xmlrpc_dialect", "network.xmlrpc.dialect.set"); - - CMD2_REDIRECT_GENERIC("xmlrpc_size_limit", "network.xmlrpc.size_limit.set"); - CMD2_REDIRECT ("get_xmlrpc_size_limit", "network.xmlrpc.size_limit"); - CMD2_REDIRECT_GENERIC("set_xmlrpc_size_limit", "network.xmlrpc.size_limit.set"); - - // - // HTTP stuff: - // - - CMD2_REDIRECT_GENERIC("http_capath", "network.http.capath.set"); - CMD2_REDIRECT ("get_http_capath", "network.http.capath"); - CMD2_REDIRECT_GENERIC("set_http_capath", "network.http.capath.set"); - - CMD2_REDIRECT_GENERIC("http_cacert", "network.http.cacert.set"); - CMD2_REDIRECT ("get_http_cacert", "network.http.cacert"); - CMD2_REDIRECT_GENERIC("set_http_cacert", "network.http.cacert.set"); - - CMD2_REDIRECT ("get_max_open_http", "network.http.max_open"); - CMD2_REDIRECT_GENERIC("set_max_open_http", "network.http.max_open.set"); - - CMD2_REDIRECT_GENERIC("http_proxy", "network.http.proxy_address.set"); - CMD2_REDIRECT ("get_http_proxy", "network.http.proxy_address"); - CMD2_REDIRECT_GENERIC("set_http_proxy", "network.http.proxy_address.set"); - - CMD2_REDIRECT ("peer_exchange", "protocol.pex.set"); - CMD2_REDIRECT ("get_peer_exchange", "protocol.pex"); - CMD2_REDIRECT_GENERIC("set_peer_exchange", "protocol.pex.set"); - - // - // Trackers: - // - - CMD2_REDIRECT ("tracker_numwant", "trackers.numwant.set"); - CMD2_REDIRECT ("get_tracker_numwant", "trackers.numwant"); - CMD2_REDIRECT_GENERIC("set_tracker_numwant", "trackers.numwant.set"); - - CMD2_REDIRECT ("use_udp_trackers", "trackers.use_udp.set"); - CMD2_REDIRECT ("get_use_udp_trackers", "trackers.use_udp"); - CMD2_REDIRECT_GENERIC("set_use_udp_trackers", "trackers.use_udp.set"); - - // - // DHT stuff - // - - CMD2_REDIRECT ("dht_add_node", "dht.add_node"); - CMD2_REDIRECT ("dht_statistics", "dht.statistics"); - CMD2_REDIRECT ("get_dht_port", "dht.port"); - CMD2_REDIRECT_GENERIC("set_dht_port", "dht.port.set"); - CMD2_REDIRECT ("get_dht_throttle", "dht.throttle.name"); - CMD2_REDIRECT_GENERIC("set_dht_throttle", "dht.throttle.name.set"); - - // - // Various system stuff: - // - - CMD2_REDIRECT ("get_session_lock", "session.use_lock"); - CMD2_REDIRECT_GENERIC("set_session_lock", "session.use_lock.set"); - CMD2_REDIRECT ("get_session_on_completion", "session.on_completion"); - CMD2_REDIRECT_GENERIC("set_session_on_completion", "session.on_completion.set"); - - CMD2_REDIRECT ("get_check_hash", "pieces.hash.on_completion"); - CMD2_REDIRECT_GENERIC("set_check_hash", "pieces.hash.on_completion.set"); - - // - // Download: - // - - CMD2_REDIRECT ("d.get_hash", "d.hash"); - CMD2_REDIRECT ("d.get_local_id", "d.local_id"); - CMD2_REDIRECT ("d.get_local_id_html", "d.local_id_html"); - CMD2_REDIRECT ("d.get_bitfield", "d.bitfield"); - CMD2_REDIRECT ("d.get_base_path", "d.base_path"); - CMD2_REDIRECT ("d.get_base_filename", "d.base_filename"); - - CMD2_REDIRECT ("d.get_name", "d.name"); - CMD2_REDIRECT ("d.get_creation_date", "d.creation_date"); - - CMD2_REDIRECT ("d.get_peer_exchange", "d.peer_exchange"); - - CMD2_REDIRECT ("d.get_up_rate", "d.up.rate"); - CMD2_REDIRECT ("d.get_up_total", "d.up.total"); - CMD2_REDIRECT ("d.get_down_rate", "d.down.rate"); - CMD2_REDIRECT ("d.get_down_total", "d.down.total"); - CMD2_REDIRECT ("d.get_skip_rate", "d.skip.rate"); - CMD2_REDIRECT ("d.get_skip_total", "d.skip.total"); - - // - CMD2_REDIRECT ("d.get_bytes_done", "d.bytes_done"); - CMD2_REDIRECT ("d.get_chunk_size", "d.chunk_size"); - CMD2_REDIRECT ("d.get_chunks_hashed", "d.chunks_hashed"); - CMD2_REDIRECT ("d.get_complete", "d.complete"); - CMD2_REDIRECT ("d.get_completed_bytes", "d.completed_bytes"); - CMD2_REDIRECT ("d.get_completed_chunks", "d.completed_chunks"); - CMD2_REDIRECT ("d.get_connection_current", "d.connection_current"); - CMD2_REDIRECT ("d.get_connection_leech", "d.connection_leech"); - CMD2_REDIRECT ("d.get_connection_seed", "d.connection_seed"); - CMD2_REDIRECT ("d.get_custom", "d.custom"); - CMD2_REDIRECT ("d.get_custom1", "d.custom1"); - CMD2_REDIRECT ("d.get_custom2", "d.custom2"); - CMD2_REDIRECT ("d.get_custom3", "d.custom3"); - CMD2_REDIRECT ("d.get_custom4", "d.custom4"); - CMD2_REDIRECT ("d.get_custom5", "d.custom5"); - CMD2_REDIRECT ("d.get_custom_throw", "d.custom_throw"); - CMD2_REDIRECT ("d.get_directory", "d.directory"); - CMD2_REDIRECT ("d.get_directory_base", "d.directory_base"); - CMD2_REDIRECT ("d.get_free_diskspace", "d.free_diskspace"); - CMD2_REDIRECT ("d.get_hashing", "d.hashing"); - CMD2_REDIRECT ("d.get_hashing_failed", "d.hashing_failed"); - CMD2_REDIRECT ("d.get_ignore_commands", "d.ignore_commands"); - CMD2_REDIRECT ("d.get_left_bytes", "d.left_bytes"); - CMD2_REDIRECT ("d.get_loaded_file", "d.loaded_file"); - CMD2_REDIRECT ("d.get_max_file_size", "d.max_file_size"); - CMD2_REDIRECT ("d.get_max_size_pex", "d.max_size_pex"); - CMD2_REDIRECT ("d.get_message", "d.message"); - CMD2_REDIRECT ("d.get_mode", "d.mode"); - CMD2_REDIRECT ("d.get_peers_accounted", "d.peers_accounted"); - CMD2_REDIRECT ("d.get_peers_complete", "d.peers_complete"); - CMD2_REDIRECT ("d.get_peers_connected", "d.peers_connected"); - CMD2_REDIRECT ("d.get_peers_max", "d.peers_max"); - CMD2_REDIRECT ("d.get_peers_min", "d.peers_min"); - CMD2_REDIRECT ("d.get_peers_not_connected", "d.peers_not_connected"); - CMD2_REDIRECT ("d.get_priority", "d.priority"); - CMD2_REDIRECT ("d.get_priority_str", "d.priority_str"); - CMD2_REDIRECT ("d.get_ratio", "d.ratio"); - CMD2_REDIRECT ("d.get_size_bytes", "d.size_bytes"); - CMD2_REDIRECT ("d.get_size_chunks", "d.size_chunks"); - CMD2_REDIRECT ("d.get_size_files", "d.size_files"); - CMD2_REDIRECT ("d.get_size_pex", "d.size_pex"); - CMD2_REDIRECT ("d.get_state", "d.state"); - CMD2_REDIRECT ("d.get_state_changed", "d.state_changed"); - CMD2_REDIRECT ("d.get_state_counter", "d.state_counter"); - CMD2_REDIRECT ("d.get_throttle_name", "d.throttle_name"); - CMD2_REDIRECT ("d.get_tied_to_file", "d.tied_to_file"); - CMD2_REDIRECT ("d.get_tracker_focus", "d.tracker_focus"); - CMD2_REDIRECT ("d.get_tracker_numwant", "d.tracker_numwant"); - CMD2_REDIRECT ("d.get_tracker_size", "d.tracker_size"); - CMD2_REDIRECT ("d.get_uploads_max", "d.uploads_max"); - - CMD2_REDIRECT ("d.set_connection_current", "d.connection_current.set"); - CMD2_REDIRECT ("d.set_custom", "d.custom.set"); - CMD2_REDIRECT ("d.set_custom1", "d.custom1.set"); - CMD2_REDIRECT ("d.set_custom2", "d.custom2.set"); - CMD2_REDIRECT ("d.set_custom3", "d.custom3.set"); - CMD2_REDIRECT ("d.set_custom4", "d.custom4.set"); - CMD2_REDIRECT ("d.set_custom5", "d.custom5.set"); - CMD2_REDIRECT ("d.set_directory", "d.directory.set"); - CMD2_REDIRECT ("d.set_directory_base", "d.directory_base.set"); - CMD2_REDIRECT ("d.set_hashing_failed", "d.hashing_failed.set"); - CMD2_REDIRECT ("d.set_ignore_commands", "d.ignore_commands.set"); - CMD2_REDIRECT ("d.set_max_file_size", "d.max_file_size.set"); - CMD2_REDIRECT ("d.set_message", "d.message.set"); - CMD2_REDIRECT ("d.set_peers_max", "d.peers_max.set"); - CMD2_REDIRECT ("d.set_peers_min", "d.peers_min.set"); - CMD2_REDIRECT ("d.set_priority", "d.priority.set"); - CMD2_REDIRECT ("d.set_throttle_name", "d.throttle_name.set"); - CMD2_REDIRECT ("d.set_tied_to_file", "d.tied_to_file.set"); - CMD2_REDIRECT ("d.set_tracker_numwant", "d.tracker_numwant.set"); - CMD2_REDIRECT ("d.set_uploads_max", "d.uploads_max.set"); - - CMD2_REDIRECT ("create_link", "d.create_link"); - CMD2_REDIRECT ("delete_link", "d.delete_link"); - CMD2_REDIRECT ("delete_tied", "d.delete_tied"); - - // - // Tracker: - // - - CMD2_REDIRECT_TRACKER("t.get_group", "t.group"); - CMD2_REDIRECT_TRACKER("t.get_id", "t.id"); - CMD2_REDIRECT_TRACKER("t.get_min_interval", "t.min_interval"); - CMD2_REDIRECT_TRACKER("t.get_normal_interval", "t.normal_interval"); - CMD2_REDIRECT_TRACKER("t.get_scrape_complete", "t.scrape_complete"); - CMD2_REDIRECT_TRACKER("t.get_scrape_downloaded", "t.scrape_downloaded"); - CMD2_REDIRECT_TRACKER("t.get_scrape_incomplete", "t.scrape_incomplete"); - CMD2_REDIRECT_TRACKER("t.get_scrape_time_last", "t.scrape_time_last"); - CMD2_REDIRECT_TRACKER("t.get_type", "t.type"); - CMD2_REDIRECT_TRACKER("t.get_url", "t.url"); - CMD2_REDIRECT_TRACKER("t.set_enabled", "t.is_enabled.set"); - - // - // File: - // - - CMD2_REDIRECT_FILE ("f.get_completed_chunks", "f.completed_chunks"); - CMD2_REDIRECT_FILE ("f.get_frozen_path", "f.frozen_path"); - CMD2_REDIRECT_FILE ("f.get_last_touched", "f.last_touched"); - CMD2_REDIRECT_FILE ("f.get_match_depth_next", "f.match_depth_next"); - CMD2_REDIRECT_FILE ("f.get_match_depth_prev", "f.match_depth_prev"); - CMD2_REDIRECT_FILE ("f.get_offset", "f.offset"); - CMD2_REDIRECT_FILE ("f.get_path", "f.path"); - CMD2_REDIRECT_FILE ("f.get_path_components", "f.path_components"); - CMD2_REDIRECT_FILE ("f.get_path_depth", "f.path_depth"); - CMD2_REDIRECT_FILE ("f.get_priority", "f.priority"); - CMD2_REDIRECT_FILE ("f.get_range_first", "f.range_first"); - CMD2_REDIRECT_FILE ("f.get_range_second", "f.range_second"); - CMD2_REDIRECT_FILE ("f.get_size_bytes", "f.size_bytes"); - CMD2_REDIRECT_FILE ("f.get_size_chunks", "f.size_chunks"); - CMD2_REDIRECT_FILE ("f.set_priority", "f.priority.set"); - CMD2_REDIRECT_FILE ("fi.get_filename_last", "fi.filename_last"); - - // - // Peer: - // - - CMD2_REDIRECT ("p.get_address", "p.address"); - CMD2_REDIRECT ("p.get_client_version", "p.client_version"); - CMD2_REDIRECT ("p.get_completed_percent", "p.completed_percent"); - CMD2_REDIRECT ("p.get_down_rate", "p.down_rate"); - CMD2_REDIRECT ("p.get_down_total", "p.down_total"); - CMD2_REDIRECT ("p.get_id", "p.id"); - CMD2_REDIRECT ("p.get_id_html", "p.id_html"); - CMD2_REDIRECT ("p.get_options_str", "p.options_str"); - CMD2_REDIRECT ("p.get_peer_rate", "p.peer_rate"); - CMD2_REDIRECT ("p.get_peer_total", "p.peer_total"); - CMD2_REDIRECT ("p.get_port", "p.port"); - CMD2_REDIRECT ("p.get_up_rate", "p.up_rate"); - CMD2_REDIRECT ("p.get_up_total", "p.up_total"); - - // - // View: - // - - CMD2_REDIRECT_GENERIC("view_add", "view.add"); - CMD2_REDIRECT_GENERIC("view_filter", "view.filter"); - CMD2_REDIRECT_GENERIC("view_filter_on", "view.filter_on"); - CMD2_REDIRECT_GENERIC("view_list", "view.list"); - CMD2_REDIRECT_GENERIC("view_set", "view.set"); - CMD2_REDIRECT_GENERIC("view_sort", "view.sort"); - CMD2_REDIRECT_GENERIC("view_sort_current", "view.sort_current"); - CMD2_REDIRECT_GENERIC("view_sort_new", "view.sort_new"); - - // Rename these to avoid conflicts with old style. - CMD2_REDIRECT_GENERIC("d.multicall", "d.multicall2"); - - CMD2_REDIRECT_GENERIC("execute_throw", "execute.throw"); - CMD2_REDIRECT_GENERIC("execute_nothrow", "execute.nothrow"); - CMD2_REDIRECT_GENERIC("execute_raw", "execute.raw"); - CMD2_REDIRECT_GENERIC("execute_raw_nothrow", "execute.raw_nothrow"); - CMD2_REDIRECT_GENERIC("execute_capture", "execute.capture"); - CMD2_REDIRECT_GENERIC("execute_capture_nothrow", "execute.capture_nothrow"); } #endif From a194da08b0e8d5f423daabb9ed1cab7aeba6cc4d Mon Sep 17 00:00:00 2001 From: mvucBmM0 Date: Sat, 6 Aug 2016 03:08:13 +0100 Subject: [PATCH 41/46] Fix Merzlya display (PR #474) --- src/ui/element_download_list.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ui/element_download_list.cc b/src/ui/element_download_list.cc index 5a782751..3f34bb90 100644 --- a/src/ui/element_download_list.cc +++ b/src/ui/element_download_list.cc @@ -225,6 +225,12 @@ ElementDownloadList::receive_change_view(const std::string& name) { void ElementDownloadList::toggle_layout() { - rpc::call_command("download.list.layout.set", (rpc::call_command_value("download.list.layout") + 1)%2); + const std::string layout_name = rpc::call_command_string("ui.torrent_list.layout"); + + if (layout_name == "full") { + rpc::call_command("ui.torrent_list.layout.set", "compact"); + } else if (layout_name == "compact") { + rpc::call_command("ui.torrent_list.layout.set", "full"); + } } } From 55c61e9099f7e6d73e7578bab55386d0953e1fe3 Mon Sep 17 00:00:00 2001 From: kannibalox Date: Sat, 6 Aug 2016 18:41:11 -0400 Subject: [PATCH 42/46] Expose the number of current HTTP connections --- src/command_network.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/command_network.cc b/src/command_network.cc index 93af73bc..760645f6 100644 --- a/src/command_network.cc +++ b/src/command_network.cc @@ -264,6 +264,7 @@ initialize_command_network() { CMD2_ANY_STRING_V("network.http.capath.set", std::bind(&core::CurlStack::set_http_capath, httpStack, std::placeholders::_2)); CMD2_ANY ("network.http.dns_cache_timeout", std::bind(&core::CurlStack::dns_timeout, httpStack)); CMD2_ANY_VALUE_V ("network.http.dns_cache_timeout.set", std::bind(&core::CurlStack::set_dns_timeout, httpStack, std::placeholders::_2)); + CMD2_ANY ("network.http.current_open", std::bind(&core::CurlStack::active, httpStack)); CMD2_ANY ("network.http.max_open", std::bind(&core::CurlStack::max_active, httpStack)); CMD2_ANY_VALUE_V ("network.http.max_open.set", std::bind(&core::CurlStack::set_max_active, httpStack, std::placeholders::_2)); CMD2_ANY ("network.http.proxy_address", std::bind(&core::CurlStack::http_proxy, httpStack)); From 41a059c999339cefd2c1077be9fce4106f3a7869 Mon Sep 17 00:00:00 2001 From: pyroscope Date: Sat, 13 Aug 2016 14:45:00 +0200 Subject: [PATCH 43/46] scale integer values with given unit, not only converted strings (closes #484) --- src/rpc/command.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/command.cc b/src/rpc/command.cc index 1057071c..6d6233c8 100644 --- a/src/rpc/command.cc +++ b/src/rpc/command.cc @@ -77,7 +77,7 @@ command_base_call_value_base(command_base* rawCommand, target_type target, const return command_base::_call::type, T>(rawCommand, target, val); } - return command_base::_call::type, T>(rawCommand, target, arg.as_value()); + return command_base::_call::type, T>(rawCommand, target, unit * arg.as_value()); } template const torrent::Object From 5838b8e68ce51264a0047e48883f2e503b01edc8 Mon Sep 17 00:00:00 2001 From: chros Date: Thu, 25 Aug 2016 12:47:14 +0100 Subject: [PATCH 44/46] Fix fast resume script breaking single file torrents (See #7) --- doc/rtorrent_fast_resume.pl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/rtorrent_fast_resume.pl b/doc/rtorrent_fast_resume.pl index e01849f5..ea9daa8f 100755 --- a/doc/rtorrent_fast_resume.pl +++ b/doc/rtorrent_fast_resume.pl @@ -85,7 +85,7 @@ foreach my $f (0..$#files) { my $mtime = (stat "$d$files[$f]")[9]; # Compute number of chunks per file - my $fsize = $t->{info}{files}[$f]{length}; + my $fsize = (exists $t->{info}{files}) ? $t->{info}{files}[$f]{length} : 1; my $fchunks = ($pmod ? 1 : 0); if ($pmod >= $fsize) { ($fsize, $pmod ) = (0, $pmod-$fsize); } else { ($pmod, $fsize) = (0, $fsize-$pmod); } @@ -101,7 +101,10 @@ foreach my $f (0..$#files) { $t->{libtorrent_resume}{'uncertain_pieces.timestamp'} = time; # Some extra information to re-enforce the fact that this is a finished torrent -$d .= $t->{info}{name}; +if (exists $t->{info}{files}) { + $d .= $t->{info}{name}; +} + $t->{rtorrent} = { state => 1, # started state_changed => time, From dfdbf5e69cd5ad0d930c6f36f76553322e0392be Mon Sep 17 00:00:00 2001 From: chros Date: Thu, 25 Aug 2016 18:38:58 +0100 Subject: [PATCH 45/46] Add init scripts into doc directory (See #10) --- doc/scripts/init/rtorrentInitScreen.bash | 164 ++++++++++++++++++++++ doc/scripts/init/rtorrentInitScreen.sh | 137 +++++++++++++++++++ doc/scripts/init/rtorrentInitTmux.bash | 167 +++++++++++++++++++++++ 3 files changed, 468 insertions(+) create mode 100755 doc/scripts/init/rtorrentInitScreen.bash create mode 100755 doc/scripts/init/rtorrentInitScreen.sh create mode 100755 doc/scripts/init/rtorrentInitTmux.bash diff --git a/doc/scripts/init/rtorrentInitScreen.bash b/doc/scripts/init/rtorrentInitScreen.bash new file mode 100755 index 00000000..75636a03 --- /dev/null +++ b/doc/scripts/init/rtorrentInitScreen.bash @@ -0,0 +1,164 @@ +#!/bin/bash +############# +###### +############# +# This script depends on screen. +# For the stop function to work, you must set an +# explicit session directory using absolute paths (no, ~ is not absolute) in your rtorrent.rc. +# If you typically just start rtorrent with just "rtorrent" on the +# command line, all you need to change is the "user" option. +# Attach to the screen session as your user with +# "screen -dr rtorrent". Change "rtorrent" with srnname option. +# Licensed under the GPLv2 by lostnihilist: lostnihilist _at_ gmail _dot_ com +############## +###### +############## + +####################### +##Start Configuration## +####################### +# You can specify your configuration in a different file +# (so that it is saved with upgrades, saved in your home directory, +# or whatever reason you want to) +# by commenting out/deleting the configuration lines and placing them +# in a text file (say /home/user/.rtorrent.init.conf) exactly as you would +# have written them here (you can leave the comments if you desire +# and then uncommenting the following line correcting the path/filename +# for the one you used. note the space after the ".". +# . /etc/rtorrent.init.conf + + +#Do not put a space on either side of the equal signs e.g. +# user = user +# will not work +# system user to run as (can only use one) +user="user" + +# system user to run as # not implemented, see d_start for beginning implementation +# group=$(id -ng "$user") + +# the full path to the filename where you store your rtorrent configuration +# must keep parentheses around the entire statement, quotations around each config file +config=("$(su -c 'echo $HOME' $user)/.rtorrent.rc") +# Examples: +# config=("/home/user/.rtorrent.rc") +# config=("/home/user/.rtorrent.rc" "/mnt/some/drive/.rtorrent2.rc") +# config=("/home/user/.rtorrent.rc" +# "/mnt/some/drive/.rtorrent2.rc" +# "/mnt/another/drive/.rtorrent3.rc") + +# set of options to run with each instance, separated by a new line +# must keep parentheses around the entire statement +#if no special options, specify with: "" +options=("") +# Examples: +# starts one instance, sourcing both .rtorrent.rc and .rtorrent2.rc +# options=("-o import=~/.rtorrent2.rc") +# starts two instances, ignoring .rtorrent.rc for both, and using +# .rtorrent2.rc for the first, and .rtorrent3.rc for the second +# we do not check for valid options +# options=("-n -o import=~/.rtorrent2.rc" "-n -o import=~/rtorrent3.rc") + +# default directory for screen, needs to be an absolute path +base=$(su -c 'echo $HOME' $user) + +# name of screen session +srnname="rtorrent" + +# file to log to (makes for easier debugging if something goes wrong) +logfile="/var/log/rtorrentInit.log" +####################### +###END CONFIGURATION### +####################### + +PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin +DESC="rtorrent" +NAME=rtorrent +DAEMON=$NAME +SCRIPTNAME=/etc/init.d/$NAME + +checkcnfg() { + exists=0 + for i in `echo "$PATH" | tr ':' '\n'` ; do + if [ -f $i/$NAME ] ; then + exists=1 + break + fi + done + if [ $exists -eq 0 ] ; then + echo "cannot find $NAME binary in PATH: $PATH" | tee -a "$logfile" >&2 + exit 3 + fi + for (( i=0 ; i < ${#config[@]} ; i++ )) ; do + if ! [ -r "${config[i]}" ] ; then + echo "cannot find readable config ${config[i]}. check that it is there and permissions are appropriate" | tee -a "$logfile" >&2 + exit 3 + fi + session=$(getsession "${config[i]}") + if ! [ -d "${session}" ] ; then + echo "cannot find readable session directory ${session} from config ${config[i]}. check permissions" | tee -a "$logfile" >&2 + exit 3 + fi + done +} + +d_start() { + [ -d "${base}" ] && cd "${base}" + stty stop undef && stty start undef + su -c "screen -S "${srnname}" -X screen rtorrent ${options} 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2 + # this works for the screen command, but starting rtorrent below adopts screen session gid + # even if it is not the screen session we started (e.g. running under an undesirable gid + #su -c "screen -ls | grep -sq "\.${srnname}[[:space:]]" " ${user} || su -c "sg \"$group\" -c \"screen -fn -dm -S ${srnname} 2>&1 1>/dev/null\"" ${user} | tee -a "$logfile" >&2 + for (( i=0 ; i < ${#options[@]} ; i++ )) ; do + sleep 3 + su -c "screen -S "${srnname}" -X screen rtorrent ${options[i]} 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2 + done +} + +d_stop() { + for (( i=0 ; i < ${#config[@]} ; i++ )) ; do + session=$(getsession "${config[i]}") + if ! [ -s ${session}/rtorrent.lock ] ; then + return + fi + pid=$(cat ${session}/rtorrent.lock | awk -F: '{print($2)}' | sed "s/[^0-9]//g") + # make sure the pid doesn't belong to another process + if ps -A | grep -sq ${pid}.*rtorrent ; then + kill -s INT ${pid} + fi + done +} + +getsession() { + session=$(cat "$1" | grep "^[[:space:]]*session[[:space:]]*=" | sed "s/^[[:space:]]*session[[:space:]]*=[[:space:]]*//" ) + #session=${session/#~/`getent passwd ${user}|cut -d: -f6`} + echo $session +} + +checkcnfg + +case "$1" in + start) + echo -n "Starting $DESC: $NAME" + d_start + echo "." + ;; + stop) + echo -n "Stopping $DESC: $NAME" + d_stop + echo "." + ;; + restart|force-reload) + echo -n "Restarting $DESC: $NAME" + d_stop + sleep 1 + d_start + echo "." + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/doc/scripts/init/rtorrentInitScreen.sh b/doc/scripts/init/rtorrentInitScreen.sh new file mode 100755 index 00000000..cb71212a --- /dev/null +++ b/doc/scripts/init/rtorrentInitScreen.sh @@ -0,0 +1,137 @@ +#!/bin/sh +############# +###### +############# +# This script depends on screen. +# For the stop function to work, you must set an +# explicit session directory using ABSOLUTE paths (no, ~ is not absolute) in your rtorrent.rc. +# If you typically just start rtorrent with just "rtorrent" on the +# command line, all you need to change is the "user" option. +# Attach to the screen session as your user with +# "screen -dr rtorrent". Change "rtorrent" with srnname option. +# Licensed under the GPLv2 by lostnihilist: lostnihilist _at_ gmail _dot_ com +############## +###### +############## + +####################### +##Start Configuration## +####################### +# You can specify your configuration in a different file +# (so that it is saved with upgrades, saved in your home directory, +# or whateve reason you want to) +# by commenting out/deleting the configuration lines and placing them +# in a text file (say /home/user/.rtorrent.init.conf) exactly as you would +# have written them here (you can leave the comments if you desire +# and then uncommenting the following line correcting the path/filename +# for the one you used. note the space after the ".". +# . /etc/rtorrent.init.conf + +#Do not put a space on either side of the equal signs e.g. +# user = user +# will not work +# system user to run as +user="user" + +# the system group to run as, not implemented, see d_start for beginning implementation +# group=`id -ng "$user"` + +# the full path to the filename where you store your rtorrent configuration +config="`su -c 'echo $HOME' $user`/.rtorrent.rc" + +# set of options to run with +options="" + +# default directory for screen, needs to be an absolute path +base="`su -c 'echo $HOME' $user`" + +# name of screen session +srnname="rtorrent" + +# file to log to (makes for easier debugging if something goes wrong) +logfile="/var/log/rtorrentInit.log" +####################### +###END CONFIGURATION### +####################### +PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin +DESC="rtorrent" +NAME=rtorrent +DAEMON=$NAME +SCRIPTNAME=/etc/init.d/$NAME + +checkcnfg() { + exists=0 + for i in `echo "$PATH" | tr ':' '\n'` ; do + if [ -f $i/$NAME ] ; then + exists=1 + break + fi + done + if [ $exists -eq 0 ] ; then + echo "cannot find rtorrent binary in PATH $PATH" | tee -a "$logfile" >&2 + exit 3 + fi + if ! [ -r "${config}" ] ; then + echo "cannot find readable config ${config}. check that it is there and permissions are appropriate" | tee -a "$logfile" >&2 + exit 3 + fi + session=`getsession "$config"` + if ! [ -d "${session}" ] ; then + echo "cannot find readable session directory ${session} from config ${config}. check permissions" | tee -a "$logfile" >&2 + exit 3 + fi +} + +d_start() { + [ -d "${base}" ] && cd "${base}" + stty stop undef && stty start undef + su -c "screen -ls | grep -sq "\.${srnname}[[:space:]]" " ${user} || su -c "screen -dm -S ${srnname} 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2 + # this works for the screen command, but starting rtorrent below adopts screen session gid + # even if it is not the screen session we started (e.g. running under an undesirable gid + #su -c "screen -ls | grep -sq "\.${srnname}[[:space:]]" " ${user} || su -c "sg \"$group\" -c \"screen -fn -dm -S ${srnname} 2>&1 1>/dev/null\"" ${user} | tee -a "$logfile" >&2 + su -c "screen -S "${srnname}" -X screen rtorrent ${options} 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2 +} + +d_stop() { + session=`getsession "$config"` + if ! [ -s ${session}/rtorrent.lock ] ; then + return + fi + pid=`cat ${session}/rtorrent.lock | awk -F: '{print($2)}' | sed "s/[^0-9]//g"` + if ps -A | grep -sq ${pid}.*rtorrent ; then # make sure the pid doesn't belong to another process + kill -s INT ${pid} + fi +} + +getsession() { + session=`cat "$1" | grep "^[[:space:]]*session[[:space:]]*=" | sed "s/^[[:space:]]*session[[:space:]]*=[[:space:]]*//" ` + echo $session +} + +checkcnfg + +case "$1" in + start) + echo -n "Starting $DESC: $NAME" + d_start + echo "." + ;; + stop) + echo -n "Stopping $DESC: $NAME" + d_stop + echo "." + ;; + restart|force-reload) + echo -n "Restarting $DESC: $NAME" + d_stop + sleep 1 + d_start + echo "." + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/doc/scripts/init/rtorrentInitTmux.bash b/doc/scripts/init/rtorrentInitTmux.bash new file mode 100755 index 00000000..5af84337 --- /dev/null +++ b/doc/scripts/init/rtorrentInitTmux.bash @@ -0,0 +1,167 @@ +#!/bin/bash +### BEGIN INIT INFO +# Provides: rtorrent_autostart +# Required-Start: $local_fs $remote_fs $network $syslog $netdaemons +# Required-Stop: $local_fs $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: rtorrent script using tmux +# Description: rtorrent script using tmux +### END INIT INFO + +############# +###### +############# +# This script depends on tmux and is based on 'rtorrentInitScreen.sh' script +# with the following enhancements: +# - init script 'start' option can be called without breaking anything +# - init script 'status' option can be used in scripts to determine whether rtorrent is running or not +# - auto removes damaged/stuck 'rtorrent.lock' file if necessary +# - saves session (just in case) before stopping with 'rtxmlrp' if it exists +# - provides examples how to script tmux windows +# +# For the stop function to work, you must set an explicit session directory +# using ABSOLUTE paths (no, ~ is not absolute) in your rtorrent.rc and with +# "sessiondir" option. +# If you typically just start rtorrent with just "rtorrent" on the +# command line, all you need to change is the "user" and "sessiondir" option. +# Attach to the tmux session as your user with +# "tmux -2u new-session -A -s rtorrent". Change "rtorrent" with "tmuxname" option. +# Licensed under the GPLv2 by lostnihilist: lostnihilist _at_ gmail _dot_ com +############## +###### +############## + +####################### +##Start Configuration## +####################### +# You can specify your configuration in a different file. +# (so that it is saved with upgrades, saved in your home directory, +# or whatever reason you want to) +# by commenting out/deleting the configuration lines and placing them +# in a text file (say /home/user/.rtorrent.init.conf) exactly as you would +# have written them here (you can leave the comments if you desire +# and then uncommenting the following line correcting the path/filename. +# for the one you used. note the space after the ".". +# . /etc/rtorrent.init.conf + +# system user to run as +user="username" + +# default directory for tmux, needs to be an absolute path +base=$(su -c 'echo $HOME' $user) + +# the full path to the filename where you store your rtorrent configuration +config="$base/.rtorrent.rc" + +# the full path to the session directory of rtorrent +sessiondir="/mnt/Torrents/.rtorrent/.session" + +# options to pass to rtorrent; e.g. don't read config from $HOME but load alternate +#options="-n -O import=$config" +options="" + +# name of tmux session +tmuxname="rtorrent" + +# name of window in tmux session +DESC="rT" +####################### +###END CONFIGURATION### +####################### +PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin +NAME=rtorrent +DDIR="/opt/rtorrent/bin" +DAEMON=$NAME +SCRIPTNAME=/etc/init.d/$NAME +RTXMLRPCBIN="$base/bin/rtxmlrpc" + + +checkcnfg() { + if [ -z "$(which $DAEMON)" ] ; then + echo "Cannot find $DAEMON binary in PATH: $PATH" + exit 3 + fi + if ! [ -r "$config" ] ; then + echo "Cannot find readable config $config. Check that it is there and permissions are appropriate" + exit 3 + fi + if ! [ -d "$sessiondir" ] ; then + echo "Cannot find readable session directory $sessiondir from config $config. Check permissions" + exit 3 + fi +} + + +status() { + if [ -e "${sessiondir}/rtorrent.lock" ] ; then + pid=`cat ${sessiondir}/rtorrent.lock | awk -F: '{print($2)}' | sed "s/[^0-9]//g"` + # make sure the pid isn't empty and doesn't belong to another process : this will match lines containing rtorrent, which grep '[r]torrent' does not! + # if there is no process as the 'pid' suggests then delete the stuck "rtorrent.lock" file (to be able to start rtorrent) + [[ -n "$pid" ]] && ps aux | grep -sq ${pid}.*[r]torrent && echo -e ${pid} || rm -f "${sessiondir}/rtorrent.lock" + fi +} + + +d_start() { + [ -d "$base" ] && cd "$base" + # if STDIN is a terminal (we are using interactive mode) + [ -t 0 ] && stty stop undef && stty start undef + # start the default 2 tmux window (bash and mc) if there isn't tmux session called "tmuxname" option (rtorrent) + if ! su -c "tmux ls | grep -sq ${tmuxname}: " $user ; then + # 1st window (0): split it into 3 panes, display 'date' in the last one + su -c "tmux -2u new-session -d -s ${tmuxname} -n 'shell1'" $user + su -c "tmux -2u split-window -v -t ${tmuxname}:0 'bash'" $user + su -c "tmux -2u split-window -h -t ${tmuxname}:0 'date; bash'" $user + # 2nd window (1): start 'mc' if it exists + su -c "tmux -2u new-window -t ${tmuxname}:1 -n 'mc1' 'command which mc && mc ~/; bash'" $user + fi + # start rtorrent always in the 3rd tmux window (2) if it's not running and leave shell behind to be able to see reason of a crash + if [ "$(status)" == "" ]; then + su -c "tmux -2u list-panes -t ${tmuxname}:2 &>/dev/null && tmux -2u respawn-pane -t ${tmuxname}:2 -k \"${DDIR}/${DAEMON} ${options}; bash\" || tmux -2u new-window -t ${tmuxname}:2 -n ${DESC} \"${DDIR}/${DAEMON} ${options}; bash\"" $user + fi +} + + +d_stop() { + pid=$(status) + if [ "$pid" != "" ]; then + # save session before stopping explicitly (just in case) if rtxmlrpc util exists then wait for 5 seconds to be able to complete it + [ -L "$RTXMLRPCBIN" ] && "$RTXMLRPCBIN" session.save &>/dev/null && sleep 5 + # INT (2, Interrupt from keyboard): normal shutdown + kill -s INT $pid + fi +} + + +checkcnfg + + +case "$1" in + start) + echo -n "Starting $DESC: $NAME" + d_start + echo "." + ;; + stop) + echo -n "Stopping $DESC: $NAME" + d_stop + echo "." + ;; + restart|force-reload) + echo -n "Restarting $DESC: $NAME" + d_stop + sleep 1 + d_start + echo "." + ;; + status) + status + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}" >&2 + exit 1 + ;; +esac + +exit 0 From 017cb1bd591750accb92e88023b84b69feba91aa Mon Sep 17 00:00:00 2001 From: chros Date: Thu, 25 Aug 2016 19:04:11 +0100 Subject: [PATCH 46/46] Fixing variables in rtorrentInitTmux.bash script (See #10) --- doc/scripts/init/rtorrentInitTmux.bash | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/scripts/init/rtorrentInitTmux.bash b/doc/scripts/init/rtorrentInitTmux.bash index 5af84337..1b93cc79 100755 --- a/doc/scripts/init/rtorrentInitTmux.bash +++ b/doc/scripts/init/rtorrentInitTmux.bash @@ -65,13 +65,12 @@ options="" tmuxname="rtorrent" # name of window in tmux session -DESC="rT" +tmuxwindowname="rT" ####################### ###END CONFIGURATION### ####################### PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin NAME=rtorrent -DDIR="/opt/rtorrent/bin" DAEMON=$NAME SCRIPTNAME=/etc/init.d/$NAME RTXMLRPCBIN="$base/bin/rtxmlrpc" @@ -118,7 +117,7 @@ d_start() { fi # start rtorrent always in the 3rd tmux window (2) if it's not running and leave shell behind to be able to see reason of a crash if [ "$(status)" == "" ]; then - su -c "tmux -2u list-panes -t ${tmuxname}:2 &>/dev/null && tmux -2u respawn-pane -t ${tmuxname}:2 -k \"${DDIR}/${DAEMON} ${options}; bash\" || tmux -2u new-window -t ${tmuxname}:2 -n ${DESC} \"${DDIR}/${DAEMON} ${options}; bash\"" $user + su -c "tmux -2u list-panes -t ${tmuxname}:2 &>/dev/null && tmux -2u respawn-pane -t ${tmuxname}:2 -k \"${DAEMON} ${options}; bash\" || tmux -2u new-window -t ${tmuxname}:2 -n ${tmuxwindowname} \"${DAEMON} ${options}; bash\"" $user fi } @@ -139,17 +138,17 @@ checkcnfg case "$1" in start) - echo -n "Starting $DESC: $NAME" + echo -n "Starting $tmuxwindowname: $NAME" d_start echo "." ;; stop) - echo -n "Stopping $DESC: $NAME" + echo -n "Stopping $tmuxwindowname: $NAME" d_stop echo "." ;; restart|force-reload) - echo -n "Restarting $DESC: $NAME" + echo -n "Restarting $tmuxwindowname: $NAME" d_stop sleep 1 d_start