Branched v2.2.x

This commit is contained in:
Christophe Dumez
2010-03-14 20:44:17 +00:00
parent 9034094cf9
commit b10e606dda
92 changed files with 11223 additions and 12340 deletions

View File

@@ -61,6 +61,7 @@
#include <libtorrent/alert_types.hpp>
#include <libtorrent/torrent_info.hpp>
#include <boost/filesystem/exception.hpp>
#include <queue>
const int MAX_TRACKER_ERRORS = 2;
const float MAX_RATIO = 100.;
@@ -69,13 +70,13 @@ enum VersionType { NORMAL,ALPHA,BETA,RELEASE_CANDIDATE,DEVEL };
// Main constructor
Bittorrent::Bittorrent()
: m_scanFolders(ScanFoldersModel::instance(this)),
preAllocateAll(false), addInPause(false), ratio_limit(-1),
UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false),
DHTEnabled(false), current_dht_port(0), queueingEnabled(false),
torrentExport(false), exiting(false)
: m_scanFolders(ScanFoldersModel::instance(this)),
preAllocateAll(false), addInPause(false), ratio_limit(-1),
UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false),
DHTEnabled(false), current_dht_port(0), queueingEnabled(false),
torrentExport(false), exiting(false)
#ifndef DISABLE_GUI
, geoipDBLoaded(false), resolve_countries(false)
, geoipDBLoaded(false), resolve_countries(false)
#endif
{
// To avoid some exceptions
@@ -107,9 +108,9 @@ Bittorrent::Bittorrent()
}
}
// Construct session
s = new session(fingerprint(peer_id.toLocal8Bit().data(), version.at(0), version.at(1), version.at(2), version.at(3)), 0);
std::cout << "Peer ID: " << fingerprint(peer_id.toLocal8Bit().data(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string() << std::endl;
addConsoleMessage("Peer ID: "+misc::toQString(fingerprint(peer_id.toLocal8Bit().data(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string()));
s = new session(fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)), 0);
std::cout << "Peer ID: " << fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string() << std::endl;
addConsoleMessage("Peer ID: "+misc::toQString(fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string()));
// Set severity level of libtorrent session
s->set_alert_mask(alert::error_notification | alert::peer_notification | alert::port_mapping_notification | alert::storage_notification | alert::tracker_notification | alert::status_notification | alert::ip_block_notification);
@@ -139,9 +140,9 @@ Bittorrent::Bittorrent()
#ifdef LIBTORRENT_0_15
appendqBExtension = Preferences::useIncompleteFilesExtension();
#endif
connect(m_scanFolders, SIGNAL(torrentsAdded(QStringList&)), this, SLOT(addTorrentsFromScanFolder(QStringList&)));
// Apply user settings to Bittorrent session
configureSession();
connect(m_scanFolders, SIGNAL(torrentsAdded(QStringList&)), this, SLOT(addTorrentsFromScanFolder(QStringList&)));
qDebug("* BTSession constructed");
}
@@ -201,7 +202,7 @@ void Bittorrent::deleteBigRatios() {
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
const QTorrentHandle &h(*torrentIT);
const QTorrentHandle h(*torrentIT);
if(!h.is_valid()) continue;
if(h.is_seed()) {
const QString hash = h.hash();
@@ -717,7 +718,7 @@ void Bittorrent::banIP(QString ip) {
// Delete a torrent from the session, given its hash
// permanent = true means that the torrent will be removed from the hard-drive too
void Bittorrent::deleteTorrent(QString hash, bool delete_local_files) {
qDebug("Deleting torrent with hash: %s", hash.toLocal8Bit().data());
qDebug("Deleting torrent with hash: %s", qPrintable(hash));
const QTorrentHandle &h = getTorrentHandle(hash);
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
@@ -798,7 +799,7 @@ QTorrentHandle Bittorrent::addMagnetUri(QString magnet_uri, bool resumed) {
}
const QDir &torrentBackup(misc::BTBackupLocation());
if(resumed) {
qDebug("Resuming magnet URI: %s", hash.toLocal8Bit().data());
qDebug("Resuming magnet URI: %s", qPrintable(hash));
// Load metadata
if(QFile::exists(torrentBackup.path()+QDir::separator()+hash+QString(".torrent")))
return addTorrent(torrentBackup.path()+QDir::separator()+hash+QString(".torrent"), false, false, true);
@@ -810,7 +811,7 @@ QTorrentHandle Bittorrent::addMagnetUri(QString magnet_uri, bool resumed) {
Q_ASSERT(magnet_uri.startsWith("magnet:"));
// Check if torrent is already in download list
if(s->find_torrent(sha1_hash(hash.toLocal8Bit().data())).is_valid()) {
if(s->find_torrent(sha1_hash(hash.toLocal8Bit().constData())).is_valid()) {
qDebug("/!\\ Torrent is already in download list");
// Update info Bar
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(magnet_uri));
@@ -821,8 +822,9 @@ QTorrentHandle Bittorrent::addMagnetUri(QString magnet_uri, bool resumed) {
//Getting fast resume data if existing
std::vector<char> buf;
if(resumed) {
qDebug("Trying to load fastresume data: %s", (torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data());
if (load_file((torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data(), buf) == 0) {
const QString &fastresume_path = torrentBackup.path()+QDir::separator()+hash+QString(".fastresume");
qDebug("Trying to load fastresume data: %s", qPrintable(fastresume_path));
if (load_file(fastresume_path.toLocal8Bit().constData(), buf) == 0) {
fastResume = true;
p.resume_data = &buf;
qDebug("Successfuly loaded");
@@ -928,7 +930,7 @@ QTorrentHandle Bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
// create it if it is not
if(! torrentBackup.exists()) {
if(! torrentBackup.mkpath(torrentBackup.path())) {
std::cerr << "Couldn't create the directory: '" << torrentBackup.path().toLocal8Bit().data() << "'\n";
std::cerr << "Couldn't create the directory: '" << qPrintable(torrentBackup.path()) << "'\n";
exit(1);
}
}
@@ -970,56 +972,55 @@ QTorrentHandle Bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
if(s->find_torrent(t->info_hash()).is_valid()) {
qDebug("/!\\ Torrent is already in download list");
// Update info Bar
if(!fromScanDir) {
if(!from_url.isNull()) {
// If download from url, remove temp file
QFile::remove(file);
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(from_url));
//emit duplicateTorrent(from_url);
}else{
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(file));
//emit duplicateTorrent(file);
}
// Check if the torrent contains trackers or url seeds we don't know about
// and add them
QTorrentHandle h_ex = getTorrentHandle(hash);
if(h_ex.is_valid()) {
std::vector<announce_entry> old_trackers = h_ex.trackers();
std::vector<announce_entry> new_trackers = t->trackers();
bool trackers_added = false;
for(std::vector<announce_entry>::iterator it=new_trackers.begin();it!=new_trackers.end();it++) {
std::string tracker_url = it->url;
bool found = false;
for(std::vector<announce_entry>::iterator itold=old_trackers.begin();itold!=old_trackers.end();itold++) {
if(tracker_url == itold->url) {
found = true;
break;
}
}
if(found) {
trackers_added = true;
announce_entry entry(tracker_url);
h_ex.add_tracker(entry);
}
}
if(trackers_added) {
addConsoleMessage(tr("Note: new trackers were added to the existing torrent."));
}
bool urlseeds_added = false;
const QStringList &old_urlseeds = h_ex.url_seeds();
std::vector<std::string> new_urlseeds = t->url_seeds();
for(std::vector<std::string>::iterator it = new_urlseeds.begin(); it != new_urlseeds.end(); it++) {
const QString &new_url = misc::toQString(it->c_str());
if(!old_urlseeds.contains(new_url)) {
urlseeds_added = true;
h_ex.add_url_seed(new_url);
}
}
if(urlseeds_added) {
addConsoleMessage(tr("Note: new URL seeds were added to the existing torrent."));
}
}
if(!from_url.isNull()) {
// If download from url, remove temp file
QFile::remove(file);
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(from_url));
//emit duplicateTorrent(from_url);
}else{
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(file));
//emit duplicateTorrent(file);
}
// Check if the torrent contains trackers or url seeds we don't know about
// and add them
QTorrentHandle h_ex = getTorrentHandle(hash);
if(h_ex.is_valid()) {
std::vector<announce_entry> old_trackers = h_ex.trackers();
std::vector<announce_entry> new_trackers = t->trackers();
bool trackers_added = false;
for(std::vector<announce_entry>::iterator it=new_trackers.begin();it!=new_trackers.end();it++) {
std::string tracker_url = it->url;
bool found = false;
for(std::vector<announce_entry>::iterator itold=old_trackers.begin();itold!=old_trackers.end();itold++) {
if(tracker_url == itold->url) {
found = true;
break;
}
}
if(found) {
trackers_added = true;
announce_entry entry(tracker_url);
h_ex.add_tracker(entry);
}
}
if(trackers_added) {
addConsoleMessage(tr("Note: new trackers were added to the existing torrent."));
}
bool urlseeds_added = false;
const QStringList &old_urlseeds = h_ex.url_seeds();
std::vector<std::string> new_urlseeds = t->url_seeds();
for(std::vector<std::string>::iterator it = new_urlseeds.begin(); it != new_urlseeds.end(); it++) {
const QString &new_url = misc::toQString(it->c_str());
if(!old_urlseeds.contains(new_url)) {
urlseeds_added = true;
h_ex.add_url_seed(new_url);
}
}
if(urlseeds_added) {
addConsoleMessage(tr("Note: new URL seeds were added to the existing torrent."));
}
}
if(fromScanDir) {
// Delete torrent from scan dir
QFile::remove(file);
}
@@ -1029,8 +1030,9 @@ QTorrentHandle Bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
//Getting fast resume data if existing
std::vector<char> buf;
if(resumed) {
qDebug("Trying to load fastresume data: %s", (torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data());
if (load_file((torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data(), buf) == 0) {
const QString &fastresume_path = torrentBackup.path()+QDir::separator()+hash+QString(".fastresume");
qDebug("Trying to load fastresume data: %s", qPrintable(fastresume_path));
if (load_file(fastresume_path.toLocal8Bit().constData(), buf) == 0) {
fastResume = true;
p.resume_data = &buf;
qDebug("Successfuly loaded");
@@ -1060,11 +1062,6 @@ QTorrentHandle Bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
p.seed_mode=false;
}
#endif
// TODO: Remove in v1.6.0: For backward compatibility only
if(QFile::exists(misc::BTBackupLocation()+QDir::separator()+hash+".finished")) {
p.save_path = savePath.toLocal8Bit().constData();
QFile::remove(misc::BTBackupLocation()+QDir::separator()+hash+".finished");
}
p.ti = t;
// Preallocate all?
if(preAllocateAll)
@@ -1134,7 +1131,7 @@ QTorrentHandle Bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
}
// Save save_path
if(!defaultTempPath.isEmpty()) {
qDebug("addTorrent: Saving save_path in persistent data: %s", savePath.toLocal8Bit().data());
qDebug("addTorrent: Saving save_path in persistent data: %s", qPrintable(savePath));
TorrentPersistentData::saveSavePath(hash, savePath);
}
#ifdef LIBTORRENT_0_15
@@ -1204,7 +1201,7 @@ void Bittorrent::exportTorrentFiles(QString path) {
std::vector<torrent_handle> handles = s->get_torrents();
std::vector<torrent_handle>::iterator itr;
for(itr=handles.begin(); itr != handles.end(); itr++) {
const QTorrentHandle &h(*itr);
const QTorrentHandle h(*itr);
if(!h.is_valid()) {
std::cerr << "Torrent Export: torrent is invalid, skipping..." << std::endl;
continue;
@@ -1238,7 +1235,7 @@ void Bittorrent::setMaxConnectionsPerTorrent(int max) {
std::vector<torrent_handle> handles = s->get_torrents();
unsigned int nbHandles = handles.size();
for(unsigned int i=0; i<nbHandles; ++i) {
QTorrentHandle h = handles[i];
QTorrentHandle h(handles[i]);
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
continue;
@@ -1252,7 +1249,7 @@ void Bittorrent::setMaxUploadsPerTorrent(int max) {
std::vector<torrent_handle> handles = s->get_torrents();
unsigned int nbHandles = handles.size();
for(unsigned int i=0; i<nbHandles; ++i) {
QTorrentHandle h = handles[i];
QTorrentHandle h(handles[i]);
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
continue;
@@ -1319,7 +1316,8 @@ void Bittorrent::enableLSD(bool b) {
}
void Bittorrent::loadSessionState() {
boost::filesystem::ifstream ses_state_file((misc::cacheLocation()+QDir::separator()+QString::fromUtf8("ses_state")).toLocal8Bit().data()
const QString &state_path = misc::cacheLocation()+QDir::separator()+QString::fromUtf8("ses_state");
boost::filesystem::ifstream ses_state_file(state_path.toLocal8Bit().constData()
, std::ios_base::binary);
ses_state_file.unsetf(std::ios_base::skipws);
s->load_state(bdecode(
@@ -1330,7 +1328,8 @@ void Bittorrent::loadSessionState() {
void Bittorrent::saveSessionState() {
qDebug("Saving session state to disk...");
entry session_state = s->state();
boost::filesystem::ofstream out((misc::cacheLocation()+QDir::separator()+QString::fromUtf8("ses_state")).toLocal8Bit().data()
const QString &state_path = misc::cacheLocation()+QDir::separator()+QString::fromUtf8("ses_state");
boost::filesystem::ofstream out(state_path.toLocal8Bit().constData()
, std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), session_state);
@@ -1343,7 +1342,7 @@ bool Bittorrent::enableDHT(bool b) {
entry dht_state;
const QString &dht_state_path = misc::cacheLocation()+QDir::separator()+QString::fromUtf8("dht_state");
if(QFile::exists(dht_state_path)) {
boost::filesystem::ifstream dht_state_file(dht_state_path.toLocal8Bit().data(), std::ios_base::binary);
boost::filesystem::ifstream dht_state_file(dht_state_path.toLocal8Bit().constData(), std::ios_base::binary);
dht_state_file.unsetf(std::ios_base::skipws);
try{
dht_state = bdecode(std::istream_iterator<char>(dht_state_file), std::istream_iterator<char>());
@@ -1438,7 +1437,7 @@ void Bittorrent::saveFastResumeData() {
--num_resume_data;
if (!rd->resume_data) continue;
QDir torrentBackup(misc::BTBackupLocation());
const QTorrentHandle &h(rd->handle);
const QTorrentHandle h(rd->handle);
if(!h.is_valid()) continue;
// Remove old fastresume file if it exists
QFile::remove(torrentBackup.path()+QDir::separator()+ h.hash() + ".fastresume");
@@ -1491,7 +1490,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
}
const unsigned int nbFiles = h.num_files();
for(unsigned int i=0; i<nbFiles; ++i) {
const QString &extension = h.file_at(i).split('.').last();
QString extension = h.file_at(i).split('.').last();
if(misc::isPreviewable(extension))
return true;
}
@@ -1502,7 +1501,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
foreach(const QString &file, pathList) {
qDebug("File %s added", qPrintable(file));
try {
torrent_info t(file.toLocal8Bit().data());
torrent_info t(file.toLocal8Bit().constData());
if(t.is_valid())
addTorrent(file, true);
} catch(std::exception&) {
@@ -1557,15 +1556,17 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
if(file_size > 0 && (fp[i]/(double)file_size) < 1.) {
const QString &name = misc::toQString(h.get_torrent_info().file_at(i).path.string());
if(!name.endsWith(".!qB")) {
qDebug("Renaming %s to %s", qPrintable(name), qPrintable(name+".!qB"));
h.rename_file(i, name + ".!qB");
const QString &new_name = name+".!qB";
qDebug("Renaming %s to %s", qPrintable(name), qPrintable(new_name));
h.rename_file(i, new_name);
}
}
} else {
QString name = misc::toQString(h.get_torrent_info().file_at(i).path.string());
if(name.endsWith(".!qB")) {
const QString old_name = name;
name.chop(4);
qDebug("Renaming %s to %s", qPrintable(name+".!qB"), qPrintable(name));
qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(name));
h.rename_file(i, name);
}
}
@@ -1869,7 +1870,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
}
else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a.get())) {
const QDir &torrentBackup(misc::BTBackupLocation());
const QTorrentHandle &h(p->handle);
const QTorrentHandle h(p->handle);
if(h.is_valid()) {
const QString &file = h.hash()+".fastresume";
// Delete old fastresume file if necessary
@@ -1949,8 +1950,9 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
if(appendqBExtension) {
QString name = misc::toQString(h.get_torrent_info().file_at(p->index).path.string());
if(name.endsWith(".!qB")) {
const QString old_name = name;
name.chop(4);
qDebug("Renaming %s to %s", qPrintable(name+".!qB"), qPrintable(name));
qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(name));
h.rename_file(p->index, name);
}
}
@@ -1958,14 +1960,13 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
#endif
/*else if (torrent_paused_alert* p = dynamic_cast<torrent_paused_alert*>(a.get())) {
QTorrentHandle h(p->handle);
qDebug("Received a torrent_paused_alert for %s", h.hash().toLocal8Bit().data());
if(h.is_valid()) {
emit torrentPaused(h);
}
}*/
else if (tracker_error_alert* p = dynamic_cast<tracker_error_alert*>(a.get())) {
// Level: fatal
const QTorrentHandle &h(p->handle);
QTorrentHandle h(p->handle);
if(h.is_valid()){
// Authentication
if(p->status_code != 401) {
@@ -1986,7 +1987,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
}
}
else if (tracker_reply_alert* p = dynamic_cast<tracker_reply_alert*>(a.get())) {
const QTorrentHandle &h(p->handle);
const QTorrentHandle h(p->handle);
if(h.is_valid()){
qDebug("Received a tracker reply from %s (Num_peers=%d)", p->url.c_str(), p->num_peers);
// Connection was successful now. Remove possible old errors
@@ -2003,7 +2004,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
trackersInfos[h.hash()] = trackers_data;
}
} else if (tracker_warning_alert* p = dynamic_cast<tracker_warning_alert*>(a.get())) {
const QTorrentHandle &h(p->handle);
const QTorrentHandle h(p->handle);
if(h.is_valid()){
// Connection was successful now but there is a warning message
QHash<QString, TrackerInfos> trackers_data = trackersInfos.value(h.hash(), QHash<QString, TrackerInfos>());
@@ -2037,7 +2038,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
//emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str()));
}
else if (fastresume_rejected_alert* p = dynamic_cast<fastresume_rejected_alert*>(a.get())) {
const QTorrentHandle &h(p->handle);
const QTorrentHandle h(p->handle);
if(h.is_valid()){
qDebug("/!\\ Fast resume failed for %s, reason: %s", qPrintable(h.name()), p->message().c_str());
addConsoleMessage(tr("Fast resume data was rejected for torrent %1, checking again...").arg(h.name()), QString::fromUtf8("red"));
@@ -2108,7 +2109,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
if(TorrentTempData::hasTempData(hash)) {
savePath = TorrentTempData::getSavePath(hash);
if(savePath.isEmpty()) {
savePath = defaultSavePath;
savePath = defaultSavePath;
}
if(appendLabelToSavePath) {
qDebug("appendLabelToSavePath is true");
@@ -2165,7 +2166,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
);
//emit aboutToDownloadFromUrl(url);
// Launch downloader thread
downloader->downloadUrl(url);
downloader->downloadTorrentUrl(url);
}
void Bittorrent::downloadFromURLList(const QStringList& urls) {
@@ -2222,7 +2223,8 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
if(DHTEnabled) {
try{
entry dht_state = s->dht_state();
boost::filesystem::ofstream out((misc::cacheLocation()+QDir::separator()+QString::fromUtf8("dht_state")).toLocal8Bit().constData(), std::ios_base::binary);
const QString &dht_path = misc::cacheLocation()+QDir::separator()+QString::fromUtf8("dht_state");
boost::filesystem::ofstream out(dht_path.toLocal8Bit().constData(), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), dht_state);
qDebug("DHT entry saved");
@@ -2241,16 +2243,9 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
// backup directory
void Bittorrent::startUpTorrents() {
qDebug("Resuming unfinished torrents");
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
const QDir &torrentBackup(misc::BTBackupLocation());
const QStringList &known_torrents = TorrentPersistentData::knownTorrents();
if(known_torrents.empty() && !settings.value("v1_4_x_torrent_imported", false).toBool()) {
qDebug("No known torrent, importing old torrents");
importOldTorrents();
return;
}
// Safety measure because some people reported torrent loss since
// we switch the v1.5 way of resuming torrents on startup
QStringList filters;
@@ -2267,7 +2262,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
qDebug("Starting up torrents");
if(isQueueingEnabled()) {
QList<QPair<int, QString> > hashes;
priority_queue<QPair<int, QString>, vector<QPair<int, QString> >, std::greater<QPair<int, QString> > > torrent_queue;
foreach(const QString &hash, known_torrents) {
QString filePath;
if(TorrentPersistentData::isMagnet(hash)) {
@@ -2276,12 +2271,15 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
filePath = torrentBackup.path()+QDir::separator()+hash+".torrent";
}
const int prio = TorrentPersistentData::getPriority(hash);
misc::insertSort2<QString>(hashes, qMakePair(prio, hash));
torrent_queue.push(qMakePair(prio, hash));
}
// Resume downloads
QPair<int, QString> couple;
foreach(couple, hashes) {
const QString &hash = couple.second;
int prio = -1;
while(!torrent_queue.empty()) {
int new_prio = torrent_queue.top().first;
Q_ASSERT(new_prio >= prio);
const QString &hash = torrent_queue.top().second;
torrent_queue.pop();
qDebug("Starting up torrent %s", qPrintable(hash));
if(TorrentPersistentData::isMagnet(hash)) {
addMagnetUri(TorrentPersistentData::getMagnetUri(hash), true);
@@ -2301,199 +2299,3 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
}
qDebug("Unfinished torrents resumed");
}
// Import torrents temp data from v1.4.0 or earlier: save_path, filtered pieces
// TODO: Remove in qBittorrent v2.2.0
void Bittorrent::importOldTempData(QString torrent_path) {
// Create torrent hash
try {
boost::intrusive_ptr<torrent_info> t = new torrent_info(torrent_path.toLocal8Bit().data());
const QString &hash = misc::toQString(t->info_hash());
// Load save path
QFile savepath_file(misc::BTBackupLocation()+QDir::separator()+hash+".savepath");
QByteArray line;
QString savePath;
if(savepath_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
line = savepath_file.readAll();
savepath_file.close();
qDebug(" -> Save path: %s", line.constData());
savePath = QString::fromUtf8(line.data());
qDebug("Imported the following save path: %s", qPrintable(savePath));
TorrentTempData::setSavePath(hash, savePath);
}
// Load pieces priority
QFile pieces_file(misc::BTBackupLocation()+QDir::separator()+hash+".priorities");
if(pieces_file.exists()){
// Read saved file
if(pieces_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
const QByteArray &pieces_priorities = pieces_file.readAll();
pieces_file.close();
const QList<QByteArray> &pieces_priorities_list = pieces_priorities.split('\n');
std::vector<int> pp;
for(int i=0; i<t->num_files(); ++i) {
int priority = pieces_priorities_list.at(i).toInt();
if( priority < 0 || priority > 7) {
priority = 1;
}
//qDebug("Setting piece piority to %d", priority);
pp.push_back(priority);
}
TorrentTempData::setFilesPriority(hash, pp);
qDebug("Successfuly imported pieces_priority");
}
}
// Load sequential
if(QFile::exists(misc::BTBackupLocation()+QDir::separator()+hash+".incremental")) {
qDebug("Imported torrent was sequential");
TorrentTempData::setSequential(hash, true);
}
} catch(std::exception&) {
}
}
// Trackers, web seeds, speed limits
// TODO: Remove in qBittorrent v2.2.0
void Bittorrent::applyFormerAttributeFiles(QTorrentHandle h) {
// Load trackers
const QDir &torrentBackup(misc::BTBackupLocation());
QFile tracker_file(torrentBackup.path()+QDir::separator()+ h.hash() + ".trackers");
if(tracker_file.exists()) {
if(tracker_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
const QStringList &lines = QString::fromUtf8(tracker_file.readAll().data()).split("\n");
std::vector<announce_entry> trackers;
foreach(const QString &line, lines) {
const QStringList &parts = line.split("|");
if(parts.size() != 2) continue;
announce_entry t(parts[0].toStdString());
t.tier = parts[1].toInt();
trackers.push_back(t);
}
if(!trackers.empty()) {
h.replace_trackers(trackers);
h.force_reannounce();
}
}
}
// Load Web seeds
QFile urlseeds_file(misc::BTBackupLocation()+QDir::separator()+h.hash()+".urlseeds");
if(urlseeds_file.exists()) {
if(urlseeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
const QByteArray &urlseeds_lines = urlseeds_file.readAll();
urlseeds_file.close();
const QList<QByteArray> &url_seeds = urlseeds_lines.split('\n');
// First remove from the torrent the url seeds that were deleted
// in a previous session
QStringList seeds_to_delete;
const QStringList &existing_seeds = h.url_seeds();
foreach(const QString &existing_seed, existing_seeds) {
if(!url_seeds.contains(existing_seed.toLocal8Bit())) {
seeds_to_delete << existing_seed;
}
}
foreach(const QString &existing_seed, seeds_to_delete) {
h.remove_url_seed(existing_seed);
}
// Add the ones that were added in a previous session
foreach(const QByteArray &url_seed, url_seeds) {
if(!url_seed.isEmpty()) {
// XXX: Should we check if it is already in the list before adding it
// or is libtorrent clever enough to know
h.add_url_seed(url_seed);
}
}
}
}
// Load speed limits
QFile speeds_file(misc::BTBackupLocation()+QDir::separator()+h.hash()+".speedLimits");
if(speeds_file.exists()) {
if(speeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
const QByteArray &speed_limits = speeds_file.readAll();
speeds_file.close();
const QList<QByteArray> &speeds = speed_limits.split(' ');
if(speeds.size() != 2) {
std::cerr << "Invalid .speedLimits file for " << qPrintable(h.hash()) << '\n';
return;
}
h.set_download_limit(speeds.at(0).toInt());
h.set_upload_limit(speeds.at(1).toInt());
}
}
}
// Import torrents from v1.4.0 or earlier
// TODO: Remove in qBittorrent v2.2.0
void Bittorrent::importOldTorrents() {
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
Q_ASSERT(!settings.value("v1_4_x_torrent_imported", false).toBool());
// Import old torrent
const QDir &torrentBackup(misc::BTBackupLocation());
QStringList filters;
filters << "*.torrent";
const QStringList &fileNames = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted);
if(isQueueingEnabled()) {
QList<QPair<int, QString> > filePaths;
foreach(const QString &fileName, fileNames) {
QString filePath = torrentBackup.path()+QDir::separator()+fileName;
int prio = 99999;
// Get priority
const QString &prioPath = filePath.replace(".torrent", ".prio");
if(QFile::exists(prioPath)) {
QFile prio_file(prioPath);
if(prio_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
bool ok = false;
prio = prio_file.readAll().toInt(&ok);
if(!ok)
prio = 99999;
prio_file.close();
}
}
misc::insertSort2<QString>(filePaths, qMakePair(prio, filePath));
}
// Resume downloads
QPair<int, QString> fileName;
foreach(fileName, filePaths) {
importOldTempData(fileName.second);
QTorrentHandle h = addTorrent(fileName.second, false, QString(), true);
// Sequential download
if(TorrentTempData::hasTempData(h.hash())) {
qDebug("addTorrent: Setting download as sequential (from tmp data)");
h.set_sequential_download(TorrentTempData::isSequential(h.hash()));
}
applyFormerAttributeFiles(h);
const QString &savePath = TorrentTempData::getSavePath(h.hash());
// Save persistent data for new torrent
TorrentPersistentData::saveTorrentPersistentData(h);
// Save save_path
if(!defaultTempPath.isEmpty() && !savePath.isNull()) {
qDebug("addTorrent: Saving save_path in persistent data: %s", qPrintable(savePath));
TorrentPersistentData::saveSavePath(h.hash(), savePath);
}
}
} else {
QStringList filePaths;
foreach(const QString &fileName, fileNames) {
filePaths.append(torrentBackup.path()+QDir::separator()+fileName);
}
// Resume downloads
foreach(const QString &fileName, filePaths) {
importOldTempData(fileName);
QTorrentHandle h = addTorrent(fileName, false, QString(), true);
// Sequential download
if(TorrentTempData::hasTempData(h.hash())) {
qDebug("addTorrent: Setting download as sequential (from tmp data)");
h.set_sequential_download(TorrentTempData::isSequential(h.hash()));
}
applyFormerAttributeFiles(h);
const QString &savePath = TorrentTempData::getSavePath(h.hash());
// Save persistent data for new torrent
TorrentPersistentData::saveTorrentPersistentData(h);
// Save save_path
if(!defaultTempPath.isEmpty() && !savePath.isNull()) {
qDebug("addTorrent: Saving save_path in persistent data: %s", qPrintable(savePath));
TorrentPersistentData::saveSavePath(h.hash(), savePath);
}
}
}
settings.setValue("v1_4_x_torrent_imported", true);
std::cout << "Successfully imported torrents from v1.4.x (or previous) instance" << std::endl;
}