mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
New: Filter releases by search criteria
Co-Authored-By: Bogdan <mynameisbogdan@users.noreply.github.com>
This commit is contained in:
@@ -12,10 +12,13 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
|
|||||||
|
|
||||||
public override bool IsRssSearch =>
|
public override bool IsRssSearch =>
|
||||||
SearchTerm.IsNullOrWhiteSpace() &&
|
SearchTerm.IsNullOrWhiteSpace() &&
|
||||||
Author.IsNullOrWhiteSpace() &&
|
!IsIdSearch;
|
||||||
Title.IsNullOrWhiteSpace() &&
|
|
||||||
Publisher.IsNullOrWhiteSpace() &&
|
public override bool IsIdSearch =>
|
||||||
Genre.IsNullOrWhiteSpace() &&
|
Author.IsNotNullOrWhiteSpace() ||
|
||||||
!Year.HasValue;
|
Title.IsNotNullOrWhiteSpace() ||
|
||||||
|
Publisher.IsNotNullOrWhiteSpace() ||
|
||||||
|
Genre.IsNotNullOrWhiteSpace() ||
|
||||||
|
Year.HasValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,12 +15,15 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
|
|||||||
|
|
||||||
public override bool IsRssSearch =>
|
public override bool IsRssSearch =>
|
||||||
SearchTerm.IsNullOrWhiteSpace() &&
|
SearchTerm.IsNullOrWhiteSpace() &&
|
||||||
ImdbId.IsNullOrWhiteSpace() &&
|
!IsIdSearch;
|
||||||
Genre.IsNullOrWhiteSpace() &&
|
|
||||||
!TmdbId.HasValue &&
|
public override bool IsIdSearch =>
|
||||||
!TraktId.HasValue &&
|
ImdbId.IsNotNullOrWhiteSpace() ||
|
||||||
!DoubanId.HasValue &&
|
Genre.IsNotNullOrWhiteSpace() ||
|
||||||
!Year.HasValue;
|
TmdbId.HasValue ||
|
||||||
|
TraktId.HasValue ||
|
||||||
|
DoubanId.HasValue ||
|
||||||
|
Year.HasValue;
|
||||||
|
|
||||||
public string FullImdbId => ParseUtil.GetFullImdbId(ImdbId);
|
public string FullImdbId => ParseUtil.GetFullImdbId(ImdbId);
|
||||||
|
|
||||||
|
@@ -13,11 +13,14 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
|
|||||||
|
|
||||||
public override bool IsRssSearch =>
|
public override bool IsRssSearch =>
|
||||||
SearchTerm.IsNullOrWhiteSpace() &&
|
SearchTerm.IsNullOrWhiteSpace() &&
|
||||||
Album.IsNullOrWhiteSpace() &&
|
!IsIdSearch;
|
||||||
Artist.IsNullOrWhiteSpace() &&
|
|
||||||
Label.IsNullOrWhiteSpace() &&
|
public override bool IsIdSearch =>
|
||||||
Genre.IsNullOrWhiteSpace() &&
|
Album.IsNotNullOrWhiteSpace() ||
|
||||||
Track.IsNullOrWhiteSpace() &&
|
Artist.IsNotNullOrWhiteSpace() ||
|
||||||
!Year.HasValue;
|
Label.IsNotNullOrWhiteSpace() ||
|
||||||
|
Genre.IsNotNullOrWhiteSpace() ||
|
||||||
|
Track.IsNotNullOrWhiteSpace() ||
|
||||||
|
Year.HasValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,8 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
|
|||||||
|
|
||||||
public virtual bool IsRssSearch => SearchTerm.IsNullOrWhiteSpace();
|
public virtual bool IsRssSearch => SearchTerm.IsNullOrWhiteSpace();
|
||||||
|
|
||||||
|
public virtual bool IsIdSearch => false;
|
||||||
|
|
||||||
public string SanitizedSearchTerm => GetSanitizedTerm(SearchTerm);
|
public string SanitizedSearchTerm => GetSanitizedTerm(SearchTerm);
|
||||||
|
|
||||||
private static string GetSanitizedTerm(string term)
|
private static string GetSanitizedTerm(string term)
|
||||||
|
@@ -28,15 +28,18 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
|
|||||||
|
|
||||||
public override bool IsRssSearch =>
|
public override bool IsRssSearch =>
|
||||||
SearchTerm.IsNullOrWhiteSpace() &&
|
SearchTerm.IsNullOrWhiteSpace() &&
|
||||||
Episode.IsNullOrWhiteSpace() &&
|
!IsIdSearch;
|
||||||
ImdbId.IsNullOrWhiteSpace() &&
|
|
||||||
!Season.HasValue &&
|
public override bool IsIdSearch =>
|
||||||
!TvdbId.HasValue &&
|
Episode.IsNotNullOrWhiteSpace() ||
|
||||||
!RId.HasValue &&
|
ImdbId.IsNotNullOrWhiteSpace() ||
|
||||||
!TraktId.HasValue &&
|
Season.HasValue ||
|
||||||
!TvMazeId.HasValue &&
|
TvdbId.HasValue ||
|
||||||
!TmdbId.HasValue &&
|
RId.HasValue ||
|
||||||
!DoubanId.HasValue;
|
TraktId.HasValue ||
|
||||||
|
TvMazeId.HasValue ||
|
||||||
|
TmdbId.HasValue ||
|
||||||
|
DoubanId.HasValue;
|
||||||
|
|
||||||
public override string SearchQuery
|
public override string SearchQuery
|
||||||
{
|
{
|
||||||
|
@@ -7,8 +7,10 @@ using NLog;
|
|||||||
using NzbDrone.Common.Cache;
|
using NzbDrone.Common.Cache;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
using NzbDrone.Core.IndexerVersions;
|
using NzbDrone.Core.IndexerVersions;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
|
||||||
@@ -77,6 +79,18 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override IList<ReleaseInfo> CleanupReleases(IEnumerable<ReleaseInfo> releases, SearchCriteriaBase searchCriteria)
|
||||||
|
{
|
||||||
|
var cleanReleases = base.CleanupReleases(releases, searchCriteria);
|
||||||
|
|
||||||
|
if (_definitionService.GetCachedDefinition(Settings.DefinitionFile).Search?.Rows?.Filters?.Any(x => x.Name == "andmatch") ?? false)
|
||||||
|
{
|
||||||
|
cleanReleases = FilterReleasesByQuery(releases, searchCriteria).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cleanReleases;
|
||||||
|
}
|
||||||
|
|
||||||
protected override IDictionary<string, string> GetCookies()
|
protected override IDictionary<string, string> GetCookies()
|
||||||
{
|
{
|
||||||
if (Settings.ExtraFieldData.TryGetValue("cookie", out var cookies))
|
if (Settings.ExtraFieldData.TryGetValue("cookie", out var cookies))
|
||||||
|
@@ -1,7 +1,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Definitions
|
namespace NzbDrone.Core.Indexers.Definitions
|
||||||
{
|
{
|
||||||
@@ -19,6 +22,13 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override IList<ReleaseInfo> CleanupReleases(IEnumerable<ReleaseInfo> releases, SearchCriteriaBase searchCriteria)
|
||||||
|
{
|
||||||
|
var cleanReleases = base.CleanupReleases(releases, searchCriteria);
|
||||||
|
|
||||||
|
return FilterReleasesByQuery(cleanReleases, searchCriteria).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
protected override IndexerCapabilities SetCapabilities()
|
protected override IndexerCapabilities SetCapabilities()
|
||||||
{
|
{
|
||||||
var caps = new IndexerCapabilities
|
var caps = new IndexerCapabilities
|
||||||
|
@@ -60,7 +60,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
return Task.FromResult(new IndexerPageableQueryResult());
|
return Task.FromResult(new IndexerPageableQueryResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria));
|
return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria), searchCriteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<IndexerPageableQueryResult> Fetch(MusicSearchCriteria searchCriteria)
|
public override Task<IndexerPageableQueryResult> Fetch(MusicSearchCriteria searchCriteria)
|
||||||
@@ -70,7 +70,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
return Task.FromResult(new IndexerPageableQueryResult());
|
return Task.FromResult(new IndexerPageableQueryResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria));
|
return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria), searchCriteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<IndexerPageableQueryResult> Fetch(TvSearchCriteria searchCriteria)
|
public override Task<IndexerPageableQueryResult> Fetch(TvSearchCriteria searchCriteria)
|
||||||
@@ -80,7 +80,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
return Task.FromResult(new IndexerPageableQueryResult());
|
return Task.FromResult(new IndexerPageableQueryResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria));
|
return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria), searchCriteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<IndexerPageableQueryResult> Fetch(BookSearchCriteria searchCriteria)
|
public override Task<IndexerPageableQueryResult> Fetch(BookSearchCriteria searchCriteria)
|
||||||
@@ -90,7 +90,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
return Task.FromResult(new IndexerPageableQueryResult());
|
return Task.FromResult(new IndexerPageableQueryResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria));
|
return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria), searchCriteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<IndexerPageableQueryResult> Fetch(BasicSearchCriteria searchCriteria)
|
public override Task<IndexerPageableQueryResult> Fetch(BasicSearchCriteria searchCriteria)
|
||||||
@@ -100,7 +100,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
return Task.FromResult(new IndexerPageableQueryResult());
|
return Task.FromResult(new IndexerPageableQueryResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria));
|
return FetchReleases(g => SetCookieFunctions(g).GetSearchRequests(searchCriteria), searchCriteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<byte[]> Download(Uri link)
|
public override async Task<byte[]> Download(Uri link)
|
||||||
@@ -233,7 +233,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
_indexerStatusService.UpdateCookies(Definition.Id, cookies, expiration);
|
_indexerStatusService.UpdateCookies(Definition.Id, cookies, expiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual async Task<IndexerPageableQueryResult> FetchReleases(Func<IIndexerRequestGenerator, IndexerPageableRequestChain> pageableRequestChainSelector, bool isRecent = false)
|
protected virtual async Task<IndexerPageableQueryResult> FetchReleases(Func<IIndexerRequestGenerator, IndexerPageableRequestChain> pageableRequestChainSelector, SearchCriteriaBase searchCriteria, bool isRecent = false)
|
||||||
{
|
{
|
||||||
var releases = new List<ReleaseInfo>();
|
var releases = new List<ReleaseInfo>();
|
||||||
var result = new IndexerPageableQueryResult();
|
var result = new IndexerPageableQueryResult();
|
||||||
@@ -367,7 +367,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
_logger.Error(ex, "An error occurred while processing indexer feed. {0}", url);
|
_logger.Error(ex, "An error occurred while processing indexer feed. {0}", url);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Releases = CleanupReleases(releases);
|
result.Releases = CleanupReleases(releases, searchCriteria);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
@@ -104,7 +105,7 @@ namespace NzbDrone.Core.Indexers
|
|||||||
|
|
||||||
public abstract IndexerCapabilities GetCapabilities();
|
public abstract IndexerCapabilities GetCapabilities();
|
||||||
|
|
||||||
protected virtual IList<ReleaseInfo> CleanupReleases(IEnumerable<ReleaseInfo> releases)
|
protected virtual IList<ReleaseInfo> CleanupReleases(IEnumerable<ReleaseInfo> releases, SearchCriteriaBase searchCriteria)
|
||||||
{
|
{
|
||||||
var result = releases.ToList();
|
var result = releases.ToList();
|
||||||
|
|
||||||
@@ -146,6 +147,24 @@ namespace NzbDrone.Core.Indexers
|
|||||||
return result.DistinctBy(v => v.Guid).ToList();
|
return result.DistinctBy(v => v.Guid).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected IEnumerable<ReleaseInfo> FilterReleasesByQuery(IEnumerable<ReleaseInfo> releases, SearchCriteriaBase searchCriteria)
|
||||||
|
{
|
||||||
|
var commonWords = new[] { "and", "the", "an", "of" };
|
||||||
|
|
||||||
|
if (!searchCriteria.IsRssSearch && !searchCriteria.IsIdSearch)
|
||||||
|
{
|
||||||
|
var splitRegex = new Regex("[^\\w]+");
|
||||||
|
|
||||||
|
// split search term to individual terms for less aggressive filtering, filter common terms
|
||||||
|
var terms = splitRegex.Split(searchCriteria.SearchTerm).Where(t => t.IsNotNullOrWhiteSpace() && t.Length > 1 && !commonWords.ContainsIgnoreCase(t));
|
||||||
|
|
||||||
|
// check in title and description for any term searched for
|
||||||
|
releases = releases.Where(r => terms.Any(t => r.Title.ContainsIgnoreCase(t) || r.Description.ContainsIgnoreCase(t))).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return releases;
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual TSettings GetDefaultBaseUrl(TSettings settings)
|
protected virtual TSettings GetDefaultBaseUrl(TSettings settings)
|
||||||
{
|
{
|
||||||
var defaultLink = IndexerUrls.FirstOrDefault();
|
var defaultLink = IndexerUrls.FirstOrDefault();
|
||||||
|
Reference in New Issue
Block a user