mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-14 14:12:31 +00:00
* Fixed a regression that threw an exception for torrents with
empty directories. * When receiving zero length pieces, remove them from the request list. * Send the interested state before any requests as some clients, BitTornado 0.7.14 and uTorrent 0.3.0, disconnect if a request has been received while uninterested. * WITH_POSIX_FALLOCATE configure macro should check against "yes", not "no". * The new priority queue would cause arg torrents to load before session torrents in some cases. Fixed to perform the session torrent tasks before loading arg torrents. * Allow '*' wildcard in filenames when loading torrents. * Added load, load_run, stop_tied and remove_tied settings which can be used to scan a directory for new/removed torrents. These torrents are tied to the lifetime of the torrent file. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@616 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+83
-6
@@ -43,6 +43,8 @@
|
||||
#include <istream>
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
#include <rak/regex.h>
|
||||
#include <rak/string_manip.h>
|
||||
#include <sigc++/bind.h>
|
||||
#include <sigc++/hide.h>
|
||||
#include <torrent/bencode.h>
|
||||
@@ -50,6 +52,7 @@
|
||||
|
||||
#include "curl_get.h"
|
||||
#include "download.h"
|
||||
#include "download_factory.h"
|
||||
#include "manager.h"
|
||||
#include "poll_manager_epoll.h"
|
||||
#include "poll_manager_select.h"
|
||||
@@ -149,13 +152,15 @@ Manager::shutdown(bool force) {
|
||||
}
|
||||
|
||||
Manager::DListItr
|
||||
Manager::insert(std::istream* s) {
|
||||
Manager::insert(std::istream* s, bool printLog) {
|
||||
try {
|
||||
return m_downloadList.insert(s);
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
m_logImportant.push_front(e.what());
|
||||
m_logComplete.push_front(e.what());
|
||||
if (printLog) {
|
||||
m_logImportant.push_front(e.what());
|
||||
m_logComplete.push_front(e.what());
|
||||
}
|
||||
|
||||
return m_downloadList.end();
|
||||
}
|
||||
@@ -173,7 +178,7 @@ Manager::erase(DListItr itr) {
|
||||
}
|
||||
|
||||
void
|
||||
Manager::start(Download* d) {
|
||||
Manager::start(Download* d, bool printLog) {
|
||||
try {
|
||||
d->get_bencode().get_key("rtorrent").get_key("state") = "started";
|
||||
|
||||
@@ -190,8 +195,10 @@ Manager::start(Download* d) {
|
||||
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());
|
||||
m_logComplete.push_front(e.what());
|
||||
if (printLog) {
|
||||
m_logImportant.push_front(e.what());
|
||||
m_logComplete.push_front(e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,4 +309,74 @@ Manager::receive_download_done_hash_checked(Download* d) {
|
||||
d->get_download().tracker_send_completed();
|
||||
}
|
||||
|
||||
void
|
||||
Manager::try_create_download(const std::string& uri, bool start, bool printLog, bool tied) {
|
||||
// Adding download.
|
||||
DownloadFactory* f = new DownloadFactory(uri, this);
|
||||
|
||||
f->set_start(start);
|
||||
f->set_print_log(printLog);
|
||||
f->set_tied_to_file(tied);
|
||||
f->slot_finished(sigc::bind(sigc::ptr_fun(&rak::call_delete_func<core::DownloadFactory>), f));
|
||||
f->load();
|
||||
f->commit();
|
||||
}
|
||||
|
||||
// Move this somewhere better.
|
||||
void
|
||||
path_expand(std::vector<std::string>* paths, const std::string& pattern) {
|
||||
std::vector<utils::Directory> currentCache;
|
||||
std::vector<utils::Directory> nextCache;
|
||||
|
||||
rak::split_iterator_t<std::string> first = rak::split_iterator(pattern, '/');
|
||||
rak::split_iterator_t<std::string> last = rak::split_iterator(pattern);
|
||||
|
||||
if (first == last)
|
||||
return;
|
||||
|
||||
// Check for initial '/' that indicates the root.
|
||||
if ((*first).empty()) {
|
||||
currentCache.push_back(utils::Directory("/"));
|
||||
++first;
|
||||
} else {
|
||||
currentCache.push_back(utils::Directory("./"));
|
||||
}
|
||||
|
||||
// Might be an idea to use depth-first search instead.
|
||||
|
||||
for (; first != last; ++first) {
|
||||
rak::regex r(*first);
|
||||
|
||||
if (r.pattern().empty())
|
||||
continue;
|
||||
|
||||
for (std::vector<utils::Directory>::iterator itr = currentCache.begin(); itr != currentCache.end(); ++itr) {
|
||||
itr->update(false);
|
||||
itr->erase(std::remove_if(itr->begin(), itr->end(), std::not1(r)), itr->end());
|
||||
|
||||
std::transform(itr->begin(), itr->end(), std::back_inserter(nextCache), std::bind1st(std::plus<std::string>(), itr->get_path() + "/"));
|
||||
}
|
||||
|
||||
currentCache.clear();
|
||||
currentCache.swap(nextCache);
|
||||
}
|
||||
|
||||
std::transform(currentCache.begin(), currentCache.end(), std::back_inserter(*paths), std::mem_fun_ref(&utils::Directory::get_path));
|
||||
}
|
||||
|
||||
void
|
||||
Manager::try_create_download_expand(const std::string& uri, bool start, bool printLog, bool tied) {
|
||||
std::vector<std::string> paths;
|
||||
paths.reserve(32);
|
||||
|
||||
path_expand(&paths, uri);
|
||||
|
||||
if (!paths.empty())
|
||||
for (std::vector<std::string>::iterator itr = paths.begin(); itr != paths.end(); ++itr)
|
||||
try_create_download(*itr, start, printLog, tied);
|
||||
|
||||
else
|
||||
try_create_download(uri, start, printLog, tied);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user