From a0e0c148f98e0ad53d94e12f1214033777977ec3 Mon Sep 17 00:00:00 2001 From: Oscar Date: Mon, 6 Apr 2026 10:12:26 +0200 Subject: [PATCH] Prefer season search over per-episode for anime When searching for anime seasons, try the season pack search first across all indexers. Only fall back to per-episode search if the season search returns zero results. Previously, SearchAnimeSeason always ran both: a season query followed by individual queries for every episode. For a 10-episode season this meant 10+ separate indexer requests on top of the season query. On indexers like Nyaa (via Prowlarr/Torznab), each per-episode request can take 10-15s, so a full season search could exceed 120s and trigger timeout cascades that disable indexers mid-search. The season query alone consistently returns results for actively airing anime on Newznab, Torznab, and Nyaa indexers. Per-episode fallback is still available when the season search genuinely finds nothing (e.g. older or niche titles). Also removes the AnimeStandardFormatSearch gate from NyaaRequestGenerator and NewznabRequestGenerator for season-level searches. The toggle still controls per-episode search format, but season pack queries should always fire regardless of that setting. --- .../IndexerSearch/ReleaseSearchService.cs | 13 +++++++++++-- .../Indexers/Newznab/NewznabRequestGenerator.cs | 2 +- .../Indexers/Nyaa/NyaaRequestGenerator.cs | 4 ++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs index 3af963f78..13fcddc62 100644 --- a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs @@ -421,9 +421,18 @@ private async Task> SearchAnimeSeason(Series series, List downloadDecisions.AddRange(decisions); } - foreach (var episode in episodesToSearch) + if (downloadDecisions.Any()) { - downloadDecisions.AddRange(await SearchAnime(series, episode, monitoredOnly, userInvokedSearch, interactiveSearch, true)); + _logger.Debug("Season search returned results for {0}, skipping per-episode search for {1} episodes", series.Title, episodesToSearch.Count); + } + else + { + _logger.Debug("No season results for {0}, falling back to per-episode search for {1} episodes", series.Title, episodesToSearch.Count); + + foreach (var episode in episodesToSearch) + { + downloadDecisions.AddRange(await SearchAnime(series, episode, monitoredOnly, userInvokedSearch, interactiveSearch, true)); + } } return DeDupeDecisions(downloadDecisions); diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabRequestGenerator.cs index 4dd06eb2a..b0ca4e6f4 100644 --- a/src/NzbDrone.Core/Indexers/Newznab/NewznabRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabRequestGenerator.cs @@ -450,7 +450,7 @@ public virtual IndexerPageableRequestChain GetSearchRequests(AnimeSeasonSearchCr { var pageableRequests = new IndexerPageableRequestChain(); - if (SupportsSearch && Settings.AnimeStandardFormatSearch && searchCriteria.SeasonNumber > 0) + if (SupportsSearch && searchCriteria.SeasonNumber > 0) { AddTvIdPageableRequests(pageableRequests, Settings.AnimeCategories, diff --git a/src/NzbDrone.Core/Indexers/Nyaa/NyaaRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Nyaa/NyaaRequestGenerator.cs index 92e9d6254..367fed877 100644 --- a/src/NzbDrone.Core/Indexers/Nyaa/NyaaRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Nyaa/NyaaRequestGenerator.cs @@ -87,9 +87,9 @@ public virtual IndexerPageableRequestChain GetSearchRequests(AnimeSeasonSearchCr { var pageableRequests = new IndexerPageableRequestChain(); - foreach (var searchTitle in searchCriteria.SceneTitles.Select(PrepareQuery)) + if (searchCriteria.SeasonNumber > 0) { - if (Settings.AnimeStandardFormatSearch && searchCriteria.SeasonNumber > 0) + foreach (var searchTitle in searchCriteria.SceneTitles.Select(PrepareQuery)) { pageableRequests.Add(GetPagedRequests($"{searchTitle}+s{searchCriteria.SeasonNumber:00}")); }