new: smarter validation for newznab indexer settings
This commit is contained in:
parent
53cebdee17
commit
be3ec7ddb8
|
@ -1 +1,2 @@
|
||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/Environment/ExternalSources/Decompiler/DecompileMethodBodies/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -138,6 +138,7 @@
|
||||||
<Compile Include="IndexerTests\BasicRssParserFixture.cs" />
|
<Compile Include="IndexerTests\BasicRssParserFixture.cs" />
|
||||||
<Compile Include="IndexerTests\IndexerServiceFixture.cs" />
|
<Compile Include="IndexerTests\IndexerServiceFixture.cs" />
|
||||||
<Compile Include="IndexerTests\IntegrationTests\IndexerIntegrationTests.cs" />
|
<Compile Include="IndexerTests\IntegrationTests\IndexerIntegrationTests.cs" />
|
||||||
|
<Compile Include="IndexerTests\NewznabTests\NewznabSettingFixture.cs" />
|
||||||
<Compile Include="IndexerTests\XElementExtensionsFixture.cs" />
|
<Compile Include="IndexerTests\XElementExtensionsFixture.cs" />
|
||||||
<Compile Include="JobTests\JobRepositoryFixture.cs" />
|
<Compile Include="JobTests\JobRepositoryFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\LanguageSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\LanguageSpecificationFixture.cs" />
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
@ -7,6 +8,12 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
{
|
{
|
||||||
public class NewznabParser : RssParserBase
|
public class NewznabParser : RssParserBase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private static readonly string[] IgnoredErrors =
|
||||||
|
{
|
||||||
|
"Request limit reached",
|
||||||
|
};
|
||||||
|
|
||||||
protected override string GetNzbInfoUrl(XElement item)
|
protected override string GetNzbInfoUrl(XElement item)
|
||||||
{
|
{
|
||||||
return item.Comments().Replace("#comments", "");
|
return item.Comments().Replace("#comments", "");
|
||||||
|
@ -25,6 +32,23 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
return ParseSize(item.Description());
|
return ParseSize(item.Description());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<ReleaseInfo> 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<ReleaseInfo>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override ReleaseInfo PostProcessor(XElement item, ReleaseInfo currentResult)
|
protected override ReleaseInfo PostProcessor(XElement item, ReleaseInfo currentResult)
|
||||||
{
|
{
|
||||||
if (currentResult != null)
|
if (currentResult != null)
|
||||||
|
|
|
@ -15,10 +15,17 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
if (error == null) return;
|
if (error == null) return;
|
||||||
|
|
||||||
var code = Convert.ToInt32(error.Attribute("code").Value);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
|
@ -10,9 +11,25 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
{
|
{
|
||||||
public class NewznabSettingsValidator : AbstractValidator<NewznabSettings>
|
public class NewznabSettingsValidator : AbstractValidator<NewznabSettings>
|
||||||
{
|
{
|
||||||
|
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()
|
public NewznabSettingsValidator()
|
||||||
{
|
{
|
||||||
RuleFor(c => c.Url).ValidRootUrl();
|
RuleFor(c => c.Url).ValidRootUrl();
|
||||||
|
RuleFor(c => c.ApiKey).NotEmpty().When(ShouldHaveApiKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,14 @@ namespace NzbDrone.Core.Indexers
|
||||||
|
|
||||||
NewznabPreProcessor.Process(xml, url);
|
NewznabPreProcessor.Process(xml, url);
|
||||||
}
|
}
|
||||||
catch (ApiKeyException apiKeyException)
|
catch (ApiKeyException)
|
||||||
{
|
{
|
||||||
_logger.Warn("Indexer returned result for Newznab RSS URL, API Key appears to be invalid");
|
_logger.Warn("Indexer returned result for Newznab RSS URL, API Key appears to be invalid");
|
||||||
|
|
||||||
var apiKeyFailure = new ValidationFailure("ApiKey", "Invalid API Key");
|
var apiKeyFailure = new ValidationFailure("ApiKey", "Invalid API Key");
|
||||||
throw new ValidationException(new List<ValidationFailure> { apiKeyFailure }.ToArray());
|
throw new ValidationException(new List<ValidationFailure> { apiKeyFailure }.ToArray());
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
_logger.Warn("Indexer doesn't appear to be Newznab based");
|
_logger.Warn("Indexer doesn't appear to be Newznab based");
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
public abstract class RssParserBase : IParseFeed
|
public abstract class RssParserBase : IParseFeed
|
||||||
{
|
{
|
||||||
private readonly Logger _logger;
|
protected readonly Logger _logger;
|
||||||
|
|
||||||
protected virtual ReleaseInfo CreateNewReleaseInfo()
|
protected virtual ReleaseInfo CreateNewReleaseInfo()
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
_logger = NzbDroneLogger.GetLogger(this);
|
_logger = NzbDroneLogger.GetLogger(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ReleaseInfo> Process(string xml, string url)
|
public virtual IEnumerable<ReleaseInfo> Process(string xml, string url)
|
||||||
{
|
{
|
||||||
PreProcess(xml, url);
|
PreProcess(xml, url);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue