diff --git a/README.md b/README.md index 49d5b2d3..bf9f1dc7 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ services: - QUEUECLEANER__STALLED_IGNORE_PRIVATE=false - CONTENTBLOCKER__ENABLED=true + - CONTENTBLOCKER__IGNORE_PRIVATE=true - CONTENTBLOCKER__BLACKLIST__ENABLED=true - CONTENTBLOCKER__BLACKLIST__PATH=https://raw.githubusercontent.com/flmorg/cleanuperr/refs/heads/main/blacklist # OR @@ -166,6 +167,7 @@ services: | QUEUECLEANER__STALLED_IGNORE_PRIVATE | No | Whether to ignore stalled downloads from private trackers | false | ||||| | CONTENTBLOCKER__ENABLED | No | Enable or disable the content blocker | false | +| CONTENTBLOCKER__IGNORE_PRIVATE | No | Whether to ignore downloads from private trackers | false | | CONTENTBLOCKER__BLACKLIST__ENABLED | Yes if content blocker is enabled and whitelist is not enabled | Enable or disable the blacklist | false | | CONTENTBLOCKER__BLACKLIST__PATH | Yes if blacklist is enabled | Path to the blacklist (local file or url)
Needs to be json compatible | empty | | CONTENTBLOCKER__WHITELIST__ENABLED | Yes if content blocker is enabled and blacklist is not enabled | Enable or disable the whitelist | false | diff --git a/code/Common/Configuration/ContentBlocker/ContentBlockerConfig.cs b/code/Common/Configuration/ContentBlocker/ContentBlockerConfig.cs index 1e50a5b1..5d57f58a 100644 --- a/code/Common/Configuration/ContentBlocker/ContentBlockerConfig.cs +++ b/code/Common/Configuration/ContentBlocker/ContentBlockerConfig.cs @@ -1,4 +1,6 @@ -namespace Common.Configuration.ContentBlocker; +using Microsoft.Extensions.Configuration; + +namespace Common.Configuration.ContentBlocker; public sealed record ContentBlockerConfig : IJobConfig { @@ -6,6 +8,9 @@ public sealed record ContentBlockerConfig : IJobConfig public required bool Enabled { get; init; } + [ConfigurationKeyName("IGNORE_PRIVATE")] + public bool IgnorePrivate { get; init; } + public PatternConfig? Blacklist { get; init; } public PatternConfig? Whitelist { get; init; } diff --git a/code/Executable/appsettings.Development.json b/code/Executable/appsettings.Development.json index c217c5c0..ffa7f62a 100644 --- a/code/Executable/appsettings.Development.json +++ b/code/Executable/appsettings.Development.json @@ -13,6 +13,7 @@ }, "ContentBlocker": { "Enabled": true, + "IGNORE_PRIVATE": true, "Blacklist": { "Enabled": false, "Path": "https://raw.githubusercontent.com/flmorg/cleanuperr/refs/heads/main/blacklist" diff --git a/code/Executable/appsettings.json b/code/Executable/appsettings.json index dd9d597a..df6894ce 100644 --- a/code/Executable/appsettings.json +++ b/code/Executable/appsettings.json @@ -13,6 +13,7 @@ }, "ContentBlocker": { "Enabled": false, + "IGNORE_PRIVATE": false, "Blacklist": { "Enabled": false, "Path": "" diff --git a/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs b/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs index 0b32e851..62862db2 100644 --- a/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs +++ b/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs @@ -82,6 +82,13 @@ public sealed class DelugeService : DownloadServiceBase return; } + if (_queueCleanerConfig.StalledIgnorePrivate && status.Private) + { + // ignore private trackers + _logger.LogDebug("skip files check | download is private | {name}", status.Name); + return; + } + DelugeContents? contents = null; try diff --git a/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs b/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs index deeb571a..d918f2dd 100644 --- a/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs +++ b/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs @@ -83,6 +83,34 @@ public sealed class QBitService : DownloadServiceBase public override async Task BlockUnwantedFilesAsync(string hash) { + TorrentInfo? torrent = (await _client.GetTorrentListAsync(new TorrentListQuery { Hashes = [hash] })) + .FirstOrDefault(); + + if (torrent is null) + { + _logger.LogDebug("failed to find torrent {hash} in the download client", hash); + return; + } + + TorrentProperties? torrentProperties = await _client.GetTorrentPropertiesAsync(hash); + + if (torrentProperties is null) + { + _logger.LogDebug("failed to find torrent properties {hash} in the download client", hash); + return; + } + + bool isPrivate = torrentProperties.AdditionalData.TryGetValue("is_private", out var dictValue) && + bool.TryParse(dictValue?.ToString(), out bool boolValue) + && boolValue; + + if (_queueCleanerConfig.StalledIgnorePrivate && isPrivate) + { + // ignore private trackers + _logger.LogDebug("skip files check | download is private | {name}", torrent.Name); + return; + } + IReadOnlyList? files = await _client.GetTorrentContentsAsync(hash); if (files is null) diff --git a/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs b/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs index 48821f6c..070a80d3 100644 --- a/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs +++ b/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs @@ -81,6 +81,13 @@ public sealed class TransmissionService : DownloadServiceBase { return; } + + if (_queueCleanerConfig.StalledIgnorePrivate && (torrent.IsPrivate ?? false)) + { + // ignore private trackers + _logger.LogDebug("skip files check | download is private | {name}", torrent.Name); + return; + } List unwantedFiles = []; diff --git a/code/test/docker-compose.yml b/code/test/docker-compose.yml index 7b3a2e6b..e6a5c508 100644 --- a/code/test/docker-compose.yml +++ b/code/test/docker-compose.yml @@ -188,6 +188,7 @@ services: - QUEUECLEANER__STALLED_IGNORE_PRIVATE=true - CONTENTBLOCKER__ENABLED=true + - CONTENTBLOCKER__IGNORE_PRIVATE=true - CONTENTBLOCKER__BLACKLIST__ENABLED=true - CONTENTBLOCKER__BLACKLIST__PATH=https://raw.githubusercontent.com/flmorg/cleanuperr/refs/heads/main/blacklist # OR