findIncompleteFiles(): Replace dir listing with individual checks. Closes #6265.

Looking for incomplete files in a new torrent by using a pre-generated
directory listing presents several disadvantages:

  - It requires us to extract the top-level directory name (in case it
    was renamed).
  - It requires us to know whether the top-level directory was stripped.
  - In the latter case, it may result in recursively traversing the
    entire contents of all downloaded torrents.

Calling QFile::exists() individually for each file solves all these
issues.

In so doing, the handling of single-file and multiple-file torrents are
rendered pretty much identical, and can therefore be merged.
This commit is contained in:
Frédéric Brière 2017-04-27 15:31:30 -04:00
parent 818dcce462
commit e8f6149a6d

View file

@ -33,7 +33,6 @@
#include <QDateTime> #include <QDateTime>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QDirIterator>
#include <QHostAddress> #include <QHostAddress>
#include <QNetworkAddressEntry> #include <QNetworkAddressEntry>
#include <QNetworkInterface> #include <QNetworkInterface>
@ -156,16 +155,6 @@ namespace
return expanded; return expanded;
} }
QStringList findAllFiles(const QString &dirPath)
{
QStringList files;
QDirIterator it(dirPath, QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext())
files << it.next();
return files;
}
template <typename T> template <typename T>
struct LowerLimited struct LowerLimited
{ {
@ -1729,35 +1718,19 @@ bool Session::findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) c
{ {
auto findInDir = [](const QString &dirPath, TorrentInfo &torrentInfo) -> bool auto findInDir = [](const QString &dirPath, TorrentInfo &torrentInfo) -> bool
{ {
const QDir dir(dirPath);
bool found = false; 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<QString> 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) { for (int i = 0; i < torrentInfo.filesCount(); ++i) {
QString filePath = torrentInfo.filePath(i); const QString filePath = torrentInfo.filePath(i);
if (allFiles.contains(filePath)) { if (dir.exists(filePath)) {
found = true; found = true;
} }
else { else if (dir.exists(filePath + QB_EXT)) {
filePath += QB_EXT;
if (allFiles.contains(filePath)) {
found = true; found = true;
torrentInfo.renameFile(i, filePath); torrentInfo.renameFile(i, filePath + QB_EXT);
}
}
} }
if ((i % 100) == 0)
qApp->processEvents();
} }
return found; return found;