Newznab Responses for Caps and Movie Search (rough)

This commit is contained in:
Qstick
2020-10-21 01:47:20 -04:00
parent 84cbfe870f
commit cfb1a80c58
46 changed files with 526 additions and 1226 deletions
@@ -20,7 +20,7 @@ namespace NzbDrone.Core.Indexers.Newznab
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
public override int PageSize => _capabilitiesProvider.GetCapabilities(Settings).DefaultPageSize;
public override int PageSize => _capabilitiesProvider.GetCapabilities(Settings).LimitsDefault.Value;
public override IIndexerRequestGenerator GetRequestGenerator()
{
@@ -36,6 +36,14 @@ namespace NzbDrone.Core.Indexers.Newznab
return new NewznabRssParser(Settings);
}
public override IndexerCapabilities GetCapabilities()
{
// TODO: This uses indexer capabilities when called so we don't have to keep up with all of them
// however, this is not pulled on a all pull from UI, doing so will kill the UI load if an indexer is down
// should we just purge and manage
return _capabilitiesProvider.GetCapabilities(Settings);
}
public override IEnumerable<ProviderDefinition> DefaultDefinitions
{
get
@@ -75,7 +83,8 @@ namespace NzbDrone.Core.Indexers.Newznab
Protocol = DownloadProtocol.Usenet,
Privacy = IndexerPrivacy.Private,
SupportsRss = SupportsRss,
SupportsSearch = SupportsSearch
SupportsSearch = SupportsSearch,
Capabilities = Capabilities
};
}
@@ -107,15 +116,15 @@ namespace NzbDrone.Core.Indexers.Newznab
failures.AddIfNotNull(TestCapabilities());
}
protected static List<int> CategoryIds(List<NewznabCategory> categories)
protected static List<int> CategoryIds(List<IndexerCategory> categories)
{
var l = categories.Select(c => c.Id).ToList();
foreach (var category in categories)
{
if (category.Subcategories != null)
if (category.SubCategories != null)
{
l.AddRange(CategoryIds(category.Subcategories));
l.AddRange(CategoryIds(category.SubCategories));
}
}
@@ -139,14 +148,14 @@ namespace NzbDrone.Core.Indexers.Newznab
}
}
if (capabilities.SupportedSearchParameters != null && capabilities.SupportedSearchParameters.Contains("q"))
if (capabilities.SearchParams != null && capabilities.SearchParams.Contains(SearchParam.Q))
{
return null;
}
if (capabilities.SupportedMovieSearchParameters != null &&
new[] { "q", "imdbid" }.Any(v => capabilities.SupportedMovieSearchParameters.Contains(v)) &&
new[] { "imdbtitle", "imdbyear" }.All(v => capabilities.SupportedMovieSearchParameters.Contains(v)))
if (capabilities.MovieSearchParams != null &&
new[] { MovieSearchParam.Q, MovieSearchParam.ImdbId }.Any(v => capabilities.MovieSearchParams.Contains(v)) &&
new[] { MovieSearchParam.ImdbTitle, MovieSearchParam.ImdbYear }.All(v => capabilities.MovieSearchParams.Contains(v)))
{
return null;
}
@@ -1,33 +0,0 @@
using System.Collections.Generic;
namespace NzbDrone.Core.Indexers.Newznab
{
public class NewznabCapabilities
{
public int DefaultPageSize { get; set; }
public int MaxPageSize { get; set; }
public string[] SupportedSearchParameters { get; set; }
public string[] SupportedMovieSearchParameters { get; set; }
public bool SupportsAggregateIdSearch { get; set; }
public List<NewznabCategory> Categories { get; set; }
public NewznabCapabilities()
{
DefaultPageSize = 100;
MaxPageSize = 100;
SupportedSearchParameters = new[] { "q" };
SupportedMovieSearchParameters = new[] { "q", "imdbid", "imdbtitle", "imdbyear" };
SupportsAggregateIdSearch = false;
Categories = new List<NewznabCategory>();
}
}
public class NewznabCategory
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<NewznabCategory> Subcategories { get; set; }
}
}
@@ -12,23 +12,23 @@ namespace NzbDrone.Core.Indexers.Newznab
{
public interface INewznabCapabilitiesProvider
{
NewznabCapabilities GetCapabilities(NewznabSettings settings);
IndexerCapabilities GetCapabilities(NewznabSettings settings);
}
public class NewznabCapabilitiesProvider : INewznabCapabilitiesProvider
{
private readonly ICached<NewznabCapabilities> _capabilitiesCache;
private readonly ICached<IndexerCapabilities> _capabilitiesCache;
private readonly IHttpClient _httpClient;
private readonly Logger _logger;
public NewznabCapabilitiesProvider(ICacheManager cacheManager, IHttpClient httpClient, Logger logger)
{
_capabilitiesCache = cacheManager.GetCache<NewznabCapabilities>(GetType());
_capabilitiesCache = cacheManager.GetCache<IndexerCapabilities>(GetType());
_httpClient = httpClient;
_logger = logger;
}
public NewznabCapabilities GetCapabilities(NewznabSettings indexerSettings)
public IndexerCapabilities GetCapabilities(NewznabSettings indexerSettings)
{
var key = indexerSettings.ToJson();
var capabilities = _capabilitiesCache.Get(key, () => FetchCapabilities(indexerSettings), TimeSpan.FromDays(7));
@@ -36,9 +36,9 @@ namespace NzbDrone.Core.Indexers.Newznab
return capabilities;
}
private NewznabCapabilities FetchCapabilities(NewznabSettings indexerSettings)
private IndexerCapabilities FetchCapabilities(NewznabSettings indexerSettings)
{
var capabilities = new NewznabCapabilities();
var capabilities = new IndexerCapabilities();
var url = string.Format("{0}{1}?t=caps", indexerSettings.BaseUrl.TrimEnd('/'), indexerSettings.ApiPath.TrimEnd('/'));
@@ -81,9 +81,9 @@ namespace NzbDrone.Core.Indexers.Newznab
return capabilities;
}
private NewznabCapabilities ParseCapabilities(HttpResponse response)
private IndexerCapabilities ParseCapabilities(HttpResponse response)
{
var capabilities = new NewznabCapabilities();
var capabilities = new IndexerCapabilities();
var xDoc = XDocument.Parse(response.Content);
@@ -104,8 +104,8 @@ namespace NzbDrone.Core.Indexers.Newznab
var xmlLimits = xmlRoot.Element("limits");
if (xmlLimits != null)
{
capabilities.DefaultPageSize = int.Parse(xmlLimits.Attribute("default").Value);
capabilities.MaxPageSize = int.Parse(xmlLimits.Attribute("max").Value);
capabilities.LimitsDefault = int.Parse(xmlLimits.Attribute("default").Value);
capabilities.LimitsMax = int.Parse(xmlLimits.Attribute("max").Value);
}
var xmlSearching = xmlRoot.Element("searching");
@@ -114,22 +114,81 @@ namespace NzbDrone.Core.Indexers.Newznab
var xmlBasicSearch = xmlSearching.Element("search");
if (xmlBasicSearch == null || xmlBasicSearch.Attribute("available").Value != "yes")
{
capabilities.SupportedSearchParameters = null;
capabilities.SearchParams = new List<SearchParam>();
}
else if (xmlBasicSearch.Attribute("supportedParams") != null)
{
capabilities.SupportedSearchParameters = xmlBasicSearch.Attribute("supportedParams").Value.Split(',');
foreach (var param in xmlBasicSearch.Attribute("supportedParams").Value.Split(','))
{
if (Enum.TryParse(param, true, out SearchParam searchParam))
{
capabilities.SearchParams.AddIfNotNull(searchParam);
}
}
}
var xmlMovieSearch = xmlSearching.Element("movie-search");
if (xmlMovieSearch == null || xmlMovieSearch.Attribute("available").Value != "yes")
{
capabilities.SupportedMovieSearchParameters = null;
capabilities.MovieSearchParams = new List<MovieSearchParam>();
}
else if (xmlMovieSearch.Attribute("supportedParams") != null)
{
capabilities.SupportedMovieSearchParameters = xmlMovieSearch.Attribute("supportedParams").Value.Split(',');
capabilities.SupportsAggregateIdSearch = true;
foreach (var param in xmlMovieSearch.Attribute("supportedParams").Value.Split(','))
{
if (Enum.TryParse(param, true, out MovieSearchParam searchParam))
{
capabilities.MovieSearchParams.AddIfNotNull(searchParam);
}
}
}
var xmlTvSearch = xmlSearching.Element("tv-search");
if (xmlTvSearch == null || xmlTvSearch.Attribute("available").Value != "yes")
{
capabilities.TvSearchParams = new List<TvSearchParam>();
}
else if (xmlTvSearch.Attribute("supportedParams") != null)
{
foreach (var param in xmlTvSearch.Attribute("supportedParams").Value.Split(','))
{
if (Enum.TryParse(param, true, out TvSearchParam searchParam))
{
capabilities.TvSearchParams.AddIfNotNull(searchParam);
}
}
}
var xmlAudioSearch = xmlSearching.Element("audio-search");
if (xmlAudioSearch == null || xmlAudioSearch.Attribute("available").Value != "yes")
{
capabilities.MusicSearchParams = new List<MusicSearchParam>();
}
else if (xmlAudioSearch.Attribute("supportedParams") != null)
{
foreach (var param in xmlAudioSearch.Attribute("supportedParams").Value.Split(','))
{
if (Enum.TryParse(param, true, out MusicSearchParam searchParam))
{
capabilities.MusicSearchParams.AddIfNotNull(searchParam);
}
}
}
var xmlBookSearch = xmlSearching.Element("book-search");
if (xmlBookSearch == null || xmlBookSearch.Attribute("available").Value != "yes")
{
capabilities.BookSearchParams = new List<BookSearchParam>();
}
else if (xmlBookSearch.Attribute("supportedParams") != null)
{
foreach (var param in xmlBookSearch.Attribute("supportedParams").Value.Split(','))
{
if (Enum.TryParse(param, true, out BookSearchParam searchParam))
{
capabilities.BookSearchParams.AddIfNotNull(searchParam);
}
}
}
}
@@ -138,17 +197,16 @@ namespace NzbDrone.Core.Indexers.Newznab
{
foreach (var xmlCategory in xmlCategories.Elements("category"))
{
var cat = new NewznabCategory
var cat = new IndexerCategory
{
Id = int.Parse(xmlCategory.Attribute("id").Value),
Name = xmlCategory.Attribute("name").Value,
Description = xmlCategory.Attribute("description") != null ? xmlCategory.Attribute("description").Value : string.Empty,
Subcategories = new List<NewznabCategory>()
Description = xmlCategory.Attribute("description") != null ? xmlCategory.Attribute("description").Value : string.Empty
};
foreach (var xmlSubcat in xmlCategory.Elements("subcat"))
{
cat.Subcategories.Add(new NewznabCategory
cat.SubCategories.Add(new IndexerCategory
{
Id = int.Parse(xmlSubcat.Attribute("id").Value),
Name = xmlSubcat.Attribute("name").Value,
@@ -28,8 +28,8 @@ namespace NzbDrone.Core.Indexers.Newznab
{
var capabilities = _capabilitiesProvider.GetCapabilities(Settings);
return capabilities.SupportedSearchParameters != null &&
capabilities.SupportedSearchParameters.Contains("q");
return capabilities.SearchParams != null &&
capabilities.SearchParams.Contains(SearchParam.Q);
}
}
@@ -39,8 +39,8 @@ namespace NzbDrone.Core.Indexers.Newznab
{
var capabilities = _capabilitiesProvider.GetCapabilities(Settings);
return capabilities.SupportedMovieSearchParameters != null &&
capabilities.SupportedMovieSearchParameters.Contains("imdbid");
return capabilities.MovieSearchParams != null &&
capabilities.MovieSearchParams.Contains(MovieSearchParam.ImdbId);
}
}
@@ -50,8 +50,8 @@ namespace NzbDrone.Core.Indexers.Newznab
{
var capabilities = _capabilitiesProvider.GetCapabilities(Settings);
return capabilities.SupportedMovieSearchParameters != null &&
capabilities.SupportedMovieSearchParameters.Contains("tmdbid");
return capabilities.MovieSearchParams != null &&
capabilities.MovieSearchParams.Contains(MovieSearchParam.TmdbId);
}
}
@@ -61,7 +61,8 @@ namespace NzbDrone.Core.Indexers.Newznab
{
var capabilities = _capabilitiesProvider.GetCapabilities(Settings);
return capabilities.SupportsAggregateIdSearch;
// TODO: Fix this, return capabilities.SupportsAggregateIdSearch;
return true;
}
}
@@ -72,11 +73,11 @@ namespace NzbDrone.Core.Indexers.Newznab
var capabilities = _capabilitiesProvider.GetCapabilities(Settings);
// Some indexers might forget to enable movie search, but normal search still works fine. Thus we force a normal search.
if (capabilities.SupportedMovieSearchParameters != null)
if (capabilities.MovieSearchParams != null)
{
pageableRequests.Add(GetPagedRequests(MaxPages, Settings.Categories, "movie", ""));
}
else if (capabilities.SupportedSearchParameters != null)
else if (capabilities.SearchParams != null)
{
pageableRequests.Add(GetPagedRequests(MaxPages, Settings.Categories, "search", ""));
}
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using NzbDrone.Common.Extensions;
@@ -148,19 +147,6 @@ namespace NzbDrone.Core.Indexers.Newznab
return 0;
}
protected virtual string GetImdbTitle(XElement item)
{
var imdbTitle = TryGetNewznabAttribute(item, "imdbtitle");
if (!imdbTitle.IsNullOrWhiteSpace())
{
return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(
Parser.Parser.ReplaceGermanUmlauts(
Parser.Parser.NormalizeTitle(imdbTitle).Replace(" ", ".")));
}
return string.Empty;
}
protected virtual int GetImdbYear(XElement item)
{
var imdbYearString = TryGetNewznabAttribute(item, "imdbyear");