Add file name filter/blacklist

Blacklist filtered file names from being downloaded from torrent(s).
Files matching any of the filters in this list will have their priority automatically set to "Do not download".
See Options > Downloads >Do not download.

Closes #3369.
PR #17106.
This commit is contained in:
mxtsdev
2022-06-09 22:37:46 -07:00
committed by GitHub
parent c47e29c7c8
commit 5e6174c087
9 changed files with 144 additions and 17 deletions

View File

@@ -414,6 +414,7 @@ Session::Session(QObject *parent)
, m_peerTurnoverCutoff(BITTORRENT_SESSION_KEY(u"PeerTurnoverCutOff"_qs), 90)
, m_peerTurnoverInterval(BITTORRENT_SESSION_KEY(u"PeerTurnoverInterval"_qs), 300)
, m_requestQueueSize(BITTORRENT_SESSION_KEY(u"RequestQueueSize"_qs), 500)
, m_excludedFileNames(BITTORRENT_SESSION_KEY(u"ExcludedFileNames"_qs))
, m_bannedIPs(u"State/BannedIPs"_qs
, QStringList()
, [](const QStringList &value)
@@ -466,6 +467,7 @@ Session::Session(QObject *parent)
enqueueRefresh();
updateSeedingLimitTimer();
populateAdditionalTrackers();
populateExcludedFileNamesRegExpList();
enableTracker(isTrackerEnabled());
@@ -2244,19 +2246,30 @@ bool Session::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source
}
const auto nativeIndexes = torrentInfo.nativeIndexes();
if (!filePaths.isEmpty())
{
for (int index = 0; index < filePaths.size(); ++index)
p.renamed_files[nativeIndexes[index]] = filePaths.at(index).toString().toStdString();
}
for (int index = 0; index < filePaths.size(); ++index)
p.renamed_files[nativeIndexes[index]] = filePaths.at(index).toString().toStdString();
Q_ASSERT(p.file_priorities.empty());
Q_ASSERT(addTorrentParams.filePriorities.isEmpty() || (addTorrentParams.filePriorities.size() == nativeIndexes.size()));
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));
Q_ASSERT(addTorrentParams.filePriorities.isEmpty() || (addTorrentParams.filePriorities.size() == nativeIndexes.size()));
for (int i = 0; i < addTorrentParams.filePriorities.size(); ++i)
p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(addTorrentParams.filePriorities[i]);
if (addTorrentParams.filePriorities.size() == 0)
{
// 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]);
}
p.ti = torrentInfo.nativeInfo();
}
@@ -3078,6 +3091,43 @@ void Session::setIPFilterFile(const Path &path)
}
}
QStringList Session::excludedFileNames() const
{
return m_excludedFileNames;
}
void Session::setExcludedFileNames(const QStringList &excludedFileNames)
{
if (excludedFileNames != m_excludedFileNames)
{
m_excludedFileNames = excludedFileNames;
populateExcludedFileNamesRegExpList();
}
}
void Session::populateExcludedFileNamesRegExpList()
{
const QStringList excludedNames = excludedFileNames();
m_excludedFileNamesRegExpList.clear();
m_excludedFileNamesRegExpList.reserve(excludedNames.size());
for (const QString &str : excludedNames)
{
const QString pattern = QRegularExpression::anchoredPattern(QRegularExpression::wildcardToRegularExpression(str));
const QRegularExpression re {pattern, QRegularExpression::CaseInsensitiveOption};
m_excludedFileNamesRegExpList.append(re);
}
}
bool Session::isFilenameExcluded(const QString &fileName) const
{
return std::any_of(m_excludedFileNamesRegExpList.begin(), m_excludedFileNamesRegExpList.end(), [&fileName](const QRegularExpression &re)
{
return re.match(fileName).hasMatch();
});
}
void Session::setBannedIPs(const QStringList &newList)
{
if (newList == m_bannedIPs)

View File

@@ -455,6 +455,9 @@ namespace BitTorrent
void setBlockPeersOnPrivilegedPorts(bool enabled);
bool isTrackerFilteringEnabled() const;
void setTrackerFilteringEnabled(bool enabled);
QStringList excludedFileNames() const;
void setExcludedFileNames(const QStringList &newList);
bool isFilenameExcluded(const QString &fileName) const;
QStringList bannedIPs() const;
void setBannedIPs(const QStringList &newList);
ResumeDataStorageType resumeDataStorageType() const;
@@ -624,6 +627,7 @@ namespace BitTorrent
void applyOSMemoryPriority() const;
#endif
void processTrackerStatuses();
void populateExcludedFileNamesRegExpList();
bool loadTorrent(LoadTorrentParams params);
LoadTorrentParams initLoadTorrentParams(const AddTorrentParams &addTorrentParams);
@@ -778,6 +782,7 @@ namespace BitTorrent
CachedSettingValue<int> m_peerTurnoverCutoff;
CachedSettingValue<int> m_peerTurnoverInterval;
CachedSettingValue<int> m_requestQueueSize;
CachedSettingValue<QStringList> m_excludedFileNames;
CachedSettingValue<QStringList> m_bannedIPs;
CachedSettingValue<ResumeDataStorageType> m_resumeDataStorageType;
#if defined(Q_OS_WIN)
@@ -792,6 +797,7 @@ namespace BitTorrent
int m_numResumeData = 0;
int m_extraLimit = 0;
QVector<TrackerEntry> m_additionalTrackerList;
QVector<QRegularExpression> m_excludedFileNamesRegExpList;
bool m_refreshEnqueued = false;
QTimer *m_seedingLimitTimer = nullptr;

View File

@@ -1519,9 +1519,8 @@ void TorrentImpl::endReceivedMetadataHandling(const Path &savePath, const PathLi
m_torrentInfo = TorrentInfo(*metadata);
m_filePriorities.reserve(filesCount());
const auto nativeIndexes = m_torrentInfo.nativeIndexes();
const std::vector<lt::download_priority_t> filePriorities =
resized(p.file_priorities, metadata->files().num_files()
, LT::toNative(p.file_priorities.empty() ? DownloadPriority::Normal : DownloadPriority::Ignored));
p.file_priorities = resized(p.file_priorities, metadata->files().num_files()
, LT::toNative(p.file_priorities.empty() ? DownloadPriority::Normal : DownloadPriority::Ignored));
m_completedFiles.fill(static_cast<bool>(p.flags & lt::torrent_flags::seed_mode), filesCount());
@@ -1529,17 +1528,20 @@ void TorrentImpl::endReceivedMetadataHandling(const Path &savePath, const PathLi
{
const auto nativeIndex = nativeIndexes.at(i);
const Path filePath = fileNames.at(i);
p.renamed_files[nativeIndex] = filePath.toString().toStdString();
const Path actualFilePath = fileNames.at(i);
p.renamed_files[nativeIndex] = actualFilePath.toString().toStdString();
m_filePaths.append(filePath.removedExtension(QB_EXT));
const Path filePath = actualFilePath.removedExtension(QB_EXT);
m_filePaths.append(filePath);
const auto priority = LT::fromNative(filePriorities[LT::toUnderlyingType(nativeIndex)]);
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);
}
p.save_path = savePath.toString().toStdString();
p.ti = metadata;
p.file_priorities = filePriorities;
reload();