diff --git a/NzbDrone.sln.DotSettings b/NzbDrone.sln.DotSettings
index e7d45a2a8..4657be0e3 100644
--- a/NzbDrone.sln.DotSettings
+++ b/NzbDrone.sln.DotSettings
@@ -1 +1,2 @@
-
\ No newline at end of file
+
+ True
\ No newline at end of file
diff --git a/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabSettingFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabSettingFixture.cs
new file mode 100644
index 000000000..7ef91def5
--- /dev/null
+++ b/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabSettingFixture.cs
@@ -0,0 +1,41 @@
+using FluentAssertions;
+using NUnit.Framework;
+using NzbDrone.Core.Indexers.Newznab;
+using NzbDrone.Core.Test.Framework;
+
+namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
+{
+ public class NewznabSettingFixture : CoreTest
+ {
+
+ [TestCase("http://nzbs.org")]
+ [TestCase("http:///www.nzbplanet.net")]
+ public void requires_apikey(string url)
+ {
+ var setting = new NewznabSettings()
+ {
+ ApiKey = "",
+ Url = url
+ };
+
+
+ setting.Validate().IsValid.Should().BeFalse();
+ setting.Validate().Errors.Should().Contain(c => c.PropertyName == "ApiKey");
+
+ }
+
+
+ [TestCase("http://nzbs2.org")]
+ public void doesnt_requires_apikey(string url)
+ {
+ var setting = new NewznabSettings()
+ {
+ ApiKey = "",
+ Url = url
+ };
+
+
+ setting.Validate().IsValid.Should().BeTrue();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
index 6f0904eda..313d67d3a 100644
--- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
+++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
@@ -138,6 +138,7 @@
+
diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabParser.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabParser.cs
index 451c6222b..85fe2d4e4 100644
--- a/src/NzbDrone.Core/Indexers/Newznab/NewznabParser.cs
+++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabParser.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using NzbDrone.Core.Parser.Model;
@@ -7,6 +8,12 @@ namespace NzbDrone.Core.Indexers.Newznab
{
public class NewznabParser : RssParserBase
{
+
+ private static readonly string[] IgnoredErrors =
+ {
+ "Request limit reached",
+ };
+
protected override string GetNzbInfoUrl(XElement item)
{
return item.Comments().Replace("#comments", "");
@@ -25,6 +32,23 @@ namespace NzbDrone.Core.Indexers.Newznab
return ParseSize(item.Description());
}
+ public override IEnumerable Process(string xml, string url)
+ {
+ try
+ {
+ return base.Process(xml, url);
+ }
+ catch (NewznabException e)
+ {
+ if (!IgnoredErrors.Any(ignoredError => e.Message.Contains(ignoredError)))
+ {
+ throw;
+ }
+ _logger.Error(e.Message);
+ return new List();
+ }
+ }
+
protected override ReleaseInfo PostProcessor(XElement item, ReleaseInfo currentResult)
{
if (currentResult != null)
diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabPreProcessor.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabPreProcessor.cs
index 3977a2c75..4cd4d66c8 100644
--- a/src/NzbDrone.Core/Indexers/Newznab/NewznabPreProcessor.cs
+++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabPreProcessor.cs
@@ -15,10 +15,17 @@ namespace NzbDrone.Core.Indexers.Newznab
if (error == null) return;
var code = Convert.ToInt32(error.Attribute("code").Value);
+ var errorMessage = error.Attribute("description").Value;
- if (code >= 100 && code <= 199) throw new ApiKeyException("Invalid API key: {0}");
- throw new NewznabException("Newznab error detected: {0}", error.Attribute("description").Value);
+ if (code >= 100 && code <= 199) throw new ApiKeyException("Invalid API key");
+
+ if (!url.Contains("apikey=") && errorMessage == "Missing parameter")
+ {
+ throw new ApiKeyException("Indexer requires and API key");
+ }
+
+ throw new NewznabException("Newznab error detected: {0}", errorMessage);
}
}
}
diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs
index c66dcf56e..c5a0eb230 100644
--- a/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs
+++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using FluentValidation;
using FluentValidation.Results;
using NzbDrone.Core.Annotations;
@@ -10,9 +11,25 @@ namespace NzbDrone.Core.Indexers.Newznab
{
public class NewznabSettingsValidator : AbstractValidator
{
+ private static readonly string[] ApiKeyWhiteList =
+ {
+ "nzbs.org",
+ "nzb.su",
+ "dognzb.cr",
+ "nzbplanet.net",
+ "nzbid.org",
+ "nzbndx.com",
+ };
+
+ private static bool ShouldHaveApiKey(NewznabSettings settings)
+ {
+ return ApiKeyWhiteList.Any(c => settings.Url.ToLowerInvariant().Contains(c));
+ }
+
public NewznabSettingsValidator()
{
RuleFor(c => c.Url).ValidRootUrl();
+ RuleFor(c => c.ApiKey).NotEmpty().When(ShouldHaveApiKey);
}
}
diff --git a/src/NzbDrone.Core/Indexers/NewznabTestService.cs b/src/NzbDrone.Core/Indexers/NewznabTestService.cs
index c56b9b464..9055aa5e7 100644
--- a/src/NzbDrone.Core/Indexers/NewznabTestService.cs
+++ b/src/NzbDrone.Core/Indexers/NewznabTestService.cs
@@ -41,14 +41,14 @@ namespace NzbDrone.Core.Indexers
NewznabPreProcessor.Process(xml, url);
}
- catch (ApiKeyException apiKeyException)
+ catch (ApiKeyException)
{
_logger.Warn("Indexer returned result for Newznab RSS URL, API Key appears to be invalid");
var apiKeyFailure = new ValidationFailure("ApiKey", "Invalid API Key");
throw new ValidationException(new List { apiKeyFailure }.ToArray());
}
- catch (Exception ex)
+ catch (Exception)
{
_logger.Warn("Indexer doesn't appear to be Newznab based");
diff --git a/src/NzbDrone.Core/Indexers/RssParserBase.cs b/src/NzbDrone.Core/Indexers/RssParserBase.cs
index 7eae9a117..1065631aa 100644
--- a/src/NzbDrone.Core/Indexers/RssParserBase.cs
+++ b/src/NzbDrone.Core/Indexers/RssParserBase.cs
@@ -15,7 +15,7 @@ namespace NzbDrone.Core.Indexers
{
public abstract class RssParserBase : IParseFeed
{
- private readonly Logger _logger;
+ protected readonly Logger _logger;
protected virtual ReleaseInfo CreateNewReleaseInfo()
{
@@ -27,7 +27,7 @@ namespace NzbDrone.Core.Indexers
_logger = NzbDroneLogger.GetLogger(this);
}
- public IEnumerable Process(string xml, string url)
+ public virtual IEnumerable Process(string xml, string url)
{
PreProcess(xml, url);