mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-19 23:17:21 -06:00
Branched v2.2.x
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user