mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-15 01:33:07 -07:00
- Rewrited torrent resume code to make it cleaner and more generic
* magnet URI support should be easy to implement now Warning: Since a lot of code was rewrited, some bugs may have been introduced
This commit is contained in:
parent
360a327d7d
commit
2742a54d6e
11 changed files with 1879 additions and 1656 deletions
|
@ -40,6 +40,7 @@
|
|||
#include "misc.h"
|
||||
#include "downloadThread.h"
|
||||
#include "filterParserThread.h"
|
||||
#include "torrentPersistentData.h"
|
||||
#include <libtorrent/extensions/ut_metadata.hpp>
|
||||
#include <libtorrent/extensions/ut_pex.hpp>
|
||||
#include <libtorrent/extensions/smart_ban.hpp>
|
||||
|
@ -107,8 +108,8 @@ bittorrent::~bittorrent() {
|
|||
delete filterParser;
|
||||
delete downloader;
|
||||
if(FSWatcher) {
|
||||
delete FSWatcher;
|
||||
delete FSMutex;
|
||||
delete FSWatcher;
|
||||
delete FSMutex;
|
||||
}
|
||||
// Delete BT session
|
||||
qDebug("Deleting session");
|
||||
|
@ -126,22 +127,22 @@ void bittorrent::preAllocateAllFiles(bool b) {
|
|||
|
||||
void bittorrent::deleteBigRatios() {
|
||||
if(ratio_limit == -1) return;
|
||||
std::vector<torrent_handle> torrents = getTorrents();
|
||||
std::vector<torrent_handle>::iterator torrentIT;
|
||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid()) continue;
|
||||
if(h.is_seed()) {
|
||||
QString hash = h.hash();
|
||||
float ratio = getRealRatio(hash);
|
||||
if(ratio <= MAX_RATIO && ratio > ratio_limit) {
|
||||
QString fileName = h.name();
|
||||
addConsoleMessage(tr("%1 reached the maximum ratio you set.").arg(fileName));
|
||||
deleteTorrent(hash);
|
||||
//emit torrent_ratio_deleted(fileName);
|
||||
}
|
||||
}
|
||||
std::vector<torrent_handle> torrents = getTorrents();
|
||||
std::vector<torrent_handle>::iterator torrentIT;
|
||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid()) continue;
|
||||
if(h.is_seed()) {
|
||||
QString hash = h.hash();
|
||||
float ratio = getRealRatio(hash);
|
||||
if(ratio <= MAX_RATIO && ratio > ratio_limit) {
|
||||
QString fileName = h.name();
|
||||
addConsoleMessage(tr("%1 reached the maximum ratio you set.").arg(fileName));
|
||||
deleteTorrent(hash);
|
||||
//emit torrent_ratio_deleted(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bittorrent::setDownloadLimit(QString hash, long val) {
|
||||
|
@ -206,22 +207,22 @@ int bittorrent::getUpTorrentPriority(QString hash) const {
|
|||
// Calculate the ETA using GASA
|
||||
// GASA: global Average Speed Algorithm
|
||||
qlonglong bittorrent::getETA(QString hash) const {
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
if(!h.is_valid()) return -1;
|
||||
switch(h.state()) {
|
||||
case torrent_status::downloading: {
|
||||
if(h.active_time() == 0)
|
||||
return -1;
|
||||
double avg_speed = (double)h.all_time_download() / h.active_time();
|
||||
return (qlonglong) floor((double) (h.actual_size() - h.total_wanted_done()) / avg_speed);
|
||||
}
|
||||
default:
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
if(!h.is_valid()) return -1;
|
||||
switch(h.state()) {
|
||||
case torrent_status::downloading: {
|
||||
if(h.active_time() == 0)
|
||||
return -1;
|
||||
double avg_speed = (double)h.all_time_download() / h.active_time();
|
||||
return (qlonglong) floor((double) (h.actual_size() - h.total_wanted_done()) / avg_speed);
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<torrent_handle> bittorrent::getTorrents() const {
|
||||
return s->get_torrents();
|
||||
return s->get_torrents();
|
||||
}
|
||||
|
||||
// Return the torrent handle, given its hash
|
||||
|
@ -232,28 +233,28 @@ QTorrentHandle bittorrent::getTorrentHandle(QString hash) const{
|
|||
unsigned int bittorrent::getFinishedPausedTorrentsNb() const {
|
||||
unsigned int nbPaused = 0;
|
||||
std::vector<torrent_handle> torrents = getTorrents();
|
||||
std::vector<torrent_handle>::iterator torrentIT;
|
||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid()) continue;
|
||||
if(h.is_seed() && h.is_paused()) {
|
||||
++nbPaused;
|
||||
}
|
||||
std::vector<torrent_handle>::iterator torrentIT;
|
||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid()) continue;
|
||||
if(h.is_seed() && h.is_paused()) {
|
||||
++nbPaused;
|
||||
}
|
||||
}
|
||||
return nbPaused;
|
||||
}
|
||||
|
||||
unsigned int bittorrent::getUnfinishedPausedTorrentsNb() const {
|
||||
unsigned int nbPaused = 0;
|
||||
std::vector<torrent_handle> torrents = getTorrents();
|
||||
std::vector<torrent_handle>::iterator torrentIT;
|
||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid()) continue;
|
||||
if(!h.is_seed() && h.is_paused()) {
|
||||
++nbPaused;
|
||||
}
|
||||
std::vector<torrent_handle>::iterator torrentIT;
|
||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid()) continue;
|
||||
if(!h.is_seed() && h.is_paused()) {
|
||||
++nbPaused;
|
||||
}
|
||||
}
|
||||
return nbPaused;
|
||||
}
|
||||
|
||||
|
@ -270,7 +271,7 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
|
|||
QString fileName = h.name();
|
||||
// Remove it from session
|
||||
if(permanent)
|
||||
s->remove_torrent(h.get_torrent_handle(), session::delete_files);
|
||||
s->remove_torrent(h.get_torrent_handle(), session::delete_files);
|
||||
else
|
||||
s->remove_torrent(h.get_torrent_handle());
|
||||
// Remove it from torrent backup directory
|
||||
|
@ -281,6 +282,7 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
|
|||
foreach(const QString &file, files) {
|
||||
torrentBackup.remove(file);
|
||||
}
|
||||
TorrentPersistentData::deletePersistentData(hash);
|
||||
// Remove tracker errors
|
||||
trackersErrors.remove(hash);
|
||||
if(permanent)
|
||||
|
@ -291,53 +293,49 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
|
|||
}
|
||||
|
||||
void bittorrent::pauseAllTorrents() {
|
||||
std::vector<torrent_handle> torrents = getTorrents();
|
||||
std::vector<torrent_handle>::iterator torrentIT;
|
||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid()) continue;
|
||||
if(!h.is_paused()) {
|
||||
h.pause();
|
||||
emit pausedTorrent(h);
|
||||
}
|
||||
std::vector<torrent_handle> torrents = getTorrents();
|
||||
std::vector<torrent_handle>::iterator torrentIT;
|
||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid()) continue;
|
||||
if(!h.is_paused()) {
|
||||
h.pause();
|
||||
emit pausedTorrent(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bittorrent::resumeAllTorrents() {
|
||||
std::vector<torrent_handle> torrents = getTorrents();
|
||||
std::vector<torrent_handle>::iterator torrentIT;
|
||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid()) continue;
|
||||
if(h.is_paused()) {
|
||||
h.resume();
|
||||
emit resumedTorrent(h);
|
||||
}
|
||||
std::vector<torrent_handle> torrents = getTorrents();
|
||||
std::vector<torrent_handle>::iterator torrentIT;
|
||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid()) continue;
|
||||
if(h.is_paused()) {
|
||||
h.resume();
|
||||
emit resumedTorrent(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bittorrent::pauseTorrent(QString hash) {
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
if(!h.is_paused()) {
|
||||
h.pause();
|
||||
emit pausedTorrent(h);
|
||||
}
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
if(!h.is_paused()) {
|
||||
h.pause();
|
||||
emit pausedTorrent(h);
|
||||
}
|
||||
}
|
||||
|
||||
void bittorrent::resumeTorrent(QString hash) {
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
if(h.is_paused()) {
|
||||
h.resume();
|
||||
emit resumedTorrent(h);
|
||||
}
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
if(h.is_paused()) {
|
||||
h.resume();
|
||||
emit resumedTorrent(h);
|
||||
}
|
||||
}
|
||||
|
||||
void bittorrent::loadWebSeeds(QString hash) {
|
||||
QFile urlseeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".urlseeds");
|
||||
if(!urlseeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
|
||||
QByteArray urlseeds_lines = urlseeds_file.readAll();
|
||||
urlseeds_file.close();
|
||||
QList<QByteArray> url_seeds = urlseeds_lines.split('\n');
|
||||
QVariantList url_seeds = TorrentPersistentData::getUrlSeeds(hash);
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
// First remove from the torrent the url seeds that were deleted
|
||||
// in a previous session
|
||||
|
@ -352,7 +350,8 @@ void bittorrent::loadWebSeeds(QString hash) {
|
|||
h.remove_url_seed(existing_seed);
|
||||
}
|
||||
// Add the ones that were added in a previous session
|
||||
foreach(const QByteArray &url_seed, url_seeds) {
|
||||
foreach(const QVariant &var_url_seed, url_seeds) {
|
||||
QString url_seed = var_url_seed.toString();
|
||||
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
|
||||
|
@ -362,11 +361,12 @@ void bittorrent::loadWebSeeds(QString hash) {
|
|||
}
|
||||
|
||||
// Add a torrent to the bittorrent session
|
||||
QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bool) {
|
||||
QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bool resumed) {
|
||||
QTorrentHandle h;
|
||||
bool fastResume=false;
|
||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||
QString file, dest_file;
|
||||
QString file, dest_file, hash;
|
||||
boost::intrusive_ptr<torrent_info> t;
|
||||
|
||||
// Checking if BT_backup Dir exists
|
||||
// create it if it is not
|
||||
|
@ -382,75 +382,71 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
|||
return h;
|
||||
}
|
||||
Q_ASSERT(!file.startsWith("http://", Qt::CaseInsensitive) && !file.startsWith("https://", Qt::CaseInsensitive) && !file.startsWith("ftp://", Qt::CaseInsensitive));
|
||||
|
||||
qDebug("Adding %s to download list", file.toLocal8Bit().data());
|
||||
boost::intrusive_ptr<torrent_info> t;
|
||||
try {
|
||||
// Getting torrent file informations
|
||||
t = new torrent_info(file.toLocal8Bit().data());
|
||||
// Getting torrent file informations
|
||||
t = new torrent_info(file.toLocal8Bit().data());
|
||||
} catch(std::exception&) {
|
||||
if(!from_url.isNull()) {
|
||||
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), QString::fromUtf8("red"));
|
||||
//emit invalidTorrent(from_url);
|
||||
QFile::remove(file);
|
||||
}else{
|
||||
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(file), QString::fromUtf8("red"));
|
||||
//emit invalidTorrent(file);
|
||||
}
|
||||
addConsoleMessage(tr("This file is either corrupted or this isn't a torrent."),QString::fromUtf8("red"));
|
||||
if(fromScanDir) {
|
||||
// Remove file
|
||||
QFile::remove(file);
|
||||
}
|
||||
return h;
|
||||
if(!from_url.isNull()) {
|
||||
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), QString::fromUtf8("red"));
|
||||
//emit invalidTorrent(from_url);
|
||||
QFile::remove(file);
|
||||
}else{
|
||||
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(file), QString::fromUtf8("red"));
|
||||
//emit invalidTorrent(file);
|
||||
}
|
||||
addConsoleMessage(tr("This file is either corrupted or this isn't a torrent."),QString::fromUtf8("red"));
|
||||
if(fromScanDir) {
|
||||
// Remove file
|
||||
QFile::remove(file);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
qDebug(" -> Hash: %s", misc::toString(t->info_hash()).c_str());
|
||||
qDebug(" -> Name: %s", t->name().c_str());
|
||||
QString hash = misc::toQString(t->info_hash());
|
||||
hash = misc::toQString(t->info_hash());
|
||||
if(file.startsWith(torrentBackup.path())) {
|
||||
QFileInfo fi(file);
|
||||
QString old_hash = fi.baseName();
|
||||
if(old_hash != hash){
|
||||
qDebug("* ERROR: Strange, hash changed from %s to %s", old_hash.toLocal8Bit().data(), hash.toLocal8Bit().data());
|
||||
}
|
||||
QFileInfo fi(file);
|
||||
QString old_hash = fi.baseName();
|
||||
if(old_hash != hash){
|
||||
qDebug("* ERROR: Strange, hash changed from %s to %s", old_hash.toLocal8Bit().data(), hash.toLocal8Bit().data());
|
||||
}
|
||||
}
|
||||
// Check if torrent is already in download list
|
||||
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);
|
||||
}
|
||||
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{
|
||||
// Delete torrent from scan dir
|
||||
QFile::remove(file);
|
||||
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(file));
|
||||
//emit duplicateTorrent(file);
|
||||
}
|
||||
return h;
|
||||
}else{
|
||||
// Delete torrent from scan dir
|
||||
QFile::remove(file);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
add_torrent_params p;
|
||||
//Getting fast resume data if existing
|
||||
std::vector<char> buf;
|
||||
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) {
|
||||
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) {
|
||||
fastResume = true;
|
||||
p.resume_data = &buf;
|
||||
qDebug("Successfuly loaded");
|
||||
}
|
||||
}
|
||||
QString savePath = getSavePath(hash);
|
||||
// Save save_path to hard drive
|
||||
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
|
||||
if(!savepath_file.exists()) {
|
||||
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
savepath_file.write(savePath.toLocal8Bit());
|
||||
savepath_file.close();
|
||||
}
|
||||
if(defaultTempPath.isEmpty() || QFile::exists(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".finished"))) {
|
||||
qDebug("addTorrent: using save_path: %s", savePath.toUtf8().data());
|
||||
if(defaultTempPath.isEmpty() || (resumed && TorrentPersistentData::isSeed(hash))) {
|
||||
p.save_path = savePath.toLocal8Bit().data();
|
||||
} else {
|
||||
p.save_path = defaultTempPath.toLocal8Bit().data();
|
||||
|
@ -467,17 +463,17 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
|||
p.auto_managed = false; // Because it is added in paused state
|
||||
// Adding torrent to bittorrent session
|
||||
try {
|
||||
h = QTorrentHandle(s->add_torrent(p));
|
||||
h = QTorrentHandle(s->add_torrent(p));
|
||||
}catch(std::exception e){
|
||||
qDebug("Error: %s", e.what());
|
||||
}
|
||||
// Check if it worked
|
||||
if(!h.is_valid()) {
|
||||
// No need to keep on, it failed.
|
||||
qDebug("/!\\ Error: Invalid handle");
|
||||
// If download from url, remove temp file
|
||||
if(!from_url.isNull()) QFile::remove(file);
|
||||
return h;
|
||||
// No need to keep on, it failed.
|
||||
qDebug("/!\\ Error: Invalid handle");
|
||||
// If download from url, remove temp file
|
||||
if(!from_url.isNull()) QFile::remove(file);
|
||||
return h;
|
||||
}
|
||||
// Connections limit per torrent
|
||||
h.set_max_connections(maxConnecsPerTorrent);
|
||||
|
@ -485,76 +481,71 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
|||
h.set_max_uploads(maxUploadsPerTorrent);
|
||||
// Load filtered files
|
||||
loadFilesPriorities(h);
|
||||
// Load custom url seeds
|
||||
loadWebSeeds(hash);
|
||||
// Load speed limit from hard drive
|
||||
loadTorrentSpeedLimits(hash);
|
||||
// Load trackers
|
||||
bool loaded_trackers = loadTrackerFile(hash);
|
||||
// Doing this to order trackers well
|
||||
if(!loaded_trackers) {
|
||||
saveTrackerFile(hash);
|
||||
loadTrackerFile(hash);
|
||||
if(resumed) {
|
||||
// Load custom url seeds
|
||||
loadWebSeeds(hash);
|
||||
// Load speed limit from hard drive
|
||||
loadTorrentSpeedLimits(hash);
|
||||
// Load trackers
|
||||
loadTrackerFile(hash);
|
||||
} else {
|
||||
// Sequential download
|
||||
if(TorrentTempData::hasTempData(hash)) {
|
||||
qDebug("addTorrent: Setting download as sequential (from tmp data)");
|
||||
h.set_sequential_download(TorrentTempData::isSequential(hash));
|
||||
}
|
||||
// Save persistent data for new torrent
|
||||
TorrentPersistentData::saveTorrentPersistentData(h);
|
||||
// Save save_path
|
||||
if(!defaultTempPath.isEmpty()) {
|
||||
qDebug("addTorrent: Saving save_path in persistent data: %s", savePath.toUtf8().data());
|
||||
TorrentPersistentData::saveSavePath(hash, savePath);
|
||||
}
|
||||
}
|
||||
QString newFile = torrentBackup.path() + QDir::separator() + hash + ".torrent";
|
||||
if(file != newFile) {
|
||||
// Delete file from torrentBackup directory in case it exists because
|
||||
// QFile::copy() do not overwrite
|
||||
QFile::remove(newFile);
|
||||
// Copy it to torrentBackup directory
|
||||
QFile::copy(file, newFile);
|
||||
}
|
||||
// Incremental download
|
||||
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".incremental")) {
|
||||
qDebug("Incremental download enabled for %s", t->name().c_str());
|
||||
h.set_sequential_download(true);
|
||||
// Delete file from torrentBackup directory in case it exists because
|
||||
// QFile::copy() do not overwrite
|
||||
QFile::remove(newFile);
|
||||
// Copy it to torrentBackup directory
|
||||
QFile::copy(file, newFile);
|
||||
}
|
||||
if(!addInPause && !fastResume) {
|
||||
// Start torrent because it was added in paused state
|
||||
h.resume();
|
||||
// Start torrent because it was added in paused state
|
||||
h.resume();
|
||||
}
|
||||
// If download from url, remove temp file
|
||||
if(!from_url.isNull()) QFile::remove(file);
|
||||
// Delete from scan dir to avoid trying to download it again
|
||||
if(fromScanDir) {
|
||||
QFile::remove(file);
|
||||
QFile::remove(file);
|
||||
}
|
||||
// Send torrent addition signal
|
||||
if(!from_url.isNull()) {
|
||||
if(fastResume)
|
||||
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(from_url));
|
||||
else
|
||||
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(from_url));
|
||||
if(fastResume)
|
||||
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(from_url));
|
||||
else
|
||||
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(from_url));
|
||||
}else{
|
||||
if(fastResume)
|
||||
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(file));
|
||||
else
|
||||
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(file));
|
||||
if(fastResume)
|
||||
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(file));
|
||||
else
|
||||
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(file));
|
||||
}
|
||||
emit addedTorrent(h);
|
||||
return h;
|
||||
}
|
||||
|
||||
// Check in .priorities file if the user filtered files
|
||||
// in this torrent.
|
||||
// Check if the user filtered files in this torrent.
|
||||
bool bittorrent::has_filtered_files(QString hash) const{
|
||||
QFile pieces_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".priorities");
|
||||
// Read saved file
|
||||
if(!pieces_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
QByteArray pieces_text = pieces_file.readAll();
|
||||
pieces_file.close();
|
||||
QList<QByteArray> pieces_priorities_list = pieces_text.split('\n');
|
||||
unsigned int listSize = pieces_priorities_list.size();
|
||||
for(unsigned int i=0; i<listSize-1; ++i) {
|
||||
int priority = pieces_priorities_list.at(i).toInt();
|
||||
QVariantList files_priority = TorrentPersistentData::getFilesPriority(hash);
|
||||
foreach(QVariant var_prio, files_priority) {
|
||||
int priority = var_prio.toInt();
|
||||
if( priority < 0 || priority > 7) {
|
||||
priority = 1;
|
||||
}
|
||||
if(!priority) {
|
||||
if(!priority)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -648,21 +639,21 @@ void bittorrent::enableLSD(bool b) {
|
|||
}
|
||||
|
||||
void bittorrent::loadSessionState() {
|
||||
boost::filesystem::ifstream ses_state_file((misc::qBittorrentPath()+QString::fromUtf8("ses_state")).toLocal8Bit().data()
|
||||
, std::ios_base::binary);
|
||||
ses_state_file.unsetf(std::ios_base::skipws);
|
||||
s->load_state(bdecode(
|
||||
std::istream_iterator<char>(ses_state_file)
|
||||
, std::istream_iterator<char>()));
|
||||
boost::filesystem::ifstream ses_state_file((misc::qBittorrentPath()+QString::fromUtf8("ses_state")).toLocal8Bit().data()
|
||||
, std::ios_base::binary);
|
||||
ses_state_file.unsetf(std::ios_base::skipws);
|
||||
s->load_state(bdecode(
|
||||
std::istream_iterator<char>(ses_state_file)
|
||||
, std::istream_iterator<char>()));
|
||||
}
|
||||
|
||||
void bittorrent::saveSessionState() {
|
||||
qDebug("Saving session state to disk...");
|
||||
entry session_state = s->state();
|
||||
boost::filesystem::ofstream out((misc::qBittorrentPath()+QString::fromUtf8("ses_state")).toLocal8Bit().data()
|
||||
, std::ios_base::binary);
|
||||
out.unsetf(std::ios_base::skipws);
|
||||
bencode(std::ostream_iterator<char>(out), session_state);
|
||||
qDebug("Saving session state to disk...");
|
||||
entry session_state = s->state();
|
||||
boost::filesystem::ofstream out((misc::qBittorrentPath()+QString::fromUtf8("ses_state")).toLocal8Bit().data()
|
||||
, std::ios_base::binary);
|
||||
out.unsetf(std::ios_base::skipws);
|
||||
bencode(std::ostream_iterator<char>(out), session_state);
|
||||
}
|
||||
|
||||
// Enable DHT
|
||||
|
@ -677,18 +668,18 @@ bool bittorrent::enableDHT(bool b) {
|
|||
try{
|
||||
dht_state = bdecode(std::istream_iterator<char>(dht_state_file), std::istream_iterator<char>());
|
||||
}catch (std::exception&) {}
|
||||
}
|
||||
}
|
||||
try {
|
||||
s->start_dht(dht_state);
|
||||
s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881));
|
||||
s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881));
|
||||
s->add_dht_router(std::make_pair(std::string("router.bitcomet.com"), 6881));
|
||||
DHTEnabled = true;
|
||||
qDebug("DHT enabled");
|
||||
}catch(std::exception e) {
|
||||
qDebug("Could not enable DHT, reason: %s", e.what());
|
||||
return false;
|
||||
}
|
||||
s->start_dht(dht_state);
|
||||
s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881));
|
||||
s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881));
|
||||
s->add_dht_router(std::make_pair(std::string("router.bitcomet.com"), 6881));
|
||||
DHTEnabled = true;
|
||||
qDebug("DHT enabled");
|
||||
}catch(std::exception e) {
|
||||
qDebug("Could not enable DHT, reason: %s", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(DHTEnabled) {
|
||||
|
@ -715,7 +706,7 @@ void bittorrent::saveTorrentSpeedLimits(QString hash) {
|
|||
}
|
||||
|
||||
void bittorrent::loadTorrentSpeedLimits(QString hash) {
|
||||
// qDebug("Loading speedLimits file for %s", hash.toLocal8Bit().data());
|
||||
// qDebug("Loading speedLimits file for %s", hash.toLocal8Bit().data());
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
QFile speeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".speedLimits");
|
||||
if(!speeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
|
@ -732,7 +723,7 @@ void bittorrent::loadTorrentSpeedLimits(QString hash) {
|
|||
h.set_upload_limit(speeds.at(1).toInt());
|
||||
}
|
||||
|
||||
// Read pieces priorities from .priorities file
|
||||
// Read pieces priorities from hard disk
|
||||
// and ask QTorrentHandle to consider them
|
||||
void bittorrent::loadFilesPriorities(QTorrentHandle &h) {
|
||||
qDebug("Applying pieces priorities");
|
||||
|
@ -740,31 +731,19 @@ void bittorrent::loadFilesPriorities(QTorrentHandle &h) {
|
|||
qDebug("/!\\ Error: Invalid handle");
|
||||
return;
|
||||
}
|
||||
unsigned int nbFiles = h.num_files();
|
||||
QString hash = h.hash();
|
||||
QFile pieces_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".priorities");
|
||||
if(!pieces_file.exists()){
|
||||
return;
|
||||
}
|
||||
// Read saved file
|
||||
if(!pieces_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qDebug("* Error: Couldn't open priorities file: %s", hash.toLocal8Bit().data());
|
||||
return;
|
||||
}
|
||||
QByteArray pieces_priorities = pieces_file.readAll();
|
||||
pieces_file.close();
|
||||
QList<QByteArray> pieces_priorities_list = pieces_priorities.split('\n');
|
||||
if((unsigned int)pieces_priorities_list.size() != nbFiles+1) {
|
||||
std::cerr << "* Error: Corrupted priorities file\n";
|
||||
return;
|
||||
}
|
||||
std::vector<int> v;
|
||||
for(unsigned int i=0; i<nbFiles; ++i) {
|
||||
int priority = pieces_priorities_list.at(i).toInt();
|
||||
QVariantList files_priority;
|
||||
if(TorrentTempData::hasTempData(h.hash())) {
|
||||
files_priority = TorrentTempData::getFilesPriority(h.hash());
|
||||
} else {
|
||||
files_priority = TorrentPersistentData::getFilesPriority(h.hash());
|
||||
}
|
||||
foreach(const QVariant &var_prio, files_priority) {
|
||||
int priority = var_prio.toInt();
|
||||
if( priority < 0 || priority > 7) {
|
||||
priority = 1;
|
||||
}
|
||||
qDebug("Setting piece piority to %d", priority);
|
||||
qDebug("Setting file piority to %d", priority);
|
||||
v.push_back(priority);
|
||||
}
|
||||
h.prioritize_files(v);
|
||||
|
@ -800,47 +779,47 @@ void bittorrent::saveFastResumeData() {
|
|||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||
if(!h.is_valid() || !h.has_metadata()) continue;
|
||||
if(isQueueingEnabled())
|
||||
saveTorrentPriority(h.hash(), h.queue_position());
|
||||
TorrentPersistentData::savePriority(h);
|
||||
if(h.is_paused()) continue;
|
||||
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) continue;
|
||||
h.save_resume_data();
|
||||
++num_resume_data;
|
||||
}
|
||||
while (num_resume_data > 0) {
|
||||
alert const* a = s->wait_for_alert(seconds(30));
|
||||
if (a == 0) {
|
||||
std::cerr << " aborting with " << num_resume_data << " outstanding "
|
||||
"torrents to save resume data for" << std::endl;
|
||||
break;
|
||||
}
|
||||
// Saving fastresume data can fail
|
||||
save_resume_data_failed_alert const* rda = dynamic_cast<save_resume_data_failed_alert const*>(a);
|
||||
if (rda) {
|
||||
--num_resume_data;
|
||||
s->pop_alert();
|
||||
// Remove torrent from session
|
||||
s->remove_torrent(rda->handle);
|
||||
continue;
|
||||
}
|
||||
save_resume_data_alert const* rd = dynamic_cast<save_resume_data_alert const*>(a);
|
||||
if (!rd) {
|
||||
s->pop_alert();
|
||||
continue;
|
||||
}
|
||||
// Saving fast resume data was successful
|
||||
alert const* a = s->wait_for_alert(seconds(30));
|
||||
if (a == 0) {
|
||||
std::cerr << " aborting with " << num_resume_data << " outstanding "
|
||||
"torrents to save resume data for" << std::endl;
|
||||
break;
|
||||
}
|
||||
// Saving fastresume data can fail
|
||||
save_resume_data_failed_alert const* rda = dynamic_cast<save_resume_data_failed_alert const*>(a);
|
||||
if (rda) {
|
||||
--num_resume_data;
|
||||
if (!rd->resume_data) continue;
|
||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||
QTorrentHandle h(rd->handle);
|
||||
// Remove old fastresume file if it exists
|
||||
QFile::remove(torrentBackup.path()+QDir::separator()+ h.hash() + ".fastresume");
|
||||
QString file = h.hash()+".fastresume";
|
||||
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toLocal8Bit().data()) / file.toLocal8Bit().data(), std::ios_base::binary);
|
||||
out.unsetf(std::ios_base::skipws);
|
||||
bencode(std::ostream_iterator<char>(out), *rd->resume_data);
|
||||
// Remove torrent from session
|
||||
s->remove_torrent(rd->handle);
|
||||
s->pop_alert();
|
||||
// Remove torrent from session
|
||||
s->remove_torrent(rda->handle);
|
||||
continue;
|
||||
}
|
||||
save_resume_data_alert const* rd = dynamic_cast<save_resume_data_alert const*>(a);
|
||||
if (!rd) {
|
||||
s->pop_alert();
|
||||
continue;
|
||||
}
|
||||
// Saving fast resume data was successful
|
||||
--num_resume_data;
|
||||
if (!rd->resume_data) continue;
|
||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||
QTorrentHandle h(rd->handle);
|
||||
// Remove old fastresume file if it exists
|
||||
QFile::remove(torrentBackup.path()+QDir::separator()+ h.hash() + ".fastresume");
|
||||
QString file = h.hash()+".fastresume";
|
||||
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toLocal8Bit().data()) / file.toLocal8Bit().data(), std::ios_base::binary);
|
||||
out.unsetf(std::ios_base::skipws);
|
||||
bencode(std::ostream_iterator<char>(out), *rd->resume_data);
|
||||
// Remove torrent from session
|
||||
s->remove_torrent(rd->handle);
|
||||
s->pop_alert();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -896,14 +875,14 @@ void bittorrent::scanDirectory(QString scan_dir) {
|
|||
filters << "*.torrent";
|
||||
QStringList files = dir.entryList(filters, QDir::Files, QDir::Unsorted);
|
||||
foreach(const QString &file, files) {
|
||||
QString fullPath = dir.path()+QDir::separator()+file;
|
||||
QFile torrent(fullPath);
|
||||
if(torrent.size() != 0) {
|
||||
qDebug("Adding for scan_dir: %s", fullPath.toLocal8Bit().data());
|
||||
addTorrent(fullPath, true);
|
||||
} else {
|
||||
qDebug("Ignoring empty file: %s", fullPath.toLocal8Bit().data());
|
||||
}
|
||||
QString fullPath = dir.path()+QDir::separator()+file;
|
||||
QFile torrent(fullPath);
|
||||
if(torrent.size() != 0) {
|
||||
qDebug("Adding for scan_dir: %s", fullPath.toLocal8Bit().data());
|
||||
addTorrent(fullPath, true);
|
||||
} else {
|
||||
qDebug("Ignoring empty file: %s", fullPath.toLocal8Bit().data());
|
||||
}
|
||||
}
|
||||
FSMutex->unlock();
|
||||
}
|
||||
|
@ -912,6 +891,10 @@ void bittorrent::setDefaultSavePath(QString savepath) {
|
|||
defaultSavePath = savepath;
|
||||
}
|
||||
|
||||
bool bittorrent::useTemporaryFolder() const {
|
||||
return !defaultTempPath.isEmpty();
|
||||
}
|
||||
|
||||
void bittorrent::setDefaultTempPath(QString temppath) {
|
||||
if(defaultTempPath == temppath)
|
||||
return;
|
||||
|
@ -938,23 +921,28 @@ void bittorrent::setDefaultTempPath(QString temppath) {
|
|||
defaultTempPath = temppath;
|
||||
}
|
||||
|
||||
void bittorrent::saveTrackerFile(QString hash) {
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
TorrentPersistentData::saveTrackers(h);
|
||||
}
|
||||
|
||||
// Enable directory scanning
|
||||
void bittorrent::enableDirectoryScanning(QString scan_dir) {
|
||||
if(!scan_dir.isEmpty()) {
|
||||
if(FSWatcher == 0) {
|
||||
FSMutex = new QMutex();
|
||||
FSWatcher = new QFileSystemWatcher(QStringList(scan_dir), this);
|
||||
connect(FSWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(scanDirectory(QString)));
|
||||
FSMutex = new QMutex();
|
||||
FSWatcher = new QFileSystemWatcher(QStringList(scan_dir), this);
|
||||
connect(FSWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(scanDirectory(QString)));
|
||||
// Initial scan
|
||||
scanDirectory(scan_dir);
|
||||
} else {
|
||||
QString old_scan_dir = FSWatcher->directories().first();
|
||||
if(old_scan_dir != scan_dir) {
|
||||
FSWatcher->removePath(old_scan_dir);
|
||||
FSWatcher->addPath(scan_dir);
|
||||
// Initial scan
|
||||
scanDirectory(scan_dir);
|
||||
} else {
|
||||
QString old_scan_dir = FSWatcher->directories().first();
|
||||
if(old_scan_dir != scan_dir) {
|
||||
FSWatcher->removePath(old_scan_dir);
|
||||
FSWatcher->addPath(scan_dir);
|
||||
// Initial scan
|
||||
scanDirectory(scan_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -962,8 +950,8 @@ void bittorrent::enableDirectoryScanning(QString scan_dir) {
|
|||
// Disable directory scanning
|
||||
void bittorrent::disableDirectoryScanning() {
|
||||
if(FSWatcher) {
|
||||
delete FSWatcher;
|
||||
delete FSMutex;
|
||||
delete FSWatcher;
|
||||
delete FSMutex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1032,46 +1020,21 @@ void bittorrent::setDeleteRatio(float ratio) {
|
|||
}
|
||||
}
|
||||
|
||||
bool bittorrent::loadTrackerFile(QString hash) {
|
||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||
QFile tracker_file(torrentBackup.path()+QDir::separator()+ hash + ".trackers");
|
||||
if(!tracker_file.exists()) return false;
|
||||
tracker_file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
QStringList lines = QString::fromUtf8(tracker_file.readAll().data()).split("\n");
|
||||
void bittorrent::loadTrackerFile(QString hash) {
|
||||
QHash<QString, QVariant> tiers = TorrentPersistentData::getTrackers(hash);
|
||||
std::vector<announce_entry> trackers;
|
||||
foreach(const QString &line, lines) {
|
||||
QStringList parts = line.split("|");
|
||||
if(parts.size() != 2) continue;
|
||||
announce_entry t(parts[0].toStdString());
|
||||
t.tier = parts[1].toInt();
|
||||
foreach(const QString tracker_url, tiers.keys()) {
|
||||
announce_entry t(tracker_url.toStdString());
|
||||
t.tier = tiers[tracker_url].toInt();
|
||||
trackers.push_back(t);
|
||||
}
|
||||
if(!trackers.empty()) {
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
h.replace_trackers(trackers);
|
||||
h.force_reannounce();
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void bittorrent::saveTrackerFile(QString hash) {
|
||||
qDebug("Saving tracker file for %s", hash.toLocal8Bit().data());
|
||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||
QFile tracker_file(torrentBackup.path()+QDir::separator()+ hash + ".trackers");
|
||||
if(tracker_file.exists()) {
|
||||
tracker_file.remove();
|
||||
}
|
||||
tracker_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
std::vector<announce_entry> trackers = h.trackers();
|
||||
for(unsigned int i=0; i<trackers.size(); ++i) {
|
||||
tracker_file.write(QByteArray(trackers[i].url.c_str())+QByteArray("|")+QByteArray(misc::toString(i).c_str())+QByteArray("\n"));
|
||||
}
|
||||
tracker_file.close();
|
||||
}
|
||||
|
||||
// Set DHT port (>= 1000 or 0 if same as BT)
|
||||
void bittorrent::setDHTPort(int dht_port) {
|
||||
if(dht_port == 0 or dht_port >= 1000) {
|
||||
|
@ -1149,10 +1112,8 @@ void bittorrent::readAlerts() {
|
|||
if(h.is_valid()){
|
||||
emit finishedTorrent(h);
|
||||
QString hash = h.hash();
|
||||
// Create .finished file if necessary
|
||||
QFile finished_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished");
|
||||
finished_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
finished_file.close();
|
||||
// Remember finished state
|
||||
TorrentPersistentData::saveSeedStatus(h);
|
||||
// Move to download directory if necessary
|
||||
if(!defaultTempPath.isEmpty()) {
|
||||
// Check if directory is different
|
||||
|
@ -1167,19 +1128,19 @@ void bittorrent::readAlerts() {
|
|||
}
|
||||
}
|
||||
else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a.get())) {
|
||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||
QTorrentHandle h(p->handle);
|
||||
QString file = h.hash()+".fastresume";
|
||||
// Delete old fastresume file if necessary
|
||||
if(QFile::exists(file))
|
||||
QFile::remove(file);
|
||||
qDebug("Saving fastresume data in %s", file.toLocal8Bit().data());
|
||||
if (p->resume_data)
|
||||
{
|
||||
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toLocal8Bit().data()) / file.toLocal8Bit().data(), std::ios_base::binary);
|
||||
out.unsetf(std::ios_base::skipws);
|
||||
bencode(std::ostream_iterator<char>(out), *p->resume_data);
|
||||
}
|
||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||
QTorrentHandle h(p->handle);
|
||||
QString file = h.hash()+".fastresume";
|
||||
// Delete old fastresume file if necessary
|
||||
if(QFile::exists(file))
|
||||
QFile::remove(file);
|
||||
qDebug("Saving fastresume data in %s", file.toLocal8Bit().data());
|
||||
if (p->resume_data)
|
||||
{
|
||||
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toLocal8Bit().data()) / file.toLocal8Bit().data(), std::ios_base::binary);
|
||||
out.unsetf(std::ios_base::skipws);
|
||||
bencode(std::ostream_iterator<char>(out), *p->resume_data);
|
||||
}
|
||||
}
|
||||
else if (file_error_alert* p = dynamic_cast<file_error_alert*>(a.get())) {
|
||||
QTorrentHandle h(p->handle);
|
||||
|
@ -1284,17 +1245,17 @@ session_status bittorrent::getSessionStatus() const{
|
|||
}
|
||||
|
||||
QString bittorrent::getSavePath(QString hash) {
|
||||
QFile savepath_file(misc::qBittorrentPath()+"BT_backup"+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.data());
|
||||
savePath = QString::fromUtf8(line.data());
|
||||
}else{
|
||||
// use default save path
|
||||
qDebug("Using default save path because none was set");
|
||||
if(TorrentTempData::hasTempData(hash)) {
|
||||
savePath = TorrentTempData::getSavePath(hash);
|
||||
qDebug("getSavePath, got save_path from temp data: %s", savePath.toUtf8().data());
|
||||
} else {
|
||||
savePath = TorrentPersistentData::getSavePath(hash);
|
||||
qDebug("getSavePath, got save_path from persistent data: %s", savePath.toUtf8().data());
|
||||
}
|
||||
if(savePath.isEmpty()) {
|
||||
// use default save path if no other can be found
|
||||
qDebug("Using default save path because none was set: %s", defaultSavePath.toUtf8().data());
|
||||
savePath = defaultSavePath;
|
||||
}
|
||||
// Checking if savePath Dir exists
|
||||
|
@ -1383,58 +1344,39 @@ void bittorrent::applyEncryptionSettings(pe_settings se) {
|
|||
s->set_pe_settings(se);
|
||||
}
|
||||
|
||||
void bittorrent::saveTorrentPriority(QString hash, int prio) {
|
||||
// Write .queued file
|
||||
QFile prio_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".prio");
|
||||
prio_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
prio_file.write(QByteArray::number(prio));
|
||||
prio_file.close();
|
||||
}
|
||||
|
||||
// Will fast resume torrents in
|
||||
// backup directory
|
||||
void bittorrent::resumeUnfinishedTorrents() {
|
||||
void bittorrent::startUpTorrents() {
|
||||
qDebug("Resuming unfinished torrents");
|
||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||
QStringList fileNames;
|
||||
// Scan torrentBackup directory
|
||||
QStringList filters;
|
||||
filters << "*.torrent";
|
||||
fileNames = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted);
|
||||
QStringList known_torrents = TorrentPersistentData::knownTorrents();
|
||||
if(isQueueingEnabled()) {
|
||||
QList<QPair<int, QString> > filePaths;
|
||||
foreach(const QString &fileName, fileNames) {
|
||||
QString filePath = torrentBackup.path()+QDir::separator()+fileName;
|
||||
int prio = 99999;
|
||||
// Get priority
|
||||
QString prioPath = filePath;
|
||||
prioPath.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));
|
||||
QList<QPair<int, QString> > filePaths;
|
||||
foreach(const QString &hash, known_torrents) {
|
||||
QString filePath;
|
||||
if(TorrentPersistentData::isMagnet(hash)) {
|
||||
filePath = TorrentPersistentData::getMagnetUri(hash);
|
||||
} else {
|
||||
filePath = torrentBackup.path()+QDir::separator()+hash+".torrent";
|
||||
}
|
||||
// Resume downloads
|
||||
QPair<int, QString> fileName;
|
||||
foreach(fileName, filePaths) {
|
||||
addTorrent(fileName.second, false, QString(), true);
|
||||
}
|
||||
} else {
|
||||
QStringList filePaths;
|
||||
foreach(const QString &fileName, fileNames) {
|
||||
filePaths.append(torrentBackup.path()+QDir::separator()+fileName);
|
||||
}
|
||||
// Resume downloads
|
||||
foreach(const QString &fileName, filePaths) {
|
||||
addTorrent(fileName, false, QString(), true);
|
||||
}
|
||||
int prio = TorrentPersistentData::getPriority(hash);
|
||||
misc::insertSort2<QString>(filePaths, qMakePair(prio, filePath));
|
||||
}
|
||||
// Resume downloads
|
||||
QPair<int, QString> fileName;
|
||||
foreach(fileName, filePaths) {
|
||||
addTorrent(fileName.second, false, QString(), true);
|
||||
}
|
||||
} else {
|
||||
QStringList filePaths;
|
||||
foreach(const QString &fileName, fileNames) {
|
||||
filePaths.append(torrentBackup.path()+QDir::separator()+fileName);
|
||||
}
|
||||
// Resume downloads
|
||||
foreach(const QString &fileName, filePaths) {
|
||||
addTorrent(fileName, false, QString(), true);
|
||||
}
|
||||
}
|
||||
qDebug("Unfinished torrents resumed");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue