From d89f289f82fb6ff4305841c7d4c7899ffe12f896 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Wed, 12 Jun 2024 09:02:10 +0300 Subject: [PATCH] Apply filename filter to subfolder names as well PR #20902. Closes #14480. --- src/base/bittorrent/session.h | 2 +- src/base/bittorrent/sessionimpl.cpp | 58 +++++++++++++++++++++++-------------- src/base/bittorrent/sessionimpl.h | 2 +- src/base/bittorrent/torrentimpl.cpp | 11 +++---- src/gui/addnewtorrentdialog.cpp | 15 ++++------ 5 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index d4d3e758a..a5b1bc7b4 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -425,7 +425,7 @@ namespace BitTorrent virtual void setExcludedFileNamesEnabled(bool enabled) = 0; virtual QStringList excludedFileNames() const = 0; virtual void setExcludedFileNames(const QStringList &newList) = 0; - virtual bool isFilenameExcluded(const QString &fileName) const = 0; + virtual void applyFilenameFilter(const PathList &files, QList &priorities) = 0; virtual QStringList bannedIPs() const = 0; virtual void setBannedIPs(const QStringList &newList) = 0; virtual ResumeDataStorageType resumeDataStorageType() const = 0; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 5822bcb63..e34c93acb 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -2769,26 +2769,22 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr Q_ASSERT(p.file_priorities.empty()); Q_ASSERT(addTorrentParams.filePriorities.isEmpty() || (addTorrentParams.filePriorities.size() == nativeIndexes.size())); + QList filePriorities = addTorrentParams.filePriorities; + + if (filePriorities.isEmpty() && isExcludedFileNamesEnabled()) + { + // Check file name blacklist when priorities are not explicitly set + applyFilenameFilter(filePaths, filePriorities); + } + const int internalFilesCount = torrentInfo.nativeInfo()->files().num_files(); // including .pad files // Use qBittorrent default priority rather than libtorrent's (4) p.file_priorities = std::vector(internalFilesCount, LT::toNative(DownloadPriority::Normal)); - if (addTorrentParams.filePriorities.isEmpty()) + if (!filePriorities.isEmpty()) { - if (isExcludedFileNamesEnabled()) - { - // Check file name blacklist when priorities are not explicitly set - for (int i = 0; i < filePaths.size(); ++i) - { - if (isFilenameExcluded(filePaths.at(i).filename())) - p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = lt::dont_download; - } - } - } - else - { - for (int i = 0; i < addTorrentParams.filePriorities.size(); ++i) - p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(addTorrentParams.filePriorities[i]); + for (int i = 0; i < filePriorities.size(); ++i) + p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(filePriorities[i]); } Q_ASSERT(p.ti); @@ -3874,21 +3870,41 @@ void SessionImpl::populateExcludedFileNamesRegExpList() for (const QString &str : excludedNames) { - const QString pattern = QRegularExpression::anchoredPattern(QRegularExpression::wildcardToRegularExpression(str)); + const QString pattern = QRegularExpression::wildcardToRegularExpression(str); const QRegularExpression re {pattern, QRegularExpression::CaseInsensitiveOption}; m_excludedFileNamesRegExpList.append(re); } } -bool SessionImpl::isFilenameExcluded(const QString &fileName) const +void SessionImpl::applyFilenameFilter(const PathList &files, QList &priorities) { if (!isExcludedFileNamesEnabled()) - return false; + return; - return std::any_of(m_excludedFileNamesRegExpList.begin(), m_excludedFileNamesRegExpList.end(), [&fileName](const QRegularExpression &re) + const auto isFilenameExcluded = [patterns = m_excludedFileNamesRegExpList](const Path &fileName) { - return re.match(fileName).hasMatch(); - }); + return std::any_of(patterns.begin(), patterns.end(), [&fileName](const QRegularExpression &re) + { + Path path = fileName; + while (!re.match(path.filename()).hasMatch()) + { + path = path.parentPath(); + if (path.isEmpty()) + return false; + } + return true; + }); + }; + + priorities.resize(files.count(), DownloadPriority::Normal); + for (int i = 0; i < priorities.size(); ++i) + { + if (priorities[i] == BitTorrent::DownloadPriority::Ignored) + continue; + + if (isFilenameExcluded(files.at(i))) + priorities[i] = BitTorrent::DownloadPriority::Ignored; + } } void SessionImpl::setBannedIPs(const QStringList &newList) diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index 40ffbfffa..32a334c9b 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -402,7 +402,7 @@ namespace BitTorrent void setExcludedFileNamesEnabled(bool enabled) override; QStringList excludedFileNames() const override; void setExcludedFileNames(const QStringList &excludedFileNames) override; - bool isFilenameExcluded(const QString &fileName) const override; + void applyFilenameFilter(const PathList &files, QList &priorities) override; QStringList bannedIPs() const override; void setBannedIPs(const QStringList &newList) override; ResumeDataStorageType resumeDataStorageType() const override; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 4cc41c084..d98e5f4e1 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -1791,12 +1791,13 @@ void TorrentImpl::endReceivedMetadataHandling(const Path &savePath, const PathLi const Path filePath = actualFilePath.removedExtension(QB_EXT); m_filePaths.append(filePath); - lt::download_priority_t &nativePriority = p.file_priorities[LT::toUnderlyingType(nativeIndex)]; - if ((nativePriority != lt::dont_download) && m_session->isFilenameExcluded(filePath.filename())) - nativePriority = lt::dont_download; - const auto priority = LT::fromNative(nativePriority); - m_filePriorities.append(priority); + m_filePriorities.append(LT::fromNative(p.file_priorities[LT::toUnderlyingType(nativeIndex)])); } + + m_session->applyFilenameFilter(fileNames, m_filePriorities); + for (int i = 0; i < m_filePriorities.size(); ++i) + p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(m_filePriorities[i]); + p.save_path = savePath.toString().toStdString(); p.ti = metadata; diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index 99ecdda59..98c778e2d 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -181,6 +181,11 @@ public: return (m_filePaths.isEmpty() ? m_torrentInfo.filePath(index) : m_filePaths.at(index)); } + PathList filePaths() const + { + return (m_filePaths.isEmpty() ? m_torrentInfo.filePaths() : m_filePaths); + } + void renameFile(const int index, const Path &newFilePath) override { Q_ASSERT((index >= 0) && (index < filesCount())); @@ -886,15 +891,7 @@ void AddNewTorrentDialog::setupTreeview() { // Check file name blacklist for torrents that are manually added QVector priorities = m_contentAdaptor->filePriorities(); - for (int i = 0; i < priorities.size(); ++i) - { - if (priorities[i] == BitTorrent::DownloadPriority::Ignored) - continue; - - if (BitTorrent::Session::instance()->isFilenameExcluded(torrentInfo.filePath(i).filename())) - priorities[i] = BitTorrent::DownloadPriority::Ignored; - } - + BitTorrent::Session::instance()->applyFilenameFilter(m_contentAdaptor->filePaths(), priorities); m_contentAdaptor->prioritizeFiles(priorities); } -- 2.11.4.GIT