diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs index c1fe712a6..51881debc 100644 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs @@ -54,6 +54,11 @@ namespace NzbDrone.Core.Download.Clients.Hadouken foreach (var torrent in torrents) { + if (Settings.Category.IsNotNullOrWhiteSpace() && torrent.Label != Settings.Category) + { + continue; + } + var outputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(torrent.SavePath)); var eta = TimeSpan.FromSeconds(0); diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenError.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenError.cs deleted file mode 100644 index 2d8c64b4f..000000000 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenError.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace NzbDrone.Core.Download.Clients.Hadouken -{ - public class HadoukenError - { - public int Code { get; set; } - public string Message { get; set; } - } -} diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenProxy.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenProxy.cs index 766f46b53..e044dd912 100644 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenProxy.cs @@ -1,48 +1,61 @@ using System; using System.Collections.Generic; -using System.Text; +using System.Net; using NLog; +using NzbDrone.Common.Http; +using NzbDrone.Common.Serializer; using NzbDrone.Core.Download.Clients.Hadouken.Models; -using NzbDrone.Core.Rest; -using RestSharp; namespace NzbDrone.Core.Download.Clients.Hadouken { + public interface IHadoukenProxy + { + HadoukenSystemInfo GetSystemInfo(HadoukenSettings settings); + HadoukenTorrent[] GetTorrents(HadoukenSettings settings); + IDictionary GetConfig(HadoukenSettings settings); + string AddTorrentFile(HadoukenSettings settings, byte[] fileContent); + void AddTorrentUri(HadoukenSettings settings, string torrentUrl); + void RemoveTorrent(HadoukenSettings settings, string downloadId); + void RemoveTorrentAndData(HadoukenSettings settings, string downloadId); + } + public class HadoukenProxy : IHadoukenProxy { private static int _callId; + private readonly IHttpClient _httpClient; private readonly Logger _logger; - public HadoukenProxy(Logger logger) + public HadoukenProxy(IHttpClient httpClient, Logger logger) { + _httpClient = httpClient; _logger = logger; } public HadoukenSystemInfo GetSystemInfo(HadoukenSettings settings) { - return ProcessRequest(settings, "core.getSystemInfo").Result; + return ProcessRequest(settings, "core.getSystemInfo"); } public HadoukenTorrent[] GetTorrents(HadoukenSettings settings) { - var result = ProcessRequest(settings, "webui.list").Result; + var result = ProcessRequest(settings, "webui.list"); return GetTorrents(result.Torrents); } public IDictionary GetConfig(HadoukenSettings settings) { - return ProcessRequest>(settings, "webui.getSettings").Result; + return ProcessRequest>(settings, "webui.getSettings"); } public string AddTorrentFile(HadoukenSettings settings, byte[] fileContent) { - return ProcessRequest(settings, "webui.addTorrent", "file", Convert.ToBase64String(fileContent)).Result; + return ProcessRequest(settings, "webui.addTorrent", "file", Convert.ToBase64String(fileContent), new { label = settings.Category }); } public void AddTorrentUri(HadoukenSettings settings, string torrentUrl) { - ProcessRequest(settings, "webui.addTorrent", "url", torrentUrl); + ProcessRequest(settings, "webui.addTorrent", "url", torrentUrl, new { label = settings.Category }); } public void RemoveTorrent(HadoukenSettings settings, string downloadId) @@ -55,53 +68,24 @@ namespace NzbDrone.Core.Download.Clients.Hadouken ProcessRequest(settings, "webui.perform", "removedata", new string[] { downloadId }); } - private HadoukenResponse ProcessRequest(HadoukenSettings settings, string method, params object[] parameters) + private T ProcessRequest(HadoukenSettings settings, string method, params object[] parameters) { - var client = BuildClient(settings); - return ProcessRequest(client, method, parameters); - } + var baseUrl = HttpRequestBuilder.BuildBaseUrl(settings.UseSsl, settings.Host, settings.Port, "api"); + var requestBuilder = new JsonRpcRequestBuilder(baseUrl, method, parameters); + requestBuilder.LogResponseContent = true; + requestBuilder.NetworkCredential = new NetworkCredential(settings.Username, settings.Password); + requestBuilder.Headers.Add("Accept-Encoding", "gzip,deflate"); - private HadoukenResponse ProcessRequest(IRestClient client, string method, params object[] parameters) - { - var request = new RestRequest(Method.POST); - request.Resource = "api"; - request.RequestFormat = DataFormat.Json; - request.AddHeader("Accept-Encoding", "gzip,deflate"); + var httpRequest = requestBuilder.Build(); + var response = _httpClient.Execute(httpRequest); + var result = Json.Deserialize>(response.Content); - var data = new Dictionary(); - data.Add("id", GetCallId()); - data.Add("method", method); - - if (parameters != null) + if (result.Error != null) { - data.Add("params", parameters); + throw new DownloadClientException("Error response received from Hadouken: {0}", result.Error.ToString()); } - request.AddBody(data); - - _logger.Debug("Url: {0} Method: {1}", client.BuildUri(request), method); - return client.ExecuteAndValidate>(request); - } - - private IRestClient BuildClient(HadoukenSettings settings) - { - var protocol = settings.UseSsl ? "https" : "http"; - var url = string.Format(@"{0}://{1}:{2}", protocol, settings.Host, settings.Port); - - var restClient = RestClientFactory.BuildClient(url); - restClient.Timeout = 4000; - - var basicData = Encoding.UTF8.GetBytes(string.Format("{0}:{1}", settings.Username, settings.Password)); - var basicHeader = Convert.ToBase64String(basicData); - - restClient.AddDefaultHeader("Authorization", string.Format("Basic {0}", basicHeader)); - - return restClient; - } - - private int GetCallId() - { - return System.Threading.Interlocked.Increment(ref _callId); + return result.Result; } private HadoukenTorrent[] GetTorrents(object[][] torrentsRaw) @@ -141,6 +125,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken Progress = Convert.ToDouble(item[4]), DownloadedBytes = Convert.ToInt64(item[5]), DownloadRate = Convert.ToInt64(item[9]), + Label = Convert.ToString(item[11]), Error = Convert.ToString(item[21]), SavePath = Convert.ToString(item[26]) }; diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenResponse.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenResponse.cs deleted file mode 100644 index 0d2c75309..000000000 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenResponse.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace NzbDrone.Core.Download.Clients.Hadouken -{ - public class HadoukenResponse - { - public int Id { get; set; } - public TResult Result { get; set; } - public HadoukenError Error { get; set; } - } - - public class HadoukenResponseResult - { - public object[][] Torrents { get; set; } - } -} diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettings.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettings.cs index afac566cb..5291c9515 100644 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettings.cs @@ -1,9 +1,25 @@ -using NzbDrone.Core.Annotations; +using FluentValidation; +using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.Hadouken { + public class HadoukenSettingsValidator : AbstractValidator + { + public HadoukenSettingsValidator() + { + RuleFor(c => c.Host).ValidHost(); + RuleFor(c => c.Port).GreaterThan(0); + + RuleFor(c => c.Username).NotEmpty() + .WithMessage("Username must not be empty."); + + RuleFor(c => c.Password).NotEmpty() + .WithMessage("Password must not be empty."); + } + } + public class HadoukenSettings : IProviderConfig { private static readonly HadoukenSettingsValidator Validator = new HadoukenSettingsValidator(); @@ -12,6 +28,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken { Host = "localhost"; Port = 7070; + Category = "sonarr-tv"; } [FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)] @@ -26,7 +43,10 @@ namespace NzbDrone.Core.Download.Clients.Hadouken [FieldDefinition(3, Label = "Password", Type = FieldType.Password)] public string Password { get; set; } - [FieldDefinition(4, Label = "Use SSL", Type = FieldType.Checkbox, Advanced = true)] + [FieldDefinition(4, Label = "Category", Type = FieldType.Textbox)] + public string Category { get; set; } + + [FieldDefinition(5, Label = "Use SSL", Type = FieldType.Checkbox, Advanced = true)] public bool UseSsl { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettingsValidator.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettingsValidator.cs deleted file mode 100644 index 195caaaec..000000000 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettingsValidator.cs +++ /dev/null @@ -1,20 +0,0 @@ -using FluentValidation; -using NzbDrone.Core.Validation; - -namespace NzbDrone.Core.Download.Clients.Hadouken -{ - public class HadoukenSettingsValidator : AbstractValidator - { - public HadoukenSettingsValidator() - { - RuleFor(c => c.Host).ValidHost(); - RuleFor(c => c.Port).GreaterThan(0); - - RuleFor(c => c.Username).NotEmpty() - .WithMessage("Username must not be empty."); - - RuleFor(c => c.Password).NotEmpty() - .WithMessage("Password must not be empty."); - } - } -} diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/IHadoukenProxy.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/IHadoukenProxy.cs deleted file mode 100644 index b3eae437f..000000000 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/IHadoukenProxy.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Collections.Generic; -using NzbDrone.Core.Download.Clients.Hadouken.Models; - -namespace NzbDrone.Core.Download.Clients.Hadouken -{ - public interface IHadoukenProxy - { - HadoukenSystemInfo GetSystemInfo(HadoukenSettings settings); - HadoukenTorrent[] GetTorrents(HadoukenSettings settings); - IDictionary GetConfig(HadoukenSettings settings); - string AddTorrentFile(HadoukenSettings settings, byte[] fileContent); - void AddTorrentUri(HadoukenSettings settings, string torrentUrl); - void RemoveTorrent(HadoukenSettings settings, string downloadId); - void RemoveTorrentAndData(HadoukenSettings settings, string downloadId); - } -} diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/Models/HadoukenTorrent.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/Models/HadoukenTorrent.cs index d75bafdc7..a52180ca2 100644 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/Models/HadoukenTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/Models/HadoukenTorrent.cs @@ -5,6 +5,7 @@ public string InfoHash { get; set; } public double Progress { get; set; } public string Name { get; set; } + public string Label { get; set; } public string SavePath { get; set; } public HadoukenTorrentState State { get; set; } public bool IsFinished { get; set; } diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/Models/HadoukenTorrentResponse.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/Models/HadoukenTorrentResponse.cs new file mode 100644 index 000000000..0b3c1f6a4 --- /dev/null +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/Models/HadoukenTorrentResponse.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NzbDrone.Core.Download.Clients.Hadouken.Models +{ + public class HadoukenTorrentResponse + { + public object[][] Torrents { get; set; } + } +} diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index b249e20cc..f44765751 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -349,12 +349,9 @@ - - - - +