From e0d9ae3116ce5595192f60d28cb4e9491fe57138 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Tue, 19 Apr 2016 09:54:48 +0300 Subject: [PATCH] Try to find incomplete files for new torrent --- src/base/bittorrent/session.cpp | 132 ++++++++++++++++++-------- src/base/bittorrent/session.h | 3 +- src/base/bittorrent/torrenthandle.cpp | 8 +- src/base/bittorrent/torrenthandle.h | 2 + 4 files changed, 103 insertions(+), 42 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index d0fdd4c44..267109e49 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -28,63 +28,63 @@ * exception statement from your version. */ +#include "session.h" + +#include +#include #include #include -#include -#include -#include -#include +#include #include #include -#include +#include #include -#include -#include #include +#include +#include +#include +#include #include #include #include -#include -#include +#include #include #include -#include -#include -#include -#include -#include #include #include #include #include -//#include +#include +#include +#include +#include +#include +#include +#include "base/logger.h" +#include "base/net/downloadhandler.h" +#include "base/net/downloadmanager.h" +#include "base/net/portforwarder.h" +#include "base/preferences.h" +#include "base/settingsstorage.h" +#include "base/torrentfilter.h" +#include "base/unicodestrings.h" #include "base/utils/misc.h" #include "base/utils/fs.h" #include "base/utils/string.h" -#include "base/unicodestrings.h" -#include "base/logger.h" -#include "base/settingsstorage.h" -#include "base/preferences.h" -#include "base/torrentfilter.h" -#include "base/net/downloadmanager.h" -#include "base/net/downloadhandler.h" -#include "base/net/portforwarder.h" -#include "base/utils/string.h" +#include "cachestatus.h" +#include "magneturi.h" #include "private/filterparserthread.h" #include "private/statistics.h" #include "private/bandwidthscheduler.h" #include "private/resumedatasavingmanager.h" -#include "trackerentry.h" -#include "tracker.h" -#include "magneturi.h" -#include "cachestatus.h" #include "sessionstatus.h" #include "torrenthandle.h" -#include "session.h" +#include "tracker.h" +#include "trackerentry.h" static const char PEER_ID[] = "qB"; static const char RESUME_FOLDER[] = "BT_backup"; @@ -155,6 +155,16 @@ namespace return expanded; } + + QStringList findAllFiles(const QString &dirPath) + { + QStringList files; + QDirIterator it(dirPath, QDir::Files, QDirIterator::Subdirectories); + while (it.hasNext()) + files << it.next(); + + return files; + } } // Session @@ -1225,7 +1235,7 @@ bool Session::addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams // Add a torrent to the BitTorrent session bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri, - const TorrentInfo &torrentInfo, const QByteArray &fastresumeData) + TorrentInfo torrentInfo, const QByteArray &fastresumeData) { addData.savePath = normalizeSavePath( addData.savePath, @@ -1243,6 +1253,12 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri std::vector buf(fastresumeData.constData(), fastresumeData.constData() + fastresumeData.size()); std::vector filePriorities; + QString savePath; + if (addData.savePath.isEmpty()) // using Advanced mode + savePath = categorySavePath(addData.category); + else // using Simple mode + savePath = addData.savePath; + bool fromMagnetUri = magnetUri.isValid(); if (fromMagnetUri) { hash = magnetUri.hash(); @@ -1271,6 +1287,8 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri } else if (torrentInfo.isValid()) { // Metadata + if (!addData.resumed && !addData.hasSeedStatus) + findIncompleteFiles(torrentInfo, savePath); p.ti = torrentInfo.nativeInfo(); hash = torrentInfo.hash(); } @@ -1329,13 +1347,6 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri Preferences *const pref = Preferences::instance(); p.max_connections = pref->getMaxConnecsPerTorrent(); p.max_uploads = pref->getMaxUploadsPerTorrent(); - - QString savePath; - if (addData.savePath.isEmpty()) // using Advanced mode - savePath = categorySavePath(addData.category); - else // using Simple mode - savePath = addData.savePath; - p.save_path = Utils::String::toStdString(Utils::Fs::toNativePath(savePath)); // Check if save path exists, creating it otherwise if (!QDir(savePath).exists()) @@ -1347,6 +1358,53 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri return true; } +bool Session::findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const +{ + auto findInDir = [](const QString &dirPath, TorrentInfo &torrentInfo) -> bool + { + bool found = false; + if (torrentInfo.filesCount() == 1) { + const QString filePath = dirPath + torrentInfo.filePath(0); + if (QFile(filePath).exists()) { + found = true; + } + else if (QFile(filePath + QB_EXT).exists()) { + found = true; + torrentInfo.renameFile(0, torrentInfo.filePath(0) + QB_EXT); + } + } + else { + QSet allFiles; + int dirPathSize = dirPath.size(); + foreach (const QString &file, findAllFiles(dirPath + torrentInfo.name())) + allFiles << file.mid(dirPathSize); + for (int i = 0; i < torrentInfo.filesCount(); ++i) { + QString filePath = torrentInfo.filePath(i); + if (allFiles.contains(filePath)) { + found = true; + } + else { + filePath += QB_EXT; + if (allFiles.contains(filePath)) { + found = true; + torrentInfo.renameFile(i, filePath); + } + } + } + } + + return found; + }; + + bool found = findInDir(savePath, torrentInfo); + if (!found && isTempPathEnabled()) { + savePath = m_tempPath; + found = findInDir(savePath, torrentInfo); + } + + return found; +} + // Add a torrent to the BitTorrent session in hidden mode // and force it to load its metadata bool Session::loadMetadata(const MagnetUri &magnetUri) diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index 072e478bd..4b9e30a1c 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -356,8 +356,9 @@ namespace BitTorrent void startUpTorrents(); bool addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri, - const TorrentInfo &torrentInfo = TorrentInfo(), + TorrentInfo torrentInfo = TorrentInfo(), const QByteArray &fastresumeData = QByteArray()); + bool findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const; void updateRatioTimer(); void exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolder folder = TorrentExportFolder::Regular); diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 8aa4ce317..2db90d8c6 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -60,7 +60,7 @@ #include "trackerentry.h" #include "torrenthandle.h" -static const char QB_EXT[] = ".!qB"; +const QString QB_EXT {".!qB"}; namespace libt = libtorrent; using namespace BitTorrent; @@ -1611,7 +1611,7 @@ void TorrentHandle::handleFileCompletedAlert(libtorrent::file_completed_alert *p QString name = filePath(p->index); if (name.endsWith(QB_EXT)) { const QString oldName = name; - name.chop(QString(QB_EXT).size()); + name.chop(QB_EXT.size()); qDebug("Renaming %s to %s", qPrintable(oldName), qPrintable(name)); renameFile(p->index, name); } @@ -1733,7 +1733,7 @@ void TorrentHandle::appendExtensionsToIncompleteFiles() else { if (name.endsWith(QB_EXT)) { const QString oldName = name; - name.chop(QString(QB_EXT).size()); + name.chop(QB_EXT.size()); qDebug() << "Renaming" << oldName << "to" << name; renameFile(i, name); } @@ -1747,7 +1747,7 @@ void TorrentHandle::removeExtensionsFromIncompleteFiles() QString name = filePath(i); if (name.endsWith(QB_EXT)) { const QString oldName = name; - name.chop(QString(QB_EXT).size()); + name.chop(QB_EXT.size()); qDebug("Renaming %s to %s", qPrintable(oldName), qPrintable(name)); renameFile(i, name); } diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index fef582b00..a956d6576 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -54,6 +54,8 @@ class QBitArray; class QStringList; template struct QPair; +extern const QString QB_EXT; + namespace libtorrent { class alert;