New: Support stoppedUP and stoppedDL states from qBittorrent

This commit is contained in:
Mickaël Thomas 2024-05-09 03:41:59 +02:00 committed by GitHub
parent 47ba002806
commit 73a4bdea52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 74 additions and 54 deletions

View File

@ -178,8 +178,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
VerifyWarning(item); VerifyWarning(item);
} }
[Test] [TestCase("pausedDL")]
public void paused_item_should_have_required_properties() [TestCase("stoppedDL")]
public void paused_item_should_have_required_properties(string state)
{ {
var torrent = new QBittorrentTorrent var torrent = new QBittorrentTorrent
{ {
@ -188,7 +189,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
Size = 1000, Size = 1000,
Progress = 0.7, Progress = 0.7,
Eta = 8640000, Eta = 8640000,
State = "pausedDL", State = state,
Label = "", Label = "",
SavePath = "" SavePath = ""
}; };
@ -200,6 +201,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
} }
[TestCase("pausedUP")] [TestCase("pausedUP")]
[TestCase("stoppedUP")]
[TestCase("queuedUP")] [TestCase("queuedUP")]
[TestCase("uploading")] [TestCase("uploading")]
[TestCase("stalledUP")] [TestCase("stalledUP")]
@ -418,8 +420,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
result.OutputPath.FullPath.Should().Be(Path.Combine(torrent.SavePath, "Droned.S01.12")); result.OutputPath.FullPath.Should().Be(Path.Combine(torrent.SavePath, "Droned.S01.12"));
} }
[Test] [TestCase("pausedUP")]
public void api_261_should_use_content_path() [TestCase("stoppedUP")]
public void api_261_should_use_content_path(string state)
{ {
var torrent = new QBittorrentTorrent var torrent = new QBittorrentTorrent
{ {
@ -428,7 +431,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
Size = 1000, Size = 1000,
Progress = 0.7, Progress = 0.7,
Eta = 8640000, Eta = 8640000,
State = "pausedUP", State = state,
Label = "", Label = "",
SavePath = @"C:\Torrents".AsOsAgnostic(), SavePath = @"C:\Torrents".AsOsAgnostic(),
ContentPath = @"C:\Torrents\Droned.S01.12".AsOsAgnostic() ContentPath = @"C:\Torrents\Droned.S01.12".AsOsAgnostic()
@ -657,44 +660,48 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.CanMoveFiles.Should().BeFalse(); item.CanMoveFiles.Should().BeFalse();
} }
[Test] [TestCase("pausedUP")]
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_is_not_set() [TestCase("stoppedUP")]
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_is_not_set(string state)
{ {
GivenGlobalSeedLimits(-1); GivenGlobalSeedLimits(-1);
GivenCompletedTorrent("pausedUP", ratio: 1.0f); GivenCompletedTorrent(state, ratio: 1.0f);
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse(); item.CanBeRemoved.Should().BeFalse();
item.CanMoveFiles.Should().BeFalse(); item.CanMoveFiles.Should().BeFalse();
} }
[Test] [TestCase("pausedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_ratio_reached_and_paused() [TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_ratio_reached_and_paused(string state)
{ {
GivenGlobalSeedLimits(1.0f); GivenGlobalSeedLimits(1.0f);
GivenCompletedTorrent("pausedUP", ratio: 1.0f); GivenCompletedTorrent(state, ratio: 1.0f);
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue(); item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue(); item.CanMoveFiles.Should().BeTrue();
} }
[Test] [TestCase("pausedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_ratio_reached_and_paused() [TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_ratio_reached_and_paused(string state)
{ {
GivenGlobalSeedLimits(2.0f); GivenGlobalSeedLimits(2.0f);
GivenCompletedTorrent("pausedUP", ratio: 1.0f, ratioLimit: 0.8f); GivenCompletedTorrent(state, ratio: 1.0f, ratioLimit: 0.8f);
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue(); item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue(); item.CanMoveFiles.Should().BeTrue();
} }
[Test] [TestCase("pausedUP")]
public void should_not_be_removable_if_overridden_max_ratio_not_reached_and_paused() [TestCase("stoppedUP")]
public void should_not_be_removable_if_overridden_max_ratio_not_reached_and_paused(string state)
{ {
GivenGlobalSeedLimits(0.2f); GivenGlobalSeedLimits(0.2f);
GivenCompletedTorrent("pausedUP", ratio: 0.5f, ratioLimit: 0.8f); GivenCompletedTorrent(state, ratio: 0.5f, ratioLimit: 0.8f);
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse(); item.CanBeRemoved.Should().BeFalse();
@ -712,33 +719,36 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.CanMoveFiles.Should().BeFalse(); item.CanMoveFiles.Should().BeFalse();
} }
[Test] [TestCase("pausedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_seedingtime_reached_and_paused() [TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_seedingtime_reached_and_paused(string state)
{ {
GivenGlobalSeedLimits(-1, 20); GivenGlobalSeedLimits(-1, 20);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 20); GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 20);
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue(); item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue(); item.CanMoveFiles.Should().BeTrue();
} }
[Test] [TestCase("pausedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_seedingtime_reached_and_paused() [TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_seedingtime_reached_and_paused(string state)
{ {
GivenGlobalSeedLimits(-1, 40); GivenGlobalSeedLimits(-1, 40);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 20, seedingTimeLimit: 10); GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 20, seedingTimeLimit: 10);
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue(); item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue(); item.CanMoveFiles.Should().BeTrue();
} }
[Test] [TestCase("pausedUP")]
public void should_not_be_removable_if_overridden_max_seedingtime_not_reached_and_paused() [TestCase("stoppedUP")]
public void should_not_be_removable_if_overridden_max_seedingtime_not_reached_and_paused(string state)
{ {
GivenGlobalSeedLimits(-1, 20); GivenGlobalSeedLimits(-1, 20);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 30, seedingTimeLimit: 40); GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 30, seedingTimeLimit: 40);
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse(); item.CanBeRemoved.Should().BeFalse();
@ -756,66 +766,72 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.CanMoveFiles.Should().BeFalse(); item.CanMoveFiles.Should().BeFalse();
} }
[Test] [TestCase("pausedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_inactive_seedingtime_reached_and_paused() [TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_inactive_seedingtime_reached_and_paused(string state)
{ {
GivenGlobalSeedLimits(-1, maxInactiveSeedingTime: 20); GivenGlobalSeedLimits(-1, maxInactiveSeedingTime: 20);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(25)).ToUnixTimeSeconds()); GivenCompletedTorrent(state, ratio: 2.0f, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(25)).ToUnixTimeSeconds());
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue(); item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue(); item.CanMoveFiles.Should().BeTrue();
} }
[Test] [TestCase("pausedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_inactive_seedingtime_reached_and_paused() [TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_inactive_seedingtime_reached_and_paused(string state)
{ {
GivenGlobalSeedLimits(-1, maxInactiveSeedingTime: 40); GivenGlobalSeedLimits(-1, maxInactiveSeedingTime: 40);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 20, inactiveSeedingTimeLimit: 10, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(15)).ToUnixTimeSeconds()); GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 20, inactiveSeedingTimeLimit: 10, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(15)).ToUnixTimeSeconds());
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue(); item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue(); item.CanMoveFiles.Should().BeTrue();
} }
[Test] [TestCase("pausedUP")]
public void should_not_be_removable_if_overridden_max_inactive_seedingtime_not_reached_and_paused() [TestCase("stoppedUP")]
public void should_not_be_removable_if_overridden_max_inactive_seedingtime_not_reached_and_paused(string state)
{ {
GivenGlobalSeedLimits(-1, maxInactiveSeedingTime: 20); GivenGlobalSeedLimits(-1, maxInactiveSeedingTime: 20);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 30, inactiveSeedingTimeLimit: 40, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(30)).ToUnixTimeSeconds()); GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 30, inactiveSeedingTimeLimit: 40, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(30)).ToUnixTimeSeconds());
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse(); item.CanBeRemoved.Should().BeFalse();
item.CanMoveFiles.Should().BeFalse(); item.CanMoveFiles.Should().BeFalse();
} }
[Test] [TestCase("pausedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_seedingtime_reached_but_ratio_not_and_paused() [TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_seedingtime_reached_but_ratio_not_and_paused(string state)
{ {
GivenGlobalSeedLimits(2.0f, 20); GivenGlobalSeedLimits(2.0f, 20);
GivenCompletedTorrent("pausedUP", ratio: 1.0f, seedingTime: 30); GivenCompletedTorrent(state, ratio: 1.0f, seedingTime: 30);
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue(); item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue(); item.CanMoveFiles.Should().BeTrue();
} }
[Test] [TestCase("pausedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_inactive_seedingtime_reached_but_ratio_not_and_paused() [TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_inactive_seedingtime_reached_but_ratio_not_and_paused(string state)
{ {
GivenGlobalSeedLimits(2.0f, maxInactiveSeedingTime: 20); GivenGlobalSeedLimits(2.0f, maxInactiveSeedingTime: 20);
GivenCompletedTorrent("pausedUP", ratio: 1.0f, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(25)).ToUnixTimeSeconds()); GivenCompletedTorrent(state, ratio: 1.0f, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(25)).ToUnixTimeSeconds());
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue(); item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue(); item.CanMoveFiles.Should().BeTrue();
} }
[Test] [TestCase("pausedUP")]
public void should_not_fetch_details_twice() [TestCase("stoppedUP")]
public void should_not_fetch_details_twice(string state)
{ {
GivenGlobalSeedLimits(-1, 30); GivenGlobalSeedLimits(-1, 30);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 20); GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 20);
var item = Subject.GetItems().Single(); var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse(); item.CanBeRemoved.Should().BeFalse();
@ -827,8 +843,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
.Verify(p => p.GetTorrentProperties(It.IsAny<string>(), It.IsAny<QBittorrentSettings>()), Times.Once()); .Verify(p => p.GetTorrentProperties(It.IsAny<string>(), It.IsAny<QBittorrentSettings>()), Times.Once());
} }
[Test] [TestCase("pausedUP")]
public void should_get_category_from_the_category_if_set() [TestCase("stoppedUP")]
public void should_get_category_from_the_category_if_set(string state)
{ {
const string category = "tv-sonarr"; const string category = "tv-sonarr";
GivenGlobalSeedLimits(1.0f); GivenGlobalSeedLimits(1.0f);
@ -840,7 +857,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
Size = 1000, Size = 1000,
Progress = 1.0, Progress = 1.0,
Eta = 8640000, Eta = 8640000,
State = "pausedUP", State = state,
Category = category, Category = category,
SavePath = "", SavePath = "",
Ratio = 1.0f Ratio = 1.0f
@ -852,8 +869,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.Category.Should().Be(category); item.Category.Should().Be(category);
} }
[Test] [TestCase("pausedUP")]
public void should_get_category_from_the_label_if_the_category_is_not_available() [TestCase("stoppedUP")]
public void should_get_category_from_the_label_if_the_category_is_not_available(string state)
{ {
const string category = "tv-sonarr"; const string category = "tv-sonarr";
GivenGlobalSeedLimits(1.0f); GivenGlobalSeedLimits(1.0f);
@ -865,7 +883,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
Size = 1000, Size = 1000,
Progress = 1.0, Progress = 1.0,
Eta = 8640000, Eta = 8640000,
State = "pausedUP", State = state,
Label = category, Label = category,
SavePath = "", SavePath = "",
Ratio = 1.0f Ratio = 1.0f

View File

@ -239,7 +239,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
// Avoid removing torrents that haven't reached the global max ratio. // Avoid removing torrents that haven't reached the global max ratio.
// Removal also requires the torrent to be paused, in case a higher max ratio was set on the torrent itself (which is not exposed by the api). // Removal also requires the torrent to be paused, in case a higher max ratio was set on the torrent itself (which is not exposed by the api).
item.CanMoveFiles = item.CanBeRemoved = torrent.State == "pausedUP" && HasReachedSeedLimit(torrent, config); item.CanMoveFiles = item.CanBeRemoved = torrent.State is "pausedUP" or "stoppedUP" && HasReachedSeedLimit(torrent, config);
switch (torrent.State) switch (torrent.State)
{ {
@ -248,7 +248,8 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
item.Message = _localizationService.GetLocalizedString("DownloadClientQbittorrentTorrentStateError"); item.Message = _localizationService.GetLocalizedString("DownloadClientQbittorrentTorrentStateError");
break; break;
case "pausedDL": // torrent is paused and has NOT finished downloading case "stoppedDL": // torrent is stopped and has NOT finished downloading
case "pausedDL": // torrent is paused and has NOT finished downloading (qBittorrent < 5)
item.Status = DownloadItemStatus.Paused; item.Status = DownloadItemStatus.Paused;
break; break;
@ -259,7 +260,8 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
item.Status = DownloadItemStatus.Queued; item.Status = DownloadItemStatus.Queued;
break; break;
case "pausedUP": // torrent is paused and has finished downloading: case "pausedUP": // torrent is paused and has finished downloading (qBittorent < 5)
case "stoppedUP": // torrent is stopped and has finished downloading
case "uploading": // torrent is being seeded and data is being transferred case "uploading": // torrent is being seeded and data is being transferred
case "stalledUP": // torrent is being seeded, but no connection were made case "stalledUP": // torrent is being seeded, but no connection were made
case "queuedUP": // queuing is enabled and torrent is queued for upload case "queuedUP": // queuing is enabled and torrent is queued for upload