Skip to content

Commit

Permalink
* Added '-D' flag which turns of redirects for deprecated commands. U…
Browse files Browse the repository at this point in the history
…se this to ensure your scripts/webui.

* Moved DownloadInfo to src/torrent.

* Applied the magnet-uri patch.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1144 e378c898-3ddf-0310-93e7-cc216c733640
  • Loading branch information
rakshasa committed Mar 15, 2010
1 parent ded689d commit 19be810
Show file tree
Hide file tree
Showing 14 changed files with 138 additions and 24 deletions.
15 changes: 8 additions & 7 deletions src/command_download.cc
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ apply_d_add_peer(core::Download* download, const std::string& arg) {
char dummy;
char host[1024];

if (download->download()->is_private())
if (download->download()->info()->is_private())
throw torrent::input_error("Download is private.");

ret = std::sscanf(arg.c_str(), "%1023[^:]:%i%c", host, &port, &dummy);
Expand Down Expand Up @@ -600,13 +600,13 @@ initialize_command_download() {

ADD_CD_STRING("add_peer", std::ptr_fun(&apply_d_add_peer));

ADD_CD_VALUE("is_open", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::is_open)));
ADD_CD_VALUE("is_active", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::is_active)));
ADD_CD_VALUE("is_open", rak::on(std::mem_fun(&core::Download::info), std::mem_fun(&torrent::DownloadInfo::is_open)));
ADD_CD_VALUE("is_active", rak::on(std::mem_fun(&core::Download::info), std::mem_fun(&torrent::DownloadInfo::is_active)));
ADD_CD_VALUE("is_hash_checked", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::is_hash_checked)));
ADD_CD_VALUE("is_hash_checking", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::is_hash_checking)));
ADD_CD_VALUE("is_multi_file", rak::on(std::mem_fun(&core::Download::file_list), std::mem_fun(&torrent::FileList::is_multi_file)));
ADD_CD_VALUE("is_private", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::is_private)));
ADD_CD_VALUE("is_pex_active", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::is_pex_active)));
ADD_CD_VALUE("is_private", rak::on(std::mem_fun(&core::Download::info), std::mem_fun(&torrent::DownloadInfo::is_private)));
ADD_CD_VALUE("is_pex_active", rak::on(std::mem_fun(&core::Download::info), std::mem_fun(&torrent::DownloadInfo::is_pex_active)));

ADD_CD_VARIABLE_STRING_PUBLIC("custom1", "rtorrent", "custom1");
ADD_CD_VARIABLE_STRING_PUBLIC("custom2", "rtorrent", "custom2");
Expand Down Expand Up @@ -676,8 +676,6 @@ initialize_command_download() {
ADD_CD_VALUE_UNI("peers_complete", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::peers_complete)));
ADD_CD_VALUE_UNI("peers_accounted", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::peers_accounted)));

ADD_CD_VALUE_MEM_BI("peer_exchange", &core::Download::download, &torrent::Download::set_pex_enabled, &torrent::Download::is_pex_enabled);

