You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Prowlarr/src/NzbDrone.Core/Indexers/IndexerCapabilities.cs

330 lines
11 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace NzbDrone.Core.Indexers
{
public enum TvSearchParam
{
Q,
Season,
Ep,
ImdbId,
TvdbId,
RId,
TvMazeId
}
public enum MovieSearchParam
{
Q,
ImdbId,
TmdbId,
ImdbTitle,
ImdbYear
}
public enum MusicSearchParam
{
Q,
Album,
Artist,
Label,
Year
}
public enum SearchParam
{
Q
}
public enum BookSearchParam
{
Q
}
public class IndexerCapabilities
{
public int? LimitsMax { get; set; }
public int? LimitsDefault { get; set; }
public List<SearchParam> SearchParams;
public bool SearchAvailable => SearchParams.Count > 0;
public List<TvSearchParam> TvSearchParams;
public bool TvSearchAvailable => TvSearchParams.Count > 0;
public bool TvSearchSeasonAvailable => TvSearchParams.Contains(TvSearchParam.Season);
public bool TvSearchEpAvailable => TvSearchParams.Contains(TvSearchParam.Ep);
public bool TvSearchImdbAvailable => TvSearchParams.Contains(TvSearchParam.ImdbId);
public bool TvSearchTvdbAvailable => TvSearchParams.Contains(TvSearchParam.TvdbId);
public bool TvSearchTvRageAvailable => TvSearchParams.Contains(TvSearchParam.RId);
public bool TvSearchTvMazeAvailable => TvSearchParams.Contains(TvSearchParam.TvMazeId);
public List<MovieSearchParam> MovieSearchParams;
public bool MovieSearchAvailable => MovieSearchParams.Count > 0;
public bool MovieSearchImdbAvailable => MovieSearchParams.Contains(MovieSearchParam.ImdbId);
public bool MovieSearchTmdbAvailable => MovieSearchParams.Contains(MovieSearchParam.TmdbId);
public List<MusicSearchParam> MusicSearchParams;
public bool MusicSearchAvailable => MusicSearchParams.Count > 0;
public bool MusicSearchAlbumAvailable => MusicSearchParams.Contains(MusicSearchParam.Album);
public bool MusicSearchArtistAvailable => MusicSearchParams.Contains(MusicSearchParam.Artist);
public bool MusicSearchLabelAvailable => MusicSearchParams.Contains(MusicSearchParam.Label);
public bool MusicSearchYearAvailable => MusicSearchParams.Contains(MusicSearchParam.Year);
public List<BookSearchParam> BookSearchParams;
public bool BookSearchAvailable => BookSearchParams.Count > 0;
public List<IndexerCategory> Categories { get; private set; }
public IndexerCapabilities()
{
SearchParams = new List<SearchParam>();
TvSearchParams = new List<TvSearchParam>();
MovieSearchParams = new List<MovieSearchParam>();
MusicSearchParams = new List<MusicSearchParam>();
BookSearchParams = new List<BookSearchParam>();
Categories = new List<IndexerCategory>();
}
public void ParseTvSearchParams(IEnumerable<string> paramsList)
{
if (paramsList == null)
{
return;
}
foreach (var paramStr in paramsList)
{
if (Enum.TryParse(paramStr, true, out TvSearchParam param))
{
if (!TvSearchParams.Contains(param))
{
TvSearchParams.Add(param);
}
else
{
throw new Exception($"Duplicate tv-search param: {paramStr}");
}
}
else
{
throw new Exception($"Not supported tv-search param: {paramStr}");
}
}
}
public void ParseMovieSearchParams(IEnumerable<string> paramsList)
{
if (paramsList == null)
{
return;
}
foreach (var paramStr in paramsList)
{
if (Enum.TryParse(paramStr, true, out MovieSearchParam param))
{
if (!MovieSearchParams.Contains(param))
{
MovieSearchParams.Add(param);
}
else
{
throw new Exception($"Duplicate movie-search param: {paramStr}");
}
}
else
{
throw new Exception($"Not supported movie-search param: {paramStr}");
}
}
}
public void ParseMusicSearchParams(IEnumerable<string> paramsList)
{
if (paramsList == null)
{
return;
}
foreach (var paramStr in paramsList)
{
if (Enum.TryParse(paramStr, true, out MusicSearchParam param))
{
if (!MusicSearchParams.Contains(param))
{
MusicSearchParams.Add(param);
}
else
{
throw new Exception($"Duplicate music-search param: {paramStr}");
}
}
else
{
throw new Exception($"Not supported Music-search param: {paramStr}");
}
}
}
private string SupportedTvSearchParams()
{
var parameters = new List<string> { "q" }; // q is always enabled
if (TvSearchSeasonAvailable)
{
parameters.Add("season");
}
if (TvSearchEpAvailable)
{
parameters.Add("ep");
}
if (TvSearchImdbAvailable)
{
parameters.Add("imdbid");
}
if (TvSearchTvdbAvailable)
{
parameters.Add("tvdbid");
}
if (TvSearchTvRageAvailable)
{
parameters.Add("rid");
}
if (TvSearchTvMazeAvailable)
{
parameters.Add("tvmazeid");
}
return string.Join(",", parameters);
}
private string SupportedMovieSearchParams()
{
var parameters = new List<string> { "q" }; // q is always enabled
if (MovieSearchImdbAvailable)
{
parameters.Add("imdbid");
}
if (MovieSearchTmdbAvailable)
{
parameters.Add("tmdbid");
}
return string.Join(",", parameters);
}
private string SupportedMusicSearchParams()
{
var parameters = new List<string> { "q" }; // q is always enabled
if (MusicSearchAlbumAvailable)
{
parameters.Add("album");
}
if (MusicSearchArtistAvailable)
{
parameters.Add("artist");
}
if (MusicSearchLabelAvailable)
{
parameters.Add("label");
}
if (MusicSearchYearAvailable)
{
parameters.Add("year");
}
return string.Join(",", parameters);
}
private string SupportedBookSearchParams
{
get
{
var parameters = new List<string>() { "q" };
if (BookSearchAvailable)
{
parameters.Add("author,title");
}
return string.Join(",", parameters);
}
}
public bool SupportsCategories(int[] categories)
{
var subCategories = Categories.SelectMany(c => c.SubCategories);
var allCategories = Categories.Concat(subCategories);
var supportsCategory = allCategories.Any(i => categories.Any(c => c == i.Id));
return supportsCategory;
}
public XDocument GetXDocument()
{
var xdoc = new XDocument(
new XDeclaration("1.0", "UTF-8", null),
new XElement("caps",
new XElement("server",
new XAttribute("title", "Prowlarr")),
LimitsMax != null || LimitsDefault != null ?
new XElement("limits",
LimitsMax != null ? new XAttribute("max", LimitsMax) : null,
LimitsDefault != null ? new XAttribute("default", LimitsDefault) : null)
: null,
new XElement("searching",
new XElement("search",
new XAttribute("available", SearchAvailable ? "yes" : "no"),
new XAttribute("supportedParams", "q")),
new XElement("tv-search",
new XAttribute("available", TvSearchAvailable ? "yes" : "no"),
new XAttribute("supportedParams", SupportedTvSearchParams())),
new XElement("movie-search",
new XAttribute("available", MovieSearchAvailable ? "yes" : "no"),
new XAttribute("supportedParams", SupportedMovieSearchParams())),
new XElement("music-search",
new XAttribute("available", MusicSearchAvailable ? "yes" : "no"),
new XAttribute("supportedParams", SupportedMusicSearchParams())),
new XElement("audio-search",
new XAttribute("available", MusicSearchAvailable ? "yes" : "no"),
new XAttribute("supportedParams", SupportedMusicSearchParams())),
new XElement("book-search",
new XAttribute("available", BookSearchAvailable ? "yes" : "no"),
new XAttribute("supportedParams", SupportedBookSearchParams))),
new XElement("categories",
from c in Categories.OrderBy(x => x.Id < 100000 ? "z" + x.Id.ToString() : x.Name)
select new XElement("category",
new XAttribute("id", c.Id),
new XAttribute("name", c.Name),
from sc in c.SubCategories
select new XElement("subcat",
new XAttribute("id", sc.Id),
new XAttribute("name", sc.Name))))));
return xdoc;
}
public string ToXml() =>
GetXDocument().Declaration + Environment.NewLine + GetXDocument();
public static IndexerCapabilities Concat(IndexerCapabilities left, IndexerCapabilities right)
{
left.SearchParams = left.SearchParams.Union(right.SearchParams).ToList();
left.TvSearchParams = left.TvSearchParams.Union(right.TvSearchParams).ToList();
left.MovieSearchParams = left.MovieSearchParams.Union(right.MovieSearchParams).ToList();
left.MusicSearchParams = left.MusicSearchParams.Union(right.MusicSearchParams).ToList();
left.BookSearchParams = left.BookSearchParams.Union(right.BookSearchParams).ToList();
left.Categories.AddRange(right.Categories.Where(x => x.Id < 100000).Except(left.Categories)); // exclude indexer specific categories (>= 100000)
return left;
}
}
}