mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2026-01-03 06:02:29 -06:00
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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user