From 4a58f5ad21ee1c8d8393552b2bb55243ca63d7a5 Mon Sep 17 00:00:00 2001 From: Flaminel Date: Mon, 19 Oct 2026 23:03:56 +0300 Subject: [PATCH] fixed deluge leaving kept private torrents unblocked --- .../DownloadClient/DelugeServiceTests.cs | 37 +++++++++++++++++++ .../DownloadClient/Deluge/DelugeServiceCB.cs | 5 ++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/DelugeServiceTests.cs b/code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/DelugeServiceTests.cs index c6d76d6b..75c632c6 100644 --- a/code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/DelugeServiceTests.cs +++ b/code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/DelugeServiceTests.cs @@ -731,6 +731,43 @@ public class DelugeServiceTests : IClassFixture .ChangeFilesPriority(Arg.Any(), Arg.Any>()); } + [Fact] + public async Task AllFilesAreMalware_PrivateTorrentKeptInClient_CallsChangeFilesPriority() + { + const string hash = "all-malware-private-kept-hash"; + DelugeService sut = _fixture.CreateSut(); + SetMalwareBlockerContext(new ContentBlockerConfig { DeletePrivate = false }); + + _fixture.ClientWrapper + .GetTorrentStatus(hash) + .Returns(MakeDownloadStatus(hash) with { Private = true }); + + _fixture.ClientWrapper + .GetTorrentFiles(hash) + .Returns(new DelugeContents + { + Contents = new Dictionary + { + { "malware.exe", new DelugeFileOrDirectory { Type = "file", Priority = 1, Index = 0, Path = "malware.exe" } }, + }, + }); + + _fixture.FilenameEvaluator + .IsValid(Arg.Any(), Arg.Any(), Arg.Any>(), Arg.Any>()) + .Returns(false); + + BlockFilesResult result = await sut.BlockUnwantedFilesAsync(hash, Array.Empty()); + + result.Found.ShouldBeTrue(); + result.IsPrivate.ShouldBeTrue(); + result.ShouldRemove.ShouldBeTrue(); + result.DeleteReason.ShouldBe(DeleteReason.AllFilesBlocked); + + await _fixture.ClientWrapper + .Received(1) + .ChangeFilesPriority(hash, Arg.Is>(p => p.Count == 1 && p[0] == 0)); + } + [Fact] public async Task PartialMalware_CallsChangeFilesPriority_AndDoesNotMarkForRemoval() { diff --git a/code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Deluge/DelugeServiceCB.cs b/code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Deluge/DelugeServiceCB.cs index c923d54c..0ce24381 100644 --- a/code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Deluge/DelugeServiceCB.cs +++ b/code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Deluge/DelugeServiceCB.cs @@ -73,8 +73,9 @@ public partial class DelugeService await ApplyFileBlockingAsync(result, download.Name, scanItems, malwareBlockerConfig.DeleteIfAnyFileBlocked, async unwantedIndices => { - // Zeroing every priority before removal crashes Deluge (#281) - if (result.DeleteReason is DeleteReason.AllFilesBlocked) + // Zeroing every priority before removal crashes Deluge (#281); a kept private torrent still needs it + bool staysInClient = result.IsPrivate && !malwareBlockerConfig.DeletePrivate; + if (result.DeleteReason is DeleteReason.AllFilesBlocked && !staysInClient) { return; }