mirror of https://github.com/Jackett/Jackett
parent
10c8e33715
commit
2030d9cf13
|
@ -317,15 +317,11 @@ namespace Jackett.Common.Indexers
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
var caps = TorznabCaps;
|
var caps = TorznabCaps;
|
||||||
|
|
||||||
if (query.HasSpecifiedCategories)
|
|
||||||
if (!caps.Categories.SupportsCategories(query.Categories))
|
|
||||||
return false;
|
|
||||||
if (caps.TvSearchImdbAvailable && query.IsImdbQuery && query.IsTVSearch)
|
if (caps.TvSearchImdbAvailable && query.IsImdbQuery && query.IsTVSearch)
|
||||||
return true;
|
return true;
|
||||||
if (caps.MovieSearchImdbAvailable && query.IsImdbQuery && query.IsMovieSearch)
|
if (caps.MovieSearchImdbAvailable && query.IsImdbQuery && query.IsMovieSearch)
|
||||||
return true;
|
return true;
|
||||||
else if (!caps.MovieSearchImdbAvailable && query.IsImdbQuery && query.QueryType != "TorrentPotato") // potato query should always contain imdb+search term
|
if (!caps.MovieSearchImdbAvailable && query.IsImdbQuery && query.QueryType != "TorrentPotato") // potato query should always contain imdb+search term
|
||||||
return false;
|
return false;
|
||||||
if (caps.SearchAvailable && query.IsSearch)
|
if (caps.SearchAvailable && query.IsSearch)
|
||||||
return true;
|
return true;
|
||||||
|
@ -349,6 +345,27 @@ namespace Jackett.Common.Indexers
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected bool CanHandleCategories(TorznabQuery query, bool isMetaIndexer = false)
|
||||||
|
{
|
||||||
|
// https://torznab.github.io/spec-1.3-draft/torznab/Specification-v1.3.html#cat-parameter
|
||||||
|
if (query.HasSpecifiedCategories)
|
||||||
|
{
|
||||||
|
var supportedCats = TorznabCaps.Categories.SupportedCategories(query.Categories);
|
||||||
|
if (supportedCats.Length == 0)
|
||||||
|
{
|
||||||
|
if (!isMetaIndexer)
|
||||||
|
logger.Error($"All categories provided are unsupported in {DisplayName}: {string.Join(",", query.Categories)}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (supportedCats.Length != query.Categories.Length && !isMetaIndexer)
|
||||||
|
{
|
||||||
|
var unsupportedCats = query.Categories.Except(supportedCats);
|
||||||
|
logger.Warn($"Some of the categories provided are unsupported in {DisplayName}: {string.Join(",", unsupportedCats)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void Unconfigure()
|
public void Unconfigure()
|
||||||
{
|
{
|
||||||
IsConfigured = false;
|
IsConfigured = false;
|
||||||
|
@ -358,9 +375,9 @@ namespace Jackett.Common.Indexers
|
||||||
|
|
||||||
public abstract Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson);
|
public abstract Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson);
|
||||||
|
|
||||||
public virtual async Task<IndexerResult> ResultsForQuery(TorznabQuery query)
|
public virtual async Task<IndexerResult> ResultsForQuery(TorznabQuery query, bool isMetaIndexer)
|
||||||
{
|
{
|
||||||
if (!CanHandleQuery(query))
|
if (!CanHandleQuery(query) || !CanHandleCategories(query, isMetaIndexer))
|
||||||
return new IndexerResult(this, new ReleaseInfo[0]);
|
return new IndexerResult(this, new ReleaseInfo[0]);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -637,9 +654,9 @@ namespace Jackett.Common.Indexers
|
||||||
return releases;
|
return releases;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<IndexerResult> ResultsForQuery(TorznabQuery query)
|
public override async Task<IndexerResult> ResultsForQuery(TorznabQuery query, bool isMetaIndexer)
|
||||||
{
|
{
|
||||||
var result = await base.ResultsForQuery(query);
|
var result = await base.ResultsForQuery(query, isMetaIndexer);
|
||||||
result.Releases = CleanLinks(result.Releases);
|
result.Releases = CleanLinks(result.Releases);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace Jackett.Common.Indexers
|
||||||
|
|
||||||
void Unconfigure();
|
void Unconfigure();
|
||||||
|
|
||||||
Task<IndexerResult> ResultsForQuery(TorznabQuery query);
|
Task<IndexerResult> ResultsForQuery(TorznabQuery query, bool isMetaIndexer=false);
|
||||||
|
|
||||||
bool CanHandleQuery(TorznabQuery query);
|
bool CanHandleQuery(TorznabQuery query);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,9 +46,9 @@ namespace Jackett.Common.Indexers.Meta
|
||||||
|
|
||||||
public override Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson) => Task.FromResult(IndexerConfigurationStatus.Completed);
|
public override Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson) => Task.FromResult(IndexerConfigurationStatus.Completed);
|
||||||
|
|
||||||
public override async Task<IndexerResult> ResultsForQuery(TorznabQuery query)
|
public override async Task<IndexerResult> ResultsForQuery(TorznabQuery query, bool isMetaIndexer)
|
||||||
{
|
{
|
||||||
if (!CanHandleQuery(query))
|
if (!CanHandleQuery(query) || !CanHandleCategories(query, true))
|
||||||
return new IndexerResult(this, new ReleaseInfo[0]);
|
return new IndexerResult(this, new ReleaseInfo[0]);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -66,11 +66,11 @@ namespace Jackett.Common.Indexers.Meta
|
||||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||||
{
|
{
|
||||||
var indexers = validIndexers;
|
var indexers = validIndexers;
|
||||||
IEnumerable<Task<IndexerResult>> supportedTasks = indexers.Where(i => i.CanHandleQuery(query)).Select(i => i.ResultsForQuery(query)).ToList(); // explicit conversion to List to execute LINQ query
|
IEnumerable<Task<IndexerResult>> supportedTasks = indexers.Where(i => i.CanHandleQuery(query)).Select(i => i.ResultsForQuery(query, true)).ToList(); // explicit conversion to List to execute LINQ query
|
||||||
|
|
||||||
var fallbackStrategies = fallbackStrategyProvider.FallbackStrategiesForQuery(query);
|
var fallbackStrategies = fallbackStrategyProvider.FallbackStrategiesForQuery(query);
|
||||||
var fallbackQueries = fallbackStrategies.Select(async f => await f.FallbackQueries()).SelectMany(t => t.Result);
|
var fallbackQueries = fallbackStrategies.Select(async f => await f.FallbackQueries()).SelectMany(t => t.Result);
|
||||||
var fallbackTasks = fallbackQueries.SelectMany(q => indexers.Where(i => !i.CanHandleQuery(query) && i.CanHandleQuery(q)).Select(i => i.ResultsForQuery(q.Clone())));
|
var fallbackTasks = fallbackQueries.SelectMany(q => indexers.Where(i => !i.CanHandleQuery(query) && i.CanHandleQuery(q)).Select(i => i.ResultsForQuery(q.Clone(), true)));
|
||||||
var tasks = supportedTasks.Concat(fallbackTasks.ToList()); // explicit conversion to List to execute LINQ query
|
var tasks = supportedTasks.Concat(fallbackTasks.ToList()); // explicit conversion to List to execute LINQ query
|
||||||
|
|
||||||
// When there are many indexers used by a metaindexer querying each and every one of them can take very very
|
// When there are many indexers used by a metaindexer querying each and every one of them can take very very
|
||||||
|
|
|
@ -41,7 +41,6 @@ namespace Jackett.Common.Models.DTO
|
||||||
|
|
||||||
stringQuery.SearchTerm = queryStr;
|
stringQuery.SearchTerm = queryStr;
|
||||||
stringQuery.Categories = request.Category ?? new int[0];
|
stringQuery.Categories = request.Category ?? new int[0];
|
||||||
stringQuery.ExpandCatsToSubCats();
|
|
||||||
|
|
||||||
// try to build an IMDB Query (tt plus 6 to 8 digits)
|
// try to build an IMDB Query (tt plus 6 to 8 digits)
|
||||||
if (stringQuery.SanitizedSearchTerm.StartsWith("tt") && stringQuery.SanitizedSearchTerm.Length <= 10)
|
if (stringQuery.SanitizedSearchTerm.StartsWith("tt") && stringQuery.SanitizedSearchTerm.Length <= 10)
|
||||||
|
@ -57,7 +56,6 @@ namespace Jackett.Common.Models.DTO
|
||||||
Season = stringQuery.Season,
|
Season = stringQuery.Season,
|
||||||
Episode = stringQuery.Episode,
|
Episode = stringQuery.Episode,
|
||||||
};
|
};
|
||||||
imdbQuery.ExpandCatsToSubCats();
|
|
||||||
|
|
||||||
return imdbQuery;
|
return imdbQuery;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,6 @@ namespace Jackett.Common.Models.DTO
|
||||||
ImdbID = request.Imdbid,
|
ImdbID = request.Imdbid,
|
||||||
QueryType = "TorrentPotato"
|
QueryType = "TorrentPotato"
|
||||||
};
|
};
|
||||||
torznabQuery.ExpandCatsToSubCats();
|
|
||||||
|
|
||||||
return torznabQuery;
|
return torznabQuery;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,8 +85,6 @@ namespace Jackett.Common.Models.DTO
|
||||||
if (!string.IsNullOrWhiteSpace(request.author))
|
if (!string.IsNullOrWhiteSpace(request.author))
|
||||||
query.Author = request.author;
|
query.Author = request.author;
|
||||||
|
|
||||||
query.ExpandCatsToSubCats();
|
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,14 +104,13 @@ namespace Jackett.Common.Models
|
||||||
return cats;
|
return cats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SupportsCategories(int[] categories)
|
public int[] SupportedCategories(int[] categories)
|
||||||
{
|
{
|
||||||
if (categories == null)
|
if (categories == null || categories.Length == 0)
|
||||||
return false;
|
return new int[0];
|
||||||
var subCategories = _torznabCategoryTree.SelectMany(c => c.SubCategories);
|
var subCategories = _torznabCategoryTree.SelectMany(c => c.SubCategories);
|
||||||
var allCategories = _torznabCategoryTree.Concat(subCategories);
|
var allCategories = _torznabCategoryTree.Concat(subCategories);
|
||||||
var supportsCategory = allCategories.Any(i => categories.Any(c => c == i.ID));
|
return allCategories.Where(c => categories.Contains(c.ID)).Select(c => c.ID).ToArray();
|
||||||
return supportsCategory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Concat(TorznabCapabilitiesCategories rhs)
|
public void Concat(TorznabCapabilitiesCategories rhs)
|
||||||
|
|
|
@ -210,24 +210,5 @@ namespace Jackett.Common.Models
|
||||||
}
|
}
|
||||||
return episodeString;
|
return episodeString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExpandCatsToSubCats()
|
|
||||||
{
|
|
||||||
if (Categories.Count() == 0)
|
|
||||||
return;
|
|
||||||
var newCatList = new List<int>();
|
|
||||||
newCatList.AddRange(Categories);
|
|
||||||
foreach (var cat in Categories)
|
|
||||||
{
|
|
||||||
var majorCat = TorznabCatType.AllCats.Where(c => c.ID == cat).FirstOrDefault();
|
|
||||||
// If we search for TV we should also search for all sub cats
|
|
||||||
if (majorCat != null)
|
|
||||||
{
|
|
||||||
newCatList.AddRange(majorCat.SubCategories.Select(s => s.ID));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Categories = newCatList.Distinct().ToArray();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,8 +139,9 @@ namespace Jackett.Server.Controllers
|
||||||
|
|
||||||
if (!resultController.CurrentIndexer.CanHandleQuery(resultController.CurrentQuery))
|
if (!resultController.CurrentIndexer.CanHandleQuery(resultController.CurrentQuery))
|
||||||
{
|
{
|
||||||
context.Result = ResultsController.GetErrorActionResult(context.RouteData, HttpStatusCode.BadRequest, 201, $"{resultController.CurrentIndexer.Id} " +
|
context.Result = ResultsController.GetErrorActionResult(context.RouteData, HttpStatusCode.BadRequest, 201,
|
||||||
$"does not support the requested query. Please check the capabilities (t=caps) and make sure the search mode and categories are supported.");
|
$"{resultController.CurrentIndexer.Id} does not support the requested query. " +
|
||||||
|
"Please check the capabilities (t=caps) and make sure the search mode and parameters are supported.");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,13 +212,11 @@ namespace Jackett.Server.Controllers
|
||||||
var manualResult = new ManualSearchResult();
|
var manualResult = new ManualSearchResult();
|
||||||
var trackers = IndexerService.GetAllIndexers().ToList().Where(t => t.IsConfigured);
|
var trackers = IndexerService.GetAllIndexers().ToList().Where(t => t.IsConfigured);
|
||||||
if (request.Tracker != null)
|
if (request.Tracker != null)
|
||||||
{
|
|
||||||
trackers = trackers.Where(t => request.Tracker.Contains(t.Id));
|
trackers = trackers.Where(t => request.Tracker.Contains(t.Id));
|
||||||
}
|
|
||||||
|
|
||||||
trackers = trackers.Where(t => t.CanHandleQuery(CurrentQuery));
|
trackers = trackers.Where(t => t.CanHandleQuery(CurrentQuery));
|
||||||
|
|
||||||
var tasks = trackers.ToList().Select(t => t.ResultsForQuery(CurrentQuery)).ToList();
|
var isMetaIndexer = request.Tracker == null || request.Tracker.Length > 1;
|
||||||
|
var tasks = trackers.ToList().Select(t => t.ResultsForQuery(CurrentQuery, isMetaIndexer)).ToList();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var aggregateTask = Task.WhenAll(tasks);
|
var aggregateTask = Task.WhenAll(tasks);
|
||||||
|
|
|
@ -326,19 +326,30 @@ namespace Jackett.Test.Common.Models
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSupportsCategories()
|
public void TestSupportedCategories()
|
||||||
{
|
{
|
||||||
var tcc = CreateTestDataset();
|
var tcc = CreateTestDataset();
|
||||||
|
|
||||||
Assert.True(tcc.SupportsCategories(new []{ TorznabCatType.Movies.ID })); // parent cat
|
Assert.AreEqual( new[] { TorznabCatType.Movies.ID }, // parent cat
|
||||||
Assert.True(tcc.SupportsCategories(new []{ TorznabCatType.MoviesSD.ID })); // child cat
|
tcc.SupportedCategories(new []{ TorznabCatType.Movies.ID }));
|
||||||
Assert.True(tcc.SupportsCategories(new []{ TorznabCatType.Movies.ID, TorznabCatType.MoviesSD.ID })); // parent & child
|
Assert.AreEqual( new[] { TorznabCatType.MoviesSD.ID }, // child cat
|
||||||
Assert.True(tcc.SupportsCategories(new []{ 100040 })); // custom cat
|
tcc.SupportedCategories(new []{ TorznabCatType.MoviesSD.ID }));
|
||||||
Assert.False(tcc.SupportsCategories(new []{ TorznabCatType.Movies3D.ID })); // not supported child cat
|
Assert.AreEqual( new[] { TorznabCatType.Movies.ID, TorznabCatType.MoviesSD.ID }, // parent & child cat
|
||||||
Assert.False(tcc.SupportsCategories(new []{ 9999 })); // unknown cat
|
tcc.SupportedCategories(new []{ TorznabCatType.Movies.ID, TorznabCatType.MoviesSD.ID }));
|
||||||
Assert.False(tcc.SupportsCategories(new []{ 100001 })); // unknown custom cat
|
Assert.AreEqual( new[] { 100040 }, // custom cat
|
||||||
Assert.False(tcc.SupportsCategories(new int[]{})); // empty list
|
tcc.SupportedCategories(new []{ 100040 }));
|
||||||
Assert.False(tcc.SupportsCategories(null)); // null
|
Assert.AreEqual( new[] { TorznabCatType.Movies.ID }, // mixed good and bad
|
||||||
|
tcc.SupportedCategories(new []{ TorznabCatType.Movies.ID, 9999 }));
|
||||||
|
Assert.AreEqual( new int[] {}, // not supported child cat
|
||||||
|
tcc.SupportedCategories(new []{ TorznabCatType.Movies3D.ID }));
|
||||||
|
Assert.AreEqual( new int[] {}, // unknown cat
|
||||||
|
tcc.SupportedCategories(new []{ 9999 }));
|
||||||
|
Assert.AreEqual( new int[] {}, // unknown custom cat
|
||||||
|
tcc.SupportedCategories(new []{ 100001 }));
|
||||||
|
Assert.AreEqual( new int[]{}, // empty list
|
||||||
|
tcc.SupportedCategories(new int[]{}));
|
||||||
|
Assert.AreEqual( new int[] {}, // null
|
||||||
|
tcc.SupportedCategories(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
Loading…
Reference in New Issue