Compare commits

..

4 Commits

Author SHA1 Message Date
Bogdan
5635de96a8 Fixed: Initial state for qBittorrent v5.0
(cherry picked from commit ff724b7f4099284b8062f1625cf07b7822782edf)
2024-11-15 20:01:26 -06:00
Mickaël Thomas
ce59f32023 New: Support stoppedUP and stoppedDL states from qBittorrent
(cherry picked from commit 73a4bdea5247ee87e6bbae95f5325e1f03c88a7f)
2024-11-15 20:01:26 -06:00
bakerboy448
6d675a5207 Fix Goodreads test 2024-11-15 17:57:51 -06:00
Bogdan
b093b23900 Pin ReportGenerator in Azure Pipelines for .NET 6
(cherry picked from commit 50ce480abf043140e209d2d2959fbea8dd5dd2ab)
2024-11-15 15:45:16 -06:00
11 changed files with 105 additions and 120 deletions

View File

@@ -1211,7 +1211,7 @@ stages:
- task: SonarCloudAnalyze@2 - task: SonarCloudAnalyze@2
condition: eq(variables['System.PullRequest.IsFork'], 'False') condition: eq(variables['System.PullRequest.IsFork'], 'False')
displayName: Publish SonarCloud Results displayName: Publish SonarCloud Results
- task: reportgenerator@5 - task: reportgenerator@5.3.11
displayName: Generate Coverage Report displayName: Generate Coverage Report
inputs: inputs:
reports: '$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml' reports: '$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml'

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.IO; using System.IO;
using System.Text;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
@@ -317,14 +316,5 @@ namespace NzbDrone.Common.Test
result[2].Should().Be(@"Music"); result[2].Should().Be(@"Music");
result[3].Should().Be(@"Author Title"); result[3].Should().Be(@"Author Title");
} }
[Test]
public void should_be_equal_with_different_unicode_representations()
{
var path1 = @"C:\Test\file.mkv".AsOsAgnostic().Normalize(NormalizationForm.FormC);
var path2 = @"C:\Test\file.mkv".AsOsAgnostic().Normalize(NormalizationForm.FormD);
path1.PathEquals(path2);
}
} }
} }

View File

@@ -60,10 +60,6 @@ namespace NzbDrone.Common.Extensions
public static bool PathEquals(this string firstPath, string secondPath, StringComparison? comparison = null) public static bool PathEquals(this string firstPath, string secondPath, StringComparison? comparison = null)
{ {
// Normalize paths to ensure unicode characters are represented the same way
firstPath = firstPath.Normalize();
secondPath = secondPath?.Normalize();
if (!comparison.HasValue) if (!comparison.HasValue)
{ {
comparison = DiskProviderBase.PathStringComparison; comparison = DiskProviderBase.PathStringComparison;

View File

@@ -21,10 +21,10 @@ namespace NzbDrone.Common
{ {
if (OsInfo.IsWindows) if (OsInfo.IsWindows)
{ {
return obj.CleanFilePath().Normalize().ToLower().GetHashCode(); return obj.CleanFilePath().ToLower().GetHashCode();
} }
return obj.CleanFilePath().Normalize().GetHashCode(); return obj.CleanFilePath().GetHashCode();
} }
} }
} }

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")]
@@ -397,8 +399,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
{ {
@@ -407,7 +410,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()
@@ -684,44 +687,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();
@@ -739,33 +746,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();
@@ -783,66 +793,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();
@@ -854,8 +870,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 = "music-readarr"; const string category = "music-readarr";
GivenGlobalSeedLimits(1.0f); GivenGlobalSeedLimits(1.0f);
@@ -867,7 +884,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
@@ -879,8 +896,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 = "music-readarr"; const string category = "music-readarr";
GivenGlobalSeedLimits(1.0f); GivenGlobalSeedLimits(1.0f);
@@ -892,7 +910,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

@@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.MetadataSource.Goodreads
[TestCase("Harry Potter and the sorcerer's stone a detailed summary", 72245296)] [TestCase("Harry Potter and the sorcerer's stone a detailed summary", 72245296)]
[TestCase("B0192CTMYG", 61209488)] [TestCase("B0192CTMYG", 61209488)]
[TestCase("9780439554930", 48517161)] [TestCase("9780439554930", 3)]
public void successful_book_search(string title, int expected) public void successful_book_search(string title, int expected)
{ {
var result = Subject.Search(title); var result = Subject.Search(title);

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 = "qBittorrent is reporting an error"; item.Message = "qBittorrent is reporting an error";
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

View File

@@ -26,8 +26,6 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
Dictionary<string, QBittorrentLabel> GetLabels(QBittorrentSettings settings); Dictionary<string, QBittorrentLabel> GetLabels(QBittorrentSettings settings);
void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, QBittorrentSettings settings); void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, QBittorrentSettings settings);
void MoveTorrentToTopInQueue(string hash, QBittorrentSettings settings); void MoveTorrentToTopInQueue(string hash, QBittorrentSettings settings);
void PauseTorrent(string hash, QBittorrentSettings settings);
void ResumeTorrent(string hash, QBittorrentSettings settings);
void SetForceStart(string hash, bool enabled, QBittorrentSettings settings); void SetForceStart(string hash, bool enabled, QBittorrentSettings settings);
} }

View File

