mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-17 07:32:32 +00:00
* A seperate variable for hashing state, now properly restarts hashing
after restart. * Stop a torrent and show a message when it finishes the final hash-check and finds some chunks incomplete. This prevents full disk from causing a torrent to go into an infinit loop of re-downloading the data. * Moved various slots from core::Manager to core::DownloadList. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@679 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+3
-2
@@ -41,6 +41,7 @@
|
||||
#include <torrent/connection_manager.h>
|
||||
|
||||
#include "core/manager.h"
|
||||
#include "core/download_store.h"
|
||||
#include "core/view_manager.h"
|
||||
#include "core/scheduler.h"
|
||||
|
||||
@@ -110,7 +111,7 @@ Control::initialize() {
|
||||
|
||||
m_core->initialize_second();
|
||||
m_core->listen_open();
|
||||
m_core->download_store().enable(m_variables->get_value("session_lock"));
|
||||
m_core->download_store()->enable(m_variables->get_value("session_lock"));
|
||||
|
||||
m_scheduler->set_view(*m_viewManager->find_throw("scheduler"));
|
||||
|
||||
@@ -125,7 +126,7 @@ Control::cleanup() {
|
||||
|
||||
m_inputStdin->remove(m_core->get_poll_manager()->get_torrent_poll());
|
||||
|
||||
m_core->download_store().disable();
|
||||
m_core->download_store()->disable();
|
||||
|
||||
m_ui->cleanup();
|
||||
m_core->cleanup();
|
||||
|
||||
@@ -70,8 +70,16 @@ Download::Download(download_type d) :
|
||||
|
||||
m_variables.insert("connection_leech", new utils::VariableAny(connection_type_to_string(download_type::CONNECTION_LEECH)));
|
||||
m_variables.insert("connection_seed", new utils::VariableAny(connection_type_to_string(download_type::CONNECTION_SEED)));
|
||||
|
||||
// 0 - stopped
|
||||
// 1 - started
|
||||
m_variables.insert("state", new utils::VariableObject(bencode(), "rtorrent", "state", torrent::Object::TYPE_VALUE));
|
||||
m_variables.insert("complete", new utils::VariableObject(bencode(), "rtorrent", "complete", torrent::Object::TYPE_VALUE));
|
||||
|
||||
// 0 - Not hashing
|
||||
// 1 - Normal hashing
|
||||
// 2 - Download finished, hashing
|
||||
m_variables.insert("hashing", new utils::VariableObject(bencode(), "rtorrent", "hashing", torrent::Object::TYPE_VALUE));
|
||||
m_variables.insert("tied_to_file", new utils::VariableObject(bencode(), "rtorrent", "tied_to_file", torrent::Object::TYPE_STRING));
|
||||
|
||||
// The "state_changed" variable is required to be a valid unix time
|
||||
|
||||
@@ -55,6 +55,10 @@ public:
|
||||
typedef download_type::ConnectionType connection_type;
|
||||
typedef utils::VariableMap variable_map_type;
|
||||
|
||||
static const int64_t variable_hashing_stopped = 0;
|
||||
static const int64_t variable_hashing_started = 1;
|
||||
static const int64_t variable_hashing_last = 2;
|
||||
|
||||
Download(download_type d);
|
||||
~Download();
|
||||
|
||||
@@ -73,7 +77,9 @@ public:
|
||||
tracker_list_type* tracker_list() { return &m_trackerList; }
|
||||
|
||||
const std::string& info_hash() const { return m_download.info_hash(); }
|
||||
|
||||
const std::string& message() const { return m_message; }
|
||||
void set_message(const std::string& msg) { m_message = msg; }
|
||||
|
||||
uint32_t chunks_failed() const { return m_chunksFailed; }
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
|
||||
#include "download.h"
|
||||
#include "download_factory.h"
|
||||
#include "download_store.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -103,7 +104,7 @@ DownloadFactory::receive_load() {
|
||||
if (std::strncmp(m_uri.c_str(), "http://", 7) == 0) {
|
||||
// Http handling here.
|
||||
m_stream = new std::stringstream;
|
||||
HttpQueue::iterator itr = m_manager->http_queue().insert(m_uri, m_stream);
|
||||
HttpQueue::iterator itr = m_manager->http_queue()->insert(m_uri, m_stream);
|
||||
|
||||
(*itr)->signal_done().slots().push_front(sigc::mem_fun(*this, &DownloadFactory::receive_loaded));
|
||||
(*itr)->signal_failed().slots().push_front(sigc::mem_fun(*this, &DownloadFactory::receive_failed));
|
||||
@@ -190,7 +191,10 @@ DownloadFactory::receive_success() {
|
||||
else
|
||||
download->variable()->set("directory", rtorrent->get_key("directory"));
|
||||
|
||||
if (download->variable()->get_value("state") == 1)
|
||||
// This torrent was queued for hashing or hashing when the session
|
||||
// file was saved. Or it was in a started state.
|
||||
if (download->variable()->get_value("hashing") != Download::variable_hashing_stopped ||
|
||||
download->variable()->get_value("state") != 0)
|
||||
m_manager->download_list()->resume(download);
|
||||
|
||||
} else {
|
||||
@@ -203,7 +207,7 @@ DownloadFactory::receive_success() {
|
||||
if (m_start)
|
||||
m_manager->download_list()->start(download);
|
||||
|
||||
m_manager->download_store().save(download);
|
||||
m_manager->download_store()->save(download);
|
||||
}
|
||||
|
||||
m_slotFinished();
|
||||
@@ -237,6 +241,9 @@ DownloadFactory::initialize_rtorrent(Download* download, torrent::Object* rtorre
|
||||
if (!rtorrent->has_key_value("complete"))
|
||||
rtorrent->insert_key("complete", (int64_t)0);
|
||||
|
||||
if (!rtorrent->has_key_value("hashing"))
|
||||
rtorrent->insert_key("hashing", Download::variable_hashing_stopped);
|
||||
|
||||
if (!rtorrent->has_key_string("tied_to_file"))
|
||||
rtorrent->insert_key("tied_to_file", std::string());
|
||||
|
||||
|
||||
+124
-44
@@ -74,6 +74,18 @@ struct download_list_call {
|
||||
Download* m_download;
|
||||
};
|
||||
|
||||
DownloadList::~DownloadList() {
|
||||
std::for_each(begin(), end(), std::bind1st(std::mem_fun(&DownloadList::close), this));
|
||||
std::for_each(begin(), end(), rak::call_delete<Download>());
|
||||
|
||||
base_type::clear();
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::session_save() {
|
||||
std::for_each(begin(), end(), std::bind1st(std::mem_fun(&DownloadStore::save), control->core()->download_store()));
|
||||
}
|
||||
|
||||
Download*
|
||||
DownloadList::create(std::istream* str, bool printLog) {
|
||||
torrent::Object* object = new torrent::Object;
|
||||
@@ -113,7 +125,7 @@ DownloadList::insert(Download* download) {
|
||||
} catch (torrent::local_error& e) {
|
||||
// Should perhaps relax this, just print an error and remove the
|
||||
// downloads?
|
||||
throw torrent::internal_error("Caught during DownloadList::insert part 2: " + std::string(e.what()));
|
||||
throw torrent::internal_error("Caught during DownloadList::insert(...): " + std::string(e.what()));
|
||||
}
|
||||
|
||||
return itr;
|
||||
@@ -131,9 +143,9 @@ DownloadList::erase(iterator itr) {
|
||||
if (itr == end())
|
||||
throw torrent::internal_error("DownloadList::erase(...) could not find download.");
|
||||
|
||||
// Make safe to erase active downloads.
|
||||
if ((*itr)->download()->is_active())
|
||||
throw torrent::internal_error("DownloadList::erase(...) called on an active download.");
|
||||
close(*itr);
|
||||
|
||||
control->core()->download_store()->remove(*itr);
|
||||
|
||||
std::for_each(m_slotMapErase.begin(), m_slotMapErase.end(), download_list_call(*itr));
|
||||
|
||||
@@ -187,7 +199,14 @@ DownloadList::close_throw(Download* download) {
|
||||
if (download->download()->is_active())
|
||||
pause(download);
|
||||
|
||||
// Save the torrent on close, this covers shutdown and if a torrent
|
||||
// is manually closed which would clear the progress data. For
|
||||
// better crash protection, save regulary in addition to this.
|
||||
//
|
||||
// Used to be in pause, but this was wrong for rehashing etc.
|
||||
control->core()->download_store()->save(download);
|
||||
control->core()->hash_queue()->remove(download);
|
||||
|
||||
download->download()->close();
|
||||
|
||||
std::for_each(m_slotMapClose.begin(), m_slotMapClose.end(), download_list_call(download));
|
||||
@@ -220,29 +239,44 @@ DownloadList::resume(Download* download) {
|
||||
if (download->download()->is_active())
|
||||
return;
|
||||
|
||||
open_throw(download);
|
||||
|
||||
if (download->download()->is_hash_checked()) {
|
||||
|
||||
if (download->is_done())
|
||||
download->set_connection_type(download->variable()->get_string("connection_seed"));
|
||||
else
|
||||
download->set_connection_type(download->variable()->get_string("connection_leech"));
|
||||
|
||||
// Update the priority to ensure it has the correct
|
||||
// seeding/unfinished modifiers.
|
||||
download->set_priority(download->priority());
|
||||
download->download()->start();
|
||||
|
||||
std::for_each(m_slotMapStart.begin(), m_slotMapStart.end(), download_list_call(download));
|
||||
|
||||
} else {
|
||||
// TODO: This can cause infinit looping?
|
||||
control->core()->hash_queue()->insert(download);
|
||||
}
|
||||
// Properly escape when resume get's called during hashing. The
|
||||
// 'state' is changed by the call to DownloadList::start so it
|
||||
// will automagically start afterwards.
|
||||
if (control->core()->hash_queue()->find(download) != control->core()->hash_queue()->end())
|
||||
return;
|
||||
|
||||
download->variable()->set("state_changed", cachedTime.seconds());
|
||||
|
||||
open_throw(download);
|
||||
|
||||
// Manual or end-of-download rehashing clears the resume data so
|
||||
// we can just start the hashing again without clearing it again.
|
||||
//
|
||||
// It is also assumed the is_hash_checked flag gets cleared when
|
||||
// 'hashing' was set.
|
||||
if (!download->download()->is_hash_checked()) {
|
||||
|
||||
// Set 'hashing' to started if hashing wasn't started, else keep
|
||||
// the old value.
|
||||
if (download->variable()->get_value("hashing") == Download::variable_hashing_stopped)
|
||||
download->variable()->set("hashing", Download::variable_hashing_started);
|
||||
|
||||
control->core()->hash_queue()->insert(download);
|
||||
return;
|
||||
}
|
||||
|
||||
if (download->is_done())
|
||||
download->set_connection_type(download->variable()->get_string("connection_seed"));
|
||||
else
|
||||
download->set_connection_type(download->variable()->get_string("connection_leech"));
|
||||
|
||||
// Update the priority to ensure it has the correct
|
||||
// seeding/unfinished modifiers.
|
||||
download->set_priority(download->priority());
|
||||
download->download()->start();
|
||||
|
||||
std::for_each(m_slotMapStart.begin(), m_slotMapStart.end(), download_list_call(download));
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
control->core()->push_log(e.what());
|
||||
}
|
||||
@@ -254,6 +288,10 @@ DownloadList::pause(Download* download) {
|
||||
|
||||
try {
|
||||
|
||||
// Make sure we don't start hash checking a download that we won't
|
||||
// start.
|
||||
control->core()->hash_queue()->remove(download);
|
||||
|
||||
if (!download->download()->is_active())
|
||||
return;
|
||||
|
||||
@@ -266,7 +304,7 @@ DownloadList::pause(Download* download) {
|
||||
|
||||
// Save the state after all the slots, etc have been called so we
|
||||
// include the modifications they may make.
|
||||
control->core()->download_store().save(download);
|
||||
//control->core()->download_store()->save(download);
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
control->core()->push_log(e.what());
|
||||
@@ -274,10 +312,8 @@ DownloadList::pause(Download* download) {
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::clear() {
|
||||
std::for_each(begin(), end(), rak::call_delete<Download>());
|
||||
|
||||
base_type::clear();
|
||||
DownloadList::save(Download* d) {
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -286,17 +322,28 @@ DownloadList::check_hash(Download* download) {
|
||||
|
||||
try {
|
||||
|
||||
close_throw(download);
|
||||
download->download()->hash_resume_clear();
|
||||
open_throw(download);
|
||||
|
||||
control->core()->hash_queue()->insert(download);
|
||||
download->variable()->set("hashing", Download::variable_hashing_started);
|
||||
check_hash_throw(download);
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
control->core()->push_log(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
// Throw in addition to not setting 'hashing'.
|
||||
void
|
||||
DownloadList::check_hash_throw(Download* download) {
|
||||
check_contains(download);
|
||||
|
||||
close_throw(download);
|
||||
download->download()->hash_resume_clear();
|
||||
open_throw(download);
|
||||
|
||||
// If any more stuff is added here, make sure resume etc are still
|
||||
// correct.
|
||||
control->core()->hash_queue()->insert(download);
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::hash_done(Download* download) {
|
||||
check_contains(download);
|
||||
@@ -313,18 +360,42 @@ DownloadList::hash_done(Download* download) {
|
||||
// confirm all the data, avoiding large BW usage on f.ex. the
|
||||
// ReiserFS bug with >4GB files.
|
||||
|
||||
// Use just is_done(), have another if statement inside.
|
||||
if (download->is_done() && download->variable()->get_value("complete") == 0) {
|
||||
int64_t hashing = download->variable()->get_value("hashing");
|
||||
download->variable()->set("hashing", Download::variable_hashing_stopped);
|
||||
|
||||
if (control->variable()->get_value("session_on_completion"))
|
||||
control->core()->download_store().save(download);
|
||||
switch (hashing) {
|
||||
case Download::variable_hashing_started:
|
||||
// Normal re/hashing.
|
||||
|
||||
// Send a "truly finished message from here.
|
||||
confirm_finished(download);
|
||||
if (download->is_done())
|
||||
download->variable()->set("complete", (int64_t)1);
|
||||
|
||||
if (download->variable()->get_value("state") == 1)
|
||||
resume(download);
|
||||
|
||||
return;
|
||||
|
||||
case Download::variable_hashing_last:
|
||||
|
||||
if (download->is_done()) {
|
||||
|
||||
confirm_finished(download);
|
||||
|
||||
if (download->variable()->get_value("state") == 1)
|
||||
resume(download);
|
||||
|
||||
} else {
|
||||
download->set_message("Hash check on download completion found bad chunks.");
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case Download::variable_hashing_stopped:
|
||||
default:
|
||||
// Either an error or someone wrote to the hashing variable...
|
||||
download->set_message("Hash check completed but the \"hashing\" variable is in an invalid state.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (download->variable()->get_value("state") == 1)
|
||||
resume(download);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -335,13 +406,15 @@ DownloadList::received_finished(Download* download) {
|
||||
// Set some 'checking_finished_thingie' variable to make hash_done
|
||||
// trigger correctly, also so it can bork on missing data.
|
||||
|
||||
check_hash(download);
|
||||
download->variable()->set("hashing", Download::variable_hashing_last);
|
||||
check_hash_throw(download);
|
||||
|
||||
} else {
|
||||
confirm_finished(download);
|
||||
}
|
||||
}
|
||||
|
||||
// The download must be open when we call this function.
|
||||
void
|
||||
DownloadList::confirm_finished(Download* download) {
|
||||
check_contains(download);
|
||||
@@ -354,6 +427,13 @@ DownloadList::confirm_finished(Download* download) {
|
||||
|
||||
download->download()->tracker_list().send_completed();
|
||||
|
||||
// Do this before the slots are called in case one of them closes
|
||||
// the download.
|
||||
if (!download->is_active() && control->variable()->get_value("session_on_completion") == 1) {
|
||||
download->download()->hash_resume_save();
|
||||
control->core()->download_store()->save(download);
|
||||
}
|
||||
|
||||
std::for_each(m_slotMapFinished.begin(), m_slotMapFinished.end(), download_list_call(download));
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,9 @@ public:
|
||||
using base_type::empty;
|
||||
using base_type::size;
|
||||
|
||||
~DownloadList() { clear(); }
|
||||
~DownloadList();
|
||||
|
||||
void session_save();
|
||||
|
||||
// Might move this to DownloadFactory.
|
||||
Download* create(std::istream* str, bool printLog);
|
||||
@@ -95,7 +97,11 @@ public:
|
||||
void resume(Download* d);
|
||||
void pause(Download* d);
|
||||
|
||||
void save(Download* d);
|
||||
|
||||
void check_hash(Download* d);
|
||||
void check_hash_throw(Download* d);
|
||||
|
||||
void hash_done(Download* d);
|
||||
|
||||
slot_map& slot_map_insert() { return m_slotMapInsert; }
|
||||
@@ -129,8 +135,6 @@ public:
|
||||
private:
|
||||
inline void check_contains(Download* d);
|
||||
|
||||
void clear();
|
||||
|
||||
void received_finished(Download* d);
|
||||
void confirm_finished(Download* d);
|
||||
|
||||
|
||||
@@ -49,8 +49,7 @@ namespace core {
|
||||
|
||||
void
|
||||
HashQueue::insert(Download* download) {
|
||||
if (download->download()->is_hash_checking() ||
|
||||
find(download) != end())
|
||||
if (download->download()->is_hash_checking() || find(download) != end())
|
||||
return;
|
||||
|
||||
if (download->download()->is_hash_checked()) {
|
||||
|
||||
+10
-4
@@ -59,7 +59,9 @@
|
||||
#include "curl_get.h"
|
||||
#include "download.h"
|
||||
#include "download_factory.h"
|
||||
#include "download_store.h"
|
||||
#include "hash_queue.h"
|
||||
#include "http_queue.h"
|
||||
#include "manager.h"
|
||||
#include "poll_manager_epoll.h"
|
||||
#include "poll_manager_select.h"
|
||||
@@ -116,13 +118,19 @@ Manager::Manager() :
|
||||
m_portFirst(6890),
|
||||
m_portLast(6999) {
|
||||
|
||||
m_downloadStore = new DownloadStore();
|
||||
m_downloadList = new DownloadList();
|
||||
|
||||
m_httpQueue = new HttpQueue();
|
||||
m_hashQueue = new HashQueue(m_downloadList);
|
||||
}
|
||||
|
||||
Manager::~Manager() {
|
||||
delete m_hashQueue;
|
||||
delete m_downloadList;
|
||||
delete m_hashQueue;
|
||||
|
||||
delete m_downloadStore;
|
||||
delete m_httpQueue;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -142,7 +150,7 @@ Manager::initialize_first() {
|
||||
void
|
||||
Manager::initialize_second() {
|
||||
torrent::Http::set_factory(m_pollManager->get_http_stack()->get_http_factory());
|
||||
m_httpQueue.slot_factory(m_pollManager->get_http_stack()->get_http_factory());
|
||||
m_httpQueue->slot_factory(m_pollManager->get_http_stack()->get_http_factory());
|
||||
|
||||
CurlStack::global_init();
|
||||
|
||||
@@ -152,8 +160,6 @@ Manager::initialize_second() {
|
||||
m_downloadList->slot_map_insert()["1_connect_storage_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_storage_log), sigc::mem_fun(m_logComplete, &Log::push_front));
|
||||
m_downloadList->slot_map_insert()["1_connect_tracker_dump"] = sigc::bind(sigc::ptr_fun(&connect_signal_tracker_dump), sigc::ptr_fun(&receive_tracker_dump));
|
||||
|
||||
m_downloadList->slot_map_erase()["1_hash_queue_remove"] = sigc::mem_fun(m_hashQueue, &HashQueue::remove);
|
||||
m_downloadList->slot_map_erase()["1_store_remove"] = sigc::mem_fun(m_downloadStore, &DownloadStore::remove);
|
||||
m_downloadList->slot_map_erase()["1_delete_tied"] = sigc::ptr_fun(&delete_tied);
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -40,8 +40,6 @@
|
||||
#include <iosfwd>
|
||||
|
||||
#include "download_list.h"
|
||||
#include "download_store.h"
|
||||
#include "http_queue.h"
|
||||
#include "poll_manager.h"
|
||||
#include "log.h"
|
||||
|
||||
@@ -51,7 +49,9 @@ namespace torrent {
|
||||
|
||||
namespace core {
|
||||
|
||||
class DownloadStore;
|
||||
class HashQueue;
|
||||
class HttpQueue;
|
||||
|
||||
class Manager {
|
||||
public:
|
||||
@@ -62,11 +62,12 @@ public:
|
||||
Manager();
|
||||
~Manager();
|
||||
|
||||
DownloadStore& download_store() { return m_downloadStore; }
|
||||
HttpQueue& http_queue() { return m_httpQueue; }
|
||||
|
||||
DownloadList* download_list() { return m_downloadList; }
|
||||
DownloadStore* download_store() { return m_downloadStore; }
|
||||
|
||||
HashQueue* hash_queue() { return m_hashQueue; }
|
||||
HttpQueue* http_queue() { return m_httpQueue; }
|
||||
|
||||
PollManager* get_poll_manager() { return m_pollManager; }
|
||||
Log& get_log_important() { return m_logImportant; }
|
||||
@@ -104,9 +105,9 @@ private:
|
||||
void receive_http_failed(std::string msg);
|
||||
|
||||
DownloadList* m_downloadList;
|
||||
DownloadStore m_downloadStore;
|
||||
DownloadStore* m_downloadStore;
|
||||
HashQueue* m_hashQueue;
|
||||
HttpQueue m_httpQueue;
|
||||
HttpQueue* m_httpQueue;
|
||||
|
||||
PollManager* m_pollManager;
|
||||
Log m_logImportant;
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <stdexcept>
|
||||
#include <rak/error_number.h>
|
||||
|
||||
#include "poll_manager.h"
|
||||
|
||||
@@ -93,8 +93,8 @@ PollManager::~PollManager() {
|
||||
|
||||
void
|
||||
PollManager::check_error() {
|
||||
if (errno != EINTR)
|
||||
throw std::runtime_error("Poll::work(): select error");
|
||||
if (rak::error_number::current().value() != rak::error_number::e_intr)
|
||||
throw std::runtime_error("Poll::work(): " + std::string(rak::error_number::current().c_str()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-8
@@ -50,6 +50,7 @@
|
||||
|
||||
#include "core/download.h"
|
||||
#include "core/download_factory.h"
|
||||
#include "core/download_store.h"
|
||||
#include "core/manager.h"
|
||||
#include "display/canvas.h"
|
||||
#include "display/window.h"
|
||||
@@ -97,7 +98,7 @@ parse_options(Control* c, int argc, char** argv) {
|
||||
void
|
||||
load_session_torrents(Control* c) {
|
||||
// Load session torrents.
|
||||
std::list<std::string> l = c->core()->download_store().get_formated_entries().make_list();
|
||||
std::list<std::string> l = c->core()->download_store()->get_formated_entries().make_list();
|
||||
|
||||
for (std::list<std::string>::iterator first = l.begin(), last = l.end(); first != last; ++first) {
|
||||
core::DownloadFactory* f = new core::DownloadFactory(*first, c->core());
|
||||
@@ -164,8 +165,6 @@ main(int argc, char** argv) {
|
||||
|
||||
// Currently not doing any sorting on main.
|
||||
control->variable()->process_command("view_add = main");
|
||||
control->variable()->process_command("view_sort_new = main");
|
||||
control->variable()->process_command("view_sort_current = main");
|
||||
|
||||
control->variable()->process_command("view_add = name");
|
||||
control->variable()->process_command("view_sort_new = name,name");
|
||||
@@ -192,13 +191,14 @@ main(int argc, char** argv) {
|
||||
control->variable()->process_command("view_sort_current = incomplete,state_changed_reverse");
|
||||
|
||||
control->variable()->process_command("schedule = view_main,10,10,view_sort=main,20");
|
||||
control->variable()->process_command("schedule = view_name,10,10,view_sort=main,20");
|
||||
control->variable()->process_command("schedule = view_started,10,10,view_sort=started,20");
|
||||
control->variable()->process_command("schedule = view_stopped,10,10,view_sort=stopped,20");
|
||||
control->variable()->process_command("schedule = view_complete,10,10,view_sort=complete,20");
|
||||
control->variable()->process_command("schedule = view_incomplete,10,10,view_sort=incomplete,20");
|
||||
control->variable()->process_command("schedule = view_name,10,10,view_sort=name,20");
|
||||
control->variable()->process_command("schedule = view_started,10,10,view_sort=started,5");
|
||||
control->variable()->process_command("schedule = view_stopped,10,10,view_sort=stopped,5");
|
||||
control->variable()->process_command("schedule = view_complete,10,10,view_sort=complete,5");
|
||||
control->variable()->process_command("schedule = view_incomplete,10,10,view_sort=incomplete,5");
|
||||
|
||||
//control->variable()->process_command("schedule = scheduler,10,10,download_scheduler=");
|
||||
control->variable()->process_command("schedule = session_save,1800,1800,session_save=");
|
||||
|
||||
// Changing these will bork the (non-existant) scheduler.
|
||||
control->variable()->process_command("view_add = scheduler");
|
||||
|
||||
+21
-15
@@ -52,6 +52,7 @@
|
||||
#include <torrent/tracker_list.h>
|
||||
|
||||
#include "core/download.h"
|
||||
#include "core/download_store.h"
|
||||
#include "core/manager.h"
|
||||
#include "core/scheduler.h"
|
||||
#include "core/view_manager.h"
|
||||
@@ -97,7 +98,7 @@ apply_load_start(Control* m, const std::string& arg) {
|
||||
}
|
||||
|
||||
void
|
||||
apply_stop_untied(Control* m, __UNUSED const std::string& arg) {
|
||||
apply_stop_untied(Control* m) {
|
||||
core::Manager::DListItr itr = m->core()->download_list()->begin();
|
||||
|
||||
while ((itr = std::find_if(itr, m->core()->download_list()->end(),
|
||||
@@ -116,7 +117,7 @@ apply_stop_untied(Control* m, __UNUSED const std::string& arg) {
|
||||
}
|
||||
|
||||
void
|
||||
apply_remove_untied(Control* m, __UNUSED const std::string& arg) {
|
||||
apply_remove_untied(Control* m) {
|
||||
core::Manager::DListItr itr = m->core()->download_list()->begin();
|
||||
|
||||
while ((itr = std::find_if(itr, m->core()->download_list()->end(),
|
||||
@@ -272,8 +273,15 @@ apply_view_sort_new(Control* control, const std::string& arg) {
|
||||
}
|
||||
|
||||
void
|
||||
apply_download_scheduler(core::Scheduler* scheduler, __UNUSED const std::string& arg) {
|
||||
scheduler->update();
|
||||
apply_import(const std::string& path) {
|
||||
if (!control->variable()->process_file(path))
|
||||
throw torrent::input_error("Could not open option file: " + path);
|
||||
}
|
||||
|
||||
void
|
||||
apply_try_import(const std::string& path) {
|
||||
if (!control->variable()->process_file(path))
|
||||
control->core()->push_log("Could not read resource file: " + path);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -287,10 +295,11 @@ initialize_option_handler(Control* c) {
|
||||
|
||||
variables->insert("tracker_dump", new utils::VariableAny(std::string()));
|
||||
|
||||
variables->insert("session", new utils::VariableStringSlot(rak::mem_fn(&control->core()->download_store(), &core::DownloadStore::path),
|
||||
rak::mem_fn(&control->core()->download_store(), &core::DownloadStore::set_path)));
|
||||
variables->insert("session", new utils::VariableStringSlot(rak::mem_fn(control->core()->download_store(), &core::DownloadStore::path),
|
||||
rak::mem_fn(control->core()->download_store(), &core::DownloadStore::set_path)));
|
||||
variables->insert("session_lock", new utils::VariableBool(true));
|
||||
variables->insert("session_on_completion", new utils::VariableBool(true));
|
||||
variables->insert("session_save", new utils::VariableVoidSlot(rak::mem_fn(c->core()->download_list(), &core::DownloadList::session_save)));
|
||||
|
||||
variables->insert("connection_leech", new utils::VariableAny("leech"));
|
||||
variables->insert("connection_seed", new utils::VariableAny("seed"));
|
||||
@@ -321,10 +330,8 @@ initialize_option_handler(Control* c) {
|
||||
variables->insert("max_open_sockets", new utils::VariableValueSlot(rak::ptr_fn(&torrent::max_open_sockets), rak::ptr_fn(&torrent::set_max_open_sockets)));
|
||||
|
||||
variables->insert("print", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::mem_fn(control->core(), &core::Manager::push_log)));
|
||||
variables->insert("import", new utils::VariableStringSlot(rak::value_fn(std::string()),
|
||||
rak::mem_fn(control->variable(), &utils::VariableMap::process_file_throw)));
|
||||
variables->insert("try_import", new utils::VariableStringSlot(rak::value_fn(std::string()),
|
||||
rak::mem_fn(control->variable(), &utils::VariableMap::process_file_nothrow)));
|
||||
variables->insert("import", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::ptr_fn(&apply_import)));
|
||||
variables->insert("try_import", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::ptr_fn(&apply_try_import)));
|
||||
|
||||
variables->insert("view_add", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::mem_fn(c->view_manager(), &core::ViewManager::insert_throw)));
|
||||
variables->insert("view_filter", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_view_filter, c)));
|
||||
@@ -333,12 +340,11 @@ initialize_option_handler(Control* c) {
|
||||
variables->insert("view_sort_new", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_view_sort_new, c)));
|
||||
variables->insert("view_sort_current", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_view_sort_current, c)));
|
||||
|
||||
variables->insert("schedule", new utils::VariableStringSlot(rak::value_fn(std::string()),
|
||||
rak::mem_fn<const std::string&>(c->command_scheduler(), &CommandScheduler::parse)));
|
||||
variables->insert("schedule", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::mem_fn(c->command_scheduler(), &CommandScheduler::parse)));
|
||||
variables->insert("schedule_remove", new utils::VariableStringSlot(rak::value_fn(std::string()),
|
||||
rak::mem_fn<const std::string&>(c->command_scheduler(), &CommandScheduler::erase)));
|
||||
|
||||
variables->insert("download_scheduler", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_download_scheduler, c->scheduler())));
|
||||
variables->insert("download_scheduler", new utils::VariableVoidSlot(rak::mem_fn(control->scheduler(), &core::Scheduler::update)));
|
||||
|
||||
variables->insert("send_buffer_size", new utils::VariableValueSlot(rak::mem_fn(torrent::connection_manager(), &torrent::ConnectionManager::send_buffer_size),
|
||||
rak::mem_fn(torrent::connection_manager(), &torrent::ConnectionManager::set_send_buffer_size)));
|
||||
@@ -357,8 +363,8 @@ initialize_option_handler(Control* c) {
|
||||
|
||||
variables->insert("load", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_load, c)));
|
||||
variables->insert("load_start", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_load_start, c)));
|
||||
variables->insert("stop_untied", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_stop_untied, c)));
|
||||
variables->insert("remove_untied", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_remove_untied, c)));
|
||||
variables->insert("stop_untied", new utils::VariableVoidSlot(rak::bind_ptr_fn(&apply_stop_untied, c)));
|
||||
variables->insert("remove_untied", new utils::VariableVoidSlot(rak::bind_ptr_fn(&apply_remove_untied, c)));
|
||||
|
||||
variables->insert("enable_trackers", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_enable_trackers, c)));
|
||||
variables->insert("encoding_list", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_encoding_list, c)));
|
||||
|
||||
@@ -76,7 +76,7 @@ DownloadList::DownloadList(Control* c) :
|
||||
m_window(c->display()->end()),
|
||||
|
||||
m_windowTitle(new WTitle("rTorrent " VERSION " - libTorrent " + std::string(torrent::version()))),
|
||||
m_windowHttpQueue(new WHttp(&c->core()->http_queue())),
|
||||
m_windowHttpQueue(new WHttp(c->core()->http_queue())),
|
||||
|
||||
m_uiDownload(NULL),
|
||||
|
||||
|
||||
@@ -155,6 +155,16 @@ VariableObject::set(const torrent::Object& arg) {
|
||||
// New and prettified.
|
||||
//
|
||||
|
||||
const torrent::Object&
|
||||
VariableVoidSlot::get() {
|
||||
return m_cache;
|
||||
}
|
||||
|
||||
void
|
||||
VariableVoidSlot::set(const torrent::Object& arg) {
|
||||
m_slotSet();
|
||||
}
|
||||
|
||||
const torrent::Object&
|
||||
VariableValueSlot::get() {
|
||||
m_cache = m_slotGet() / m_unit;
|
||||
|
||||
@@ -102,6 +102,26 @@ private:
|
||||
// New and pretty.
|
||||
//
|
||||
|
||||
class VariableVoidSlot : public Variable {
|
||||
public:
|
||||
typedef rak::function0<void> slot_set_type;
|
||||
|
||||
VariableVoidSlot(slot_set_type::base_type* slotSet) {
|
||||
m_slotSet.set(slotSet);
|
||||
}
|
||||
|
||||
virtual const torrent::Object& get();
|
||||
virtual void set(const torrent::Object& arg);
|
||||
|
||||
private:
|
||||
slot_set_type m_slotSet;
|
||||
|
||||
// Store the cache here to avoid unnessesary copying and such. This
|
||||
// should not result in any unresonable memory usage since few
|
||||
// strings will be very large.
|
||||
torrent::Object m_cache;
|
||||
};
|
||||
|
||||
class VariableValueSlot : public Variable {
|
||||
public:
|
||||
typedef rak::function0<value_type> slot_get_type;
|
||||
@@ -160,7 +180,6 @@ private:
|
||||
torrent::Object m_cache;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -198,15 +198,4 @@ VariableMap::process_file(const std::string& path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VariableMap::process_file_throw(const std::string& path) {
|
||||
if (!process_file(path))
|
||||
throw torrent::input_error("Could not open option file: " + path);
|
||||
}
|
||||
|
||||
void
|
||||
VariableMap::process_file_nothrow(const std::string& path) {
|
||||
process_file(path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -77,8 +77,6 @@ public:
|
||||
void process_command(const std::string& command);
|
||||
void process_stream(std::istream* str);
|
||||
bool process_file(const std::string& path);
|
||||
void process_file_throw(const std::string& path);
|
||||
void process_file_nothrow(const std::string& path);
|
||||
|
||||
private:
|
||||
VariableMap(const VariableMap&);
|
||||
|
||||
Reference in New Issue
Block a user