diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs index a308e68aa..58fda96ac 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs @@ -23,6 +23,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests private SabnzbdHistory _failed; private SabnzbdHistory _completed; private SabnzbdConfig _config; + private SabnzbdFullStatus _fullStatus; [SetUp] public void Setup() @@ -65,7 +66,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests { Status = SabnzbdDownloadStatus.Failed, Size = 1000, - Category = "tv", + Category = "tv", Id = "sabnzbd_nzb12345", Title = "Droned.S01E01.Pilot.1080p.WEB-DL-DRONE" } @@ -80,7 +81,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests { Status = SabnzbdDownloadStatus.Completed, Size = 1000, - Category = "tv", + Category = "tv", Id = "sabnzbd_nzb12345", Title = "Droned.S01E01.Pilot.1080p.WEB-DL-DRONE", Storage = "/remote/mount/vv/Droned.S01E01.Pilot.1080p.WEB-DL-DRONE" @@ -103,6 +104,15 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests Mocker.GetMock() .Setup(s => s.GetConfig(It.IsAny())) .Returns(_config); + + _fullStatus = new SabnzbdFullStatus + { + CompleteDir = @"Y:\nzbget\root\complete".AsOsAgnostic() + }; + + Mocker.GetMock() + .Setup(s => s.GetFullStatus(It.IsAny())) + .Returns(_fullStatus); } protected void GivenFailedDownload() @@ -166,7 +176,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests GivenQueue(_queued); GivenHistory(null); - + var result = Subject.GetItems().Single(); VerifyQueued(result); @@ -386,23 +396,44 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests result.OutputPath.Should().Be(@"C:\sorted\somewhere\asdfasdf\asdfasdf.mkv".AsOsAgnostic()); } - [TestCase(@"Y:\nzbget\root", @"completed\downloads", @"vv", @"Y:\nzbget\root\completed\downloads\vv")] - [TestCase(@"Y:\nzbget\root", @"completed", @"vv", @"Y:\nzbget\root\completed\vv")] - [TestCase(@"/nzbget/root", @"completed/downloads", @"vv", @"/nzbget/root/completed/downloads/vv")] - [TestCase(@"/nzbget/root", @"completed", @"vv", @"/nzbget/root/completed/vv")] - public void should_return_status_with_outputdir(string rootFolder, string completeDir, string categoryDir, string expectedDir) + [TestCase(@"Y:\nzbget\root", @"completed\downloads", @"vv", @"Y:\nzbget\root\completed\downloads", @"Y:\nzbget\root\completed\downloads\vv")] + [TestCase(@"Y:\nzbget\root", @"completed", @"vv", @"Y:\nzbget\root\completed", @"Y:\nzbget\root\completed\vv")] + [TestCase(@"/nzbget/root", @"completed/downloads", @"vv", @"/nzbget/root/completed/downloads", @"/nzbget/root/completed/downloads/vv")] + [TestCase(@"/nzbget/root", @"completed", @"vv", @"/nzbget/root/completed", @"/nzbget/root/completed/vv")] + public void should_return_status_with_outputdir_for_version_lt_2(string rootFolder, string completeDir, string categoryDir, string fullCompleteDir, string fullCategoryDir) { + _fullStatus.CompleteDir = null; _queued.DefaultRootFolder = rootFolder; _config.Misc.complete_dir = completeDir; _config.Categories.First().Dir = categoryDir; - + + GivenQueue(null); + + var result = Subject.GetStatus(); + + result.IsLocalhost.Should().BeTrue(); + result.OutputRootFolders.Should().NotBeNull(); + result.OutputRootFolders.First().Should().Be(fullCategoryDir); + } + + [TestCase(@"Y:\nzbget\root", @"completed\downloads", @"vv", @"Y:\nzbget\root\completed\downloads", @"Y:\nzbget\root\completed\downloads\vv")] + [TestCase(@"Y:\nzbget\root", @"completed", @"vv", @"Y:\nzbget\root\completed", @"Y:\nzbget\root\completed\vv")] + [TestCase(@"/nzbget/root", @"completed/downloads", @"vv", @"/nzbget/root/completed/downloads", @"/nzbget/root/completed/downloads/vv")] + [TestCase(@"/nzbget/root", @"completed", @"vv", @"/nzbget/root/completed", @"/nzbget/root/completed/vv")] + public void should_return_status_with_outputdir_for_version_gte_2(string rootFolder, string completeDir, string categoryDir, string fullCompleteDir, string fullCategoryDir) + { + _fullStatus.CompleteDir = fullCompleteDir; + _queued.DefaultRootFolder = null; + _config.Misc.complete_dir = completeDir; + _config.Categories.First().Dir = categoryDir; + GivenQueue(null); var result = Subject.GetStatus(); result.IsLocalhost.Should().BeTrue(); result.OutputRootFolders.Should().NotBeNull(); - result.OutputRootFolders.First().Should().Be(expectedDir); + result.OutputRootFolders.First().Should().Be(fullCategoryDir); } [Test] diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Responses/SabnzbdFullStatusResponse.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Responses/SabnzbdFullStatusResponse.cs new file mode 100644 index 000000000..48c9710c5 --- /dev/null +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Responses/SabnzbdFullStatusResponse.cs @@ -0,0 +1,7 @@ +namespace NzbDrone.Core.Download.Clients.Sabnzbd.Responses +{ + public class SabnzbdFullStatusResponse + { + public SabnzbdFullStatus Status { get; set; } + } +} diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs index 46811c3e8..a214fae74 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs @@ -220,10 +220,18 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd if (!completeDir.IsRooted) { - var queue = _proxy.GetQueue(0, 1, Settings); - var defaultRootFolder = new OsPath(queue.DefaultRootFolder); + if (HasVersion(2, 0)) + { + var status = _proxy.GetFullStatus(Settings); + completeDir = new OsPath(status.CompleteDir); + } + else + { + var queue = _proxy.GetQueue(0, 1, Settings); + var defaultRootFolder = new OsPath(queue.DefaultRootFolder); - completeDir = defaultRootFolder + completeDir; + completeDir = defaultRootFolder + completeDir; + } } foreach (var category in config.Categories) diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdFullStatus.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdFullStatus.cs new file mode 100644 index 000000000..d1d691fc6 --- /dev/null +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdFullStatus.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Newtonsoft.Json; + +namespace NzbDrone.Core.Download.Clients.Sabnzbd +{ + public class SabnzbdFullStatus + { + // Added in Sabnzbd 2.0.0, my_home was previously in &mode=queue. + // This is the already resolved completedir path. + [JsonProperty(PropertyName = "completedir")] + public string CompleteDir { get; set; } + } +} diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs index a3fc32f71..397771ff2 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs @@ -15,6 +15,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd void RemoveFrom(string source, string id,bool deleteData, SabnzbdSettings settings); string GetVersion(SabnzbdSettings settings); SabnzbdConfig GetConfig(SabnzbdSettings settings); + SabnzbdFullStatus GetFullStatus(SabnzbdSettings settings); SabnzbdQueue GetQueue(int start, int limit, SabnzbdSettings settings); SabnzbdHistory GetHistory(int start, int limit, string category, SabnzbdSettings settings); string RetryDownload(string id, SabnzbdSettings settings); @@ -37,7 +38,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd request.AddQueryParam("cat", category); request.AddQueryParam("priority", priority); - + request.AddFormUpload("name", filename, nzbData, "application/x-nzb"); SabnzbdAddResponse response; @@ -84,6 +85,16 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd return response.Config; } + public SabnzbdFullStatus GetFullStatus(SabnzbdSettings settings) + { + var request = BuildRequest("fullstatus", settings); + request.AddQueryParam("skip_dashboard", "1"); + + var response = Json.Deserialize(ProcessRequest(request, settings)); + + return response.Status; + } + public SabnzbdQueue GetQueue(int start, int limit, SabnzbdSettings settings) { var request = BuildRequest("queue", settings); diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdQueue.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdQueue.cs index 5640ae4ec..405d9dec9 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdQueue.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdQueue.cs @@ -5,6 +5,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd { public class SabnzbdQueue { + // Removed in Sabnzbd 2.0.0, see mode=fullstatus instead. [JsonProperty(PropertyName = "my_home")] public string DefaultRootFolder { get; set; } diff --git a/src/NzbDrone.Core/Download/DownloadClientBase.cs b/src/NzbDrone.Core/Download/DownloadClientBase.cs index 98ade2a69..69c68bff3 100644 --- a/src/NzbDrone.Core/Download/DownloadClientBase.cs +++ b/src/NzbDrone.Core/Download/DownloadClientBase.cs @@ -110,7 +110,7 @@ namespace NzbDrone.Core.Download public ValidationResult Test() { var failures = new List(); - + try { Test(failures); diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index eb2783c43..5fa5f5167 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -438,6 +438,7 @@ + @@ -446,6 +447,7 @@ +