@@ -148,7 +148,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
{ {
request.AddFormParameter("paused", false); request.AddFormParameter("paused", false);
} }
else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause) else if ((QBittorrentState)settings.InitialState == QBittorrentState.Stop)
{ {
request.AddFormParameter("paused", true); request.AddFormParameter("paused", true);
} }
@@ -178,7 +178,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
{ {
request.AddFormParameter("paused", false); request.AddFormParameter("paused", false);
} }
else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause) else if ((QBittorrentState)settings.InitialState == QBittorrentState.Stop)
{ {
request.AddFormParameter("paused", true); request.AddFormParameter("paused", true);
} }
@@ -214,7 +214,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
catch (DownloadClientException ex) catch (DownloadClientException ex)
{ {
// if setCategory fails due to method not being found, then try older setLabel command for qBittorrent < v.3.3.5 // if setCategory fails due to method not being found, then try older setLabel command for qBittorrent < v.3.3.5
if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.NotFound) if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.NotFound)
{ {
var setLabelRequest = BuildRequest(settings).Resource("/command/setLabel") var setLabelRequest = BuildRequest(settings).Resource("/command/setLabel")
.Post() .Post()
@@ -257,7 +257,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
catch (DownloadClientException ex) catch (DownloadClientException ex)
{ {
// qBittorrent rejects all Prio commands with 403: Forbidden if Options -> BitTorrent -> Torrent Queueing is not enabled // qBittorrent rejects all Prio commands with 403: Forbidden if Options -> BitTorrent -> Torrent Queueing is not enabled
if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.Forbidden) if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.Forbidden)
{ {
return; return;
} }
@@ -266,22 +266,6 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
} }
} }
public void PauseTorrent(string hash, QBittorrentSettings settings)
{
var request = BuildRequest(settings).Resource("/command/pause")
.Post()
.AddFormParameter("hash", hash);
ProcessRequest(request, settings);
}
public void ResumeTorrent(string hash, QBittorrentSettings settings)
{
var request = BuildRequest(settings).Resource("/command/resume")
.Post()
.AddFormParameter("hash", hash);
ProcessRequest(request, settings);
}
public void SetForceStart(string hash, bool enabled, QBittorrentSettings settings) public void SetForceStart(string hash, bool enabled, QBittorrentSettings settings)
{ {
var request = BuildRequest(settings).Resource("/command/setForceStart") var request = BuildRequest(settings).Resource("/command/setForceStart")

View File

@@ -246,14 +246,20 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
request.AddFormParameter("category", settings.MusicCategory); request.AddFormParameter("category", settings.MusicCategory);
} }
// Note: ForceStart is handled by separate api call // Avoid extraneous API version check if initial state is ForceStart
if ((QBittorrentState)settings.InitialState == QBittorrentState.Start) if ((QBittorrentState)settings.InitialState is QBittorrentState.Start or QBittorrentState.Stop)
{ {
request.AddFormParameter("paused", false); var stoppedParameterName = GetApiVersion(settings) >= new Version(2, 11, 0) ? "stopped" : "paused";
}
else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause) // Note: ForceStart is handled by separate api call
{ if ((QBittorrentState)settings.InitialState == QBittorrentState.Start)
request.AddFormParameter("paused", true); {
request.AddFormParameter(stoppedParameterName, false);
}
else if ((QBittorrentState)settings.InitialState == QBittorrentState.Stop)
{
request.AddFormParameter(stoppedParameterName, true);
}
} }
if (settings.SequentialOrder) if (settings.SequentialOrder)
@@ -291,7 +297,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
catch (DownloadClientException ex) catch (DownloadClientException ex)
{ {
// setShareLimits was added in api v2.0.1 so catch it case of the unlikely event that someone has api v2.0 // setShareLimits was added in api v2.0.1 so catch it case of the unlikely event that someone has api v2.0
if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.NotFound) if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.NotFound)
{ {
return; return;
} }
@@ -313,7 +319,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
catch (DownloadClientException ex) catch (DownloadClientException ex)
{ {
// qBittorrent rejects all Prio commands with 409: Conflict if Options -> BitTorrent -> Torrent Queueing is not enabled // qBittorrent rejects all Prio commands with 409: Conflict if Options -> BitTorrent -> Torrent Queueing is not enabled
if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.Conflict) if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.Conflict)
{ {
return; return;
} }
@@ -322,22 +328,6 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
} }
} }
public void PauseTorrent(string hash, QBittorrentSettings settings)
{
var request = BuildRequest(settings).Resource("/api/v2/torrents/pause")
.Post()
.AddFormParameter("hashes", hash);
ProcessRequest(request, settings);
}
public void ResumeTorrent(string hash, QBittorrentSettings settings)
{
var request = BuildRequest(settings).Resource("/api/v2/torrents/resume")
.Post()
.AddFormParameter("hashes", hash);
ProcessRequest(request, settings);
}
public void SetForceStart(string hash, bool enabled, QBittorrentSettings settings) public void SetForceStart(string hash, bool enabled, QBittorrentSettings settings)
{ {
var request = BuildRequest(settings).Resource("/api/v2/torrents/setForceStart") var request = BuildRequest(settings).Resource("/api/v2/torrents/setForceStart")

View File

@@ -1,9 +1,16 @@
using NzbDrone.Core.Annotations;
namespace NzbDrone.Core.Download.Clients.QBittorrent namespace NzbDrone.Core.Download.Clients.QBittorrent
{ {
public enum QBittorrentState public enum QBittorrentState
{ {
[FieldOption(Label = "Started")]
Start = 0, Start = 0,
[FieldOption(Label = "Force Started")]
ForceStart = 1, ForceStart = 1,
Pause = 2
[FieldOption(Label = "Stopped")]
Stop = 2
} }
} }