ADD_CD_VALUE_MEM_UNI("up_rate", &torrent::Download::mutable_up_rate, &torrent::Rate::rate);
ADD_CD_VALUE_MEM_UNI("up_total", &torrent::Download::mutable_up_rate, &torrent::Rate::total);
ADD_CD_VALUE_MEM_UNI("down_rate", &torrent::Download::mutable_down_rate, &torrent::Rate::rate);
Expand Down Expand Up @@ -722,4 +720,7 @@ initialize_command_download() {

// NEWISH:
CMD_D_VOID("d.initialize_logs", &cmd_d_initialize_logs);

CMD_D_VOID_SLOT("d.peer_exchange", rak::on(std::mem_fun(&core::Download::info), std::mem_fun(&torrent::DownloadInfo::is_pex_enabled)));
CMD_D_VALUE_SLOT("d.peer_exchange.set", rak::on2(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::set_pex_enabled)));
}
6 changes: 6 additions & 0 deletions src/command_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ add_variable(key, NULL, NULL, &rpc::CommandVariable::get_string, NULL, std::stri
#define CMD_D_VOID(key, slot) \
CMD_D_SLOT(key, call_unknown, rpc::object_fn(slot), "i:", "")

#define CMD_D_VOID_SLOT(key, slot) \
CMD_D_SLOT(key, call_unknown, rpc::object_void_fn<core::Download*>(slot), "i:", "")

#define CMD_D_VALUE_SLOT(key, slot) \
CMD_D_SLOT(key, call_value, rpc::object_value_fn<core::Download*>(slot), "i:i", "")

#define CMD_FUNC_SINGLE(key, command) \
rpc::commands.insert_type(key, new rpc::CommandFunction(command), &rpc::CommandFunction::call, rpc::CommandMap::flag_public_xmlrpc, NULL, NULL);

Expand Down
2 changes: 1 addition & 1 deletion src/core/dht_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ DhtManager::update() {
DownloadList::const_iterator itr, end;

for (itr = control->core()->download_list()->begin(), end = control->core()->download_list()->end(); itr != end; ++itr)
if ((*itr)->is_active() && !(*itr)->download()->is_private())
if ((*itr)->download()->info()->is_active() && !(*itr)->download()->info()->is_private())
break;

if (itr == end) {
Expand Down
2 changes: 1 addition & 1 deletion src/core/download.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ Download::receive_chunk_failed(__UNUSED uint32_t idx) {

void
Download::set_throttle_name(const std::string& throttleName) {
if (m_download.is_active())
if (m_download.info()->is_active())
throw torrent::input_error("Cannot set throttle on active download.");

torrent::ThrottlePair throttles = control->core()->get_throttle(throttleName);
Expand Down
9 changes: 6 additions & 3 deletions src/core/download.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

#include <sigc++/connection.h>
#include <torrent/download.h>
#include <torrent/download_info.h>
#include <torrent/hash_string.h>
#include <torrent/tracker_list.h>
#include <torrent/data/file_list.h>
Expand Down Expand Up @@ -70,16 +71,18 @@ class Download {
Download(download_type d);
~Download();

bool is_open() const { return m_download.is_open(); }
bool is_active() const { return m_download.is_active(); }
const torrent::DownloadInfo* info() const { return m_download.info(); }

bool is_open() const { return m_download.info()->is_open(); }
bool is_active() const { return m_download.info()->is_active(); }
bool is_done() const { return m_download.file_list()->is_done(); }
bool is_downloading() const { return is_active() && !is_done(); }
bool is_seeding() const { return is_active() && is_done(); }

// FIXME: Fixed a bug in libtorrent that caused is_hash_checked to
// return true when the torrent is closed. Remove this redundant
// test in the next milestone.
bool is_hash_checked() const { return m_download.is_open() && m_download.is_hash_checked(); }
bool is_hash_checked() const { return is_open() && m_download.is_hash_checked(); }
bool is_hash_checking() const { return m_download.is_hash_checking(); }

bool is_hash_failed() const { return m_hashFailed; }
Expand Down
29 changes: 27 additions & 2 deletions src/core/download_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ download_factory_add_stream(torrent::Object* root, const char* key, const char*
return true;
}

bool
is_magnet_uri(const std::string& uri) {
return
std::strncmp(uri.c_str(), "magnet:?", 8) == 0;
}

DownloadFactory::DownloadFactory(Manager* m) :
m_manager(m),
m_stream(NULL),
Expand Down Expand Up @@ -153,6 +159,14 @@ DownloadFactory::receive_load() {

m_variables["tied_to_file"] = (int64_t)false;

} else if (is_magnet_uri(m_uri)) {
// DEBUG: Use m_object.
m_stream = new std::stringstream();
*m_stream << "d10:magnet-uri" << m_uri.length() << ":" << m_uri << "e";

m_variables["tied_to_file"] = (int64_t)false;
receive_loaded();

} else {
std::fstream stream(rak::path_expand(m_uri).c_str(), std::ios::in | std::ios::binary);

Expand Down Expand Up @@ -204,6 +218,17 @@ DownloadFactory::receive_success() {

torrent::Object* root = download->bencode();

if (download->download()->info()->is_meta_download()) {
torrent::Object& meta = root->insert_key("rtorrent_meta_download", torrent::Object::create_map());
meta.insert_key("start", m_start);
meta.insert_key("print_log", m_printLog);

torrent::Object::list_type& commands = meta.insert_key("commands", torrent::Object::create_list()).as_list();

for (command_list_type::iterator itr = m_commands.begin(); itr != m_commands.end(); ++itr)
commands.push_back(*itr);
}

if (m_session) {
download_factory_add_stream(root, "rtorrent", (rak::path_expand(m_uri) + ".rtorrent").c_str());
download_factory_add_stream(root, "libtorrent_resume", (rak::path_expand(m_uri) + ".libtorrent_resume").c_str());
Expand Down Expand Up @@ -260,9 +285,9 @@ DownloadFactory::receive_success() {
rpc::call_command("d.set_directory_base", rtorrent->get_key("directory"), rpc::make_target(download));

if (!m_session && m_variables["tied_to_file"].as_value())
rpc::call_command("d.set_tied_to_file", m_uri, rpc::make_target(download));
rpc::call_command("d.set_tied_to_file", m_uri.empty() ? m_variables["tied_file"] : m_uri, rpc::make_target(download));

rpc::call_command("d.set_peer_exchange", rpc::call_command_value("get_peer_exchange"), rpc::make_target(download));
rpc::call_command("d.peer_exchange.set", rpc::call_command_value("get_peer_exchange"), rpc::make_target(download));

torrent::resume_load_addresses(*download->download(), resumeObject);
torrent::resume_load_file_priorities(*download->download(), resumeObject);
Expand Down
1 change: 1 addition & 0 deletions src/core/download_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class DownloadFactory {
};

bool is_network_uri(const std::string& uri);
bool is_magnet_uri(const std::string& uri);

}

Expand Down
52 changes: 46 additions & 6 deletions src/core/download_list.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@
#include "config.h"

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sigc++/adaptors/bind.h>
#include <rak/functional.h>
#include <rak/string_manip.h>
#include <torrent/data/file.h>
#include <torrent/exceptions.h>
#include <torrent/download.h>
#include <torrent/hash_string.h>
Expand Down Expand Up @@ -236,7 +238,7 @@ void
DownloadList::open_throw(Download* download) {
check_contains(download);

if (download->download()->is_open())
if (download->download()->info()->is_open())
return;

int openFlags = download->resume_flags();
Expand All @@ -261,14 +263,14 @@ DownloadList::close(Download* download) {

void
DownloadList::close_directly(Download* download) {
if (download->download()->is_active()) {
if (download->download()->info()->is_active()) {
download->download()->stop(torrent::Download::stop_skip_tracker);

if (torrent::resume_check_target_files(*download->download(), download->download()->bencode()->get_key("libtorrent_resume")))
torrent::resume_save_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume"));
}

if (download->download()->is_open())
if (download->download()->info()->is_open())
download->download()->close();
}

Expand Down Expand Up @@ -320,7 +322,7 @@ DownloadList::resume(Download* download, int flags) {

try {

if (download->download()->is_active())
if (download->download()->info()->is_active())
return;

rpc::parse_command_single(rpc::make_target(download), "view.set_visible=active");
Expand Down Expand Up @@ -369,7 +371,7 @@ DownloadList::resume(Download* download, int flags) {
}

// If the DHT server is set to auto, start it now.
if (!download->download()->is_private())
if (!download->download()->info()->is_private())
control->dht_manager()->auto_start();

// Update the priority to ensure it has the correct
Expand Down Expand Up @@ -405,7 +407,7 @@ DownloadList::pause(Download* download, int flags) {
rpc::commands.call_catch("event.download.hash_removed", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
}

if (!download->download()->is_active())
if (!download->download()->info()->is_active())
return;

download->download()->stop(flags);
Expand Down Expand Up @@ -475,6 +477,9 @@ DownloadList::hash_done(Download* download) {
int64_t hashing = rpc::call_command_value("d.get_hashing", rpc::make_target(download));
rpc::call_command_set_value("d.set_hashing", Download::variable_hashing_stopped, rpc::make_target(download));

if (download->is_done() && download->download()->info()->is_meta_download())
return process_meta_download(download);

switch (hashing) {
case Download::variable_hashing_initial:
case Download::variable_hashing_rehash:
Expand Down Expand Up @@ -566,6 +571,9 @@ void
DownloadList::confirm_finished(Download* download) {
check_contains(download);

if (download->download()->info()->is_meta_download())
return process_meta_download(download);

rpc::call_command("d.set_complete", (int64_t)1, rpc::make_target(download));

rpc::call_command("d.set_connection_current", rpc::call_command_void("d.get_connection_seed", rpc::make_target(download)), rpc::make_target(download));
Expand Down Expand Up @@ -599,4 +607,36 @@ DownloadList::confirm_finished(Download* download) {
resume(download, torrent::Download::start_no_create | torrent::Download::start_skip_tracker | torrent::Download::start_keep_baseline);
}

void
DownloadList::process_meta_download(Download* download) {
rpc::call_command("d.stop", torrent::Object(), rpc::make_target(download));
rpc::call_command("d.close", torrent::Object(), rpc::make_target(download));

std::string metafile = (*download->file_list()->begin())->frozen_path();
std::fstream file(metafile.c_str(), std::ios::in | std::ios::binary);
if (!file.is_open()) {
control->core()->push_log("Could not read download metadata.");
return;
}

torrent::Object* bencode = new torrent::Object(torrent::Object::create_map());
file >> bencode->insert_key("info", torrent::Object());
if (file.fail()) {
delete bencode;
control->core()->push_log("Could not create download, the input is not a valid torrent.");
return;
}
file.close();

// Steal the keys we still need. The old download has no use for them.
bencode->insert_key("rtorrent_meta_download", torrent::Object()).swap(download->bencode()->get_key("rtorrent_meta_download"));
if (download->bencode()->has_key("announce"))
bencode->insert_key("announce", torrent::Object()).swap(download->bencode()->get_key("announce"));
if (download->bencode()->has_key("announce-list"))
bencode->insert_key("announce-list", torrent::Object()).swap(download->bencode()->get_key("announce-list"));

erase_ptr(download);
control->core()->try_create_download_from_meta_download(bencode, metafile);
}

}
2 changes: 2 additions & 0 deletions src/core/download_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ class DownloadList : private std::list<Download*> {

void received_finished(Download* d);
void confirm_finished(Download* d);

void process_meta_download(Download* d);
};

}
Expand Down
28 changes: 28 additions & 0 deletions src/core/manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <cstdio>
#include <cstring>
#include <fstream>
#include <sstream>
#include <unistd.h>
#include <sys/select.h>
#include <rak/address_info.h>
Expand All @@ -52,6 +53,7 @@
#include <torrent/connection_manager.h>
#include <torrent/error.h>
#include <torrent/exceptions.h>
#include <torrent/object_stream.h>
#include <torrent/resume.h>
#include <torrent/tracker_list.h>
#include <torrent/throttle.h>
Expand Down Expand Up @@ -395,6 +397,7 @@ Manager::try_create_download(const std::string& uri, int flags, const command_li
if ((flags & create_tied) &&
!(flags & create_raw_data) &&
!is_network_uri(uri) &&
!is_magnet_uri(uri) &&
!file_status_cache()->insert(uri, 0))
return;

Expand All @@ -416,6 +419,31 @@ Manager::try_create_download(const std::string& uri, int flags, const command_li
f->commit();
}

void
Manager::try_create_download_from_meta_download(torrent::Object* bencode, const std::string& metafile) {
DownloadFactory* f = new DownloadFactory(this);

f->variables()["tied_to_file"] = (int64_t)true;
f->variables()["tied_file"] = metafile;

torrent::Object& meta = bencode->get_key("rtorrent_meta_download");
torrent::Object::list_type& commands = meta.get_key_list("commands");
for (torrent::Object::list_type::const_iterator itr = commands.begin(); itr != commands.end(); ++itr)
f->commands().insert(f->commands().end(), itr->as_string());

f->set_start(meta.get_key_value("start"));
f->set_print_log(meta.get_key_value("print_log"));
f->slot_finished(sigc::bind(sigc::ptr_fun(&rak::call_delete_func<core::DownloadFactory>), f));

// Bit of a waste to create the bencode repesentation here
// only to have the DownloadFactory decode it.
std::stringstream s;
s.imbue(std::locale::classic());
s << *bencode;
f->load_raw_data(s.str());
f->commit();
}

utils::Directory
path_expand_transform(std::string path, const utils::directory_entry& entry) {
return path + entry.d_name;
Expand Down
1 change: 1 addition & 0 deletions src/core/manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class Manager {
// Temporary, find a better place for this.
void try_create_download(const std::string& uri, int flags, const command_list_type& commands);
void try_create_download_expand(const std::string& uri, int flags, command_list_type commands = command_list_type());
void try_create_download_from_meta_download(torrent::Object* bencode, const std::string& metafile);

private:
typedef RangeMap<uint32_t, torrent::ThrottlePair> AddressThrottleMap;
Expand Down
6 changes: 3 additions & 3 deletions src/display/utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ print_download_title(char* first, char* last, core::Download* d) {

char*
print_download_info(char* first, char* last, core::Download* d) {
if (!d->download()->is_open())
if (!d->download()->info()->is_open())
first = print_buffer(first, last, "[CLOSED] ");
else if (!d->download()->is_active())
else if (!d->download()->info()->is_active())
first = print_buffer(first, last, "[OPEN] ");
else
first = print_buffer(first, last, " ");
Expand All @@ -151,7 +151,7 @@ print_download_info(char* first, char* last, core::Download* d) {
(double)d->download()->down_rate()->rate() / (1 << 10),
(double)d->download()->up_rate()->total() / (1 << 20));

if (d->download()->is_active() && !d->is_done()) {
if (d->download()->info()->is_active() && !d->is_done()) {
first = print_buffer(first, last, " ");
first = print_download_percentage_done(first, last, d);

Expand Down
Loading

0 comments on commit 19be810

Please sign in to comment.