mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-12 11:15:43 +02:00
Translate Indexers on the backend
This commit is contained in:
parent
e68b13940d
commit
f205cfabab
@ -11,6 +11,7 @@
|
|||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
@ -70,7 +71,8 @@ protected virtual IIndexer CreateIndexer()
|
|||||||
Mocker.Resolve<IIndexerStatusService>(),
|
Mocker.Resolve<IIndexerStatusService>(),
|
||||||
Mocker.Resolve<IConfigService>(),
|
Mocker.Resolve<IConfigService>(),
|
||||||
Mocker.Resolve<IParsingService>(),
|
Mocker.Resolve<IParsingService>(),
|
||||||
Mocker.Resolve<Logger>());
|
Mocker.Resolve<Logger>(),
|
||||||
|
Mocker.Resolve<ILocalizationService>());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void VerifyIdentifiable(DownloadClientItem downloadClientItem)
|
protected void VerifyIdentifiable(DownloadClientItem downloadClientItem)
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Download.Clients.Pneumatic;
|
using NzbDrone.Core.Download.Clients.Pneumatic;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
@ -51,7 +52,8 @@ public void Setup()
|
|||||||
Mocker.Resolve<IIndexerStatusService>(),
|
Mocker.Resolve<IIndexerStatusService>(),
|
||||||
Mocker.Resolve<IConfigService>(),
|
Mocker.Resolve<IConfigService>(),
|
||||||
Mocker.Resolve<IParsingService>(),
|
Mocker.Resolve<IParsingService>(),
|
||||||
Mocker.Resolve<Logger>());
|
Mocker.Resolve<Logger>(),
|
||||||
|
Mocker.Resolve<ILocalizationService>());
|
||||||
|
|
||||||
_downloadClientItem = Builder<DownloadClientItem>
|
_downloadClientItem = Builder<DownloadClientItem>
|
||||||
.CreateNew().With(d => d.DownloadId = "_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0")
|
.CreateNew().With(d => d.DownloadId = "_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0")
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.IndexerTests
|
namespace NzbDrone.Core.Test.IndexerTests
|
||||||
@ -15,8 +16,8 @@ public class TestIndexer : HttpIndexerBase<TestIndexerSettings>
|
|||||||
public int _supportedPageSize;
|
public int _supportedPageSize;
|
||||||
public override int PageSize => _supportedPageSize;
|
public override int PageSize => _supportedPageSize;
|
||||||
|
|
||||||
public TestIndexer(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public TestIndexer(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,14 +7,15 @@
|
|||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Indexers.TorrentRss;
|
using NzbDrone.Core.Indexers.TorrentRss;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||||
{
|
{
|
||||||
public class TestTorrentRssIndexer : TorrentRssIndexer
|
public class TestTorrentRssIndexer : TorrentRssIndexer
|
||||||
{
|
{
|
||||||
public TestTorrentRssIndexer(ITorrentRssParserFactory torrentRssParserFactory, IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public TestTorrentRssIndexer(ITorrentRssParserFactory torrentRssParserFactory, IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(torrentRssParserFactory, httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(torrentRssParserFactory, httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.BroadcastheNet
|
namespace NzbDrone.Core.Indexers.BroadcastheNet
|
||||||
@ -14,8 +15,8 @@ public class BroadcastheNet : HttpIndexerBase<BroadcastheNetSettings>
|
|||||||
public override bool SupportsSearch => true;
|
public override bool SupportsSearch => true;
|
||||||
public override int PageSize => 100;
|
public override int PageSize => 100;
|
||||||
|
|
||||||
public BroadcastheNet(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public BroadcastheNet(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +25,13 @@ public BroadcastheNetSettings()
|
|||||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your API key will be sent to that host.")]
|
[FieldDefinition(0, Label = "IndexerSettingsApiUrl", Advanced = true, HelpText = "IndexerSettingsApiUrlHelpText")]
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "API Key", Privacy = PrivacyLevel.ApiKey)]
|
[FieldDefinition(1, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey)]
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
|
[FieldDefinition(2, Type = FieldType.Number, Label = "IndexerSettingsMinimumSeeders", HelpText = "IndexerSettingsMinimumSeedersHelpText", Advanced = true)]
|
||||||
public int MinimumSeeders { get; set; }
|
public int MinimumSeeders { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3)]
|
[FieldDefinition(3)]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Fanzub
|
namespace NzbDrone.Core.Indexers.Fanzub
|
||||||
@ -11,8 +12,8 @@ public class Fanzub : HttpIndexerBase<FanzubSettings>
|
|||||||
|
|
||||||
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
|
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
|
||||||
|
|
||||||
public Fanzub(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public Fanzub(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,10 +21,11 @@ public FanzubSettings()
|
|||||||
BaseUrl = "http://fanzub.com/rss/";
|
BaseUrl = "http://fanzub.com/rss/";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Rss URL", HelpText = "Enter to URL to an Fanzub compatible RSS feed")]
|
[FieldDefinition(0, Label = "IndexerSettingsRssUrl", HelpText = "IndexerSettingsRssUrlHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "IndexerSettingsRssUrl", "indexer", "Fanzub")]
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Anime Standard Format Search", Type = FieldType.Checkbox, HelpText = "Also search for anime using the standard numbering")]
|
[FieldDefinition(1, Label = "IndexerSettingsAnimeStandardFormatSearch", Type = FieldType.Checkbox, HelpText = "IndexerSettingsAnimeStandardFormatSearchHelpText")]
|
||||||
public bool AnimeStandardFormatSearch { get; set; }
|
public bool AnimeStandardFormatSearch { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.FileList
|
namespace NzbDrone.Core.Indexers.FileList
|
||||||
@ -12,8 +13,8 @@ public class FileList : HttpIndexerBase<FileListSettings>
|
|||||||
public override bool SupportsRss => true;
|
public override bool SupportsRss => true;
|
||||||
public override bool SupportsSearch => true;
|
public override bool SupportsSearch => true;
|
||||||
|
|
||||||
public FileList(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public FileList(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,19 +40,19 @@ public FileListSettings()
|
|||||||
[FieldDefinition(0, Label = "Username", Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(0, Label = "Username", Privacy = PrivacyLevel.UserName)]
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Passkey", Privacy = PrivacyLevel.ApiKey)]
|
[FieldDefinition(1, Label = "IndexerSettingsPasskey", Privacy = PrivacyLevel.ApiKey)]
|
||||||
public string Passkey { get; set; }
|
public string Passkey { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your API key will be sent to that host.")]
|
[FieldDefinition(3, Label = "IndexerSettingsApiUrl", Advanced = true, HelpText = "IndexerSettingsApiUrlHelpText")]
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Categories", Type = FieldType.Select, SelectOptions = typeof(FileListCategories), HelpText = "Categories for use in search and feeds, leave blank to disable standard/daily shows")]
|
[FieldDefinition(4, Label = "IndexerSettingsCategories", Type = FieldType.Select, SelectOptions = typeof(FileListCategories), HelpText = "IndexerSettingsCategoriesHelpText")]
|
||||||
public IEnumerable<int> Categories { get; set; }
|
public IEnumerable<int> Categories { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "Anime Categories", Type = FieldType.Select, SelectOptions = typeof(FileListCategories), HelpText = "Categories for use in search and feeds, leave blank to disable anime")]
|
[FieldDefinition(5, Label = "IndexerSettingsAnimeCategories", Type = FieldType.Select, SelectOptions = typeof(FileListCategories), HelpText = "IndexerSettingsAnimeCategoriesHelpText")]
|
||||||
public IEnumerable<int> AnimeCategories { get; set; }
|
public IEnumerable<int> AnimeCategories { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
|
[FieldDefinition(6, Type = FieldType.Number, Label = "IndexerSettingsMinimumSeeders", HelpText = "IndexerSettingsMinimumSeedersHelpText", Advanced = true)]
|
||||||
public int MinimumSeeders { get; set; }
|
public int MinimumSeeders { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7)]
|
[FieldDefinition(7)]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.HDBits
|
namespace NzbDrone.Core.Indexers.HDBits
|
||||||
@ -13,8 +14,8 @@ public class HDBits : HttpIndexerBase<HDBitsSettings>
|
|||||||
public override bool SupportsSearch => true;
|
public override bool SupportsSearch => true;
|
||||||
public override int PageSize => 30;
|
public override int PageSize => 30;
|
||||||
|
|
||||||
public HDBits(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public HDBits(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,13 +28,13 @@ public HDBitsSettings()
|
|||||||
[FieldDefinition(0, Label = "Username", Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(0, Label = "Username", Privacy = PrivacyLevel.UserName)]
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "API Key", Privacy = PrivacyLevel.ApiKey)]
|
[FieldDefinition(1, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey)]
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your API key will be sent to that host.")]
|
[FieldDefinition(2, Label = "IndexerSettingsApiUrl", Advanced = true, HelpText = "IndexerSettingsApiUrlHelpText")]
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
|
[FieldDefinition(3, Type = FieldType.Number, Label = "IndexerSettingsMinimumSeeders", HelpText = "IndexerSettingsMinimumSeedersHelpText", Advanced = true)]
|
||||||
public int MinimumSeeders { get; set; }
|
public int MinimumSeeders { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4)]
|
[FieldDefinition(4)]
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
using NzbDrone.Core.Http.CloudFlare;
|
using NzbDrone.Core.Http.CloudFlare;
|
||||||
using NzbDrone.Core.Indexers.Exceptions;
|
using NzbDrone.Core.Indexers.Exceptions;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
@ -34,8 +35,8 @@ public abstract class HttpIndexerBase<TSettings> : IndexerBase<TSettings>
|
|||||||
public abstract IIndexerRequestGenerator GetRequestGenerator();
|
public abstract IIndexerRequestGenerator GetRequestGenerator();
|
||||||
public abstract IParseIndexerResponse GetParser();
|
public abstract IParseIndexerResponse GetParser();
|
||||||
|
|
||||||
public HttpIndexerBase(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public HttpIndexerBase(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(indexerStatusService, configService, parsingService, logger)
|
: base(indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
}
|
}
|
||||||
@ -376,50 +377,50 @@ protected virtual async Task<ValidationFailure> TestConnection()
|
|||||||
|
|
||||||
if (firstRequest == null)
|
if (firstRequest == null)
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "No rss feed query available. This may be an issue with the indexer or your indexer category settings.");
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationJackettNoRssFeedQueryAvailable"));
|
||||||
}
|
}
|
||||||
|
|
||||||
var releases = await FetchPage(firstRequest, parser);
|
var releases = await FetchPage(firstRequest, parser);
|
||||||
|
|
||||||
if (releases.Empty())
|
if (releases.Empty())
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "Query successful, but no results in the configured categories were returned from your indexer. This may be an issue with the indexer or your indexer category settings.");
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationJackettNoResultsInConfiguredCategories"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ApiKeyException ex)
|
catch (ApiKeyException ex)
|
||||||
{
|
{
|
||||||
_logger.Warn("Indexer returned result for RSS URL, API Key appears to be invalid: " + ex.Message);
|
_logger.Warn("Indexer returned result for RSS URL, API Key appears to be invalid: " + ex.Message);
|
||||||
|
|
||||||
return new ValidationFailure("ApiKey", "Invalid API Key");
|
return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("IndexerValidationInvalidApiKey"));
|
||||||
}
|
}
|
||||||
catch (RequestLimitReachedException ex)
|
catch (RequestLimitReachedException ex)
|
||||||
{
|
{
|
||||||
_logger.Warn("Request limit reached: " + ex.Message);
|
_logger.Warn("Request limit reached: " + ex.Message);
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, "Request limit reached: " + ex.Message);
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationRequestLimitReached", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
catch (CloudFlareCaptchaException ex)
|
catch (CloudFlareCaptchaException ex)
|
||||||
{
|
{
|
||||||
if (ex.IsExpired)
|
if (ex.IsExpired)
|
||||||
{
|
{
|
||||||
return new ValidationFailure("CaptchaToken", "CloudFlare CAPTCHA token expired, please Refresh.");
|
return new ValidationFailure("CaptchaToken", _localizationService.GetLocalizedString("IndexerValidationCloudFlareCaptchaExpired"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new ValidationFailure("CaptchaToken", "Site protected by CloudFlare CAPTCHA. Valid CAPTCHA token required.");
|
return new ValidationFailure("CaptchaToken", _localizationService.GetLocalizedString("IndexerValidationCloudFlareCaptchaRequired"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (UnsupportedFeedException ex)
|
catch (UnsupportedFeedException ex)
|
||||||
{
|
{
|
||||||
_logger.Warn(ex, "Indexer feed is not supported");
|
_logger.Warn(ex, "Indexer feed is not supported");
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, "Indexer feed is not supported: " + ex.Message);
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationFeedNotSupported", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
catch (IndexerException ex)
|
catch (IndexerException ex)
|
||||||
{
|
{
|
||||||
_logger.Warn(ex, "Unable to connect to indexer");
|
_logger.Warn(ex, "Unable to connect to indexer");
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, "Unable to connect to indexer. " + ex.Message);
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnect", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
catch (HttpException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
@ -427,33 +428,33 @@ protected virtual async Task<ValidationFailure> TestConnection()
|
|||||||
ex.Response.Content.Contains("not support the requested query"))
|
ex.Response.Content.Contains("not support the requested query"))
|
||||||
{
|
{
|
||||||
_logger.Warn(ex, "Indexer does not support the query");
|
_logger.Warn(ex, "Indexer does not support the query");
|
||||||
return new ValidationFailure(string.Empty, "Indexer does not support the current query. Check if the categories and or searching for seasons/episodes are supported. Check the log for more details.");
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationQueryNotSupported"));
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Warn(ex, "Unable to connect to indexer");
|
_logger.Warn(ex, "Unable to connect to indexer");
|
||||||
if (ex.Response.HasHttpServerError)
|
if (ex.Response.HasHttpServerError)
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "Unable to connect to indexer, indexer's server is unavailable. Try again later. " + ex.Message);
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnectServerUnavailable", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ex.Response.StatusCode is HttpStatusCode.Forbidden or HttpStatusCode.Unauthorized)
|
if (ex.Response.StatusCode is HttpStatusCode.Forbidden or HttpStatusCode.Unauthorized)
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "Unable to connect to indexer, invalid credentials. " + ex.Message);
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnectInvalidCredentials", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, "Unable to connect to indexer, check the log above the ValidationFailure for more details. " + ex.Message);
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnect", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
catch (HttpRequestException ex)
|
catch (HttpRequestException ex)
|
||||||
{
|
{
|
||||||
_logger.Warn(ex, "Unable to connect to indexer");
|
_logger.Warn(ex, "Unable to connect to indexer");
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, "Unable to connect to indexer, please check your DNS settings and ensure IPv6 is working or disabled. " + ex.Message);
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnectHttpError", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException ex)
|
catch (TaskCanceledException ex)
|
||||||
{
|
{
|
||||||
_logger.Warn(ex, "Unable to connect to indexer");
|
_logger.Warn(ex, "Unable to connect to indexer");
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, "Unable to connect to indexer, possibly due to a timeout. Try again or check your network settings. " + ex.Message);
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnectTimeout", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
catch (WebException webException)
|
catch (WebException webException)
|
||||||
{
|
{
|
||||||
@ -461,20 +462,20 @@ protected virtual async Task<ValidationFailure> TestConnection()
|
|||||||
|
|
||||||
if (webException.Status is WebExceptionStatus.NameResolutionFailure or WebExceptionStatus.ConnectFailure)
|
if (webException.Status is WebExceptionStatus.NameResolutionFailure or WebExceptionStatus.ConnectFailure)
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "Unable to connect to indexer connection failure. Check your connection to the indexer's server and DNS." + webException.Message);
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnectResolutionFailure", new Dictionary<string, object> { { "exceptionMessage", webException.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (webException.Message.Contains("502") || webException.Message.Contains("503") ||
|
if (webException.Message.Contains("502") || webException.Message.Contains("503") ||
|
||||||
webException.Message.Contains("504") || webException.Message.Contains("timed out"))
|
webException.Message.Contains("504") || webException.Message.Contains("timed out"))
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "Unable to connect to indexer, indexer's server is unavailable. Try again later. " + webException.Message);
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnectServerUnavailable", new Dictionary<string, object> { { "exceptionMessage", webException.Message } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Warn(ex, "Unable to connect to indexer");
|
_logger.Warn(ex, "Unable to connect to indexer");
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, $"Unable to connect to indexer: {ex.Message}. Check the log surrounding this error for details");
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnect", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.IPTorrents
|
namespace NzbDrone.Core.Indexers.IPTorrents
|
||||||
@ -13,8 +14,8 @@ public class IPTorrents : HttpIndexerBase<IPTorrentsSettings>
|
|||||||
public override bool SupportsSearch => false;
|
public override bool SupportsSearch => false;
|
||||||
public override int PageSize => 0;
|
public override int PageSize => 0;
|
||||||
|
|
||||||
public IPTorrents(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public IPTorrents(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,10 +31,10 @@ public IPTorrentsSettings()
|
|||||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Feed URL", HelpText = "The full RSS feed url generated by IPTorrents, using only the categories you selected (HD, SD, x264, etc ...)")]
|
[FieldDefinition(0, Label = "IndexerIPTorrentsSettingsFeedUrl", HelpText = "IndexerIPTorrentsSettingsFeedUrlHelpText")]
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
|
[FieldDefinition(1, Type = FieldType.Number, Label = "IndexerSettingsMinimumSeeders", HelpText = "IndexerSettingsMinimumSeedersHelpText", Advanced = true)]
|
||||||
public int MinimumSeeders { get; set; }
|
public int MinimumSeeders { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2)]
|
[FieldDefinition(2)]
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
@ -20,6 +21,7 @@ public abstract class IndexerBase<TSettings> : IIndexer
|
|||||||
protected readonly IConfigService _configService;
|
protected readonly IConfigService _configService;
|
||||||
protected readonly IParsingService _parsingService;
|
protected readonly IParsingService _parsingService;
|
||||||
protected readonly Logger _logger;
|
protected readonly Logger _logger;
|
||||||
|
protected readonly ILocalizationService _localizationService;
|
||||||
|
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
public abstract DownloadProtocol Protocol { get; }
|
public abstract DownloadProtocol Protocol { get; }
|
||||||
@ -29,12 +31,13 @@ public abstract class IndexerBase<TSettings> : IIndexer
|
|||||||
public abstract bool SupportsRss { get; }
|
public abstract bool SupportsRss { get; }
|
||||||
public abstract bool SupportsSearch { get; }
|
public abstract bool SupportsSearch { get; }
|
||||||
|
|
||||||
public IndexerBase(IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public IndexerBase(IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
{
|
{
|
||||||
_indexerStatusService = indexerStatusService;
|
_indexerStatusService = indexerStatusService;
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_parsingService = parsingService;
|
_parsingService = parsingService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_localizationService = localizationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type ConfigContract => typeof(TSettings);
|
public Type ConfigContract => typeof(TSettings);
|
||||||
@ -105,7 +108,7 @@ public ValidationResult Test()
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Test aborted due to exception");
|
_logger.Error(ex, "Test aborted due to exception");
|
||||||
failures.Add(new ValidationFailure(string.Empty, "Test was aborted due to an error: " + ex.Message));
|
failures.Add(new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationTestAbortedDueToError", new Dictionary<string, object> { { "exceptionMessage", ex.Message } })));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ValidationResult(failures);
|
return new ValidationResult(failures);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
@ -22,8 +23,8 @@ public class Newznab : HttpIndexerBase<NewznabSettings>
|
|||||||
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
|
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
|
||||||
public override int PageSize => GetProviderPageSize();
|
public override int PageSize => GetProviderPageSize();
|
||||||
|
|
||||||
public Newznab(INewznabCapabilitiesProvider capabilitiesProvider, IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public Newznab(INewznabCapabilitiesProvider capabilitiesProvider, IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_capabilitiesProvider = capabilitiesProvider;
|
_capabilitiesProvider = capabilitiesProvider;
|
||||||
}
|
}
|
||||||
@ -129,13 +130,13 @@ protected virtual ValidationFailure TestCapabilities()
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, "Indexer does not support required search parameters");
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationSearchParametersNotSupported"));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Warn(ex, "Unable to connect to indexer: " + ex.Message);
|
_logger.Warn(ex, "Unable to connect to indexer: " + ex.Message);
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, $"Unable to connect to indexer: {ex.Message}. Check the log surrounding this error for details");
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnect", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,22 +60,23 @@ public NewznabSettings()
|
|||||||
[FieldDefinition(0, Label = "URL")]
|
[FieldDefinition(0, Label = "URL")]
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "API Path", HelpText = "Path to the api, usually /api", Advanced = true)]
|
[FieldDefinition(1, Label = "IndexerSettingsApiPath", HelpText = "IndexerSettingsApiPathHelpText", Advanced = true)]
|
||||||
|
[FieldToken(TokenField.HelpText, "IndexerSettingsApiPath", "url", "/api")]
|
||||||
public string ApiPath { get; set; }
|
public string ApiPath { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "API Key", Privacy = PrivacyLevel.ApiKey)]
|
[FieldDefinition(2, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey)]
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Categories", Type = FieldType.Select, SelectOptionsProviderAction = "newznabCategories", HelpText = "Drop down list, leave blank to disable standard/daily shows")]
|
[FieldDefinition(3, Label = "IndexerSettingsCategories", Type = FieldType.Select, SelectOptionsProviderAction = "newznabCategories", HelpText = "IndexerSettingsCategoriesHelpText")]
|
||||||
public IEnumerable<int> Categories { get; set; }
|
public IEnumerable<int> Categories { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Anime Categories", Type = FieldType.Select, SelectOptionsProviderAction = "newznabCategories", HelpText = "Drop down list, leave blank to disable anime")]
|
[FieldDefinition(4, Label = "IndexerSettingsAnimeCategories", Type = FieldType.Select, SelectOptionsProviderAction = "newznabCategories", HelpText = "IndexerSettingsAnimeCategoriesHelpText")]
|
||||||
public IEnumerable<int> AnimeCategories { get; set; }
|
public IEnumerable<int> AnimeCategories { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "Anime Standard Format Search", Type = FieldType.Checkbox, HelpText = "Also search for anime using the standard numbering")]
|
[FieldDefinition(5, Label = "IndexerSettingsAnimeStandardFormatSearch", Type = FieldType.Checkbox, HelpText = "IndexerSettingsAnimeStandardFormatSearchHelpText")]
|
||||||
public bool AnimeStandardFormatSearch { get; set; }
|
public bool AnimeStandardFormatSearch { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Additional Parameters", HelpText = "Additional Newznab parameters", Advanced = true)]
|
[FieldDefinition(6, Label = "IndexerSettingsAdditionalParameters", HelpText = "IndexerSettingsAdditionalNewznabParametersHelpText", Advanced = true)]
|
||||||
public string AdditionalParameters { get; set; }
|
public string AdditionalParameters { get; set; }
|
||||||
|
|
||||||
// Field 7 is used by TorznabSettings MinimumSeeders
|
// Field 7 is used by TorznabSettings MinimumSeeders
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Nyaa
|
namespace NzbDrone.Core.Indexers.Nyaa
|
||||||
@ -12,8 +13,8 @@ public class Nyaa : HttpIndexerBase<NyaaSettings>
|
|||||||
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
||||||
public override int PageSize => 100;
|
public override int PageSize => 100;
|
||||||
|
|
||||||
public Nyaa(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public Nyaa(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,16 +27,16 @@ public NyaaSettings()
|
|||||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Website URL")]
|
[FieldDefinition(0, Label = "IndexerSettingsWebsiteUrl")]
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Anime Standard Format Search", Type = FieldType.Checkbox, HelpText = "Also search for anime using the standard numbering")]
|
[FieldDefinition(1, Label = "IndexerSettingsAnimeStandardFormatSearch", Type = FieldType.Checkbox, HelpText = "IndexerSettingsAnimeStandardFormatSearchHelpText")]
|
||||||
public bool AnimeStandardFormatSearch { get; set; }
|
public bool AnimeStandardFormatSearch { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Additional Parameters", Advanced = true, HelpText = "Please note if you change the category you will have to add required/restricted rules about the subgroups to avoid foreign language releases.")]
|
[FieldDefinition(2, Label = "IndexerSettingsAdditionalParameters", Advanced = true, HelpText = "IndexerSettingsAdditionalNewznabParametersHelpText")]
|
||||||
public string AdditionalParameters { get; set; }
|
public string AdditionalParameters { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
|
[FieldDefinition(3, Type = FieldType.Number, Label = "IndexerSettingsMinimumSeeders", HelpText = "IndexerSettingsMinimumSeedersHelpText", Advanced = true)]
|
||||||
public int MinimumSeeders { get; set; }
|
public int MinimumSeeders { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4)]
|
[FieldDefinition(4)]
|
||||||
|
@ -48,13 +48,13 @@ public SeedCriteriaSettingsValidator(double seedRatioMinimum = 0.0, int seedTime
|
|||||||
|
|
||||||
public class SeedCriteriaSettings
|
public class SeedCriteriaSettings
|
||||||
{
|
{
|
||||||
[FieldDefinition(0, Type = FieldType.Textbox, Label = "Seed Ratio", HelpText = "The ratio a torrent should reach before stopping, empty is download client's default. Ratio should be at least 1.0 and follow the indexers rules")]
|
[FieldDefinition(0, Type = FieldType.Textbox, Label = "IndexerSettingsSeedRatio", HelpText = "IndexerSettingsSeedRatioHelpText")]
|
||||||
public double? SeedRatio { get; set; }
|
public double? SeedRatio { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Type = FieldType.Number, Label = "Seed Time", Unit = "minutes", HelpText = "The time a torrent should be seeded before stopping, empty is download client's default", Advanced = true)]
|
[FieldDefinition(1, Type = FieldType.Number, Label = "IndexerSettingsSeedTime", Unit = "minutes", HelpText = "IndexerSettingsSeedTimeHelpText", Advanced = true)]
|
||||||
public int? SeedTime { get; set; }
|
public int? SeedTime { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Type = FieldType.Number, Label = "Season-Pack Seed Time", Unit = "minutes", HelpText = "The time a torrent should be seeded before stopping, empty is download client's default", Advanced = true)]
|
[FieldDefinition(2, Type = FieldType.Number, Label = "Season-Pack Seed Time", Unit = "minutes", HelpText = "IndexerSettingsSeasonPackSeedTimeHelpText", Advanced = true)]
|
||||||
public int? SeasonPackSeedTime { get; set; }
|
public int? SeasonPackSeedTime { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.TorrentRss
|
namespace NzbDrone.Core.Indexers.TorrentRss
|
||||||
@ -15,8 +16,8 @@ public class TorrentRssIndexer : HttpIndexerBase<TorrentRssIndexerSettings>
|
|||||||
|
|
||||||
private readonly ITorrentRssParserFactory _torrentRssParserFactory;
|
private readonly ITorrentRssParserFactory _torrentRssParserFactory;
|
||||||
|
|
||||||
public TorrentRssIndexer(ITorrentRssParserFactory torrentRssParserFactory, IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public TorrentRssIndexer(ITorrentRssParserFactory torrentRssParserFactory, IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_torrentRssParserFactory = torrentRssParserFactory;
|
_torrentRssParserFactory = torrentRssParserFactory;
|
||||||
}
|
}
|
||||||
|
@ -25,16 +25,16 @@ public TorrentRssIndexerSettings()
|
|||||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Full RSS Feed URL")]
|
[FieldDefinition(0, Label = "IndexerSettingsRssUrl")]
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Cookie", HelpText = "If you site requires a login cookie to access the rss, you'll have to retrieve it via a browser.")]
|
[FieldDefinition(1, Label = "IndexerSettingsCookie", HelpText = "IndexerSettingsCookieHelpText")]
|
||||||
public string Cookie { get; set; }
|
public string Cookie { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Type = FieldType.Checkbox, Label = "Allow Zero Size", HelpText="Enabling this will allow you to use feeds that don't specify release size, but be careful, size related checks will not be performed.")]
|
[FieldDefinition(2, Type = FieldType.Checkbox, Label = "Allow Zero Size", HelpText="IndexerSettingsAllowZeroSizeHelpText")]
|
||||||
public bool AllowZeroSize { get; set; }
|
public bool AllowZeroSize { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
|
[FieldDefinition(3, Type = FieldType.Number, Label = "IndexerSettingsMinimumSeeders", HelpText = "IndexerSettingsMinimumSeedersHelpText", Advanced = true)]
|
||||||
public int MinimumSeeders { get; set; }
|
public int MinimumSeeders { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4)]
|
[FieldDefinition(4)]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Torrentleech
|
namespace NzbDrone.Core.Indexers.Torrentleech
|
||||||
@ -13,8 +14,8 @@ public class Torrentleech : HttpIndexerBase<TorrentleechSettings>
|
|||||||
public override bool SupportsSearch => false;
|
public override bool SupportsSearch => false;
|
||||||
public override int PageSize => 0;
|
public override int PageSize => 0;
|
||||||
|
|
||||||
public Torrentleech(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public Torrentleech(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +25,13 @@ public TorrentleechSettings()
|
|||||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Website URL")]
|
[FieldDefinition(0, Label = "IndexerSettingsWebsiteUrl")]
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "API Key", Privacy = PrivacyLevel.ApiKey)]
|
[FieldDefinition(1, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey)]
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
|
[FieldDefinition(2, Type = FieldType.Number, Label = "IndexerSettingsMinimumSeeders", HelpText = "IndexerSettingsMinimumSeedersHelpText", Advanced = true)]
|
||||||
public int MinimumSeeders { get; set; }
|
public int MinimumSeeders { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3)]
|
[FieldDefinition(3)]
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers.Newznab;
|
using NzbDrone.Core.Indexers.Newznab;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
@ -23,8 +24,8 @@ public class Torznab : HttpIndexerBase<TorznabSettings>
|
|||||||
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
||||||
public override int PageSize => GetProviderPageSize();
|
public override int PageSize => GetProviderPageSize();
|
||||||
|
|
||||||
public Torznab(INewznabCapabilitiesProvider capabilitiesProvider, IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
public Torznab(INewznabCapabilitiesProvider capabilitiesProvider, IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger, ILocalizationService localizationService)
|
||||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
: base(httpClient, indexerStatusService, configService, parsingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_capabilitiesProvider = capabilitiesProvider;
|
_capabilitiesProvider = capabilitiesProvider;
|
||||||
}
|
}
|
||||||
@ -123,13 +124,13 @@ protected virtual ValidationFailure TestCapabilities()
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, "Indexer does not support required search parameters");
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationSearchParametersNotSupported"));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Warn(ex, "Unable to connect to indexer: " + ex.Message);
|
_logger.Warn(ex, "Unable to connect to indexer: " + ex.Message);
|
||||||
|
|
||||||
return new ValidationFailure(string.Empty, $"Unable to connect to indexer: {ex.Message}. Check the log surrounding this error for details");
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("IndexerValidationUnableToConnect", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,10 +141,10 @@ protected virtual ValidationFailure JackettAll()
|
|||||||
Settings.BaseUrl.Contains("/torznab/all") ||
|
Settings.BaseUrl.Contains("/torznab/all") ||
|
||||||
Settings.BaseUrl.Contains("/api/v2.0/indexers/all/results/torznab"))
|
Settings.BaseUrl.Contains("/api/v2.0/indexers/all/results/torznab"))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("ApiPath", "Jackett's all endpoint is not supported, please add indexers individually")
|
return new NzbDroneValidationFailure("ApiPath", _localizationService.GetLocalizedString("IndexerValidationJackettAllNotSupported"))
|
||||||
{
|
{
|
||||||
IsWarning = true,
|
IsWarning = true,
|
||||||
DetailedDescription = "Jackett's all endpoint is not supported, please add indexers individually"
|
DetailedDescription = _localizationService.GetLocalizedString("IndexerValidationJackettAllNotSupportedHelpText")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public TorznabSettings()
|
|||||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(7, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
|
[FieldDefinition(7, Type = FieldType.Number, Label = "IndexerSettingsMinimumSeeders", HelpText = "IndexerSettingsMinimumSeedersHelpText", Advanced = true)]
|
||||||
public int MinimumSeeders { get; set; }
|
public int MinimumSeeders { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8)]
|
[FieldDefinition(8)]
|
||||||
|
@ -770,6 +770,8 @@
|
|||||||
"Indexer": "Indexer",
|
"Indexer": "Indexer",
|
||||||
"IndexerDownloadClientHealthCheckMessage": "Indexers with invalid download clients: {indexerNames}.",
|
"IndexerDownloadClientHealthCheckMessage": "Indexers with invalid download clients: {indexerNames}.",
|
||||||
"IndexerDownloadClientHelpText": "Specify which download client is used for grabs from this indexer",
|
"IndexerDownloadClientHelpText": "Specify which download client is used for grabs from this indexer",
|
||||||
|
"IndexerIPTorrentsSettingsFeedUrl": "Feed URL",
|
||||||
|
"IndexerIPTorrentsSettingsFeedUrlHelpText": "The full RSS feed url generated by IPTorrents, using only the categories you selected (HD, SD, x264, etc ...)",
|
||||||
"IndexerJackettAllHealthCheckMessage": "Indexers using the unsupported Jackett 'all' endpoint: {indexerNames}",
|
"IndexerJackettAllHealthCheckMessage": "Indexers using the unsupported Jackett 'all' endpoint: {indexerNames}",
|
||||||
"IndexerLongTermStatusAllUnavailableHealthCheckMessage": "All indexers are unavailable due to failures for more than 6 hours",
|
"IndexerLongTermStatusAllUnavailableHealthCheckMessage": "All indexers are unavailable due to failures for more than 6 hours",
|
||||||
"IndexerLongTermStatusUnavailableHealthCheckMessage": "Indexers unavailable due to failures for more than 6 hours: {indexerNames}",
|
"IndexerLongTermStatusUnavailableHealthCheckMessage": "Indexers unavailable due to failures for more than 6 hours: {indexerNames}",
|
||||||
@ -782,9 +784,56 @@
|
|||||||
"IndexerSearchNoAvailableIndexersHealthCheckMessage": "All search-capable indexers are temporarily unavailable due to recent indexer errors",
|
"IndexerSearchNoAvailableIndexersHealthCheckMessage": "All search-capable indexers are temporarily unavailable due to recent indexer errors",
|
||||||
"IndexerSearchNoInteractiveHealthCheckMessage": "No indexers available with Interactive Search enabled, {appName} will not provide any interactive search results",
|
"IndexerSearchNoInteractiveHealthCheckMessage": "No indexers available with Interactive Search enabled, {appName} will not provide any interactive search results",
|
||||||
"IndexerSettings": "Indexer Settings",
|
"IndexerSettings": "Indexer Settings",
|
||||||
|
"IndexerSettingsAdditionalNewznabParametersHelpText": "Please note if you change the category you will have to add required/restricted rules about the subgroups to avoid foreign language releases.",
|
||||||
|
"IndexerSettingsAdditionalParameters": "Additional Parameters",
|
||||||
|
"IndexerSettingsAdditionalParametersNyaa": "Additional Parameters",
|
||||||
|
"IndexerSettingsAllowZeroSize": "Allow Zero Size",
|
||||||
|
"IndexerSettingsAllowZeroSizeHelpText": "Enabling this will allow you to use feeds that don't specify release size, but be careful, size related checks will not be performed.",
|
||||||
|
"IndexerSettingsAnimeCategories": "Anime Categories",
|
||||||
|
"IndexerSettingsAnimeCategoriesHelpText": "Drop down list, leave blank to disable anime",
|
||||||
|
"IndexerSettingsAnimeStandardFormatSearch": "Anime Standard Format Search",
|
||||||
|
"IndexerSettingsAnimeStandardFormatSearchHelpText": "Also search for anime using the standard numbering",
|
||||||
|
"IndexerSettingsApiPath": "API Path",
|
||||||
|
"IndexerSettingsApiPathHelpText": "Path to the api, usually {url}",
|
||||||
|
"IndexerSettingsApiUrl": "API URL",
|
||||||
|
"IndexerSettingsApiUrlHelpText": "Do not change this unless you know what you're doing. Since your API key will be sent to that host.",
|
||||||
|
"IndexerSettingsCategories": "Categories",
|
||||||
|
"IndexerSettingsCategoriesHelpText": "Drop down list, leave blank to disable standard/daily shows",
|
||||||
|
"IndexerSettingsCookie": "Cookie",
|
||||||
|
"IndexerSettingsCookieHelpText": "If your site requires a login cookie to access the rss, you'll have to retrieve it via a browser.",
|
||||||
|
"IndexerSettingsMinimumSeeders": "Minimum Seeders",
|
||||||
|
"IndexerSettingsMinimumSeedersHelpText": "Minimum number of seeders required.",
|
||||||
|
"IndexerSettingsPasskey": "Passkey",
|
||||||
|
"IndexerSettingsRssUrl": "RSS URL",
|
||||||
|
"IndexerSettingsRssUrlHelpText": "Enter to URL to an {indexer} compatible RSS feed",
|
||||||
|
"IndexerSettingsSeasonPackSeedTime": "Season-Pack Seed Time",
|
||||||
|
"IndexerSettingsSeasonPackSeedTimeHelpText": "The time a season-pack torrent should be seeded before stopping, empty uses the download client's default",
|
||||||
|
"IndexerSettingsSeedRatio": "Seed Ratio",
|
||||||
|
"IndexerSettingsSeedRatioHelpText": "The ratio a torrent should reach before stopping, empty uses the download client's default. Ratio should be at least 1.0 and follow the indexers rules",
|
||||||
|
"IndexerSettingsSeedTime": "Seed Time",
|
||||||
|
"IndexerSettingsSeedTimeHelpText": "The time a torrent should be seeded before stopping, empty uses the download client's default",
|
||||||
|
"IndexerSettingsWebsiteUrl": "Website URL",
|
||||||
"IndexerStatusAllUnavailableHealthCheckMessage": "All indexers are unavailable due to failures",
|
"IndexerStatusAllUnavailableHealthCheckMessage": "All indexers are unavailable due to failures",
|
||||||
"IndexerStatusUnavailableHealthCheckMessage": "Indexers unavailable due to failures: {indexerNames}",
|
"IndexerStatusUnavailableHealthCheckMessage": "Indexers unavailable due to failures: {indexerNames}",
|
||||||
"IndexerTagHelpText": "Only use this indexer for series with at least one matching tag. Leave blank to use with all series.",
|
"IndexerTagHelpText": "Only use this indexer for series with at least one matching tag. Leave blank to use with all series.",
|
||||||
|
"IndexerValidationCloudFlareCaptchaExpired": "CloudFlare CAPTCHA token expired, please refresh it.",
|
||||||
|
"IndexerValidationCloudFlareCaptchaRequired": "Site protected by CloudFlare CAPTCHA. Valid CAPTCHA token required.",
|
||||||
|
"IndexerValidationFeedNotSupported": "Indexer feed is not supported: {exceptionMessage}",
|
||||||
|
"IndexerValidationInvalidApiKey": "Invalid API Key",
|
||||||
|
"IndexerValidationJackettAllNotSupported": "Jackett's all endpoint is not supported, please add indexers individually",
|
||||||
|
"IndexerValidationJackettAllNotSupportedHelpText": "Jackett's all endpoint is not supported, please add indexers individually",
|
||||||
|
"IndexerValidationJackettNoResultsInConfiguredCategories": "Query successful, but no results in the configured categories were returned from your indexer. This may be an issue with the indexer or your indexer category settings.",
|
||||||
|
"IndexerValidationJackettNoRssFeedQueryAvailable": "No RSS feed query available. This may be an issue with the indexer or your indexer category settings.",
|
||||||
|
"IndexerValidationQueryNotSupported": "Indexer does not support the current query. Check if the categories and or searching for seasons/episodes are supported. Check the log for more details.",
|
||||||
|
"IndexerValidationRequestLimitReached": "Request limit reached: {exceptionMessage}",
|
||||||
|
"IndexerValidationSearchParametersNotSupported": "Indexer does not support required search parameters",
|
||||||
|
"IndexerValidationTestAbortedDueToError": "Test was aborted due to an error: {exceptionMessage}",
|
||||||
|
"IndexerValidationUnableToConnect": "Unable to connect to indexer: {exceptionMessage}. Check the log surrounding this error for details",
|
||||||
|
"IndexerValidationUnableToConnectHttpError": "Unable to connect to indexer, please check your DNS settings and ensure that IPv6 is working or disabled. {exceptionMessage}.",
|
||||||
|
"IndexerValidationUnableToConnectInvalidCredentials": "Unable to connect to indexer, invalid credentials. {exceptionMessage}.",
|
||||||
|
"IndexerValidationUnableToConnectResolutionFailure": "Unable to connect to indexer connection failure. Check your connection to the indexer's server and DNS. {exceptionMessage}.",
|
||||||
|
"IndexerValidationUnableToConnectServerUnavailable": "Unable to connect to indexer, indexer's server is unavailable. Try again later. {exceptionMessage}.",
|
||||||
|
"IndexerValidationUnableToConnectTimeout": "Unable to connect to indexer, possibly due to a timeout. Try again or check your network settings. {exceptionMessage}.",
|
||||||
"Indexers": "Indexers",
|
"Indexers": "Indexers",
|
||||||
"IndexersLoadError": "Unable to load Indexers",
|
"IndexersLoadError": "Unable to load Indexers",
|
||||||
"IndexersSettingsSummary": "Indexers and indexer options",
|
"IndexersSettingsSummary": "Indexers and indexer options",
|
||||||
|
Loading…
Reference in New Issue
Block a user