From 4348ebe187caf8dbb6352f89d7bd8247354cb2e7 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 5 Mar 2023 18:37:04 +0200 Subject: [PATCH] Fixed: (Indexers) Add `SupportsPagination` to prevent fetching the first page multiple times --- src/NzbDrone.Core/Datastore/TableMapping.cs | 1 + .../Indexers/Definitions/AnimeBytes.cs | 6 ----- .../Indexers/Definitions/BinSearch.cs | 1 + .../BroadcastheNet/BroadcastheNet.cs | 1 + .../Definitions/Cardigann/Cardigann.cs | 1 + .../Cardigann/CardigannRequestGenerator.cs | 9 ------- .../Definitions/Headphones/Headphones.cs | 1 + .../Indexers/Definitions/IPTorrents.cs | 19 +++++++------- .../Indexers/Definitions/Libble.cs | 3 ++- .../Indexers/Definitions/MyAnonamouse.cs | 1 + .../Indexers/Definitions/Nebulance.cs | 1 + .../Indexers/Definitions/Newznab/Newznab.cs | 2 ++ .../Indexers/Definitions/NzbIndex.cs | 1 + .../Definitions/SpeedApp/SpeedAppBase.cs | 16 +++++------- .../TorrentPotato/TorrentPotato.cs | 3 ++- .../Indexers/Definitions/Torznab/Torznab.cs | 1 + src/NzbDrone.Core/Indexers/HttpIndexerBase.cs | 26 +++++++++++++++++++ src/NzbDrone.Core/Indexers/IIndexer.cs | 1 + src/NzbDrone.Core/Indexers/IndexerBase.cs | 8 ++---- .../Indexers/IndexerDefinition.cs | 1 + src/NzbDrone.Core/Indexers/IndexerFactory.cs | 3 ++- .../Indexers/IndexerResource.cs | 8 +++--- 22 files changed, 69 insertions(+), 45 deletions(-) diff --git a/src/NzbDrone.Core/Datastore/TableMapping.cs b/src/NzbDrone.Core/Datastore/TableMapping.cs index 81337e682..93f4616d4 100644 --- a/src/NzbDrone.Core/Datastore/TableMapping.cs +++ b/src/NzbDrone.Core/Datastore/TableMapping.cs @@ -55,6 +55,7 @@ namespace NzbDrone.Core.Datastore .Ignore(i => i.SupportsRss) .Ignore(i => i.SupportsSearch) .Ignore(i => i.SupportsRedirect) + .Ignore(i => i.SupportsPagination) .Ignore(i => i.Capabilities) .HasOne(a => a.AppProfile, a => a.AppProfileId); diff --git a/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs b/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs index 79fd808f3..47366ef6f 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs @@ -124,12 +124,6 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - // TODO: Remove this once Prowlarr has proper support for non Pageable Indexers and can tell Sonarr that indexer doesn't support pagination in a proper way, for now just return empty release list on all request containing an offset - if (searchCriteria.Offset is > 0) - { - return pageableRequests; - } - pageableRequests.Add(GetRequest(searchType, searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)); return pageableRequests; diff --git a/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs b/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs index 2fe150edc..8a59271da 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs @@ -29,6 +29,7 @@ namespace NzbDrone.Core.Indexers.Definitions public override DownloadProtocol Protocol => DownloadProtocol.Usenet; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override bool SupportsRss => false; + public override bool SupportsPagination => true; public override IndexerCapabilities Capabilities => SetCapabilities(); public BinSearch(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, IValidateNzbs nzbValidationService, Logger logger) diff --git a/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs b/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs index 45f036260..a4832964e 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs @@ -15,6 +15,7 @@ namespace NzbDrone.Core.Indexers.BroadcastheNet public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override bool SupportsRss => true; public override bool SupportsSearch => true; + public override bool SupportsPagination => true; public override int PageSize => 100; public override IndexerCapabilities Capabilities => SetCapabilities(); public override TimeSpan RateLimit => TimeSpan.FromSeconds(5); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs index 04552917f..a75bbc037 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs @@ -165,6 +165,7 @@ namespace NzbDrone.Core.Indexers.Cardigann SupportsRss = SupportsRss, SupportsSearch = SupportsSearch, SupportsRedirect = SupportsRedirect, + SupportsPagination = SupportsPagination, Capabilities = new IndexerCapabilities(), ExtraFields = settings }; diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs index 3554ca5ad..97f588648 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs @@ -1022,15 +1022,6 @@ namespace NzbDrone.Core.Indexers.Cardigann private IEnumerable GetRequest(Dictionary variables, SearchCriteriaBase searchCriteria) { - var limit = searchCriteria.Limit ?? 100; - var offset = searchCriteria.Offset ?? 0; - - if (offset > 0 && limit > 0 && offset / limit > 0) - { - // Pagination doesn't work yet, this is to prevent fetching the first page multiple times. - yield break; - } - var search = _definition.Search; var mappedCategories = _categories.MapTorznabCapsToTrackers((int[])variables[".Query.Categories"]); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Headphones/Headphones.cs b/src/NzbDrone.Core/Indexers/Definitions/Headphones/Headphones.cs index 65a0734af..e0ecb4a70 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Headphones/Headphones.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Headphones/Headphones.cs @@ -19,6 +19,7 @@ namespace NzbDrone.Core.Indexers.Headphones public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override string[] IndexerUrls => new string[] { "https://indexer.codeshy.com" }; public override string Description => "A Private Usenet indexer for music"; + public override bool SupportsPagination => true; public override IndexerCapabilities Capabilities => SetCapabilities(); public override IIndexerRequestGenerator GetRequestGenerator() diff --git a/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs b/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs index a635a9b53..534dc9881 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs @@ -40,6 +40,7 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "IPTorrents (IPT) is a Private Torrent Tracker for 0DAY / GENERAL."; public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; + public override bool SupportsPagination => true; public override IndexerCapabilities Capabilities => SetCapabilities(); public IPTorrents(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger) @@ -175,13 +176,13 @@ namespace NzbDrone.Core.Indexers.Definitions public IPTorrentsSettings Settings { get; set; } public IndexerCapabilities Capabilities { get; set; } - private IEnumerable GetPagedRequests(string term, int[] categories, int limit, int offset, string imdbId = null) + private IEnumerable GetPagedRequests(string term, SearchCriteriaBase searchCriteria, string imdbId = null) { var searchUrl = Settings.BaseUrl + "t"; var qc = new NameValueCollection(); - foreach (var cat in Capabilities.Categories.MapTorznabCapsToTrackers(categories)) + foreach (var cat in Capabilities.Categories.MapTorznabCapsToTrackers(searchCriteria.Categories)) { qc.Add(cat, string.Empty); } @@ -204,9 +205,9 @@ namespace NzbDrone.Core.Indexers.Definitions qc.Add("q", "+(" + term + ")"); } - if (offset > 0 && limit > 0) + if (searchCriteria.Limit is > 0 && searchCriteria.Offset is > 0) { - var page = (int)(offset / limit) + 1; + var page = (int)(searchCriteria.Offset / searchCriteria.Limit) + 1; qc.Add("p", page.ToString()); } @@ -229,7 +230,7 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SearchTerm), searchCriteria.Categories, searchCriteria.Limit ?? 100, searchCriteria.Offset ?? 0, searchCriteria.FullImdbId)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SearchTerm}", searchCriteria, searchCriteria.FullImdbId)); return pageableRequests; } @@ -238,7 +239,7 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories, searchCriteria.Limit ?? 100, searchCriteria.Offset ?? 0)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedSearchTerm}", searchCriteria)); return pageableRequests; } @@ -247,7 +248,7 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedTvSearchString), searchCriteria.Categories, searchCriteria.Limit ?? 100, searchCriteria.Offset ?? 0, searchCriteria.FullImdbId)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedTvSearchString}", searchCriteria, searchCriteria.FullImdbId)); return pageableRequests; } @@ -256,7 +257,7 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories, searchCriteria.Limit ?? 100, searchCriteria.Offset ?? 0)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedSearchTerm}", searchCriteria)); return pageableRequests; } @@ -265,7 +266,7 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories, searchCriteria.Limit ?? 100, searchCriteria.Offset ?? 0)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedSearchTerm}", searchCriteria)); return pageableRequests; } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Libble.cs b/src/NzbDrone.Core/Indexers/Definitions/Libble.cs index e6a806780..1f0305568 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Libble.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Libble.cs @@ -33,6 +33,7 @@ public class Libble : TorrentIndexerBase public override Encoding Encoding => Encoding.UTF8; public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; + public override bool SupportsPagination => true; public override int PageSize => 50; public override IndexerCapabilities Capabilities => SetCapabilities(); @@ -206,7 +207,7 @@ public class LibbleRequestGenerator : IIndexerRequestGenerator queryCats.ForEach(cat => parameters.Set($"filter_cat[{cat}]", "1")); } - if (searchCriteria.Offset.HasValue && searchCriteria.Limit.HasValue && searchCriteria.Offset > 0 && searchCriteria.Limit > 0) + if (searchCriteria.Limit is > 0 && searchCriteria.Offset is > 0) { var page = (int)(searchCriteria.Offset / searchCriteria.Limit) + 1; parameters.Set("page", page.ToString()); diff --git a/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs b/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs index abb3948c6..f53633e95 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs @@ -32,6 +32,7 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "MyAnonaMouse (MAM) is a large ebook and audiobook tracker."; public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; + public override bool SupportsPagination => true; public override int PageSize => 100; public override IndexerCapabilities Capabilities => SetCapabilities(); private readonly ICacheManager _cacheManager; diff --git a/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs b/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs index 8202ebba0..8592165d9 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs @@ -29,6 +29,7 @@ namespace NzbDrone.Core.Indexers.Definitions public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override bool SupportsRedirect => true; + public override bool SupportsPagination => true; public override IndexerCapabilities Capabilities => SetCapabilities(); public Nebulance(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Newznab/Newznab.cs b/src/NzbDrone.Core/Indexers/Definitions/Newznab/Newznab.cs index f5b882e0e..a05ba29ef 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Newznab/Newznab.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Newznab/Newznab.cs @@ -23,6 +23,7 @@ namespace NzbDrone.Core.Indexers.Newznab public override string Description => "Newznab is an API search specification for Usenet"; public override bool FollowRedirect => true; public override bool SupportsRedirect => true; + public override bool SupportsPagination => true; public override DownloadProtocol Protocol => DownloadProtocol.Usenet; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; @@ -135,6 +136,7 @@ namespace NzbDrone.Core.Indexers.Newznab SupportsRss = SupportsRss, SupportsSearch = SupportsSearch, SupportsRedirect = SupportsRedirect, + SupportsPagination = SupportsPagination, Capabilities = Capabilities }; } diff --git a/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs b/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs index a9594650e..fd490f462 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs @@ -25,6 +25,7 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "A Usenet Indexer"; public override DownloadProtocol Protocol => DownloadProtocol.Usenet; public override IndexerPrivacy Privacy => IndexerPrivacy.SemiPrivate; + public override bool SupportsPagination => true; public override IndexerCapabilities Capabilities => SetCapabilities(); public NzbIndex(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger) diff --git a/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs b/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs index 91f4aa0c5..e5fdbf503 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs @@ -30,6 +30,7 @@ namespace NzbDrone.Core.Indexers.Definitions private string LoginUrl => Settings.BaseUrl + "api/login"; public override Encoding Encoding => Encoding.UTF8; public override DownloadProtocol Protocol => DownloadProtocol.Torrent; + public override bool SupportsPagination => true; public override int PageSize => 100; public override IndexerCapabilities Capabilities => SetCapabilities(); protected virtual int MinimumSeedTime => 172800; // 48 hours @@ -169,26 +170,23 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedSearchTerm}", searchCriteria.Categories, searchCriteria.Limit ?? _pageSize, searchCriteria.Offset ?? 0, imdbId, season, episode)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedSearchTerm}", searchCriteria, imdbId, season, episode)); return pageableRequests; } - private IEnumerable GetPagedRequests(string term, int[] categories, int limit, int offset, string imdbId = null, int? season = null, string episode = null) + private IEnumerable GetPagedRequests(string term, SearchCriteriaBase searchCriteria, string imdbId = null, int? season = null, string episode = null) { - limit = Math.Min(_pageSize, limit); - offset = Math.Max(0, offset); - var parameters = new NameValueCollection { - { "itemsPerPage", limit.ToString() }, + { "itemsPerPage", Math.Min(_pageSize, searchCriteria.Limit.GetValueOrDefault(_pageSize)).ToString() }, { "sort", "torrent.createdAt" }, { "direction", "desc" } }; - if (limit > 0 && offset > 0) + if (searchCriteria.Limit is > 0 && searchCriteria.Offset is > 0) { - var page = (offset / limit) + 1; + var page = (int)(searchCriteria.Offset / searchCriteria.Limit) + 1; parameters.Set("page", page.ToString()); } @@ -211,7 +209,7 @@ namespace NzbDrone.Core.Indexers.Definitions parameters.Set("episode", episode); } - var cats = _capabilities.Categories.MapTorznabCapsToTrackers(categories); + var cats = _capabilities.Categories.MapTorznabCapsToTrackers(searchCriteria.Categories); if (cats.Count > 0) { foreach (var cat in cats) diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentPotato/TorrentPotato.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentPotato/TorrentPotato.cs index c6367c099..b9e20d678 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentPotato/TorrentPotato.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentPotato/TorrentPotato.cs @@ -32,7 +32,8 @@ namespace NzbDrone.Core.Indexers.TorrentPotato Protocol = DownloadProtocol.Torrent, SupportsRss = SupportsRss, SupportsSearch = SupportsSearch, - SupportsRedirect = SupportsRedirect + SupportsRedirect = SupportsRedirect, + SupportsPagination = SupportsPagination }; } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Torznab/Torznab.cs b/src/NzbDrone.Core/Indexers/Definitions/Torznab/Torznab.cs index a26b46bf3..d9dca9ee3 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Torznab/Torznab.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Torznab/Torznab.cs @@ -113,6 +113,7 @@ namespace NzbDrone.Core.Indexers.Torznab SupportsRss = SupportsRss, SupportsSearch = SupportsSearch, SupportsRedirect = SupportsRedirect, + SupportsPagination = SupportsPagination, Capabilities = Capabilities }; } diff --git a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs index 29f819c99..f0819e9d8 100644 --- a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs @@ -33,6 +33,7 @@ namespace NzbDrone.Core.Indexers public override bool SupportsRss => true; public override bool SupportsSearch => true; public override bool SupportsRedirect => false; + public override bool SupportsPagination => false; public override Encoding Encoding => Encoding.UTF8; public override string Language => "en-US"; @@ -60,6 +61,11 @@ namespace NzbDrone.Core.Indexers return Task.FromResult(new IndexerPageableQueryResult()); } + if (!SupportsPagination && searchCriteria.Offset is > 0) + { + return Task.FromResult(new IndexerPageableQueryResult()); + } + return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria), searchCriteria); } @@ -70,6 +76,11 @@ namespace NzbDrone.Core.Indexers return Task.FromResult(new IndexerPageableQueryResult()); } + if (!SupportsPagination && searchCriteria.Offset is > 0) + { + return Task.FromResult(new IndexerPageableQueryResult()); + } + return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria), searchCriteria); } @@ -80,6 +91,11 @@ namespace NzbDrone.Core.Indexers return Task.FromResult(new IndexerPageableQueryResult()); } + if (!SupportsPagination && searchCriteria.Offset is > 0) + { + return Task.FromResult(new IndexerPageableQueryResult()); + } + return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria), searchCriteria); } @@ -90,6 +106,11 @@ namespace NzbDrone.Core.Indexers return Task.FromResult(new IndexerPageableQueryResult()); } + if (!SupportsPagination && searchCriteria.Offset is > 0) + { + return Task.FromResult(new IndexerPageableQueryResult()); + } + return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria), searchCriteria); } @@ -100,6 +121,11 @@ namespace NzbDrone.Core.Indexers return Task.FromResult(new IndexerPageableQueryResult()); } + if (!SupportsPagination && searchCriteria.Offset is > 0) + { + return Task.FromResult(new IndexerPageableQueryResult()); + } + return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria), searchCriteria); } diff --git a/src/NzbDrone.Core/Indexers/IIndexer.cs b/src/NzbDrone.Core/Indexers/IIndexer.cs index f2bf11c6e..25d12db9a 100644 --- a/src/NzbDrone.Core/Indexers/IIndexer.cs +++ b/src/NzbDrone.Core/Indexers/IIndexer.cs @@ -11,6 +11,7 @@ namespace NzbDrone.Core.Indexers bool SupportsRss { get; } bool SupportsSearch { get; } bool SupportsRedirect { get; } + bool SupportsPagination { get; } IndexerCapabilities Capabilities { get; } string[] IndexerUrls { get; } diff --git a/src/NzbDrone.Core/Indexers/IndexerBase.cs b/src/NzbDrone.Core/Indexers/IndexerBase.cs index cca703f31..8164c0345 100644 --- a/src/NzbDrone.Core/Indexers/IndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/IndexerBase.cs @@ -36,6 +36,7 @@ namespace NzbDrone.Core.Indexers public abstract bool SupportsRss { get; } public abstract bool SupportsSearch { get; } public abstract bool SupportsRedirect { get; } + public abstract bool SupportsPagination { get; } public abstract IndexerCapabilities Capabilities { get; protected set; } public IndexerBase(IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger) @@ -51,12 +52,7 @@ namespace NzbDrone.Core.Indexers { var attributes = GetType().GetCustomAttributes(false); - foreach (ObsoleteAttribute attribute in attributes.OfType()) - { - return true; - } - - return false; + return attributes.OfType().Any(); } public virtual ProviderMessage Message => null; diff --git a/src/NzbDrone.Core/Indexers/IndexerDefinition.cs b/src/NzbDrone.Core/Indexers/IndexerDefinition.cs index 4979bf32b..2961f2399 100644 --- a/src/NzbDrone.Core/Indexers/IndexerDefinition.cs +++ b/src/NzbDrone.Core/Indexers/IndexerDefinition.cs @@ -20,6 +20,7 @@ namespace NzbDrone.Core.Indexers public bool SupportsRss { get; set; } public bool SupportsSearch { get; set; } public bool SupportsRedirect { get; set; } + public bool SupportsPagination { get; set; } public IndexerCapabilities Capabilities { get; set; } public int Priority { get; set; } = 25; public bool Redirect { get; set; } diff --git a/src/NzbDrone.Core/Indexers/IndexerFactory.cs b/src/NzbDrone.Core/Indexers/IndexerFactory.cs index a1fa5c659..5ab772dfb 100644 --- a/src/NzbDrone.Core/Indexers/IndexerFactory.cs +++ b/src/NzbDrone.Core/Indexers/IndexerFactory.cs @@ -201,9 +201,10 @@ namespace NzbDrone.Core.Indexers definition.SupportsRss = provider.SupportsRss; definition.SupportsSearch = provider.SupportsSearch; definition.SupportsRedirect = provider.SupportsRedirect; + definition.SupportsPagination = provider.SupportsPagination; //We want to use the definition Caps and Privacy for Cardigann instead of the provider. - if (definition.Implementation != typeof(Cardigann.Cardigann).Name) + if (definition.Implementation != nameof(Cardigann.Cardigann)) { definition.IndexerUrls = provider.IndexerUrls; definition.LegacyUrls = provider.LegacyUrls; diff --git a/src/Prowlarr.Api.V1/Indexers/IndexerResource.cs b/src/Prowlarr.Api.V1/Indexers/IndexerResource.cs index eb1e88c97..cca799967 100644 --- a/src/Prowlarr.Api.V1/Indexers/IndexerResource.cs +++ b/src/Prowlarr.Api.V1/Indexers/IndexerResource.cs @@ -25,6 +25,7 @@ namespace Prowlarr.Api.V1.Indexers public bool SupportsRss { get; set; } public bool SupportsSearch { get; set; } public bool SupportsRedirect { get; set; } + public bool SupportsPagination { get; set; } public int AppProfileId { get; set; } public DownloadProtocol Protocol { get; set; } public IndexerPrivacy Privacy { get; set; } @@ -57,9 +58,9 @@ namespace Prowlarr.Api.V1.Indexers var infoLinkName = definition.ImplementationName; - if (definition.Implementation == typeof(Cardigann).Name) + if (definition.Implementation == nameof(Cardigann)) { - var extraFields = definition.ExtraFields?.Select((x, i) => MapField(x, i)).ToList() ?? new List(); + var extraFields = definition.ExtraFields?.Select(MapField).ToList() ?? new List(); resource.Fields.AddRange(extraFields); @@ -79,7 +80,7 @@ namespace Prowlarr.Api.V1.Indexers infoLinkName = settings.DefinitionFile; } - resource.InfoLink = string.Format("https://wiki.servarr.com/prowlarr/supported-indexers#{0}", infoLinkName.ToLower().Replace(' ', '-')); + resource.InfoLink = $"https://wiki.servarr.com/prowlarr/supported-indexers#{infoLinkName.ToLower().Replace(' ', '-')}"; resource.AppProfileId = definition.AppProfileId; resource.IndexerUrls = definition.IndexerUrls; resource.LegacyUrls = definition.LegacyUrls; @@ -91,6 +92,7 @@ namespace Prowlarr.Api.V1.Indexers resource.SupportsRss = definition.SupportsRss; resource.SupportsSearch = definition.SupportsSearch; resource.SupportsRedirect = definition.SupportsRedirect; + resource.SupportsPagination = definition.SupportsPagination; resource.Capabilities = definition.Capabilities.ToResource(); resource.Protocol = definition.Protocol; resource.Privacy = definition.Privacy;