From ea73466f6a714bfc00131861ce13f1701c2c745f Mon Sep 17 00:00:00 2001 From: TwentyNine78 <31310559+twentynine78@users.noreply.github.com> Date: Tue, 22 Jun 2021 05:29:50 +0200 Subject: [PATCH] Fixed: Compatibility with the new Download Station API (cherry picked from commit 49e90463e57929e7b9885f1b7b0eb05bd7cc3ebe) --- .../Clients/DownloadStation/DiskStationApi.cs | 3 +- .../DownloadStation/DiskStationApiInfo.cs | 2 +- .../DownloadStation/DownloadStation2Task.cs | 27 ++++ .../DownloadStation/DownloadStationTask.cs | 2 +- .../DownloadStationTaskAdditional.cs | 2 +- .../DownloadStationTaskFile.cs | 2 +- .../DownloadStation/Proxies/DSMInfoProxy.cs | 4 +- .../Proxies/DiskStationProxyBase.cs | 18 ++- .../Proxies/DownloadStationInfoProxy.cs | 4 +- .../DownloadStationTaskProxySelector.cs | 68 ++++++++++ ...Proxy.cs => DownloadStationTaskProxyV1.cs} | 17 ++- .../Proxies/DownloadStationTaskProxyV2.cs | 119 ++++++++++++++++++ .../Proxies/FileStationProxy.cs | 2 +- .../Responses/DSMInfoResponse.cs | 2 +- .../Responses/DiskStationAuthResponse.cs | 2 +- .../Responses/DiskStationError.cs | 22 ++-- .../Responses/DiskStationInfoResponse.cs | 2 +- .../Responses/DiskStationResponse.cs | 2 +- .../DownloadStation2TaskInfoResponse.cs | 11 ++ .../DownloadStationTaskInfoResponse.cs | 2 +- .../FileStationListFileInfoResponse.cs | 2 +- .../Responses/FileStationListResponse.cs | 2 +- .../DownloadStation/SerialNumberProvider.cs | 3 +- .../DownloadStation/SharedFolderMapping.cs | 2 +- .../DownloadStation/SharedFolderResolver.cs | 3 +- .../DownloadStation/TorrentDownloadStation.cs | 17 +-- .../DownloadStation/UsenetDownloadStation.cs | 17 +-- 27 files changed, 305 insertions(+), 54 deletions(-) create mode 100644 src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs create mode 100644 src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxySelector.cs rename src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/{DownloadStationTaskProxy.cs => DownloadStationTaskProxyV1.cs} (79%) create mode 100644 src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV2.cs create mode 100644 src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStation2TaskInfoResponse.cs diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApi.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApi.cs index 8fcefdd51..9b3cbfc33 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApi.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApi.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.DownloadStation +namespace NzbDrone.Core.Download.Clients.DownloadStation { public enum DiskStationApi { @@ -6,6 +6,7 @@ Auth, DownloadStationInfo, DownloadStationTask, + DownloadStation2Task, FileStationList, DSMInfo, } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApiInfo.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApiInfo.cs index 60f84c672..b507747b3 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApiInfo.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DiskStationApiInfo.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.DownloadStation +namespace NzbDrone.Core.Download.Clients.DownloadStation { public class DiskStationApiInfo { diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs new file mode 100644 index 000000000..ef52bb7e0 --- /dev/null +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs @@ -0,0 +1,27 @@ +namespace NzbDrone.Core.Download.Clients.DownloadStation +{ + public class DownloadStation2Task + { + public string Username { get; set; } + + public string Id { get; set; } + + public string Title { get; set; } + + public long Size { get; set; } + + /// + /// /// Possible values are: BT, NZB, http, ftp, eMule and https + /// + public string Type { get; set; } + + public int Status { get; set; } + + public DownloadStationTaskAdditional Additional { get; set; } + + public override string ToString() + { + return this.Title; + } + } +} diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTask.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTask.cs index 41faac633..3c5de2fb9 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTask.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTask.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Newtonsoft.Json; using NzbDrone.Common.Serializer; diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTaskAdditional.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTaskAdditional.cs index 81e55569e..79c893ab5 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTaskAdditional.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTaskAdditional.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Newtonsoft.Json; namespace NzbDrone.Core.Download.Clients.DownloadStation diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTaskFile.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTaskFile.cs index 2538e3e10..6cc396cd7 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTaskFile.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTaskFile.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Converters; namespace NzbDrone.Core.Download.Clients.DownloadStation diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DSMInfoProxy.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DSMInfoProxy.cs index 322296c06..46808fcbc 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DSMInfoProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DSMInfoProxy.cs @@ -1,4 +1,4 @@ -using NLog; +using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Http; using NzbDrone.Core.Download.Clients.DownloadStation.Responses; @@ -13,7 +13,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies public class DSMInfoProxy : DiskStationProxyBase, IDSMInfoProxy { public DSMInfoProxy(IHttpClient httpClient, ICacheManager cacheManager, Logger logger) - : base(DiskStationApi.DSMInfo, "SYNO.DSM.Info", httpClient, cacheManager, logger) + : base(DiskStationApi.DSMInfo, "SYNO.DSM.Info", httpClient, cacheManager, logger) { } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DiskStationProxyBase.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DiskStationProxyBase.cs index 213b3e505..c1507aa2e 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DiskStationProxyBase.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DiskStationProxyBase.cs @@ -172,7 +172,14 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies { if (apiInfo.NeedsAuthentication) { - requestBuilder.AddFormParameter("_sid", _sessionCache.Get(GenerateSessionCacheKey(settings), () => AuthenticateClient(settings), TimeSpan.FromHours(6))); + if (_apiType == DiskStationApi.DownloadStation2Task) + { + requestBuilder.AddQueryParam("_sid", _sessionCache.Get(GenerateSessionCacheKey(settings), () => AuthenticateClient(settings), TimeSpan.FromHours(6))); + } + else + { + requestBuilder.AddFormParameter("_sid", _sessionCache.Get(GenerateSessionCacheKey(settings), () => AuthenticateClient(settings), TimeSpan.FromHours(6))); + } } requestBuilder.AddFormParameter("api", apiInfo.Name); @@ -242,7 +249,14 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies if (info == null) { - throw new DownloadClientException("Info of {0} not found on {1}:{2}", api, settings.Host, settings.Port); + if (api == DiskStationApi.DownloadStation2Task) + { + _logger.Warn("Info of {0} not found on {1}:{2}", api, settings.Host, settings.Port); + } + else + { + throw new DownloadClientException("Info of {0} not found on {1}:{2}", api, settings.Host, settings.Port); + } } } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationInfoProxy.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationInfoProxy.cs index 1723fcc80..5fe44ddfd 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationInfoProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationInfoProxy.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Http; @@ -13,7 +13,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies public class DownloadStationInfoProxy : DiskStationProxyBase, IDownloadStationInfoProxy { public DownloadStationInfoProxy(IHttpClient httpClient, ICacheManager cacheManager, Logger logger) - : base(DiskStationApi.DownloadStationInfo, "SYNO.DownloadStation.Info", httpClient, cacheManager, logger) + : base(DiskStationApi.DownloadStationInfo, "SYNO.DownloadStation.Info", httpClient, cacheManager, logger) { } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxySelector.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxySelector.cs new file mode 100644 index 000000000..1eae7930e --- /dev/null +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxySelector.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using NLog; +using NzbDrone.Common.Cache; + +namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies +{ + public interface IDownloadStationTaskProxy : IDiskStationProxy + { + bool IsApiSupported(DownloadStationSettings settings); + IEnumerable GetTasks(DownloadStationSettings settings); + void RemoveTask(string downloadId, DownloadStationSettings settings); + void AddTaskFromUrl(string url, string downloadDirectory, DownloadStationSettings settings); + void AddTaskFromData(byte[] data, string filename, string downloadDirectory, DownloadStationSettings settings); + } + + public interface IDownloadStationTaskProxySelector + { + IDownloadStationTaskProxy GetProxy(DownloadStationSettings settings); + } + + public class DownloadStationTaskProxySelector : IDownloadStationTaskProxySelector + { + private readonly ICached _proxyCache; + private readonly Logger _logger; + + private readonly IDownloadStationTaskProxy _proxyV1; + private readonly IDownloadStationTaskProxy _proxyV2; + + public DownloadStationTaskProxySelector(DownloadStationTaskProxyV1 proxyV1, DownloadStationTaskProxyV2 proxyV2, ICacheManager cacheManager, Logger logger) + { + _proxyCache = cacheManager.GetCache(GetType(), "taskProxy"); + _logger = logger; + + _proxyV1 = proxyV1; + _proxyV2 = proxyV2; + } + + public IDownloadStationTaskProxy GetProxy(DownloadStationSettings settings) + { + return GetProxyCache(settings); + } + + private IDownloadStationTaskProxy GetProxyCache(DownloadStationSettings settings) + { + var propKey = $"{settings.Host}_{settings.Port}"; + + return _proxyCache.Get(propKey, () => FetchProxy(settings), TimeSpan.FromMinutes(10.0)); + } + + private IDownloadStationTaskProxy FetchProxy(DownloadStationSettings settings) + { + if (_proxyV2.IsApiSupported(settings)) + { + _logger.Trace("Using DownloadStation Task API v2"); + return _proxyV2; + } + + if (_proxyV1.IsApiSupported(settings)) + { + _logger.Trace("Using DownloadStation Task API v1"); + return _proxyV1; + } + + throw new DownloadClientException("Unable to determine DownloadStations Task API version"); + } + } +} diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxy.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV1.cs similarity index 79% rename from src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxy.cs rename to src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV1.cs index 5ae04a152..13e5131fb 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV1.cs @@ -9,21 +9,18 @@ using NzbDrone.Core.Download.Clients.DownloadStation.Responses; namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies { - public interface IDownloadStationTaskProxy : IDiskStationProxy + public class DownloadStationTaskProxyV1 : DiskStationProxyBase, IDownloadStationTaskProxy { - IEnumerable GetTasks(DownloadStationSettings settings); - void RemoveTask(string downloadId, DownloadStationSettings settings); - void AddTaskFromUrl(string url, string downloadDirectory, DownloadStationSettings settings); - void AddTaskFromData(byte[] data, string filename, string downloadDirectory, DownloadStationSettings settings); - } - - public class DownloadStationTaskProxy : DiskStationProxyBase, IDownloadStationTaskProxy - { - public DownloadStationTaskProxy(IHttpClient httpClient, ICacheManager cacheManager, Logger logger) + public DownloadStationTaskProxyV1(IHttpClient httpClient, ICacheManager cacheManager, Logger logger) : base(DiskStationApi.DownloadStationTask, "SYNO.DownloadStation.Task", httpClient, cacheManager, logger) { } + public bool IsApiSupported(DownloadStationSettings settings) + { + return GetApiInfo(settings) != null; + } + public void AddTaskFromData(byte[] data, string filename, string downloadDirectory, DownloadStationSettings settings) { var requestBuilder = BuildRequest(settings, "create", 2, HttpMethod.Post); diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV2.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV2.cs new file mode 100644 index 000000000..6f81c3ac3 --- /dev/null +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxyV2.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using NLog; +using NzbDrone.Common.Cache; +using NzbDrone.Common.Extensions; +using NzbDrone.Common.Http; +using NzbDrone.Core.Download.Clients.DownloadStation.Responses; + +namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies +{ + public class DownloadStationTaskProxyV2 : DiskStationProxyBase, IDownloadStationTaskProxy + { + public DownloadStationTaskProxyV2(IHttpClient httpClient, ICacheManager cacheManager, Logger logger) + : base(DiskStationApi.DownloadStation2Task, "SYNO.DownloadStation2.Task", httpClient, cacheManager, logger) + { + } + + public bool IsApiSupported(DownloadStationSettings settings) + { + return GetApiInfo(settings) != null; + } + + public void AddTaskFromData(byte[] data, string filename, string downloadDirectory, DownloadStationSettings settings) + { + var requestBuilder = BuildRequest(settings, "create", 2, HttpMethod.Post); + + requestBuilder.AddFormParameter("type", "\"file\""); + requestBuilder.AddFormParameter("file", "[\"fileData\"]"); + requestBuilder.AddFormParameter("create_list", "false"); + + if (downloadDirectory.IsNotNullOrWhiteSpace()) + { + requestBuilder.AddFormParameter("destination", $"\"{downloadDirectory}\""); + } + + requestBuilder.AddFormUpload("fileData", filename, data); + + ProcessRequest(requestBuilder, $"add task from data {filename}", settings); + } + + public void AddTaskFromUrl(string url, string downloadDirectory, DownloadStationSettings settings) + { + var requestBuilder = BuildRequest(settings, "create", 2); + + requestBuilder.AddQueryParam("type", "url"); + requestBuilder.AddQueryParam("url", url); + requestBuilder.AddQueryParam("create_list", "false"); + + if (downloadDirectory.IsNotNullOrWhiteSpace()) + { + requestBuilder.AddQueryParam("destination", downloadDirectory); + } + + ProcessRequest(requestBuilder, $"add task from url {url}", settings); + } + + public IEnumerable GetTasks(DownloadStationSettings settings) + { + try + { + var result = new List(); + + var requestBuilder = BuildRequest(settings, "list", 1); + requestBuilder.AddQueryParam("additional", "detail"); + + var response = ProcessRequest(requestBuilder, "get tasks with additional detail", settings); + + if (response.Success && response.Data.Total > 0) + { + requestBuilder.AddQueryParam("additional", "transfer"); + var responseTransfer = ProcessRequest(requestBuilder, "get tasks with additional transfer", settings); + + if (responseTransfer.Success) + { + foreach (var task in response.Data.Task) + { + var taskTransfer = responseTransfer.Data.Task.Where(t => t.Id == task.Id).First(); + + var combinedTask = new DownloadStationTask + { + Username = task.Username, + Id = task.Id, + Title = task.Title, + Size = task.Size, + Status = (DownloadStationTaskStatus)task.Status, + Type = task.Type, + Additional = new DownloadStationTaskAdditional + { + Detail = task.Additional.Detail, + Transfer = taskTransfer.Additional.Transfer + } + }; + + result.Add(combinedTask); + } + } + } + + return result; + } + catch (DownloadClientException e) + { + _logger.Error(e); + return Array.Empty(); + } + } + + public void RemoveTask(string downloadId, DownloadStationSettings settings) + { + var requestBuilder = BuildRequest(settings, "delete", 2); + requestBuilder.AddQueryParam("id", downloadId); + requestBuilder.AddQueryParam("force_complete", "false"); + + ProcessRequest(requestBuilder, $"remove item {downloadId}", settings); + } + } +} diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/FileStationProxy.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/FileStationProxy.cs index a07cc1b47..fbfa3b4ae 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/FileStationProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/FileStationProxy.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Http; diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DSMInfoResponse.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DSMInfoResponse.cs index 0848bba70..e2e81c4ca 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DSMInfoResponse.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DSMInfoResponse.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses { diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationAuthResponse.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationAuthResponse.cs index d02503a25..04d6444ac 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationAuthResponse.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationAuthResponse.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses +namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses { public class DiskStationAuthResponse { diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationError.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationError.cs index 50758d3af..c3f9b1090 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationError.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationError.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses { @@ -20,16 +20,22 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses { 104, "The requested version does not support the functionality" }, { 105, "The logged in session does not have permission" }, { 106, "Session timeout" }, - { 107, "Session interrupted by duplicate login" } + { 107, "Session interrupted by duplicate login" }, + { 119, "SID not found" } }; AuthMessages = new Dictionary { { 400, "No such account or incorrect password" }, - { 401, "Account disabled" }, - { 402, "Permission denied" }, - { 403, "2-step verification code required" }, - { 404, "Failed to authenticate 2-step verification code" } + { 401, "Disabled account" }, + { 402, "Denied permission" }, + { 403, "2-step authentication code required" }, + { 404, "Failed to authenticate 2-step authentication code" }, + { 406, "Enforce to authenticate with 2-factor authentication code" }, + { 407, "Blocked IP source" }, + { 408, "Expired password cannot change" }, + { 409, "Expired password" }, + { 410, "Password must be changed" } }; DownloadStationTaskMessages = new Dictionary @@ -76,7 +82,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses public int Code { get; set; } - public bool SessionError => Code == 105 || Code == 106 || Code == 107; + public bool SessionError => Code == 105 || Code == 106 || Code == 107 || Code == 119; public string GetMessage(DiskStationApi api) { @@ -85,7 +91,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses return AuthMessages[Code]; } - if (api == DiskStationApi.DownloadStationTask && DownloadStationTaskMessages.ContainsKey(Code)) + if ((api == DiskStationApi.DownloadStationTask || api == DiskStationApi.DownloadStation2Task) && DownloadStationTaskMessages.ContainsKey(Code)) { return DownloadStationTaskMessages[Code]; } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationInfoResponse.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationInfoResponse.cs index 6c40ae75c..c80b213e0 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationInfoResponse.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationInfoResponse.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses { diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationResponse.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationResponse.cs index 43c981669..6354adeb3 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationResponse.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DiskStationResponse.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses +namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses { public class DiskStationResponse where T : new() diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStation2TaskInfoResponse.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStation2TaskInfoResponse.cs new file mode 100644 index 000000000..4d98c16d7 --- /dev/null +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStation2TaskInfoResponse.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses +{ + public class DownloadStation2TaskInfoResponse + { + public int Offset { get; set; } + public List Task { get; set; } + public int Total { get; set; } + } +} diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStationTaskInfoResponse.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStationTaskInfoResponse.cs index ebd79f3d7..877b1890a 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStationTaskInfoResponse.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/DownloadStationTaskInfoResponse.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses { diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/FileStationListFileInfoResponse.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/FileStationListFileInfoResponse.cs index f31d51a68..927fd242b 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/FileStationListFileInfoResponse.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/FileStationListFileInfoResponse.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses { diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/FileStationListResponse.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/FileStationListResponse.cs index e12c60094..823465bbe 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/FileStationListResponse.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Responses/FileStationListResponse.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace NzbDrone.Core.Download.Clients.DownloadStation.Responses { diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/SerialNumberProvider.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/SerialNumberProvider.cs index 88a419d22..dfeb227a2 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/SerialNumberProvider.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/SerialNumberProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Crypto; @@ -16,6 +16,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation { private readonly IDSMInfoProxy _proxy; private readonly ILogger _logger; + private ICached _cache; public SerialNumberProvider(ICacheManager cacheManager, diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/SharedFolderMapping.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/SharedFolderMapping.cs index 15946e861..354e1d50b 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/SharedFolderMapping.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/SharedFolderMapping.cs @@ -1,4 +1,4 @@ -using NzbDrone.Common.Disk; +using NzbDrone.Common.Disk; namespace NzbDrone.Core.Download.Clients.DownloadStation { diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/SharedFolderResolver.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/SharedFolderResolver.cs index 25ff176f6..b5a308a37 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/SharedFolderResolver.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/SharedFolderResolver.cs @@ -1,4 +1,4 @@ -using System; +using System; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Disk; @@ -15,6 +15,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation { private readonly IFileStationProxy _proxy; private readonly ILogger _logger; + private ICached _cache; public SharedFolderResolver(ICacheManager cacheManager, diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs index 09db5a136..17cf57246 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs @@ -19,7 +19,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation public class TorrentDownloadStation : TorrentClientBase { protected readonly IDownloadStationInfoProxy _dsInfoProxy; - protected readonly IDownloadStationTaskProxy _dsTaskProxy; + protected readonly IDownloadStationTaskProxySelector _dsTaskProxySelector; protected readonly ISharedFolderResolver _sharedFolderResolver; protected readonly ISerialNumberProvider _serialNumberProvider; protected readonly IFileStationProxy _fileStationProxy; @@ -28,7 +28,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation ISerialNumberProvider serialNumberProvider, IFileStationProxy fileStationProxy, IDownloadStationInfoProxy dsInfoProxy, - IDownloadStationTaskProxy dsTaskProxy, + IDownloadStationTaskProxySelector dsTaskProxySelector, ITorrentFileInfoReader torrentFileInfoReader, ISeedConfigProvider seedConfigProvider, IConfigService configService, @@ -37,7 +37,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { _dsInfoProxy = dsInfoProxy; - _dsTaskProxy = dsTaskProxy; + _dsTaskProxySelector = dsTaskProxySelector; _fileStationProxy = fileStationProxy; _sharedFolderResolver = sharedFolderResolver; _serialNumberProvider = serialNumberProvider; @@ -48,16 +48,18 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation public override ProviderMessage Message => new ProviderMessage("Prowlarr is unable to connect to Download Station if 2-Factor Authentication is enabled on your DSM account", ProviderMessageType.Warning); + private IDownloadStationTaskProxy DsTaskProxy => _dsTaskProxySelector.GetProxy(Settings); + protected IEnumerable GetTasks() { - return _dsTaskProxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.BT.ToString().ToLower()); + return DsTaskProxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.BT.ToString().ToLower()); } protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings); - _dsTaskProxy.AddTaskFromUrl(magnetLink, GetDownloadDirectory(), Settings); + DsTaskProxy.AddTaskFromUrl(magnetLink, GetDownloadDirectory(), Settings); var item = GetTasks().SingleOrDefault(t => t.Additional.Detail["uri"] == magnetLink); @@ -76,7 +78,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation { var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings); - _dsTaskProxy.AddTaskFromData(fileContent, filename, GetDownloadDirectory(), Settings); + DsTaskProxy.AddTaskFromData(fileContent, filename, GetDownloadDirectory(), Settings); var items = GetTasks().Where(t => t.Additional.Detail["uri"] == Path.GetFileNameWithoutExtension(filename)); @@ -217,6 +219,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation } catch (DownloadClientAuthenticationException ex) { + // User could not have permission to access to downloadstation _logger.Error(ex, ex.Message); return new NzbDroneValidationFailure(string.Empty, ex.Message); } @@ -268,7 +271,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation protected ValidationFailure ValidateVersion() { - var info = _dsTaskProxy.GetApiInfo(Settings); + var info = DsTaskProxy.GetApiInfo(Settings); _logger.Debug("Download Station api version information: Min {0} - Max {1}", info.MinVersion, info.MaxVersion); diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs index 1759cf600..562d6d975 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs @@ -18,7 +18,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation public class UsenetDownloadStation : UsenetClientBase { protected readonly IDownloadStationInfoProxy _dsInfoProxy; - protected readonly IDownloadStationTaskProxy _dsTaskProxy; + protected readonly IDownloadStationTaskProxySelector _dsTaskProxySelector; protected readonly ISharedFolderResolver _sharedFolderResolver; protected readonly ISerialNumberProvider _serialNumberProvider; protected readonly IFileStationProxy _fileStationProxy; @@ -27,15 +27,15 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation ISerialNumberProvider serialNumberProvider, IFileStationProxy fileStationProxy, IDownloadStationInfoProxy dsInfoProxy, - IDownloadStationTaskProxy dsTaskProxy, + IDownloadStationTaskProxySelector dsTaskProxySelector, IHttpClient httpClient, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(httpClient, configService, diskProvider, logger) + : base(httpClient, configService, diskProvider, logger) { _dsInfoProxy = dsInfoProxy; - _dsTaskProxy = dsTaskProxy; + _dsTaskProxySelector = dsTaskProxySelector; _fileStationProxy = fileStationProxy; _sharedFolderResolver = sharedFolderResolver; _serialNumberProvider = serialNumberProvider; @@ -46,16 +46,18 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation public override ProviderMessage Message => new ProviderMessage("Prowlarr is unable to connect to Download Station if 2-Factor Authentication is enabled on your DSM account", ProviderMessageType.Warning); + private IDownloadStationTaskProxy DsTaskProxy => _dsTaskProxySelector.GetProxy(Settings); + protected IEnumerable GetTasks() { - return _dsTaskProxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.NZB.ToString().ToLower()); + return DsTaskProxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.NZB.ToString().ToLower()); } protected override string AddFromNzbFile(ReleaseInfo release, string filename, byte[] fileContent) { var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings); - _dsTaskProxy.AddTaskFromData(fileContent, filename, GetDownloadDirectory(), Settings); + DsTaskProxy.AddTaskFromData(fileContent, filename, GetDownloadDirectory(), Settings); var items = GetTasks().Where(t => t.Additional.Detail["uri"] == filename); @@ -127,6 +129,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation } catch (DownloadClientAuthenticationException ex) { + // User could not have permission to access to downloadstation _logger.Error(ex, ex.Message); return new NzbDroneValidationFailure(string.Empty, ex.Message); } @@ -178,7 +181,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation protected ValidationFailure ValidateVersion() { - var info = _dsTaskProxy.GetApiInfo(Settings); + var info = DsTaskProxy.GetApiInfo(Settings); _logger.Debug("Download Station api version information: Min {0} - Max {1}", info.MinVersion, info.MaxVersion);