mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-04 21:29:21 +00:00
* Added slot map's for insert/erase, open/close, start/stop and
finished downloads in DownloadList, moved stuff from core::Manager to the slot maps. * Added check hash key ^r, though triggering check hash on finished signals currently borks. * Made tracker dump into an option. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@470 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -44,8 +44,10 @@ In main window:
|
||||
|
||||
Right - View torrent
|
||||
|
||||
Ctrl-S - Start torrent
|
||||
Ctrl-D - Stop/delete torrent
|
||||
^s - Start torrent
|
||||
^d - Stop/delete torrent
|
||||
|
||||
^r - Manually start a hash check of the torrent
|
||||
|
||||
|
||||
In torrent view:
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
# Port range to use for listening.
|
||||
#port = 6890-6999
|
||||
|
||||
#
|
||||
# Do not modify the following parameters unless you know what you're doing.
|
||||
#
|
||||
|
||||
# Hash read-ahead controls how many MB to request the kernel to read
|
||||
# ahead. If the value is too low the disk may not be fully utilized,
|
||||
# while if too high the kernel might not be able to keep the read
|
||||
@@ -38,3 +42,6 @@
|
||||
|
||||
# Max number of files to keep open simultaniously.
|
||||
#max_open_files = 100
|
||||
|
||||
# Dump data received from trackers to the files "./tracker_dump.<time>".
|
||||
#dump_tracker = no
|
||||
|
||||
@@ -47,6 +47,8 @@ public:
|
||||
void open() { m_download.open(); }
|
||||
void close() { m_download.close(); }
|
||||
|
||||
void hash_resume_save() { m_download.hash_resume_save(); }
|
||||
|
||||
bool operator == (const std::string& str) { return str == m_download.get_hash(); }
|
||||
|
||||
private:
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sigc++/bind.h>
|
||||
#include <torrent/torrent.h>
|
||||
|
||||
#include "rak/functional.h"
|
||||
@@ -38,14 +39,18 @@ DownloadList::insert(std::istream* str) {
|
||||
|
||||
iterator itr = Base::insert(end(), new Download);
|
||||
(*itr)->set_download(d);
|
||||
(*itr)->get_download().signal_download_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::finished), *itr));
|
||||
|
||||
m_slotMapInsert.for_each(*itr);
|
||||
|
||||
return itr;
|
||||
}
|
||||
|
||||
DownloadList::iterator
|
||||
DownloadList::erase(iterator itr) {
|
||||
(*itr)->release_download();
|
||||
m_slotMapErase.for_each(*itr);
|
||||
|
||||
(*itr)->release_download();
|
||||
torrent::download_remove((*itr)->get_hash());
|
||||
delete *itr;
|
||||
|
||||
@@ -59,4 +64,9 @@ DownloadList::clear() {
|
||||
Base::clear();
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::finished(Download* d) {
|
||||
m_slotMapFinished.for_each(d);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <iosfwd>
|
||||
#include <list>
|
||||
|
||||
#include "download_slot_map.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
class Download;
|
||||
@@ -51,11 +53,37 @@ public:
|
||||
|
||||
~DownloadList() { clear(); }
|
||||
|
||||
iterator insert(std::istream* str);
|
||||
iterator erase(iterator itr);
|
||||
iterator insert(std::istream* str);
|
||||
iterator erase(iterator itr);
|
||||
|
||||
void open(Download* d) { m_slotMapOpen.for_each(d); }
|
||||
void close(Download* d) { m_slotMapClose.for_each(d); }
|
||||
|
||||
void start(Download* d) { m_slotMapStart.for_each(d); }
|
||||
void stop(Download* d) { m_slotMapStop.for_each(d); }
|
||||
|
||||
DownloadSlotMap& slot_map_insert() { return m_slotMapInsert; }
|
||||
DownloadSlotMap& slot_map_erase() { return m_slotMapErase; }
|
||||
DownloadSlotMap& slot_map_open() { return m_slotMapOpen; }
|
||||
DownloadSlotMap& slot_map_close() { return m_slotMapClose; }
|
||||
DownloadSlotMap& slot_map_start() { return m_slotMapStart; }
|
||||
DownloadSlotMap& slot_map_stop() { return m_slotMapStop; }
|
||||
|
||||
DownloadSlotMap& slot_map_finished() { return m_slotMapFinished; }
|
||||
|
||||
private:
|
||||
void clear();
|
||||
void clear();
|
||||
|
||||
void finished(Download* d);
|
||||
|
||||
DownloadSlotMap m_slotMapInsert;
|
||||
DownloadSlotMap m_slotMapErase;
|
||||
DownloadSlotMap m_slotMapOpen;
|
||||
DownloadSlotMap m_slotMapClose;
|
||||
DownloadSlotMap m_slotMapStart;
|
||||
DownloadSlotMap m_slotMapStop;
|
||||
|
||||
DownloadSlotMap m_slotMapFinished;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ public:
|
||||
typedef sigc::slot1<void, Download*> SlotDownload;
|
||||
typedef std::map<std::string, SlotDownload> Base;
|
||||
|
||||
void insert(const std::string& key, SlotDownload s) { Base::operator[](key) = s; }
|
||||
void insert(const std::string& key, SlotDownload s) { Base::operator[](key) = s; }
|
||||
|
||||
void for_each(Download* d);
|
||||
void for_each(Download* d);
|
||||
};
|
||||
|
||||
inline void
|
||||
|
||||
+13
-13
@@ -54,36 +54,36 @@ public:
|
||||
using Base::empty;
|
||||
using Base::size;
|
||||
|
||||
void insert(Download* d, Slot s);
|
||||
void insert(Download* d, Slot s);
|
||||
|
||||
// It's safe to try to remove downloads not in the queue. The hash
|
||||
// checking is not stopped if it has already started.
|
||||
void remove(Download* d);
|
||||
void remove(Download* d);
|
||||
|
||||
iterator find(Download* d);
|
||||
iterator find(Download* d);
|
||||
|
||||
private:
|
||||
void receive_hash_done(Download* d);
|
||||
void receive_hash_done(Download* d);
|
||||
|
||||
void fill_queue();
|
||||
void fill_queue();
|
||||
};
|
||||
|
||||
class HashQueueNode {
|
||||
public:
|
||||
HashQueueNode(Download* d, HashQueue::Slot s) : m_download(d), m_slot(s) {}
|
||||
~HashQueueNode() { disconnect(); }
|
||||
~HashQueueNode() { disconnect(); }
|
||||
|
||||
void disconnect() { m_connection.disconnect(); }
|
||||
void disconnect() { m_connection.disconnect(); }
|
||||
|
||||
Download* get_download() { return m_download; }
|
||||
HashQueue::Slot get_slot() { return m_slot; }
|
||||
Download* get_download() { return m_download; }
|
||||
HashQueue::Slot get_slot() { return m_slot; }
|
||||
|
||||
void set_connection(sigc::connection c) { m_connection = c; }
|
||||
void set_connection(sigc::connection c) { m_connection = c; }
|
||||
|
||||
private:
|
||||
Download* m_download;
|
||||
HashQueue::Slot m_slot;
|
||||
sigc::connection m_connection;
|
||||
Download* m_download;
|
||||
HashQueue::Slot m_slot;
|
||||
sigc::connection m_connection;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+69
-61
@@ -27,9 +27,8 @@
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
#include <sigc++/bind.h>
|
||||
#include <sigc++/hide.h>
|
||||
#include <torrent/bencode.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/torrent.h>
|
||||
@@ -40,6 +39,11 @@
|
||||
|
||||
namespace core {
|
||||
|
||||
static void
|
||||
connect_signal_network_log(Download* d, torrent::Download::SlotString s) {
|
||||
d->get_download().signal_network_log(s);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::initialize() {
|
||||
torrent::Http::set_factory(m_poll.get_http_factory());
|
||||
@@ -47,12 +51,32 @@ Manager::initialize() {
|
||||
|
||||
CurlStack::init();
|
||||
|
||||
//torrent::initialize();
|
||||
|
||||
if (!torrent::listen_open(m_portFirst, m_portLast))
|
||||
throw std::runtime_error("Could not open port for listening.");
|
||||
|
||||
// Register log signals.
|
||||
// Register slots to be called when a download is inserted/erased,
|
||||
// opened or closed.
|
||||
m_downloadList.slot_map_insert().insert("1_connect_network_log", sigc::bind(sigc::ptr_fun(&connect_signal_network_log), sigc::mem_fun(m_logComplete, &Log::push_front)));
|
||||
m_downloadList.slot_map_insert().insert("2_manager_start", sigc::mem_fun(*this, &Manager::start));
|
||||
m_downloadList.slot_map_insert().insert("3_store_save", sigc::mem_fun(m_downloadStore, &DownloadStore::save));
|
||||
|
||||
m_downloadList.slot_map_erase().insert("1_hash_queue_remove", sigc::mem_fun(m_hashQueue, &HashQueue::remove));
|
||||
m_downloadList.slot_map_erase().insert("1_store_remove", sigc::mem_fun(m_downloadStore, &DownloadStore::remove));
|
||||
|
||||
m_downloadList.slot_map_open().insert("1_download_open", sigc::mem_fun(&Download::open));
|
||||
|
||||
// Currently does not call stop, might want to add a function that
|
||||
// checks if we're running, and if so stop?
|
||||
m_downloadList.slot_map_close().insert("1_download_close", sigc::mem_fun(&Download::close));
|
||||
m_downloadList.slot_map_close().insert("1_hash_queue_remove", sigc::mem_fun(m_hashQueue, &HashQueue::remove));
|
||||
|
||||
m_downloadList.slot_map_start().insert("1_download_start", sigc::mem_fun(&Download::start));
|
||||
|
||||
m_downloadList.slot_map_stop().insert("1_download_stop", sigc::mem_fun(&Download::stop));
|
||||
m_downloadList.slot_map_stop().insert("2_hash_resume_save", sigc::mem_fun(&Download::hash_resume_save));
|
||||
m_downloadList.slot_map_stop().insert("3_store_save", sigc::mem_fun(m_downloadStore, &DownloadStore::save));
|
||||
|
||||
//m_downloadList.slot_map_finished().insert("1_check_hash", sigc::mem_fun(*this, &Manager::check_hash));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -66,10 +90,12 @@ Manager::cleanup() {
|
||||
|
||||
void
|
||||
Manager::insert(std::string uri) {
|
||||
if (std::strncmp(uri.c_str(), "http://", 7))
|
||||
create_file(uri);
|
||||
else
|
||||
if (std::strncmp(uri.c_str(), "http://", 7) == 0) {
|
||||
create_http(uri);
|
||||
} else {
|
||||
std::fstream f(uri.c_str(), std::ios::in);
|
||||
create_final(&f);
|
||||
}
|
||||
}
|
||||
|
||||
Manager::iterator
|
||||
@@ -80,9 +106,6 @@ Manager::erase(DownloadList::iterator itr) {
|
||||
if (!(*itr)->get_download().is_open())
|
||||
throw std::logic_error("core::Manager::erase(...) called on an closed download");
|
||||
|
||||
m_hashQueue.remove(*itr);
|
||||
m_downloadStore.remove(*itr);
|
||||
|
||||
return m_downloadList.erase(itr);
|
||||
}
|
||||
|
||||
@@ -93,13 +116,13 @@ Manager::start(Download* d) {
|
||||
return;
|
||||
|
||||
if (!d->get_download().is_open())
|
||||
d->open();
|
||||
m_downloadList.open(d);
|
||||
|
||||
if (d->get_download().is_hash_checked())
|
||||
d->start();
|
||||
m_downloadList.start(d);
|
||||
else
|
||||
// This can cause infinit loops.
|
||||
m_hashQueue.insert(d, sigc::mem_fun(d, &Download::start));
|
||||
m_hashQueue.insert(d, sigc::bind(sigc::mem_fun(m_downloadList, &DownloadList::start), d));
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
m_logImportant.push_front(e.what());
|
||||
@@ -110,13 +133,7 @@ Manager::start(Download* d) {
|
||||
void
|
||||
Manager::stop(Download* d) {
|
||||
try {
|
||||
m_hashQueue.remove(d);
|
||||
d->stop();
|
||||
|
||||
if (d->get_download().is_hash_checked())
|
||||
d->get_download().hash_save();
|
||||
|
||||
m_downloadStore.save(d);
|
||||
m_downloadList.stop(d);
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
m_logImportant.push_front(e.what());
|
||||
@@ -125,17 +142,34 @@ Manager::stop(Download* d) {
|
||||
}
|
||||
|
||||
void
|
||||
Manager::receive_http_failed(std::string msg) {
|
||||
m_logImportant.push_front("Http download error: \"" + msg + "\"");
|
||||
m_logComplete.push_front("Http download error: \"" + msg + "\"");
|
||||
}
|
||||
Manager::check_hash(Download* d) {
|
||||
bool restart = d->get_download().is_active();
|
||||
|
||||
void
|
||||
Manager::create_file(const std::string& uri) {
|
||||
std::fstream f(uri.c_str(), std::ios::in);
|
||||
|
||||
create_final(&f);
|
||||
}
|
||||
try {
|
||||
if (d->get_download().is_active())
|
||||
m_downloadList.stop(d);
|
||||
|
||||
m_downloadList.close(d);
|
||||
d->get_download().hash_resume_clear();
|
||||
m_downloadList.open(d);
|
||||
|
||||
if (d->get_download().is_hash_checking() ||
|
||||
d->get_download().is_hash_checked())
|
||||
throw std::logic_error("Manager::check_hash(...) closed the torrent but is_hash_check{ing,ed}() == true");
|
||||
|
||||
if (m_hashQueue.find(d) != m_hashQueue.end())
|
||||
throw std::logic_error("Manager::check_hash(...) closed the torrent but it was found in m_hashQueue");
|
||||
|
||||
if (restart)
|
||||
m_hashQueue.insert(d, sigc::bind(sigc::mem_fun(m_downloadList, &DownloadList::start), d));
|
||||
else
|
||||
m_hashQueue.insert(d, sigc::slot0<void>());
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
m_logImportant.push_front(e.what());
|
||||
m_logComplete.push_front(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Manager::create_http(const std::string& uri) {
|
||||
@@ -149,12 +183,7 @@ Manager::create_http(const std::string& uri) {
|
||||
void
|
||||
Manager::create_final(std::istream* s) {
|
||||
try {
|
||||
iterator itr = m_downloadList.insert(s);
|
||||
|
||||
setup_download(*itr);
|
||||
start(*itr);
|
||||
|
||||
m_downloadStore.save(*itr);
|
||||
m_downloadList.insert(s);
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
// What to do? Keep in list for now.
|
||||
@@ -164,30 +193,9 @@ Manager::create_final(std::istream* s) {
|
||||
}
|
||||
|
||||
void
|
||||
Manager::setup_download(Download* d) {
|
||||
m_defaultSettings.for_each(d);
|
||||
|
||||
if (m_debugTracker >= 0)
|
||||
d->get_download().signal_tracker_dump(sigc::mem_fun(*this, &Manager::receive_debug_tracker));
|
||||
|
||||
// If we want to monitor network stuff.
|
||||
d->get_download().signal_network_log(sigc::mem_fun(m_logComplete, &Log::push_front));
|
||||
}
|
||||
|
||||
void
|
||||
Manager::receive_debug_tracker(std::istream* s) {
|
||||
std::stringstream filename;
|
||||
filename << "./tracker_dump." << m_debugTracker++;
|
||||
|
||||
std::fstream out(filename.str().c_str(), std::ios::out | std::ios::trunc);
|
||||
|
||||
if (!out.is_open())
|
||||
return;
|
||||
|
||||
s->seekg(0);
|
||||
|
||||
std::copy(std::istream_iterator<char>(*s), std::istream_iterator<char>(),
|
||||
std::ostream_iterator<char>(out));
|
||||
Manager::receive_http_failed(std::string msg) {
|
||||
m_logImportant.push_front("Http download error: \"" + msg + "\"");
|
||||
m_logComplete.push_front("Http download error: \"" + msg + "\"");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-11
@@ -26,7 +26,6 @@
|
||||
#include <iosfwd>
|
||||
|
||||
#include "download_list.h"
|
||||
#include "download_slot_map.h"
|
||||
#include "download_store.h"
|
||||
#include "hash_queue.h"
|
||||
#include "http_queue.h"
|
||||
@@ -52,8 +51,6 @@ public:
|
||||
HashQueue& get_hash_queue() { return m_hashQueue; }
|
||||
HttpQueue& get_http_queue() { return m_httpQueue; }
|
||||
|
||||
DownloadSlotMap& get_default_settings() { return m_defaultSettings; }
|
||||
|
||||
Poll& get_poll() { return m_poll; }
|
||||
Log& get_log_important() { return m_logImportant; }
|
||||
Log& get_log_complete() { return m_logComplete; }
|
||||
@@ -74,24 +71,17 @@ public:
|
||||
void debug_tracker() { m_debugTracker = 0; }
|
||||
|
||||
private:
|
||||
void receive_http_failed(std::string msg);
|
||||
|
||||
void create_file(const std::string& uri);
|
||||
void create_http(const std::string& uri);
|
||||
|
||||
void create_final(std::istream* s);
|
||||
|
||||
void setup_download(Download* itr);
|
||||
|
||||
void receive_debug_tracker(std::istream* s);
|
||||
void receive_http_failed(std::string msg);
|
||||
|
||||
DownloadList m_downloadList;
|
||||
DownloadStore m_downloadStore;
|
||||
HashQueue m_hashQueue;
|
||||
HttpQueue m_httpQueue;
|
||||
|
||||
DownloadSlotMap m_defaultSettings;
|
||||
|
||||
Poll m_poll;
|
||||
Log m_logImportant;
|
||||
Log m_logComplete;
|
||||
|
||||
+30
-11
@@ -22,15 +22,17 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <torrent/http.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <sstream>
|
||||
#include <sigc++/bind.h>
|
||||
#include <sigc++/retype_return.h>
|
||||
#include <torrent/http.h>
|
||||
#include <torrent/torrent.h>
|
||||
|
||||
#ifdef USE_EXECINFO
|
||||
#include <execinfo.h>
|
||||
@@ -97,7 +99,6 @@ parse_options(ui::Control* c, OptionHandler* optionHandler, int argc, char** arg
|
||||
|
||||
// Converted.
|
||||
optionParser.insert_flag('h', sigc::ptr_fun(&print_help));
|
||||
optionParser.insert_flag('t', sigc::mem_fun(c->get_core(), &core::Manager::debug_tracker));
|
||||
|
||||
optionParser.insert_option('b', sigc::bind<0>(sigc::mem_fun(*optionHandler, &OptionHandler::process), "bind"));
|
||||
optionParser.insert_option('d', sigc::bind<0>(sigc::mem_fun(*optionHandler, &OptionHandler::process), "directory"));
|
||||
@@ -112,18 +113,19 @@ parse_options(ui::Control* c, OptionHandler* optionHandler, int argc, char** arg
|
||||
|
||||
void
|
||||
initialize_option_handler(ui::Control* c, OptionHandler* optionHandler) {
|
||||
core::DownloadSlotMap* dsm = &c->get_core().get_default_settings();
|
||||
core::DownloadSlotMap* dsmInsert = &c->get_core().get_download_list().slot_map_insert();
|
||||
|
||||
optionHandler->insert("min_peers", new OptionHandlerDownloadInt(dsm, &apply_download_min_peers, &validate_download_peers));
|
||||
optionHandler->insert("max_peers", new OptionHandlerDownloadInt(dsm, &apply_download_max_peers, &validate_download_peers));
|
||||
optionHandler->insert("max_uploads", new OptionHandlerDownloadInt(dsm, &apply_download_max_uploads, &validate_download_peers));
|
||||
optionHandler->insert("min_peers", new OptionHandlerDownloadInt(dsmInsert, &apply_download_min_peers, &validate_download_peers));
|
||||
optionHandler->insert("max_peers", new OptionHandlerDownloadInt(dsmInsert, &apply_download_max_peers, &validate_download_peers));
|
||||
optionHandler->insert("max_uploads", new OptionHandlerDownloadInt(dsmInsert, &apply_download_max_uploads, &validate_download_peers));
|
||||
|
||||
optionHandler->insert("download_rate", new OptionHandlerInt(c, &apply_global_download_rate, &validate_rate));
|
||||
optionHandler->insert("upload_rate", new OptionHandlerInt(c, &apply_global_upload_rate, &validate_rate));
|
||||
optionHandler->insert("hash_read_ahead", new OptionHandlerInt(c, &apply_hash_read_ahead, &validate_read_ahead));
|
||||
optionHandler->insert("max_open_files", new OptionHandlerInt(c, &apply_max_open_files, &validate_fd));
|
||||
|
||||
optionHandler->insert("directory", new OptionHandlerDownloadString(dsm, &apply_download_directory, &validate_directory));
|
||||
optionHandler->insert("directory", new OptionHandlerDownloadString(dsmInsert, &apply_download_directory, &validate_directory));
|
||||
optionHandler->insert("dump_tracker", new OptionHandlerDownloadString(dsmInsert, &apply_download_dump_tracker, &validate_yes_no));
|
||||
|
||||
optionHandler->insert("ip", new OptionHandlerString(c, &apply_ip, &validate_ip));
|
||||
optionHandler->insert("bind", new OptionHandlerString(c, &apply_bind, &validate_ip));
|
||||
@@ -272,6 +274,22 @@ do_panic(int signum) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
void
|
||||
receive_dump_tracker(std::istream* s) {
|
||||
std::stringstream filename;
|
||||
filename << "./tracker_dump." << utils::Timer::current().sec();
|
||||
|
||||
std::fstream out(filename.str().c_str(), std::ios::out | std::ios::trunc);
|
||||
|
||||
if (!out.is_open())
|
||||
return;
|
||||
|
||||
s->seekg(0);
|
||||
|
||||
std::copy(std::istream_iterator<char>(*s), std::istream_iterator<char>(),
|
||||
std::ostream_iterator<char>(out));
|
||||
}
|
||||
|
||||
void
|
||||
print_help() {
|
||||
std::cout << "Rakshasa's BitTorrent client " VERSION "." << std::endl;
|
||||
@@ -292,6 +310,7 @@ print_help() {
|
||||
std::cout << " backspace Add a torrent url or path" << std::endl;
|
||||
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 << " ^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;
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "ui/control.h"
|
||||
#include "option_handler_rules.h"
|
||||
|
||||
void receive_dump_tracker(std::istream* s);
|
||||
|
||||
bool
|
||||
validate_ip(const std::string& arg) {
|
||||
struct in_addr addr;
|
||||
@@ -49,6 +51,11 @@ validate_port_range(const std::string& arg) {
|
||||
a <= b && a > 0 && b < (1 << 16);
|
||||
}
|
||||
|
||||
bool
|
||||
validate_yes_no(const std::string& arg) {
|
||||
return arg == "yes" || arg == "no";
|
||||
}
|
||||
|
||||
bool
|
||||
validate_download_peers(int arg) {
|
||||
return arg > 0 && arg < (1 << 16);
|
||||
@@ -91,6 +98,11 @@ apply_download_directory(core::Download* d, const std::string& arg) {
|
||||
(d->get_download().get_entry_size() > 1 ? d->get_download().get_name() : ""));
|
||||
}
|
||||
|
||||
void
|
||||
apply_download_dump_tracker(core::Download* d, const std::string& arg) {
|
||||
d->get_download().signal_tracker_dump(sigc::ptr_fun(&receive_dump_tracker));
|
||||
}
|
||||
|
||||
void
|
||||
apply_global_download_rate(ui::Control* m, int arg) {
|
||||
torrent::set_read_throttle(arg * 1024);
|
||||
|
||||
+48
-45
@@ -37,6 +37,7 @@ namespace ui {
|
||||
bool validate_ip(const std::string& arg);
|
||||
bool validate_directory(const std::string& arg);
|
||||
bool validate_port_range(const std::string& arg);
|
||||
bool validate_yes_no(const std::string& arg);
|
||||
|
||||
bool validate_download_peers(int arg);
|
||||
bool validate_rate(int arg);
|
||||
@@ -48,6 +49,7 @@ void apply_download_max_peers(core::Download* d, int arg);
|
||||
void apply_download_max_uploads(core::Download* d, int arg);
|
||||
|
||||
void apply_download_directory(core::Download* d, const std::string& arg);
|
||||
void apply_download_dump_tracker(core::Download* d, const std::string& arg);
|
||||
|
||||
void apply_global_download_rate(ui::Control* m, int arg);
|
||||
void apply_global_upload_rate(ui::Control* m, int arg);
|
||||
@@ -58,51 +60,7 @@ void apply_max_open_files(ui::Control* m, int arg);
|
||||
void apply_ip(ui::Control* m, const std::string& arg);
|
||||
void apply_bind(ui::Control* m, const std::string& arg);
|
||||
void apply_port_range(ui::Control* m, const std::string& arg);
|
||||
|
||||
class OptionHandlerDownloadInt : public OptionHandlerBase {
|
||||
public:
|
||||
typedef void (*Apply)(core::Download*, int);
|
||||
typedef bool (*Validate)(int);
|
||||
|
||||
OptionHandlerDownloadInt(core::DownloadSlotMap* m, Apply a, Validate v) :
|
||||
m_map(m), m_apply(a), m_validate(v) {}
|
||||
|
||||
virtual void process(const std::string& key, const std::string& arg) {
|
||||
int a;
|
||||
|
||||
if (std::sscanf(arg.c_str(), "%i", &a) != 1 ||
|
||||
!m_validate(a))
|
||||
throw std::runtime_error("Invalid argument for \"" + key + "\": \"" + arg + "\"");
|
||||
|
||||
(*m_map)[key] = sigc::bind(sigc::ptr_fun(m_apply), a);
|
||||
}
|
||||
|
||||
private:
|
||||
core::DownloadSlotMap* m_map;
|
||||
Apply m_apply;
|
||||
Validate m_validate;
|
||||
};
|
||||
|
||||
class OptionHandlerString : public OptionHandlerBase {
|
||||
public:
|
||||
typedef bool (*Validate)(const std::string&);
|
||||
typedef void (*Apply)(ui::Control*, const std::string&);
|
||||
|
||||
OptionHandlerString(ui::Control* c, Apply a, Validate v) :
|
||||
m_control(c), m_apply(a), m_validate(v) {}
|
||||
|
||||
virtual void process(const std::string& key, const std::string& arg) {
|
||||
if (!m_validate(arg))
|
||||
throw std::runtime_error("Invalid argument for \"" + key + "\": \"" + arg + "\"");
|
||||
|
||||
m_apply(m_control, arg);
|
||||
}
|
||||
|
||||
private:
|
||||
ui::Control* m_control;
|
||||
Apply m_apply;
|
||||
Validate m_validate;
|
||||
};
|
||||
void apply_tracker_dump(ui::Control* m, const std::string& arg);
|
||||
|
||||
class OptionHandlerInt : public OptionHandlerBase {
|
||||
public:
|
||||
@@ -128,6 +86,51 @@ private:
|
||||
Validate m_validate;
|
||||
};
|
||||
|
||||
class OptionHandlerString : public OptionHandlerBase {
|
||||
public:
|
||||
typedef bool (*Validate)(const std::string&);
|
||||
typedef void (*Apply)(ui::Control*, const std::string&);
|
||||
|
||||
OptionHandlerString(ui::Control* c, Apply a, Validate v) :
|
||||
m_control(c), m_apply(a), m_validate(v) {}
|
||||
|
||||
virtual void process(const std::string& key, const std::string& arg) {
|
||||
if (!m_validate(arg))
|
||||
throw std::runtime_error("Invalid argument for \"" + key + "\": \"" + arg + "\"");
|
||||
|
||||
m_apply(m_control, arg);
|
||||
}
|
||||
|
||||
private:
|
||||
ui::Control* m_control;
|
||||
Apply m_apply;
|
||||
Validate m_validate;
|
||||
};
|
||||
|
||||
class OptionHandlerDownloadInt : public OptionHandlerBase {
|
||||
public:
|
||||
typedef void (*Apply)(core::Download*, int);
|
||||
typedef bool (*Validate)(int);
|
||||
|
||||
OptionHandlerDownloadInt(core::DownloadSlotMap* m, Apply a, Validate v) :
|
||||
m_map(m), m_apply(a), m_validate(v) {}
|
||||
|
||||
virtual void process(const std::string& key, const std::string& arg) {
|
||||
int a;
|
||||
|
||||
if (std::sscanf(arg.c_str(), "%i", &a) != 1 ||
|
||||
!m_validate(a))
|
||||
throw std::runtime_error("Invalid argument for \"" + key + "\": \"" + arg + "\"");
|
||||
|
||||
(*m_map)[key] = sigc::bind(sigc::ptr_fun(m_apply), a);
|
||||
}
|
||||
|
||||
private:
|
||||
core::DownloadSlotMap* m_map;
|
||||
Apply m_apply;
|
||||
Validate m_validate;
|
||||
};
|
||||
|
||||
class OptionHandlerDownloadString : public OptionHandlerBase {
|
||||
public:
|
||||
typedef void (*Apply)(core::Download*, const std::string&);
|
||||
|
||||
@@ -231,6 +231,14 @@ DownloadList::receive_exit_download() {
|
||||
m_control->get_display().adjust_layout();
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::receive_check_hash() {
|
||||
if (m_downloadList.get_focus() == m_downloadList.end())
|
||||
return;
|
||||
|
||||
m_control->get_core().check_hash(*m_downloadList.get_focus());
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::receive_view_input() {
|
||||
m_windowStatus->set_active(false);
|
||||
@@ -297,6 +305,7 @@ DownloadList::setup_keys() {
|
||||
|
||||
(*m_bindings)['\x13'] = sigc::mem_fun(*this, &DownloadList::receive_start_download);
|
||||
(*m_bindings)['\x04'] = sigc::mem_fun(*this, &DownloadList::receive_stop_download);
|
||||
(*m_bindings)['\x12'] = sigc::mem_fun(*this, &DownloadList::receive_check_hash);
|
||||
|
||||
(*m_bindings)['\x7f'] = sigc::mem_fun(*this, &DownloadList::receive_view_input);
|
||||
(*m_bindings)[KEY_BACKSPACE] = sigc::mem_fun(*this, &DownloadList::receive_view_input);
|
||||
|
||||
@@ -101,6 +101,8 @@ private:
|
||||
void receive_view_download();
|
||||
void receive_exit_download();
|
||||
|
||||
void receive_check_hash();
|
||||
|
||||
void receive_view_input();
|
||||
void receive_exit_input();
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ class Timer {
|
||||
Timer(timeval tv) : m_time((int64_t)(uint32_t)tv.tv_sec * 1000000 + (int64_t)(uint32_t)tv.tv_usec % 1000000) {}
|
||||
|
||||
int64_t usec() const { return m_time; }
|
||||
int32_t sec() const { return m_time / 1000000; }
|
||||
timeval tval() const { return (timeval) { m_time / 1000000, m_time % 1000000}; }
|
||||
|
||||
Timer round_seconds() const { return (m_time / 1000000) * 1000000; }
|
||||
@@ -55,6 +56,7 @@ class Timer {
|
||||
// time. Though system calls would be more expensive than we can afford.
|
||||
static Timer cache() { return Timer(m_cache); }
|
||||
|
||||
// TODO: Create sd::numeric_limits for these?
|
||||
static Timer min() { return 0; }
|
||||
static Timer max() { return (int64_t)std::numeric_limits<time_t>::max() * 1000000; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user