diff --git a/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs b/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs index 11469d5a6..f8343eb92 100644 --- a/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs +++ b/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using FluentValidation.Results; using Newtonsoft.Json.Linq; using NLog; @@ -31,7 +32,25 @@ namespace NzbDrone.Core.Applications.Lidarr { var failures = new List(); - failures.AddIfNotNull(_lidarrV1Proxy.Test(Settings)); + var testIndexer = new IndexerDefinition + { + Id = 0, + Name = "Test", + Protocol = DownloadProtocol.Usenet, + Capabilities = new IndexerCapabilities() + }; + + testIndexer.Capabilities.Categories.AddCategoryMapping(1, NewznabStandardCategory.Audio); + + try + { + failures.AddIfNotNull(_lidarrV1Proxy.TestConnection(BuildLidarrIndexer(testIndexer, DownloadProtocol.Usenet), Settings)); + } + catch (WebException ex) + { + _logger.Error(ex, "Unable to send test message"); + failures.AddIfNotNull(new ValidationFailure("BaseUrl", "Unable to complete application test, cannot connect to Lidarr")); + } return new ValidationResult(failures); } diff --git a/src/NzbDrone.Core/Applications/Lidarr/LidarrSettings.cs b/src/NzbDrone.Core/Applications/Lidarr/LidarrSettings.cs index 0deadda83..c73df32ab 100644 --- a/src/NzbDrone.Core/Applications/Lidarr/LidarrSettings.cs +++ b/src/NzbDrone.Core/Applications/Lidarr/LidarrSettings.cs @@ -28,7 +28,7 @@ namespace NzbDrone.Core.Applications.Lidarr public IEnumerable SyncCategories { get; set; } - [FieldDefinition(0, Label = "Prowlarr Server", HelpText = "Prowlarr server URL as Lidarr sees it, including http(s):// and port if needed")] + [FieldDefinition(0, Label = "Prowlarr Server", HelpText = "Prowlarr server URL as Lidarr sees it, including http(s)://, port, and urlbase if needed")] public string ProwlarrUrl { get; set; } [FieldDefinition(1, Label = "Lidarr Server", HelpText = "Lidarr server URL, including http(s):// and port if needed")] diff --git a/src/NzbDrone.Core/Applications/Lidarr/LidarrV1Proxy.cs b/src/NzbDrone.Core/Applications/Lidarr/LidarrV1Proxy.cs index 1fbd17872..6eff2a1a6 100644 --- a/src/NzbDrone.Core/Applications/Lidarr/LidarrV1Proxy.cs +++ b/src/NzbDrone.Core/Applications/Lidarr/LidarrV1Proxy.cs @@ -17,7 +17,7 @@ namespace NzbDrone.Core.Applications.Lidarr List GetIndexerSchema(LidarrSettings settings); void RemoveIndexer(int indexerId, LidarrSettings settings); LidarrIndexer UpdateIndexer(LidarrIndexer indexer, LidarrSettings settings); - ValidationFailure Test(LidarrSettings settings); + ValidationFailure TestConnection(LidarrIndexer indexer, LidarrSettings settings); } public class LidarrV1Proxy : ILidarrV1Proxy @@ -91,11 +91,15 @@ namespace NzbDrone.Core.Applications.Lidarr return Execute(request); } - public ValidationFailure Test(LidarrSettings settings) + public ValidationFailure TestConnection(LidarrIndexer indexer, LidarrSettings settings) { + var request = BuildRequest(settings, $"/api/v1/indexer/test", HttpMethod.POST); + + request.SetContent(indexer.ToJson()); + try { - GetStatus(settings); + Execute(request); } catch (HttpException ex) { @@ -105,8 +109,14 @@ namespace NzbDrone.Core.Applications.Lidarr return new ValidationFailure("ApiKey", "API Key is invalid"); } + if (ex.Response.StatusCode == HttpStatusCode.BadRequest) + { + _logger.Error(ex, "Prowlarr URL is invalid"); + return new ValidationFailure("ProwlarrUrl", "Prowlarr url is invalid, Lidarr cannot connect to Prowlarr"); + } + _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("ApiKey", "Unable to send test message"); + return new ValidationFailure("BaseUrl", "Unable to complete application test"); } catch (Exception ex) { diff --git a/src/NzbDrone.Core/Applications/Radarr/Radarr.cs b/src/NzbDrone.Core/Applications/Radarr/Radarr.cs index 53cd71f62..94f293125 100644 --- a/src/NzbDrone.Core/Applications/Radarr/Radarr.cs +++ b/src/NzbDrone.Core/Applications/Radarr/Radarr.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using FluentValidation.Results; using Newtonsoft.Json.Linq; using NLog; @@ -31,7 +32,25 @@ namespace NzbDrone.Core.Applications.Radarr { var failures = new List(); - failures.AddIfNotNull(_radarrV3Proxy.Test(Settings)); + var testIndexer = new IndexerDefinition + { + Id = 0, + Name = "Test", + Protocol = DownloadProtocol.Usenet, + Capabilities = new IndexerCapabilities() + }; + + testIndexer.Capabilities.Categories.AddCategoryMapping(1, NewznabStandardCategory.Movies); + + try + { + failures.AddIfNotNull(_radarrV3Proxy.TestConnection(BuildRadarrIndexer(testIndexer, DownloadProtocol.Usenet), Settings)); + } + catch (WebException ex) + { + _logger.Error(ex, "Unable to send test message"); + failures.AddIfNotNull(new ValidationFailure("BaseUrl", "Unable to complete application test, cannot connect to Radarr")); + } return new ValidationResult(failures); } diff --git a/src/NzbDrone.Core/Applications/Radarr/RadarrSettings.cs b/src/NzbDrone.Core/Applications/Radarr/RadarrSettings.cs index 11c72cf48..9e7d25946 100644 --- a/src/NzbDrone.Core/Applications/Radarr/RadarrSettings.cs +++ b/src/NzbDrone.Core/Applications/Radarr/RadarrSettings.cs @@ -28,7 +28,7 @@ namespace NzbDrone.Core.Applications.Radarr public IEnumerable SyncCategories { get; set; } - [FieldDefinition(0, Label = "Prowlarr Server", HelpText = "Prowlarr server URL as Radarr sees it, including http(s):// and port if needed")] + [FieldDefinition(0, Label = "Prowlarr Server", HelpText = "Prowlarr server URL as Radarr sees it, including http(s)://, port, and urlbase if needed")] public string ProwlarrUrl { get; set; } [FieldDefinition(1, Label = "Radarr Server", HelpText = "Radarr server URL, including http(s):// and port if needed")] diff --git a/src/NzbDrone.Core/Applications/Radarr/RadarrV3Proxy.cs b/src/NzbDrone.Core/Applications/Radarr/RadarrV3Proxy.cs index 5d53fa1ae..2277f9d0e 100644 --- a/src/NzbDrone.Core/Applications/Radarr/RadarrV3Proxy.cs +++ b/src/NzbDrone.Core/Applications/Radarr/RadarrV3Proxy.cs @@ -17,7 +17,7 @@ namespace NzbDrone.Core.Applications.Radarr List GetIndexerSchema(RadarrSettings settings); void RemoveIndexer(int indexerId, RadarrSettings settings); RadarrIndexer UpdateIndexer(RadarrIndexer indexer, RadarrSettings settings); - ValidationFailure Test(RadarrSettings settings); + ValidationFailure TestConnection(RadarrIndexer indexer, RadarrSettings settings); } public class RadarrV3Proxy : IRadarrV3Proxy @@ -91,11 +91,15 @@ namespace NzbDrone.Core.Applications.Radarr return Execute(request); } - public ValidationFailure Test(RadarrSettings settings) + public ValidationFailure TestConnection(RadarrIndexer indexer, RadarrSettings settings) { + var request = BuildRequest(settings, $"/api/v3/indexer/test", HttpMethod.POST); + + request.SetContent(indexer.ToJson()); + try { - GetStatus(settings); + Execute(request); } catch (HttpException ex) { @@ -105,8 +109,14 @@ namespace NzbDrone.Core.Applications.Radarr return new ValidationFailure("ApiKey", "API Key is invalid"); } + if (ex.Response.StatusCode == HttpStatusCode.BadRequest) + { + _logger.Error(ex, "Prowlarr URL is invalid"); + return new ValidationFailure("ProwlarrUrl", "Prowlarr url is invalid, Radarr cannot connect to Prowlarr"); + } + _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("ApiKey", "Unable to send test message"); + return new ValidationFailure("BaseUrl", "Unable to complete application test"); } catch (Exception ex) { diff --git a/src/NzbDrone.Core/Applications/Readarr/Readarr.cs b/src/NzbDrone.Core/Applications/Readarr/Readarr.cs index d8759c2c4..405bcadbb 100644 --- a/src/NzbDrone.Core/Applications/Readarr/Readarr.cs +++ b/src/NzbDrone.Core/Applications/Readarr/Readarr.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using FluentValidation.Results; using Newtonsoft.Json.Linq; using NLog; @@ -31,7 +32,25 @@ namespace NzbDrone.Core.Applications.Readarr { var failures = new List(); - failures.AddIfNotNull(_readarrV1Proxy.Test(Settings)); + var testIndexer = new IndexerDefinition + { + Id = 0, + Name = "Test", + Protocol = DownloadProtocol.Usenet, + Capabilities = new IndexerCapabilities() + }; + + testIndexer.Capabilities.Categories.AddCategoryMapping(1, NewznabStandardCategory.Books); + + try + { + failures.AddIfNotNull(_readarrV1Proxy.TestConnection(BuildReadarrIndexer(testIndexer, DownloadProtocol.Usenet), Settings)); + } + catch (WebException ex) + { + _logger.Error(ex, "Unable to send test message"); + failures.AddIfNotNull(new ValidationFailure("BaseUrl", "Unable to complete application test, cannot connect to Readarr")); + } return new ValidationResult(failures); } diff --git a/src/NzbDrone.Core/Applications/Readarr/ReadarrSettings.cs b/src/NzbDrone.Core/Applications/Readarr/ReadarrSettings.cs index 0aad0c031..c159ea0ad 100644 --- a/src/NzbDrone.Core/Applications/Readarr/ReadarrSettings.cs +++ b/src/NzbDrone.Core/Applications/Readarr/ReadarrSettings.cs @@ -28,7 +28,7 @@ namespace NzbDrone.Core.Applications.Readarr public IEnumerable SyncCategories { get; set; } - [FieldDefinition(0, Label = "Prowlarr Server", HelpText = "Prowlarr server URL as Readarr sees it, including http(s):// and port if needed")] + [FieldDefinition(0, Label = "Prowlarr Server", HelpText = "Prowlarr server URL as Readarr sees it, including http(s)://, port, and urlbase if needed")] public string ProwlarrUrl { get; set; } [FieldDefinition(1, Label = "Readarr Server", HelpText = "Readarr server URL, including http(s):// and port if needed")] diff --git a/src/NzbDrone.Core/Applications/Readarr/ReadarrV1Proxy.cs b/src/NzbDrone.Core/Applications/Readarr/ReadarrV1Proxy.cs index f4e63aee5..64319e21d 100644 --- a/src/NzbDrone.Core/Applications/Readarr/ReadarrV1Proxy.cs +++ b/src/NzbDrone.Core/Applications/Readarr/ReadarrV1Proxy.cs @@ -17,7 +17,7 @@ namespace NzbDrone.Core.Applications.Readarr List GetIndexerSchema(ReadarrSettings settings); void RemoveIndexer(int indexerId, ReadarrSettings settings); ReadarrIndexer UpdateIndexer(ReadarrIndexer indexer, ReadarrSettings settings); - ValidationFailure Test(ReadarrSettings settings); + ValidationFailure TestConnection(ReadarrIndexer indexer, ReadarrSettings settings); } public class ReadarrV1Proxy : IReadarrV1Proxy @@ -91,11 +91,15 @@ namespace NzbDrone.Core.Applications.Readarr return Execute(request); } - public ValidationFailure Test(ReadarrSettings settings) + public ValidationFailure TestConnection(ReadarrIndexer indexer, ReadarrSettings settings) { + var request = BuildRequest(settings, $"/api/v1/indexer/test", HttpMethod.POST); + + request.SetContent(indexer.ToJson()); + try { - GetStatus(settings); + Execute(request); } catch (HttpException ex) { @@ -105,8 +109,14 @@ namespace NzbDrone.Core.Applications.Readarr return new ValidationFailure("ApiKey", "API Key is invalid"); } + if (ex.Response.StatusCode == HttpStatusCode.BadRequest) + { + _logger.Error(ex, "Prowlarr URL is invalid"); + return new ValidationFailure("ProwlarrUrl", "Prowlarr url is invalid, Readarr cannot connect to Prowlarr"); + } + _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("ApiKey", "Unable to send test message"); + return new ValidationFailure("BaseUrl", "Unable to complete application test"); } catch (Exception ex) { diff --git a/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs b/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs index 6dc2fcf09..16fe2c641 100644 --- a/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs +++ b/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using FluentValidation.Results; using Newtonsoft.Json.Linq; using NLog; @@ -31,7 +32,25 @@ namespace NzbDrone.Core.Applications.Sonarr { var failures = new List(); - failures.AddIfNotNull(_sonarrV3Proxy.Test(Settings)); + var testIndexer = new IndexerDefinition + { + Id = 0, + Name = "Test", + Protocol = DownloadProtocol.Usenet, + Capabilities = new IndexerCapabilities() + }; + + testIndexer.Capabilities.Categories.AddCategoryMapping(1, NewznabStandardCategory.TV); + + try + { + failures.AddIfNotNull(_sonarrV3Proxy.TestConnection(BuildSonarrIndexer(testIndexer, DownloadProtocol.Usenet), Settings)); + } + catch (WebException ex) + { + _logger.Error(ex, "Unable to send test message"); + failures.AddIfNotNull(new ValidationFailure("BaseUrl", "Unable to complete application test, cannot connect to Sonarr")); + } return new ValidationResult(failures); } diff --git a/src/NzbDrone.Core/Applications/Sonarr/SonarrSettings.cs b/src/NzbDrone.Core/Applications/Sonarr/SonarrSettings.cs index f3b2a9446..eb12b7c6f 100644 --- a/src/NzbDrone.Core/Applications/Sonarr/SonarrSettings.cs +++ b/src/NzbDrone.Core/Applications/Sonarr/SonarrSettings.cs @@ -28,7 +28,7 @@ namespace NzbDrone.Core.Applications.Sonarr public IEnumerable SyncCategories { get; set; } - [FieldDefinition(0, Label = "Prowlarr Server", HelpText = "Prowlarr server URL as Sonarr sees it, including http(s):// and port if needed")] + [FieldDefinition(0, Label = "Prowlarr Server", HelpText = "Prowlarr server URL as Sonarr sees it, including http(s)://, port, and urlbase if needed")] public string ProwlarrUrl { get; set; } [FieldDefinition(1, Label = "Sonarr Server", HelpText = "Sonarr server URL, including http(s):// and port if needed")] diff --git a/src/NzbDrone.Core/Applications/Sonarr/SonarrV3Proxy.cs b/src/NzbDrone.Core/Applications/Sonarr/SonarrV3Proxy.cs index d06780c12..a42ec5a2c 100644 --- a/src/NzbDrone.Core/Applications/Sonarr/SonarrV3Proxy.cs +++ b/src/NzbDrone.Core/Applications/Sonarr/SonarrV3Proxy.cs @@ -17,7 +17,7 @@ namespace NzbDrone.Core.Applications.Sonarr List GetIndexerSchema(SonarrSettings settings); void RemoveIndexer(int indexerId, SonarrSettings settings); SonarrIndexer UpdateIndexer(SonarrIndexer indexer, SonarrSettings settings); - ValidationFailure Test(SonarrSettings settings); + ValidationFailure TestConnection(SonarrIndexer indexer, SonarrSettings settings); } public class SonarrV3Proxy : ISonarrV3Proxy @@ -91,11 +91,15 @@ namespace NzbDrone.Core.Applications.Sonarr return Execute(request); } - public ValidationFailure Test(SonarrSettings settings) + public ValidationFailure TestConnection(SonarrIndexer indexer, SonarrSettings settings) { + var request = BuildRequest(settings, $"/api/v3/indexer/test", HttpMethod.POST); + + request.SetContent(indexer.ToJson()); + try { - GetStatus(settings); + Execute(request); } catch (HttpException ex) { @@ -105,8 +109,14 @@ namespace NzbDrone.Core.Applications.Sonarr return new ValidationFailure("ApiKey", "API Key is invalid"); } + if (ex.Response.StatusCode == HttpStatusCode.BadRequest) + { + _logger.Error(ex, "Prowlarr URL is invalid"); + return new ValidationFailure("ProwlarrUrl", "Prowlarr url is invalid, Sonarr cannot connect to Prowlarr"); + } + _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("ApiKey", "Unable to send test message"); + return new ValidationFailure("BaseUrl", "Unable to complete application test"); } catch (Exception ex) { diff --git a/src/Prowlarr.Api.V1/Indexers/NewznabController.cs b/src/Prowlarr.Api.V1/Indexers/NewznabController.cs index b5a7992e1..dc4ba2d93 100644 --- a/src/Prowlarr.Api.V1/Indexers/NewznabController.cs +++ b/src/Prowlarr.Api.V1/Indexers/NewznabController.cs @@ -62,6 +62,39 @@ namespace NzbDrone.Api.V1.Indexers } } + if (id == 0) + { + switch (requestType) + { + case "caps": + var caps = new IndexerCapabilities(); + foreach (var cat in NewznabStandardCategory.AllCats) + { + caps.Categories.AddCategoryMapping(1, cat); + } + + return Content(caps.ToXml(), "application/rss+xml"); + case "search": + case "tvsearch": + case "music": + case "book": + case "movie": + var results = new NewznabResults(); + results.Releases = new List + { + new ReleaseInfo + { + Title = "Test Release", + Guid = "https://prowlarr.com", + DownloadUrl = "https://prowlarr.com", + PublishDate = DateTime.Now + } + }; + + return Content(results.ToXml(DownloadProtocol.Usenet), "application/rss+xml"); + } + } + var indexer = _indexerFactory.Get(id); if (indexer == null)