diff --git a/src/Jackett.Common/Indexers/CardigannIndexer.cs b/src/Jackett.Common/Indexers/CardigannIndexer.cs index b40bfef9d..3bb75cc18 100644 --- a/src/Jackett.Common/Indexers/CardigannIndexer.cs +++ b/src/Jackett.Common/Indexers/CardigannIndexer.cs @@ -120,7 +120,7 @@ namespace Jackett.Common.Indexers if (Definition.Caps.Modes.ContainsKey("movie-search")) TorznabCaps.ParseMovieSearchParams(Definition.Caps.Modes["movie-search"]); if (Definition.Caps.Modes.ContainsKey("music-search")) - TorznabCaps.SupportedMusicSearchParamsList = Definition.Caps.Modes["music-search"]; + TorznabCaps.ParseMusicSearchParams(Definition.Caps.Modes["music-search"]); // init config Data configData = new ConfigurationData(); diff --git a/src/Jackett.Common/Indexers/DICMusic.cs b/src/Jackett.Common/Indexers/DICMusic.cs index 941bfd671..fdda2a640 100644 --- a/src/Jackett.Common/Indexers/DICMusic.cs +++ b/src/Jackett.Common/Indexers/DICMusic.cs @@ -20,7 +20,10 @@ namespace Jackett.Common.Indexers link: "https://dicmusic.club/", caps: new TorznabCapabilities { - SupportedMusicSearchParamsList = new List { "q", "album", "artist", "label", "year" } + MusicSearchParams = new List + { + MusicSearchParam.Q, MusicSearchParam.Album, MusicSearchParam.Artist, MusicSearchParam.Label, MusicSearchParam.Year + } }, configService: configService, client: wc, diff --git a/src/Jackett.Common/Indexers/Libble.cs b/src/Jackett.Common/Indexers/Libble.cs index 3f8faa37e..127733d54 100644 --- a/src/Jackett.Common/Indexers/Libble.cs +++ b/src/Jackett.Common/Indexers/Libble.cs @@ -63,7 +63,10 @@ namespace Jackett.Common.Indexers link: "https://libble.me/", caps: new TorznabCapabilities { - SupportedMusicSearchParamsList = new List { "q", "album", "artist", "label", "year" } + MusicSearchParams = new List + { + MusicSearchParam.Q, MusicSearchParam.Album, MusicSearchParam.Artist, MusicSearchParam.Label, MusicSearchParam.Year + } }, configService: configService, client: wc, diff --git a/src/Jackett.Common/Indexers/NotWhatCD.cs b/src/Jackett.Common/Indexers/NotWhatCD.cs index 3e25efe24..59dd5aade 100644 --- a/src/Jackett.Common/Indexers/NotWhatCD.cs +++ b/src/Jackett.Common/Indexers/NotWhatCD.cs @@ -27,9 +27,9 @@ namespace Jackett.Common.Indexers { MovieSearchParam.Q }, - SupportedMusicSearchParamsList = new List + MusicSearchParams = new List { - "q", "album", "artist", "label", "year" + MusicSearchParam.Q, MusicSearchParam.Album, MusicSearchParam.Artist, MusicSearchParam.Label, MusicSearchParam.Year } }, configService: configService, diff --git a/src/Jackett.Common/Indexers/Orpheus.cs b/src/Jackett.Common/Indexers/Orpheus.cs index f351c295e..56b085410 100644 --- a/src/Jackett.Common/Indexers/Orpheus.cs +++ b/src/Jackett.Common/Indexers/Orpheus.cs @@ -27,9 +27,9 @@ namespace Jackett.Common.Indexers { MovieSearchParam.Q }, - SupportedMusicSearchParamsList = new List + MusicSearchParams = new List { - "q", "album", "artist", "label", "year" + MusicSearchParam.Q, MusicSearchParam.Album, MusicSearchParam.Artist, MusicSearchParam.Label, MusicSearchParam.Year } }, configService: configService, diff --git a/src/Jackett.Common/Indexers/Redacted.cs b/src/Jackett.Common/Indexers/Redacted.cs index 5d3ee069c..a3e33775f 100644 --- a/src/Jackett.Common/Indexers/Redacted.cs +++ b/src/Jackett.Common/Indexers/Redacted.cs @@ -31,9 +31,9 @@ namespace Jackett.Common.Indexers { MovieSearchParam.Q }, - SupportedMusicSearchParamsList = new List + MusicSearchParams = new List { - "q", "album", "artist", "label", "year" + MusicSearchParam.Q, MusicSearchParam.Album, MusicSearchParam.Artist, MusicSearchParam.Label, MusicSearchParam.Year } }, configService: configService, diff --git a/src/Jackett.Common/Indexers/SecretCinema.cs b/src/Jackett.Common/Indexers/SecretCinema.cs index c3b7bef1f..bfa128400 100644 --- a/src/Jackett.Common/Indexers/SecretCinema.cs +++ b/src/Jackett.Common/Indexers/SecretCinema.cs @@ -25,9 +25,9 @@ namespace Jackett.Common.Indexers { MovieSearchParam.Q, MovieSearchParam.ImdbId }, - SupportedMusicSearchParamsList = new List + MusicSearchParams = new List { - "q", "album", "artist", "label", "year" + MusicSearchParam.Q, MusicSearchParam.Album, MusicSearchParam.Artist, MusicSearchParam.Label, MusicSearchParam.Year } }, configService: configService, diff --git a/src/Jackett.Common/Models/TorznabCapabilities.cs b/src/Jackett.Common/Models/TorznabCapabilities.cs index b5ef77b4b..b8c0a1bc6 100644 --- a/src/Jackett.Common/Models/TorznabCapabilities.cs +++ b/src/Jackett.Common/Models/TorznabCapabilities.cs @@ -22,6 +22,15 @@ namespace Jackett.Common.Models TmdbId } + public enum MusicSearchParam + { + Q, + Album, + Artist, + Label, + Year + } + public class TorznabCapabilities { public int? LimitsMax { get; set; } @@ -43,8 +52,12 @@ namespace Jackett.Common.Models public bool MovieSearchImdbAvailable => (MovieSearchParams.Contains(MovieSearchParam.ImdbId)); public bool MovieSearchTmdbAvailable => (MovieSearchParams.Contains(MovieSearchParam.TmdbId)); - public List SupportedMusicSearchParamsList; - public bool MusicSearchAvailable => (SupportedMusicSearchParamsList.Count > 0); + public List 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 bool BookSearchAvailable { get; set; } @@ -55,7 +68,7 @@ namespace Jackett.Common.Models SearchAvailable = true; TvSearchParams = new List(); MovieSearchParams = new List(); - SupportedMusicSearchParamsList = new List(); + MusicSearchParams = new List(); BookSearchAvailable = false; Categories = new List(); } @@ -88,6 +101,20 @@ namespace Jackett.Common.Models throw new Exception($"Not supported movie-search param: {paramStr}"); } + public void ParseMusicSearchParams(IEnumerable 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 { "q" }; // q is always enabled @@ -114,7 +141,19 @@ namespace Jackett.Common.Models return string.Join(",", parameters); } - private string SupportedMusicSearchParams => string.Join(",", SupportedMusicSearchParamsList); + private string SupportedMusicSearchParams() + { + var parameters = new List { "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 { @@ -164,12 +203,12 @@ namespace Jackett.Common.Models ), new XElement("music-search", new XAttribute("available", MusicSearchAvailable ? "yes" : "no"), - new XAttribute("supportedParams", SupportedMusicSearchParams) + new XAttribute("supportedParams", SupportedMusicSearchParams()) ), // inconsistend but apparently already used by various newznab indexers (see #1896) new XElement("audio-search", new XAttribute("available", MusicSearchAvailable ? "yes" : "no"), - new XAttribute("supportedParams", SupportedMusicSearchParams) + new XAttribute("supportedParams", SupportedMusicSearchParams()) ), new XElement("book-search", new XAttribute("available", BookSearchAvailable ? "yes" : "no"), @@ -201,7 +240,7 @@ namespace Jackett.Common.Models lhs.SearchAvailable = lhs.SearchAvailable || rhs.SearchAvailable; lhs.TvSearchParams = lhs.TvSearchParams.Union(rhs.TvSearchParams).ToList(); lhs.MovieSearchParams = lhs.MovieSearchParams.Union(rhs.MovieSearchParams).ToList(); - // TODO: add music search + lhs.MusicSearchParams = lhs.MusicSearchParams.Union(rhs.MusicSearchParams).ToList(); lhs.BookSearchAvailable = lhs.BookSearchAvailable || rhs.BookSearchAvailable; lhs.Categories.AddRange(rhs.Categories.Where(x => x.ID < 100000).Except(lhs.Categories)); // exclude indexer specific categories (>= 100000) return lhs; diff --git a/src/Jackett.Test/Common/Models/TorznabCapabilitiesTests.cs b/src/Jackett.Test/Common/Models/TorznabCapabilitiesTests.cs index 2d63333dc..43e56f8ec 100644 --- a/src/Jackett.Test/Common/Models/TorznabCapabilitiesTests.cs +++ b/src/Jackett.Test/Common/Models/TorznabCapabilitiesTests.cs @@ -13,7 +13,6 @@ namespace Jackett.Test.Common.Models [Test] public void TestConstructors() { - // TODO: initialize MusicSearchAvailable var torznabCaps = new TorznabCapabilities(); Assert.True(torznabCaps.SearchAvailable); @@ -30,8 +29,12 @@ namespace Jackett.Test.Common.Models Assert.False(torznabCaps.MovieSearchImdbAvailable); Assert.False(torznabCaps.MovieSearchTmdbAvailable); - Assert.IsEmpty(torznabCaps.SupportedMusicSearchParamsList); - Assert.False(torznabCaps.MusicSearchAvailable); // init + Assert.IsEmpty(torznabCaps.MusicSearchParams); + Assert.False(torznabCaps.MusicSearchAvailable); + Assert.False(torznabCaps.MusicSearchAlbumAvailable); + Assert.False(torznabCaps.MusicSearchArtistAvailable); + Assert.False(torznabCaps.MusicSearchLabelAvailable); + Assert.False(torznabCaps.MusicSearchYearAvailable); Assert.False(torznabCaps.BookSearchAvailable); @@ -100,13 +103,12 @@ namespace Jackett.Test.Common.Models Assert.AreEqual("no", xDoumentSearching?.Element("movie-search")?.Attribute("available")?.Value); Assert.AreEqual("q", xDoumentSearching?.Element("movie-search")?.Attribute("supportedParams")?.Value); Assert.AreEqual("no", xDoumentSearching?.Element("music-search")?.Attribute("available")?.Value); - Assert.AreEqual("", xDoumentSearching?.Element("music-search")?.Attribute("supportedParams")?.Value); + Assert.AreEqual("q", xDoumentSearching?.Element("music-search")?.Attribute("supportedParams")?.Value); Assert.AreEqual("no", xDoumentSearching?.Element("audio-search")?.Attribute("available")?.Value); - Assert.AreEqual("", xDoumentSearching?.Element("audio-search")?.Attribute("supportedParams")?.Value); + Assert.AreEqual("q", xDoumentSearching?.Element("audio-search")?.Attribute("supportedParams")?.Value); Assert.AreEqual("no", xDoumentSearching?.Element("book-search")?.Attribute("available")?.Value); Assert.AreEqual("q", xDoumentSearching?.Element("book-search")?.Attribute("supportedParams")?.Value); - // TODO: validate invalid music params // TODO: book parameters should be configurable? // test all features enabled torznabCaps = new TorznabCapabilities @@ -120,7 +122,10 @@ namespace Jackett.Test.Common.Models { MovieSearchParam.Q, MovieSearchParam.ImdbId, MovieSearchParam.TmdbId }, - SupportedMusicSearchParamsList = new List{"q", "album", "artist", "label", "year"}, + MusicSearchParams = new List + { + MusicSearchParam.Q, MusicSearchParam.Album, MusicSearchParam.Artist, MusicSearchParam.Label, MusicSearchParam.Year + }, BookSearchAvailable = true }; xDocument = torznabCaps.GetXDocument(); diff --git a/src/Jackett.Test/Torznab/TorznabTests.cs b/src/Jackett.Test/Torznab/TorznabTests.cs index d71ff1819..53a1a684d 100644 --- a/src/Jackett.Test/Torznab/TorznabTests.cs +++ b/src/Jackett.Test/Torznab/TorznabTests.cs @@ -49,8 +49,12 @@ namespace Jackett.Test.Torznab Assert.False(TorznabCaps.MovieSearchAvailable); Assert.False(TorznabCaps.MovieSearchImdbAvailable); Assert.False(TorznabCaps.MovieSearchTmdbAvailable); - Assert.IsEmpty(TorznabCaps.SupportedMusicSearchParamsList); + Assert.IsEmpty(TorznabCaps.MusicSearchParams); Assert.False(TorznabCaps.MusicSearchAvailable); + Assert.False(TorznabCaps.MusicSearchAlbumAvailable); + Assert.False(TorznabCaps.MusicSearchArtistAvailable); + Assert.False(TorznabCaps.MusicSearchLabelAvailable); + Assert.False(TorznabCaps.MusicSearchYearAvailable); Assert.False(TorznabCaps.BookSearchAvailable); Assert.AreEqual(0, TorznabCaps.Categories.Count); @@ -261,8 +265,12 @@ namespace Jackett.Test.Torznab Assert.False(indexer.TorznabCaps.MovieSearchAvailable); Assert.False(indexer.TorznabCaps.MovieSearchImdbAvailable); Assert.False(indexer.TorznabCaps.MovieSearchTmdbAvailable); - Assert.IsEmpty(indexer.TorznabCaps.SupportedMusicSearchParamsList); + Assert.IsEmpty(indexer.TorznabCaps.MusicSearchParams); Assert.False(indexer.TorznabCaps.MusicSearchAvailable); + Assert.False(indexer.TorznabCaps.MusicSearchAlbumAvailable); + Assert.False(indexer.TorznabCaps.MusicSearchArtistAvailable); + Assert.False(indexer.TorznabCaps.MusicSearchLabelAvailable); + Assert.False(indexer.TorznabCaps.MusicSearchYearAvailable); Assert.False(indexer.TorznabCaps.BookSearchAvailable); Assert.AreEqual(0, indexer.TorznabCaps.Categories.Count); @@ -348,7 +356,7 @@ namespace Jackett.Test.Torznab Assert.True(indexer.TorznabCaps.MovieSearchImdbAvailable); Assert.True(indexer.TorznabCaps.MovieSearchTmdbAvailable); // TODO: improve this assert - Assert.AreEqual(5, indexer.TorznabCaps.SupportedMusicSearchParamsList.Count); + Assert.AreEqual(5, indexer.TorznabCaps.MusicSearchParams.Count); Assert.True(indexer.TorznabCaps.MusicSearchAvailable); Assert.True(indexer.TorznabCaps.BookSearchAvailable);