diff --git a/src/Lidarr.Api.V1/Queue/QueueController.cs b/src/Lidarr.Api.V1/Queue/QueueController.cs index 8dfd46f68..8787845da 100644 --- a/src/Lidarr.Api.V1/Queue/QueueController.cs +++ b/src/Lidarr.Api.V1/Queue/QueueController.cs @@ -218,7 +218,7 @@ namespace Lidarr.Api.V1.Queue throw new BadRequestException(); } - downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true); + downloadClient.RemoveItem(trackedDownload.DownloadItem, true); } if (blocklist) diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs index afd29fa37..b22477237 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs @@ -4,6 +4,7 @@ using System.IO; using System.IO.Abstractions; using System.Linq; using System.Net; +using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; @@ -26,6 +27,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole protected string _blackholeFolder; protected string _filePath; protected string _magnetFilePath; + protected DownloadClientItem _downloadClientItem; [SetUp] public void Setup() @@ -33,6 +35,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole _completedDownloadFolder = @"c:\blackhole\completed".AsOsAgnostic(); _blackholeFolder = @"c:\blackhole\torrent".AsOsAgnostic(); _filePath = (@"c:\blackhole\torrent\" + _title + ".torrent").AsOsAgnostic(); + _magnetFilePath = Path.ChangeExtension(_filePath, ".magnet"); + + _downloadClientItem = Builder + .CreateNew() + .With(d => d.DownloadId = "_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0") + .With(d => d.OutputPath = new OsPath(Path.Combine(_completedDownloadFolder, _title))) + .Build(); Mocker.SetConstant(Mocker.Resolve()); @@ -248,7 +257,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole .Setup(c => c.FileExists(It.IsAny())) .Returns(true); - Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true); + Subject.RemoveItem(_downloadClientItem, true); Mocker.GetMock() .Verify(c => c.DeleteFile(It.IsAny()), Times.Once()); @@ -263,7 +272,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole .Setup(c => c.FolderExists(It.IsAny())) .Returns(true); - Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true); + Subject.RemoveItem(_downloadClientItem, true); Mocker.GetMock() .Verify(c => c.DeleteFolder(It.IsAny(), true), Times.Once()); @@ -272,7 +281,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole [Test] public void RemoveItem_should_ignore_if_unknown_item() { - Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true); + Subject.RemoveItem(_downloadClientItem, true); Mocker.GetMock() .Verify(c => c.DeleteFile(It.IsAny()), Times.Never()); @@ -286,7 +295,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole { GivenCompletedItem(); - Assert.Throws(() => Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", false)); + Assert.Throws(() => Subject.RemoveItem(_downloadClientItem, false)); Mocker.GetMock() .Verify(c => c.DeleteFile(It.IsAny()), Times.Never()); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs index 4ebef2f8c..336a61d9d 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs @@ -4,6 +4,7 @@ using System.IO; using System.IO.Abstractions; using System.Linq; using System.Net; +using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; @@ -22,6 +23,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole protected string _completedDownloadFolder; protected string _blackholeFolder; protected string _filePath; + protected DownloadClientItem _downloadClientItem; [SetUp] public void Setup() @@ -30,6 +32,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole _blackholeFolder = @"c:\blackhole\nzb".AsOsAgnostic(); _filePath = (@"c:\blackhole\nzb\" + _title + ".nzb").AsOsAgnostic(); + _downloadClientItem = Builder + .CreateNew() + .With(d => d.DownloadId = "_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0") + .With(d => d.OutputPath = new OsPath(Path.Combine(_completedDownloadFolder, _title))) + .Build(); + Mocker.SetConstant(Mocker.Resolve()); Subject.Definition = new DownloadClientDefinition(); @@ -147,7 +155,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole .Setup(c => c.FileExists(It.IsAny())) .Returns(true); - Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true); + Subject.RemoveItem(_downloadClientItem, true); Mocker.GetMock() .Verify(c => c.DeleteFile(It.IsAny()), Times.Once()); @@ -162,7 +170,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole .Setup(c => c.FolderExists(It.IsAny())) .Returns(true); - Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true); + Subject.RemoveItem(_downloadClientItem, true); Mocker.GetMock() .Verify(c => c.DeleteFolder(It.IsAny(), true), Times.Once()); @@ -171,7 +179,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole [Test] public void RemoveItem_should_ignore_if_unknown_item() { - Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true); + Subject.RemoveItem(_downloadClientItem, true); Mocker.GetMock() .Verify(c => c.DeleteFile(It.IsAny()), Times.Never()); @@ -185,7 +193,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole { GivenCompletedItem(); - Assert.Throws(() => Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", false)); + Assert.Throws(() => Subject.RemoveItem(_downloadClientItem, false)); Mocker.GetMock() .Verify(c => c.DeleteFile(It.IsAny()), Times.Never()); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs index 14b3b5d85..36b212395 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs @@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests Detail = new Dictionary { { "destination", "shared/folder" }, - { "uri", FileNameBuilder.CleanFileName(_remoteAlbum.Release.Title) + ".nzb" } + { "uri", CleanFileName(_remoteAlbum.Release.Title) } }, Transfer = new Dictionary { @@ -89,7 +89,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests Detail = new Dictionary { { "destination", "shared/folder" }, - { "uri", FileNameBuilder.CleanFileName(_remoteAlbum.Release.Title) + ".nzb" } + { "uri", CleanFileName(_remoteAlbum.Release.Title) } }, Transfer = new Dictionary { @@ -112,7 +112,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests Detail = new Dictionary { { "destination", "shared/folder" }, - { "uri", FileNameBuilder.CleanFileName(_remoteAlbum.Release.Title) + ".nzb" } + { "uri", CleanFileName(_remoteAlbum.Release.Title) } }, Transfer = new Dictionary { @@ -135,7 +135,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests Detail = new Dictionary { { "destination", "shared/folder" }, - { "uri", FileNameBuilder.CleanFileName(_remoteAlbum.Release.Title) + ".nzb" } + { "uri", CleanFileName(_remoteAlbum.Release.Title) } }, Transfer = new Dictionary { @@ -158,7 +158,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests Detail = new Dictionary { { "destination", "shared/folder" }, - { "uri", FileNameBuilder.CleanFileName(_remoteAlbum.Release.Title) + ".nzb" } + { "uri", CleanFileName(_remoteAlbum.Release.Title) } }, Transfer = new Dictionary { @@ -261,6 +261,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests .Returns(tasks); } + protected static string CleanFileName(string name) + { + return FileNameBuilder.CleanFileName(name) + ".nzb"; + } + [Test] public void Download_with_TvDirectory_should_force_directory() { diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs index ef069d3f5..73d361cac 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; @@ -20,6 +21,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests private NzbgetHistoryItem _failed; private NzbgetHistoryItem _completed; private Dictionary _configItems; + private DownloadClientItem _downloadClientItem; [SetUp] public void Setup() @@ -74,6 +76,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests MarkStatus = "NONE" }; + _downloadClientItem = Builder + .CreateNew() + .With(d => d.DownloadId = "_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0") + .With(d => d.OutputPath = new OsPath("/remote/mount/tv/Droned.S01E01.Pilot.1080p.WEB-DL-DRONE".AsOsAgnostic())) + .Build(); + Mocker.GetMock() .Setup(s => s.GetGlobalStatus(It.IsAny())) .Returns(new NzbgetGlobalStatus @@ -155,7 +163,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests .Setup(v => v.FolderExists(It.IsAny())) .Returns(true); - Subject.RemoveItem("id", true); + Subject.RemoveItem(_downloadClientItem, true); Mocker.GetMock() .Verify(v => v.DeleteFolder(It.IsAny(), true), Times.Once()); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs index 3bd28c9bb..e74ef6016 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Net; +using FizzWare.NBuilder; using Moq; using NUnit.Framework; using NzbDrone.Common.Http; @@ -21,6 +22,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests private string _strmFolder; private string _nzbPath; private RemoteAlbum _remoteAlbum; + private DownloadClientItem _downloadClientItem; [SetUp] public void Setup() @@ -37,6 +39,10 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests _remoteAlbum.ParsedAlbumInfo = new ParsedAlbumInfo(); + _downloadClientItem = Builder + .CreateNew().With(d => d.DownloadId = "_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0") + .Build(); + Subject.Definition = new DownloadClientDefinition(); Subject.Definition.Settings = new PneumaticSettings { @@ -78,7 +84,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests [Test] public void should_throw_item_is_removed() { - Assert.Throws(() => Subject.RemoveItem("", true)); + Assert.Throws(() => Subject.RemoveItem(_downloadClientItem, true)); } [Test] diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs index b390a0ade..57dfcb757 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs @@ -24,6 +24,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests private SabnzbdHistory _completed; private SabnzbdConfig _config; private SabnzbdFullStatus _fullStatus; + private DownloadClientItem _downloadClientItem; [SetUp] public void Setup() @@ -101,6 +102,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests } }; + _downloadClientItem = Builder + .CreateNew() + .With(d => d.Status = DownloadItemStatus.Completed) + .With(d => d.DownloadId = _completed.Items.First().Id) + .Build(); + Mocker.GetMock() .Setup(v => v.GetVersion(It.IsAny())) .Returns("1.2.3"); @@ -583,6 +590,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests public void should_remove_output_path_folder_when_deleting_a_completed_item_and_delete_data_is_true() { var path = @"C:\Test\Series.Title.S01E01".AsOsAgnostic(); + _downloadClientItem.OutputPath = new OsPath(path); Mocker.GetMock() .Setup(s => s.FolderExists(path)) @@ -593,7 +601,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests GivenQueue(null); GivenHistory(_completed); - Subject.RemoveItem(_completed.Items.First().Id, true); + Subject.RemoveItem(_downloadClientItem, true); Mocker.GetMock() .Verify(v => v.DeleteFolder(path, true), Times.Once); @@ -606,6 +614,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests public void should_remove_output_path_file_when_deleting_a_completed_item_and_delete_data_is_true() { var path = @"C:\Test\Series.Title.S01E01.mkv".AsOsAgnostic(); + _downloadClientItem.OutputPath = new OsPath(path); Mocker.GetMock() .Setup(s => s.FolderExists(path)) @@ -620,7 +629,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests GivenQueue(null); GivenHistory(_completed); - Subject.RemoveItem(_completed.Items.First().Id, true); + Subject.RemoveItem(_downloadClientItem, true); Mocker.GetMock() .Verify(v => v.DeleteFolder(path, true), Times.Never); @@ -647,7 +656,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests GivenQueue(null); GivenHistory(_completed); - Subject.RemoveItem(_completed.Items.First().Id, true); + Subject.RemoveItem(_downloadClientItem, true); Mocker.GetMock() .Verify(v => v.DeleteFolder(path, true), Times.Never); @@ -674,7 +683,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests GivenQueue(null); GivenHistory(_completed); - Subject.RemoveItem(_completed.Items.First().Id, false); + Subject.RemoveItem(_downloadClientItem, false); Mocker.GetMock() .Verify(v => v.FolderExists(path), Times.Never); diff --git a/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs b/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs index 89949a257..e895f34de 100644 --- a/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs +++ b/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs @@ -152,10 +152,10 @@ namespace NzbDrone.Core.Download.Clients.Aria2 } } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { // Aria2 doesn't support file deletion: https://github.com/aria2/aria2/issues/728 - var hash = downloadId.ToLower(); + var hash = item.DownloadId.ToLower(); var aria2Item = _proxy.GetTorrents(Settings).FirstOrDefault(t => t.InfoHash?.ToLower() == hash); if (aria2Item == null) @@ -187,7 +187,7 @@ namespace NzbDrone.Core.Download.Clients.Aria2 if (deleteData) { - DeleteItemData(downloadId); + DeleteItemData(item); } } diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs index 40241fd15..94156a812 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs @@ -105,14 +105,14 @@ namespace NzbDrone.Core.Download.Clients.Blackhole } } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { if (!deleteData) { throw new NotSupportedException("Blackhole cannot remove DownloadItem without deleting the data as well, ignoring."); } - DeleteItemData(downloadId); + DeleteItemData(item); } public override DownloadClientInfo GetStatus() diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs index 21b849bb4..4998fbb96 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs @@ -77,14 +77,14 @@ namespace NzbDrone.Core.Download.Clients.Blackhole } } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { if (!deleteData) { throw new NotSupportedException("Blackhole cannot remove DownloadItem without deleting the data as well, ignoring."); } - DeleteItemData(downloadId); + DeleteItemData(item); } public override DownloadClientInfo GetStatus() diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs index aa8f5cd53..f9f292f68 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs @@ -188,9 +188,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge return items; } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { - _proxy.RemoveTorrent(downloadId.ToLower(), deleteData, Settings); + _proxy.RemoveTorrent(item.DownloadId.ToLower(), deleteData, Settings); } public override DownloadClientInfo GetStatus() diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApi.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApi.cs index 37ed34b80..87d1e57bf 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApi.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApi.cs @@ -7,6 +7,7 @@ DownloadStationInfo, DownloadStationTask, DownloadStation2Task, + DownloadStation2SettingsLocation, FileStationList, DSMInfo, } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs index 1240f2c87..d760b3b25 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs @@ -25,7 +25,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation public override string ToString() { - return this.Title; + return Title; } } } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationSettings.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationSettings.cs index c3294e714..07942f122 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationSettings.cs @@ -36,21 +36,21 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation [FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)] public int Port { get; set; } - [FieldDefinition(2, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)] + [FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secure connection when connecting to Download Station")] + public bool UseSsl { get; set; } + + [FieldDefinition(3, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)] public string Username { get; set; } - [FieldDefinition(3, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)] + [FieldDefinition(4, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)] public string Password { get; set; } - [FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Lidarr avoids conflicts with unrelated downloads, but it's optional. Creates a [category] subdirectory in the output directory.")] + [FieldDefinition(5, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Lidarr avoids conflicts with unrelated downloads, but it's optional. Creates a [category] subdirectory in the output directory.")] public string MusicCategory { get; set; } - [FieldDefinition(5, Label = "Directory", Type = FieldType.Textbox, HelpText = "Optional shared folder to put downloads into, leave blank to use the default Download Station location")] + [FieldDefinition(6, Label = "Directory", Type = FieldType.Textbox, HelpText = "Optional shared folder to put downloads into, leave blank to use the default Download Station location")] public string TvDirectory { get; set; } - [FieldDefinition(6, Label = "Use SSL", Type = FieldType.Checkbox)] - public bool UseSsl { get; set; } - public DownloadStationSettings() { Host = "127.0.0.1"; diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStation2SettingsLocationProxy.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStation2SettingsLocationProxy.cs new file mode 100644 index 000000000..7ca124e9c --- /dev/null +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStation2SettingsLocationProxy.cs @@ -0,0 +1,31 @@ +using NLog; +using NzbDrone.Common.Cache; +using NzbDrone.Common.Http; +using NzbDrone.Core.Download.Clients.DownloadStation.Responses; + +namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies +{ + public interface IDownloadStation2SettingsLocationProxy + { + string GetDefaultDestination(DownloadStationSettings settings); + } + + public class DownloadStation2SettingsLocationProxy : DiskStationProxyBase, IDownloadStation2SettingsLocationProxy + { + public DownloadStation2SettingsLocationProxy(IHttpClient httpClient, ICacheManager cacheManager, Logger logger) + : base(DiskStationApi.DownloadStation2SettingsLocation, "SYNO.DownloadStation2.Settings.Location", httpClient, cacheManager, logger) + { + } + + public string GetDefaultDestination(DownloadStationSettings settings) + { + var info = GetApiInfo(settings); + + var requestBuilder = BuildRequest(settings, "get", info.MinVersion); + + var response = ProcessRequest(requestBuilder, "get default destination folder", settings); + + return response.Data.Default_Destination; + } + } +} diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV2.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV2.cs index 5e5dc2a02..261f76e19 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV2.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV2.cs @@ -10,9 +10,12 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies { public class DownloadStationTaskProxyV2 : DiskStationProxyBase, IDownloadStationTaskProxy { + private readonly IDownloadStation2SettingsLocationProxy _defaultDestinationProxy; + public DownloadStationTaskProxyV2(IHttpClient httpClient, ICacheManager cacheManager, Logger logger) : base(DiskStationApi.DownloadStation2Task, "SYNO.DownloadStation2.Task", httpClient, cacheManager, logger) { + _defaultDestinationProxy = new DownloadStation2SettingsLocationProxy(httpClient, cacheManager, logger); } public bool IsApiSupported(DownloadStationSettings settings) @@ -32,6 +35,21 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies { requestBuilder.AddFormParameter("destination", $"\"{downloadDirectory}\""); } + else + { + _logger.Trace("No directory configured in settings; falling back to client default destination folder."); + string defaultDestination = _defaultDestinationProxy.GetDefaultDestination(settings); + + if (defaultDestination.IsNotNullOrWhiteSpace()) + { + _logger.Trace($"Default destination folder found: {defaultDestination}."); + requestBuilder.AddFormParameter("destination", $"\"{defaultDestination}\""); + } + else + { + _logger.Error("Unable to get default destination folder from DownloadStation."); + } + } requestBuilder.AddFormUpload("fileData", filename, data); @@ -50,6 +68,21 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies { requestBuilder.AddQueryParam("destination", downloadDirectory); } + else + { + _logger.Trace("No directory configured in settings; falling back to client default destination folder."); + string defaultDestination = _defaultDestinationProxy.GetDefaultDestination(settings); + + if (defaultDestination.IsNotNullOrWhiteSpace()) + { + _logger.Trace($"Default destination folder found: {defaultDestination}."); + requestBuilder.AddQueryParam("destination", $"\"{defaultDestination}\""); + } + else + { + _logger.Error("Unable to get default destination folder from DownloadStation."); + } + } ProcessRequest(requestBuilder, $"add task from url {url}", settings); } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStation2SettingsLocationResponse.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStation2SettingsLocationResponse.cs new file mode 100644 index 000000000..70598e050 --- /dev/null +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStation2SettingsLocationResponse.cs @@ -0,0 +1,7 @@ +namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses +{ + public class DownloadStation2SettingsLocationResponse + { + public string Default_Destination { get; set; } + } +} diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs index 1c90c0a3e..3ad3b23bd 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs @@ -116,14 +116,17 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation try { var serialNumber = _serialNumberProvider.GetSerialNumber(Settings); - var sharedFolder = GetDownloadDirectory() ?? GetDefaultDir(); - var outputPath = new OsPath($"/{sharedFolder.TrimStart('/')}"); - var path = _sharedFolderResolver.RemapToFullPath(outputPath, Settings, serialNumber); + + // Download station returns the path without the leading `/`, but the leading + // slash is required to get the full path back from download station. + var path = new OsPath($"/{GetDownloadDirectory()}"); + + var fullPath = _sharedFolderResolver.RemapToFullPath(path, Settings, serialNumber); return new DownloadClientInfo { IsLocalhost = Settings.Host == "127.0.0.1" || Settings.Host == "localhost", - OutputRootFolders = new List { _remotePathMappingService.RemapRemoteToLocal(Settings.Host, path) } + OutputRootFolders = new List { _remotePathMappingService.RemapRemoteToLocal(Settings.Host, fullPath) } }; } catch (DownloadClientException e) @@ -134,15 +137,15 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation } } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { if (deleteData) { - DeleteItemData(downloadId); + DeleteItemData(item); } - DsTaskProxy.RemoveTask(ParseDownloadId(downloadId), Settings); - _logger.Debug("{0} removed correctly", downloadId); + DsTaskProxy.RemoveTask(ParseDownloadId(item.DownloadId), Settings); + _logger.Debug("{0} removed correctly", item.DownloadId); } protected OsPath GetOutputPath(OsPath outputPath, DownloadStationTask torrent, string serialNumber) diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs index 6df9ae1a9..fbc208d29 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs @@ -140,14 +140,17 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation try { var serialNumber = _serialNumberProvider.GetSerialNumber(Settings); - var sharedFolder = GetDownloadDirectory() ?? GetDefaultDir(); - var outputPath = new OsPath($"/{sharedFolder.TrimStart('/')}"); - var path = _sharedFolderResolver.RemapToFullPath(outputPath, Settings, serialNumber); + + // Download station returns the path without the leading `/`, but the leading + // slash is required to get the full path back from download station. + var path = new OsPath($"/{GetDownloadDirectory()}"); + + var fullPath = _sharedFolderResolver.RemapToFullPath(path, Settings, serialNumber); return new DownloadClientInfo { IsLocalhost = Settings.Host == "127.0.0.1" || Settings.Host == "localhost", - OutputRootFolders = new List { _remotePathMappingService.RemapRemoteToLocal(Settings.Host, path) } + OutputRootFolders = new List { _remotePathMappingService.RemapRemoteToLocal(Settings.Host, fullPath) } }; } catch (DownloadClientException e) @@ -158,15 +161,15 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation } } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { if (deleteData) { - DeleteItemData(downloadId); + DeleteItemData(item); } - DsTaskProxy.RemoveTask(ParseDownloadId(downloadId), Settings); - _logger.Debug("{0} removed correctly", downloadId); + DsTaskProxy.RemoveTask(ParseDownloadId(item.DownloadId), Settings); + _logger.Debug("{0} removed correctly", item.DownloadId); } protected override string AddFromNzbFile(RemoteAlbum remoteAlbum, string filename, byte[] fileContent) diff --git a/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs b/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs index aae555ce6..88926d7dc 100644 --- a/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs +++ b/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs @@ -193,9 +193,9 @@ namespace NzbDrone.Core.Download.Clients.Flood } } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { - _proxy.DeleteTorrent(downloadId, deleteData, Settings); + _proxy.DeleteTorrent(item.DownloadId, deleteData, Settings); } public override DownloadClientInfo GetStatus() diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs index 75e61654a..e43bdebde 100644 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs @@ -96,15 +96,15 @@ namespace NzbDrone.Core.Download.Clients.Hadouken return items; } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { if (deleteData) { - _proxy.RemoveTorrentAndData(Settings, downloadId); + _proxy.RemoveTorrentAndData(Settings, item.DownloadId); } else { - _proxy.RemoveTorrent(Settings, downloadId); + _proxy.RemoveTorrent(Settings, item.DownloadId); } } diff --git a/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs b/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs index 6892258d0..86ab8beac 100644 --- a/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs +++ b/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs @@ -110,19 +110,19 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex return queueItems; } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { // Try to find the download by numerical ID, otherwise try by AddUUID int id; - if (int.TryParse(downloadId, out id)) + if (int.TryParse(item.DownloadId, out id)) { _proxy.Remove(id, deleteData, Settings); } else { var queue = _proxy.GetQueue(30, Settings); - var queueItem = queue.FirstOrDefault(c => c.AddUUID == downloadId); + var queueItem = queue.FirstOrDefault(c => c.AddUUID == item.DownloadId); if (queueItem != null) { diff --git a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs index 7494dbb01..c7f423b15 100644 --- a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs +++ b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs @@ -192,14 +192,14 @@ namespace NzbDrone.Core.Download.Clients.Nzbget return GetQueue().Concat(GetHistory()).Where(downloadClientItem => downloadClientItem.Category == Settings.MusicCategory); } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { if (deleteData) { - DeleteItemData(downloadId); + DeleteItemData(item); } - _proxy.RemoveItem(downloadId, Settings); + _proxy.RemoveItem(item.DownloadId, Settings); } public override DownloadClientInfo GetStatus() diff --git a/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs b/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs index 2261d1359..02ea2968f 100644 --- a/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs +++ b/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs @@ -97,7 +97,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic } } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { throw new NotSupportedException(); } diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs index e03d7eaa2..50b19fa55 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs @@ -318,9 +318,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent return queueItems; } - public override void RemoveItem(string hash, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { - Proxy.RemoveTorrent(hash.ToLower(), deleteData, Settings); + Proxy.RemoveTorrent(item.DownloadId.ToLower(), deleteData, Settings); } public override DownloadClientItem GetImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt) diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs index 356902d23..9a3f7b920 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs @@ -192,47 +192,22 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd } } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { - var historyItem = GetHistory().SingleOrDefault(v => v.DownloadId == downloadId); + var queueClientItem = GetQueue().SingleOrDefault(v => v.DownloadId == item.DownloadId); - if (historyItem == null) + if (queueClientItem == null) { - _proxy.RemoveFrom("queue", downloadId, deleteData, Settings); + if (deleteData && item.Status == DownloadItemStatus.Completed) + { + DeleteItemData(item); + } + + _proxy.RemoveFrom("history", item.DownloadId, deleteData, Settings); } else { - _proxy.RemoveFrom("history", downloadId, deleteData, Settings); - - // Completed items in SAB's history do not remove the files from the file system when deleted, even if instructed to. - // If the output path is valid delete the file(s), otherwise warn that they cannot be deleted. - if (deleteData && historyItem.Status == DownloadItemStatus.Completed) - { - if (ValidatePath(historyItem)) - { - var outputPath = historyItem.OutputPath; - - try - { - if (_diskProvider.FolderExists(outputPath.FullPath)) - { - _diskProvider.DeleteFolder(outputPath.FullPath.ToString(), true); - } - else if (_diskProvider.FileExists(outputPath.FullPath)) - { - _diskProvider.DeleteFile(outputPath.FullPath.ToString()); - } - } - catch (Exception) - { - _logger.Error("Unable to delete output path: '{0}'. Delete file(s) manually", outputPath.FullPath); - } - } - else - { - _logger.Warn("Invalid path '{0}'. Delete file(s) manually"); - } - } + _proxy.RemoveFrom("queue", item.DownloadId, deleteData, Settings); } } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs index 52fa9bb2b..bf701ce3f 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs @@ -157,9 +157,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission return false; } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { - _proxy.RemoveTorrent(downloadId.ToLower(), deleteData, Settings); + _proxy.RemoveTorrent(item.DownloadId.ToLower(), deleteData, Settings); } public override DownloadClientInfo GetStatus() diff --git a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs index b60ea1b1f..d287e0c67 100644 --- a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs +++ b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs @@ -24,9 +24,9 @@ namespace NzbDrone.Core.Download.Clients.Vuze { } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { - _proxy.RemoveTorrent(downloadId, deleteData, Settings); + _proxy.RemoveTorrent(item.DownloadId, deleteData, Settings); } protected override OsPath GetOutputPath(OsPath outputPath, TransmissionTorrent torrent) diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs index fb665a035..b752d2cb2 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs @@ -161,14 +161,14 @@ namespace NzbDrone.Core.Download.Clients.RTorrent return items; } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { if (deleteData) { - DeleteItemData(downloadId); + DeleteItemData(item); } - _proxy.RemoveTorrent(downloadId, Settings); + _proxy.RemoveTorrent(item.DownloadId, Settings); } public override DownloadClientInfo GetStatus() diff --git a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs index 4cfdbc810..139bc6629 100644 --- a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs @@ -206,9 +206,9 @@ namespace NzbDrone.Core.Download.Clients.UTorrent return torrents; } - public override void RemoveItem(string downloadId, bool deleteData) + public override void RemoveItem(DownloadClientItem item, bool deleteData) { - _proxy.RemoveTorrent(downloadId, deleteData, Settings); + _proxy.RemoveTorrent(item.DownloadId, deleteData, Settings); } public override DownloadClientInfo GetStatus() diff --git a/src/NzbDrone.Core/Download/DownloadClientBase.cs b/src/NzbDrone.Core/Download/DownloadClientBase.cs index edcf02910..d2b5b0e7f 100644 --- a/src/NzbDrone.Core/Download/DownloadClientBase.cs +++ b/src/NzbDrone.Core/Download/DownloadClientBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using FluentValidation.Results; @@ -68,20 +68,14 @@ namespace NzbDrone.Core.Download return item; } - public abstract void RemoveItem(string downloadId, bool deleteData); + public abstract void RemoveItem(DownloadClientItem item, bool deleteData); public abstract DownloadClientInfo GetStatus(); - protected virtual void DeleteItemData(string downloadId) + protected virtual void DeleteItemData(DownloadClientItem item) { - if (downloadId.IsNullOrWhiteSpace()) - { - return; - } - - var item = GetItems().FirstOrDefault(v => v.DownloadId == downloadId); if (item == null) { - _logger.Trace("DownloadItem {0} in {1} history not found, skipping delete data.", downloadId, Name); + _logger.Trace("DownloadItem {0} in {1} history not found, skipping delete data.", item.DownloadId, Name); return; } diff --git a/src/NzbDrone.Core/Download/DownloadEventHub.cs b/src/NzbDrone.Core/Download/DownloadEventHub.cs index ef219a3a0..e0359d765 100644 --- a/src/NzbDrone.Core/Download/DownloadEventHub.cs +++ b/src/NzbDrone.Core/Download/DownloadEventHub.cs @@ -62,7 +62,7 @@ namespace NzbDrone.Core.Download try { _logger.Debug("[{0}] Removing download from {1} history", trackedDownload.DownloadItem.Title, trackedDownload.DownloadItem.DownloadClientInfo.Name); - downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true); + downloadClient.RemoveItem(trackedDownload.DownloadItem, true); trackedDownload.DownloadItem.Removed = true; } catch (NotSupportedException) diff --git a/src/NzbDrone.Core/Download/IDownloadClient.cs b/src/NzbDrone.Core/Download/IDownloadClient.cs index 362e51236..5f331b934 100644 --- a/src/NzbDrone.Core/Download/IDownloadClient.cs +++ b/src/NzbDrone.Core/Download/IDownloadClient.cs @@ -12,7 +12,7 @@ namespace NzbDrone.Core.Download string Download(RemoteAlbum remoteAlbum); IEnumerable GetItems(); DownloadClientItem GetImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt); - void RemoveItem(string downloadId, bool deleteData); + void RemoveItem(DownloadClientItem item, bool deleteData); DownloadClientInfo GetStatus(); void MarkItemAsImported(DownloadClientItem downloadClientItem); }