* Cleaned up torrent::Rate and moved it to the API. Changed various

parts of the API to return torrent::Rate instead of specific functions
for each stat.

* Use 600 second time span for peer rates.

* Added core::DownloadFactory which allows for an async http get and
changing of settings. This will allow the implementation of a
configuration screen when pressing "return", while the client is
downloading or finished downloading a torrent file.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@491 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2005-07-09 15:28:56 +00:00
parent a195933a2a
commit 26a7907f0a
20 changed files with 376 additions and 92 deletions
+2
View File
@@ -7,6 +7,8 @@ libsub_core_a_SOURCES = \
curl_stack.h \
download.cc \
download.h \
download_factory.cc \
download_factory.h \
download_list.cc \
download_list.h \
download_slot_map.h \
+165
View File
@@ -0,0 +1,165 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005, 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#include "config.h"
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <torrent/bencode.h>
#include "utils/task.h"
#include "curl_get.h"
#include "http_queue.h"
#include "manager.h"
#include "download_factory.h"
namespace core {
DownloadFactory::DownloadFactory(const std::string& uri, Manager* m) :
m_manager(m),
m_stream(NULL),
m_commited(false),
m_loaded(false),
m_uri(uri),
m_session(false),
m_start(false) {
m_taskLoad.set_iterator(utils::taskScheduler.end());
m_taskLoad.set_slot(sigc::mem_fun(*this, &DownloadFactory::receive_load));
m_taskCommit.set_iterator(utils::taskScheduler.end());
m_taskCommit.set_slot(sigc::mem_fun(*this, &DownloadFactory::receive_commit));
}
DownloadFactory::~DownloadFactory() {
utils::taskScheduler.erase(&m_taskLoad);
utils::taskScheduler.erase(&m_taskCommit);
delete m_stream;
m_stream = NULL;
}
void
DownloadFactory::load() {
utils::taskScheduler.insert(&m_taskLoad, utils::Timer::cache());
}
void
DownloadFactory::commit() {
utils::taskScheduler.insert(&m_taskCommit, utils::Timer::cache());
}
void
DownloadFactory::receive_load() {
if (m_stream)
throw std::logic_error("DownloadFactory::load() called on an object with m_stream != NULL");
if (std::strncmp(m_uri.c_str(), "http://", 7) == 0) {
// Http handling here.
m_stream = new std::stringstream;
HttpQueue::iterator itr = m_manager->get_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));
} else {
m_stream = new std::fstream(m_uri.c_str(), std::ios::in);
if (m_stream->good())
receive_loaded();
else
receive_failed("Could not open file");
}
}
void
DownloadFactory::receive_loaded() {
m_loaded = true;
if (m_commited)
receive_success();
}
void
DownloadFactory::receive_commit() {
m_commited = true;
if (m_loaded)
receive_success();
}
void
DownloadFactory::receive_success() {
if (m_stream == NULL)
throw std::logic_error("DownloadFactory::receive_success() called on an object with m_stream == NULL");
Manager::DListItr itr = m_manager->insert(m_stream);
if (itr == m_manager->get_download_list().end()) {
// core::Manager should already have added the error message to
// the log.
m_slotFinished();
return;
}
if (m_session) {
torrent::Bencode& bencode = (*itr)->get_bencode();
if (bencode["rtorrent"]["state"].as_string() == "started")
m_manager->start(*itr);
} else {
if (m_start)
m_manager->start(*itr);
}
m_slotFinished();
}
void
DownloadFactory::receive_failed(const std::string& msg) {
if (m_stream == NULL)
throw std::logic_error("DownloadFactory::receive_success() called on an object with m_stream == NULL");
// Add message to log.
m_slotFinished();
}
}
+96
View File
@@ -0,0 +1,96 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005, 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_CORE_DOWNLOAD_FACTORY_H
#define RTORRENT_CORE_DOWNLOAD_FACTORY_H
#include <iosfwd>
#include <sigc++/slot.h>
#include "utils/task_item.h"
#include "http_queue.h"
namespace core {
class Manager;
class DownloadFactory {
public:
typedef sigc::slot<void> Slot;
// Do not destroy this object while it is in a HttpQueue.
DownloadFactory(const std::string& uri, Manager* m);
~DownloadFactory();
// Calling of receive_load() is delayed so you can change whatever
// you want without fear of the slots being triggered as you call
// load() or commit().
void load();
void commit();
bool get_session() const { return m_session; }
void set_session(bool v) { m_session = v; }
bool get_start() const { return m_start; }
void set_start(bool v) { m_start = v; }
void slot_finished(Slot s) { m_slotFinished = s; }
private:
void receive_load();
void receive_loaded();
void receive_commit();
void receive_success();
void receive_failed(const std::string& msg);
Manager* m_manager;
std::iostream* m_stream;
bool m_commited;
bool m_loaded;
std::string m_uri;
bool m_session;
bool m_start;
Slot m_slotFinished;
utils::TaskItem m_taskLoad;
utils::TaskItem m_taskCommit;
};
}
#endif
+1 -1
View File
@@ -49,7 +49,7 @@ namespace core {
DownloadList::iterator
DownloadList::insert(std::istream* str) {
torrent::Download d = torrent::download_create(str);
torrent::Download d = torrent::download_add(str);
iterator itr = Base::insert(end(), new Download);
(*itr)->set_download(d);
+6 -5
View File
@@ -49,12 +49,13 @@
namespace core {
HttpQueue::iterator
HttpQueue::insert(const std::string& url) {
HttpQueue::insert(const std::string& url, std::iostream* s) {
std::auto_ptr<CurlGet> h(m_slotFactory());
std::auto_ptr<std::stringstream> s(new std::stringstream);
//std::auto_ptr<std::stringstream> s(new std::stringstream);
h->set_url(url);
h->set_stream(s.get());
//h->set_stream(s.get());
h->set_stream(s);
h->set_user_agent("rtorrent/" VERSION);
iterator itr = Base::insert(end(), h.get());
@@ -65,7 +66,7 @@ HttpQueue::insert(const std::string& url) {
(*itr)->start();
h.release();
s.release();
//s.release();
m_signalInsert.emit(*itr);
@@ -76,7 +77,7 @@ void
HttpQueue::erase(iterator itr) {
m_signalErase.emit(*itr);
delete (*itr)->get_stream();
//delete (*itr)->get_stream();
delete *itr;
Base::erase(itr);
+4 -1
View File
@@ -69,7 +69,10 @@ public:
// Note that any slots connected to the CurlGet signals must be
// pushed in front of the erase slot added by HttpQueue::insert.
iterator insert(const std::string& url);
//
// Consider adding a flag to indicate whetever HttpQueue should
// delete the stream.
iterator insert(const std::string& url, std::iostream* s);
void erase(iterator itr);
void clear();
+12 -41
View File
@@ -69,7 +69,6 @@ Manager::initialize() {
// opened or closed.
m_downloadList.slot_map_insert().insert("0_initialize_bencode", sigc::mem_fun(*this, &Manager::initialize_bencode));
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("3_manager_inserted", sigc::mem_fun(*this, &Manager::receive_download_inserted));
m_downloadList.slot_map_insert().insert("4_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));
@@ -112,13 +111,16 @@ Manager::shutdown(bool force) {
std::bind1st(std::mem_fun(&DownloadList::close), &m_downloadList));
}
void
Manager::insert(std::string uri) {
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::DListItr
Manager::insert(std::istream* s) {
try {
return m_downloadList.insert(s);
} catch (torrent::local_error& e) {
m_logImportant.push_front(e.what());
m_logComplete.push_front(e.what());
return m_downloadList.end();
}
}
@@ -127,8 +129,8 @@ Manager::erase(DListItr itr) {
if ((*itr)->get_download().is_active())
throw std::logic_error("core::Manager::erase(...) called on an active download");
if (!(*itr)->get_download().is_open())
throw std::logic_error("core::Manager::erase(...) called on an closed download");
// if (!(*itr)->get_download().is_open())
// throw std::logic_error("core::Manager::erase(...) called on an closed download");
return m_downloadList.erase(itr);
}
@@ -220,27 +222,6 @@ Manager::listen_open() {
}
}
void
Manager::create_http(const std::string& uri) {
HttpQueue::iterator itr = m_httpQueue.insert(uri);
(*itr)->signal_done().slots().push_front(sigc::bind(sigc::mem_fun(*this, &Manager::create_final),
(*itr)->get_stream()));
(*itr)->signal_failed().slots().push_front(sigc::mem_fun(*this, &Manager::receive_http_failed));
}
void
Manager::create_final(std::istream* s) {
try {
m_downloadList.insert(s);
} catch (torrent::local_error& e) {
// What to do? Keep in list for now.
m_logImportant.push_front(e.what());
m_logComplete.push_front(e.what());
}
}
void
Manager::initialize_bencode(Download* d) {
torrent::Bencode& bencode = d->get_bencode();
@@ -286,14 +267,4 @@ Manager::receive_download_done_hash_checked(Download* d) {
d->get_download().tracker_send_completed();
}
void
Manager::receive_download_inserted(Download* d) {
// Check if there is an "rtorrent" section in the bencoded data.
torrent::Bencode& bencode = d->get_bencode();
if (bencode["rtorrent"]["state"].as_string() == "started")
start(d);
}
}
+1 -1
View File
@@ -77,7 +77,7 @@ public:
void shutdown(bool force);
void insert(std::string uri);
DListItr insert(std::istream* s);
DListItr erase(DListItr itr);
void start(Download* d);