mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-27 12:33:24 +02:00
core: refactor book-search (#9897)
This commit is contained in:
@@ -18,7 +18,7 @@ caps:
|
|||||||
|
|
||||||
modes:
|
modes:
|
||||||
search: [q]
|
search: [q]
|
||||||
book-search: [q, author, title]
|
book-search: [q, title, author]
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
- name: username
|
- name: username
|
||||||
|
@@ -111,16 +111,8 @@ namespace Jackett.Common.Indexers
|
|||||||
DefaultSiteLink += "/";
|
DefaultSiteLink += "/";
|
||||||
Language = Definition.Language;
|
Language = Definition.Language;
|
||||||
Type = Definition.Type;
|
Type = Definition.Type;
|
||||||
TorznabCaps = new TorznabCapabilities
|
TorznabCaps = new TorznabCapabilities();
|
||||||
{
|
TorznabCaps.ParseCardigannSearchModes(Definition.Caps.Modes);
|
||||||
BookSearchAvailable = Definition.Caps.Modes.Any(c => c.Key == "book-search" && c.Value.Contains("author") && c.Value.Contains("title"))
|
|
||||||
};
|
|
||||||
if (Definition.Caps.Modes.ContainsKey("tv-search"))
|
|
||||||
TorznabCaps.ParseTvSearchParams(Definition.Caps.Modes["tv-search"]);
|
|
||||||
if (Definition.Caps.Modes.ContainsKey("movie-search"))
|
|
||||||
TorznabCaps.ParseMovieSearchParams(Definition.Caps.Modes["movie-search"]);
|
|
||||||
if (Definition.Caps.Modes.ContainsKey("music-search"))
|
|
||||||
TorznabCaps.ParseMusicSearchParams(Definition.Caps.Modes["music-search"]);
|
|
||||||
|
|
||||||
// init config Data
|
// init config Data
|
||||||
configData = new ConfigurationData();
|
configData = new ConfigurationData();
|
||||||
|
@@ -31,6 +31,13 @@ namespace Jackett.Common.Models
|
|||||||
Year
|
Year
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum BookSearchParam
|
||||||
|
{
|
||||||
|
Q,
|
||||||
|
Title,
|
||||||
|
Author
|
||||||
|
}
|
||||||
|
|
||||||
public class TorznabCapabilities
|
public class TorznabCapabilities
|
||||||
{
|
{
|
||||||
public int? LimitsMax { get; set; }
|
public int? LimitsMax { get; set; }
|
||||||
@@ -59,9 +66,12 @@ namespace Jackett.Common.Models
|
|||||||
public bool MusicSearchLabelAvailable => (MusicSearchParams.Contains(MusicSearchParam.Label));
|
public bool MusicSearchLabelAvailable => (MusicSearchParams.Contains(MusicSearchParam.Label));
|
||||||
public bool MusicSearchYearAvailable => (MusicSearchParams.Contains(MusicSearchParam.Year));
|
public bool MusicSearchYearAvailable => (MusicSearchParams.Contains(MusicSearchParam.Year));
|
||||||
|
|
||||||
public bool BookSearchAvailable { get; set; }
|
public List<BookSearchParam> BookSearchParams;
|
||||||
|
public bool BookSearchAvailable => (BookSearchParams.Count > 0);
|
||||||
|
public bool BookSearchTitleAvailable => (BookSearchParams.Contains(BookSearchParam.Title));
|
||||||
|
public bool BookSearchAuthorAvailable => (BookSearchParams.Contains(BookSearchParam.Author));
|
||||||
|
|
||||||
public List<TorznabCategory> Categories { get; private set; }
|
public List<TorznabCategory> Categories { get; set; }
|
||||||
|
|
||||||
public TorznabCapabilities()
|
public TorznabCapabilities()
|
||||||
{
|
{
|
||||||
@@ -69,11 +79,41 @@ namespace Jackett.Common.Models
|
|||||||
TvSearchParams = new List<TvSearchParam>();
|
TvSearchParams = new List<TvSearchParam>();
|
||||||
MovieSearchParams = new List<MovieSearchParam>();
|
MovieSearchParams = new List<MovieSearchParam>();
|
||||||
MusicSearchParams = new List<MusicSearchParam>();
|
MusicSearchParams = new List<MusicSearchParam>();
|
||||||
BookSearchAvailable = false;
|
BookSearchParams = new List<BookSearchParam>();
|
||||||
Categories = new List<TorznabCategory>();
|
Categories = new List<TorznabCategory>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ParseTvSearchParams(IEnumerable<string> paramsList)
|
public void ParseCardigannSearchModes(Dictionary<string,List<string>> modes)
|
||||||
|
{
|
||||||
|
if (modes == null || !modes.Any())
|
||||||
|
throw new Exception("At least one search mode is required");
|
||||||
|
if (!modes.ContainsKey("search"))
|
||||||
|
throw new Exception("The search mode 'search' is mandatory");
|
||||||
|
foreach (var entry in modes)
|
||||||
|
switch (entry.Key)
|
||||||
|
{
|
||||||
|
case "search":
|
||||||
|
if (entry.Value == null || entry.Value.Count != 1 || entry.Value[0] != "q")
|
||||||
|
throw new Exception("In search mode 'search' only 'q' parameter is supported and it's mandatory");
|
||||||
|
break;
|
||||||
|
case "tv-search":
|
||||||
|
ParseTvSearchParams(entry.Value);
|
||||||
|
break;
|
||||||
|
case "movie-search":
|
||||||
|
ParseMovieSearchParams(entry.Value);
|
||||||
|
break;
|
||||||
|
case "music-search":
|
||||||
|
ParseMusicSearchParams(entry.Value);
|
||||||
|
break;
|
||||||
|
case "book-search":
|
||||||
|
ParseBookSearchParams(entry.Value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception($"Unsupported search mode: {entry.Key}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseTvSearchParams(IEnumerable<string> paramsList)
|
||||||
{
|
{
|
||||||
if (paramsList == null)
|
if (paramsList == null)
|
||||||
return;
|
return;
|
||||||
@@ -87,7 +127,7 @@ namespace Jackett.Common.Models
|
|||||||
throw new Exception($"Not supported tv-search param: {paramStr}");
|
throw new Exception($"Not supported tv-search param: {paramStr}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ParseMovieSearchParams(IEnumerable<string> paramsList)
|
private void ParseMovieSearchParams(IEnumerable<string> paramsList)
|
||||||
{
|
{
|
||||||
if (paramsList == null)
|
if (paramsList == null)
|
||||||
return;
|
return;
|
||||||
@@ -101,7 +141,7 @@ namespace Jackett.Common.Models
|
|||||||
throw new Exception($"Not supported movie-search param: {paramStr}");
|
throw new Exception($"Not supported movie-search param: {paramStr}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ParseMusicSearchParams(IEnumerable<string> paramsList)
|
private void ParseMusicSearchParams(IEnumerable<string> paramsList)
|
||||||
{
|
{
|
||||||
if (paramsList == null)
|
if (paramsList == null)
|
||||||
return;
|
return;
|
||||||
@@ -112,7 +152,21 @@ namespace Jackett.Common.Models
|
|||||||
else
|
else
|
||||||
throw new Exception($"Duplicate music-search param: {paramStr}");
|
throw new Exception($"Duplicate music-search param: {paramStr}");
|
||||||
else
|
else
|
||||||
throw new Exception($"Not supported Music-search param: {paramStr}");
|
throw new Exception($"Not supported music-search param: {paramStr}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseBookSearchParams(IEnumerable<string> paramsList)
|
||||||
|
{
|
||||||
|
if (paramsList == null)
|
||||||
|
return;
|
||||||
|
foreach (var paramStr in paramsList)
|
||||||
|
if (Enum.TryParse(paramStr, true, out BookSearchParam param))
|
||||||
|
if (!BookSearchParams.Contains(param))
|
||||||
|
BookSearchParams.Add(param);
|
||||||
|
else
|
||||||
|
throw new Exception($"Duplicate book-search param: {paramStr}");
|
||||||
|
else
|
||||||
|
throw new Exception($"Not supported book-search param: {paramStr}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private string SupportedTvSearchParams()
|
private string SupportedTvSearchParams()
|
||||||
@@ -155,16 +209,15 @@ namespace Jackett.Common.Models
|
|||||||
return string.Join(",", parameters);
|
return string.Join(",", parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string SupportedBookSearchParams
|
private string SupportedBookSearchParams()
|
||||||
{
|
{
|
||||||
get
|
var parameters = new List<string> { "q" }; // q is always enabled
|
||||||
{
|
if (BookSearchTitleAvailable)
|
||||||
var parameters = new List<string>() { "q" };
|
parameters.Add("title");
|
||||||
if (BookSearchAvailable)
|
if (BookSearchAuthorAvailable)
|
||||||
parameters.Add("author,title");
|
parameters.Add("author");
|
||||||
return string.Join(",", parameters);
|
return string.Join(",", parameters);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public bool SupportsCategories(int[] categories)
|
public bool SupportsCategories(int[] categories)
|
||||||
{
|
{
|
||||||
@@ -212,7 +265,7 @@ namespace Jackett.Common.Models
|
|||||||
),
|
),
|
||||||
new XElement("book-search",
|
new XElement("book-search",
|
||||||
new XAttribute("available", BookSearchAvailable ? "yes" : "no"),
|
new XAttribute("available", BookSearchAvailable ? "yes" : "no"),
|
||||||
new XAttribute("supportedParams", SupportedBookSearchParams)
|
new XAttribute("supportedParams", SupportedBookSearchParams())
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
new XElement("categories",
|
new XElement("categories",
|
||||||
@@ -241,7 +294,7 @@ namespace Jackett.Common.Models
|
|||||||
lhs.TvSearchParams = lhs.TvSearchParams.Union(rhs.TvSearchParams).ToList();
|
lhs.TvSearchParams = lhs.TvSearchParams.Union(rhs.TvSearchParams).ToList();
|
||||||
lhs.MovieSearchParams = lhs.MovieSearchParams.Union(rhs.MovieSearchParams).ToList();
|
lhs.MovieSearchParams = lhs.MovieSearchParams.Union(rhs.MovieSearchParams).ToList();
|
||||||
lhs.MusicSearchParams = lhs.MusicSearchParams.Union(rhs.MusicSearchParams).ToList();
|
lhs.MusicSearchParams = lhs.MusicSearchParams.Union(rhs.MusicSearchParams).ToList();
|
||||||
lhs.BookSearchAvailable = lhs.BookSearchAvailable || rhs.BookSearchAvailable;
|
lhs.BookSearchParams = lhs.BookSearchParams.Union(rhs.BookSearchParams).ToList();
|
||||||
lhs.Categories.AddRange(rhs.Categories.Where(x => x.ID < 100000).Except(lhs.Categories)); // exclude indexer specific categories (>= 100000)
|
lhs.Categories.AddRange(rhs.Categories.Where(x => x.ID < 100000).Except(lhs.Categories)); // exclude indexer specific categories (>= 100000)
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
@@ -36,29 +36,47 @@ namespace Jackett.Test.Common.Models
|
|||||||
Assert.False(torznabCaps.MusicSearchLabelAvailable);
|
Assert.False(torznabCaps.MusicSearchLabelAvailable);
|
||||||
Assert.False(torznabCaps.MusicSearchYearAvailable);
|
Assert.False(torznabCaps.MusicSearchYearAvailable);
|
||||||
|
|
||||||
|
Assert.IsEmpty(torznabCaps.BookSearchParams);
|
||||||
Assert.False(torznabCaps.BookSearchAvailable);
|
Assert.False(torznabCaps.BookSearchAvailable);
|
||||||
|
Assert.False(torznabCaps.BookSearchTitleAvailable);
|
||||||
|
Assert.False(torznabCaps.BookSearchAuthorAvailable);
|
||||||
|
|
||||||
Assert.IsEmpty(torznabCaps.Categories);
|
Assert.IsEmpty(torznabCaps.Categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestParseMovieSearchParams()
|
public void TestParseCardigannSearchModes()
|
||||||
{
|
{
|
||||||
var torznabCaps = new TorznabCapabilities();
|
var torznabCaps = new TorznabCapabilities();
|
||||||
torznabCaps.ParseMovieSearchParams(null);
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
Assert.IsEmpty(torznabCaps.MovieSearchParams);
|
{
|
||||||
|
{"search", new List<string> {"q"}},
|
||||||
|
{"tv-search", new List<string> {"q"}},
|
||||||
|
{"movie-search", new List<string> {"q"}},
|
||||||
|
{"music-search", new List<string> {"q"}},
|
||||||
|
{"book-search", new List<string> {"q"}}
|
||||||
|
});
|
||||||
|
Assert.True(torznabCaps.SearchAvailable);
|
||||||
|
Assert.True(torznabCaps.TvSearchAvailable);
|
||||||
|
Assert.True(torznabCaps.MovieSearchAvailable);
|
||||||
|
Assert.True(torznabCaps.MusicSearchAvailable);
|
||||||
|
Assert.True(torznabCaps.BookSearchAvailable);
|
||||||
|
|
||||||
torznabCaps = new TorznabCapabilities();
|
torznabCaps = new TorznabCapabilities();
|
||||||
torznabCaps.ParseMovieSearchParams(new List<string>());
|
try
|
||||||
Assert.IsEmpty(torznabCaps.MovieSearchParams);
|
{
|
||||||
|
torznabCaps.ParseCardigannSearchModes(null); // null search modes
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
torznabCaps = new TorznabCapabilities();
|
torznabCaps = new TorznabCapabilities();
|
||||||
torznabCaps.ParseMovieSearchParams(new List<string> {"q", "imdbid"});
|
try
|
||||||
Assert.AreEqual(new List<MovieSearchParam> { MovieSearchParam.Q, MovieSearchParam.ImdbId }, torznabCaps.MovieSearchParams);
|
{
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>()); // empty search modes
|
||||||
torznabCaps = new TorznabCapabilities();
|
|
||||||
try {
|
|
||||||
torznabCaps.ParseMovieSearchParams(new List<string> {"q", "q"}); // duplicate param
|
|
||||||
Assert.Fail();
|
Assert.Fail();
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
@@ -68,7 +86,247 @@ namespace Jackett.Test.Common.Models
|
|||||||
|
|
||||||
torznabCaps = new TorznabCapabilities();
|
torznabCaps = new TorznabCapabilities();
|
||||||
try {
|
try {
|
||||||
torznabCaps.ParseMovieSearchParams(new List<string> {"bad"}); // unsupported param
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"bad", new List<string> {"q"}} // bad search mode
|
||||||
|
});
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
try {
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string> {"bad"}} // search mode with bad parameters
|
||||||
|
});
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestParseTvSearchParams()
|
||||||
|
{
|
||||||
|
var torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"tv-search", null}
|
||||||
|
});
|
||||||
|
Assert.IsEmpty(torznabCaps.MovieSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"tv-search", new List<string>()}
|
||||||
|
});
|
||||||
|
Assert.IsEmpty(torznabCaps.MovieSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"tv-search", new List<string> {"q", "tvdbid"}}
|
||||||
|
});
|
||||||
|
Assert.AreEqual(new List<TvSearchParam> { TvSearchParam.Q, TvSearchParam.TvdbId }, torznabCaps.TvSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
try {
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"tv-search", new List<string> {"q", "q"}} // duplicate param
|
||||||
|
});
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
try {
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"tv-search", new List<string> {"bad"}} // unsupported param
|
||||||
|
});
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestParseMovieSearchParams()
|
||||||
|
{
|
||||||
|
var torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"movie-search", null}
|
||||||
|
});
|
||||||
|
Assert.IsEmpty(torznabCaps.MovieSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"movie-search", new List<string>()}
|
||||||
|
});
|
||||||
|
Assert.IsEmpty(torznabCaps.MovieSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"movie-search", new List<string> {"q", "imdbid"}}
|
||||||
|
});
|
||||||
|
Assert.AreEqual(new List<MovieSearchParam> { MovieSearchParam.Q, MovieSearchParam.ImdbId }, torznabCaps.MovieSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
try {
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"movie-search", new List<string> {"q", "q"}} // duplicate param
|
||||||
|
});
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
try {
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"movie-search", new List<string> {"bad"}} // unsupported param
|
||||||
|
});
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestParseMusicSearchParams()
|
||||||
|
{
|
||||||
|
var torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"music-search", null}
|
||||||
|
});
|
||||||
|
Assert.IsEmpty(torznabCaps.MovieSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"music-search", new List<string>()}
|
||||||
|
});
|
||||||
|
Assert.IsEmpty(torznabCaps.MovieSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"music-search", new List<string> {"q", "label"}}
|
||||||
|
});
|
||||||
|
Assert.AreEqual(new List<MusicSearchParam> { MusicSearchParam.Q, MusicSearchParam.Label }, torznabCaps.MusicSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
try {
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"music-search", new List<string> {"q", "q"}} // duplicate param
|
||||||
|
});
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
try {
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"music-search", new List<string> {"bad"}} // unsupported param
|
||||||
|
});
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestParseBookSearchParams()
|
||||||
|
{
|
||||||
|
var torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"book-search", null}
|
||||||
|
});
|
||||||
|
Assert.IsEmpty(torznabCaps.MovieSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"book-search", new List<string>()}
|
||||||
|
});
|
||||||
|
Assert.IsEmpty(torznabCaps.MovieSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"book-search", new List<string> {"q", "title"}}
|
||||||
|
});
|
||||||
|
Assert.AreEqual(new List<BookSearchParam> { BookSearchParam.Q, BookSearchParam.Title }, torznabCaps.BookSearchParams);
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
try {
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"book-search", new List<string> {"q", "q"}} // duplicate param
|
||||||
|
});
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
torznabCaps = new TorznabCapabilities();
|
||||||
|
try {
|
||||||
|
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}},
|
||||||
|
{"book-search", new List<string> {"bad"}} // unsupported param
|
||||||
|
});
|
||||||
Assert.Fail();
|
Assert.Fail();
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
@@ -88,7 +346,6 @@ namespace Jackett.Test.Common.Models
|
|||||||
Assert.True(xDocument.Root?.Element("searching")?.HasElements);
|
Assert.True(xDocument.Root?.Element("searching")?.HasElements);
|
||||||
Assert.False(xDocument.Root?.Element("categories")?.HasElements);
|
Assert.False(xDocument.Root?.Element("categories")?.HasElements);
|
||||||
|
|
||||||
// TODO: remove params when it's disabled. Review Torznab specs
|
|
||||||
// test all features disabled
|
// test all features disabled
|
||||||
torznabCaps = new TorznabCapabilities
|
torznabCaps = new TorznabCapabilities
|
||||||
{
|
{
|
||||||
@@ -109,7 +366,6 @@ namespace Jackett.Test.Common.Models
|
|||||||
Assert.AreEqual("no", xDoumentSearching?.Element("book-search")?.Attribute("available")?.Value);
|
Assert.AreEqual("no", xDoumentSearching?.Element("book-search")?.Attribute("available")?.Value);
|
||||||
Assert.AreEqual("q", xDoumentSearching?.Element("book-search")?.Attribute("supportedParams")?.Value);
|
Assert.AreEqual("q", xDoumentSearching?.Element("book-search")?.Attribute("supportedParams")?.Value);
|
||||||
|
|
||||||
// TODO: book parameters should be configurable?
|
|
||||||
// test all features enabled
|
// test all features enabled
|
||||||
torznabCaps = new TorznabCapabilities
|
torznabCaps = new TorznabCapabilities
|
||||||
{
|
{
|
||||||
@@ -126,7 +382,10 @@ namespace Jackett.Test.Common.Models
|
|||||||
{
|
{
|
||||||
MusicSearchParam.Q, MusicSearchParam.Album, MusicSearchParam.Artist, MusicSearchParam.Label, MusicSearchParam.Year
|
MusicSearchParam.Q, MusicSearchParam.Album, MusicSearchParam.Artist, MusicSearchParam.Label, MusicSearchParam.Year
|
||||||
},
|
},
|
||||||
BookSearchAvailable = true
|
BookSearchParams = new List<BookSearchParam>
|
||||||
|
{
|
||||||
|
BookSearchParam.Q, BookSearchParam.Title, BookSearchParam.Author
|
||||||
|
},
|
||||||
};
|
};
|
||||||
xDocument = torznabCaps.GetXDocument();
|
xDocument = torznabCaps.GetXDocument();
|
||||||
xDoumentSearching = xDocument.Root?.Element("searching");
|
xDoumentSearching = xDocument.Root?.Element("searching");
|
||||||
@@ -141,7 +400,7 @@ namespace Jackett.Test.Common.Models
|
|||||||
Assert.AreEqual("yes", xDoumentSearching?.Element("audio-search")?.Attribute("available")?.Value);
|
Assert.AreEqual("yes", xDoumentSearching?.Element("audio-search")?.Attribute("available")?.Value);
|
||||||
Assert.AreEqual("q,album,artist,label,year", xDoumentSearching?.Element("audio-search")?.Attribute("supportedParams")?.Value);
|
Assert.AreEqual("q,album,artist,label,year", xDoumentSearching?.Element("audio-search")?.Attribute("supportedParams")?.Value);
|
||||||
Assert.AreEqual("yes", xDoumentSearching?.Element("book-search")?.Attribute("available")?.Value);
|
Assert.AreEqual("yes", xDoumentSearching?.Element("book-search")?.Attribute("available")?.Value);
|
||||||
Assert.AreEqual("q,author,title", xDoumentSearching?.Element("book-search")?.Attribute("supportedParams")?.Value);
|
Assert.AreEqual("q,title,author", xDoumentSearching?.Element("book-search")?.Attribute("supportedParams")?.Value);
|
||||||
|
|
||||||
// test categories
|
// test categories
|
||||||
torznabCaps = new TorznabCapabilities
|
torznabCaps = new TorznabCapabilities
|
||||||
|
@@ -55,7 +55,10 @@ namespace Jackett.Test.Torznab
|
|||||||
Assert.False(TorznabCaps.MusicSearchArtistAvailable);
|
Assert.False(TorznabCaps.MusicSearchArtistAvailable);
|
||||||
Assert.False(TorznabCaps.MusicSearchLabelAvailable);
|
Assert.False(TorznabCaps.MusicSearchLabelAvailable);
|
||||||
Assert.False(TorznabCaps.MusicSearchYearAvailable);
|
Assert.False(TorznabCaps.MusicSearchYearAvailable);
|
||||||
|
Assert.IsEmpty(TorznabCaps.BookSearchParams);
|
||||||
Assert.False(TorznabCaps.BookSearchAvailable);
|
Assert.False(TorznabCaps.BookSearchAvailable);
|
||||||
|
Assert.False(TorznabCaps.BookSearchTitleAvailable);
|
||||||
|
Assert.False(TorznabCaps.BookSearchAuthorAvailable);
|
||||||
Assert.AreEqual(0, TorznabCaps.Categories.Count);
|
Assert.AreEqual(0, TorznabCaps.Categories.Count);
|
||||||
|
|
||||||
// add "int" category (parent category)
|
// add "int" category (parent category)
|
||||||
@@ -247,7 +250,10 @@ namespace Jackett.Test.Torznab
|
|||||||
Links = new List<string>{ "https://example.com" },
|
Links = new List<string>{ "https://example.com" },
|
||||||
Caps = new capabilitiesBlock
|
Caps = new capabilitiesBlock
|
||||||
{
|
{
|
||||||
Modes = new Dictionary<string, List<string>>()
|
Modes = new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Search = new searchBlock()
|
Search = new searchBlock()
|
||||||
};
|
};
|
||||||
@@ -271,7 +277,10 @@ namespace Jackett.Test.Torznab
|
|||||||
Assert.False(indexer.TorznabCaps.MusicSearchArtistAvailable);
|
Assert.False(indexer.TorznabCaps.MusicSearchArtistAvailable);
|
||||||
Assert.False(indexer.TorznabCaps.MusicSearchLabelAvailable);
|
Assert.False(indexer.TorznabCaps.MusicSearchLabelAvailable);
|
||||||
Assert.False(indexer.TorznabCaps.MusicSearchYearAvailable);
|
Assert.False(indexer.TorznabCaps.MusicSearchYearAvailable);
|
||||||
|
Assert.IsEmpty(indexer.TorznabCaps.BookSearchParams);
|
||||||
Assert.False(indexer.TorznabCaps.BookSearchAvailable);
|
Assert.False(indexer.TorznabCaps.BookSearchAvailable);
|
||||||
|
Assert.False(indexer.TorznabCaps.BookSearchTitleAvailable);
|
||||||
|
Assert.False(indexer.TorznabCaps.BookSearchAuthorAvailable);
|
||||||
Assert.AreEqual(0, indexer.TorznabCaps.Categories.Count);
|
Assert.AreEqual(0, indexer.TorznabCaps.Categories.Count);
|
||||||
|
|
||||||
definition = new IndexerDefinition // test categories (same as in C# indexer)
|
definition = new IndexerDefinition // test categories (same as in C# indexer)
|
||||||
@@ -279,7 +288,10 @@ namespace Jackett.Test.Torznab
|
|||||||
Links = new List<string>{ "https://example.com" },
|
Links = new List<string>{ "https://example.com" },
|
||||||
Caps = new capabilitiesBlock
|
Caps = new capabilitiesBlock
|
||||||
{
|
{
|
||||||
Modes = new Dictionary<string, List<string>>(),
|
Modes = new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{"search", new List<string>{"q"}}
|
||||||
|
},
|
||||||
Categories = new Dictionary<string, string>
|
Categories = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
{"1", TorznabCatType.Movies.Name}, // integer cat (has children)
|
{"1", TorznabCatType.Movies.Name}, // integer cat (has children)
|
||||||
@@ -334,7 +346,7 @@ namespace Jackett.Test.Torznab
|
|||||||
{"tv-search", new List<string>{ "q", "season", "ep", "imdbid", "tvdbid", "rid" }},
|
{"tv-search", new List<string>{ "q", "season", "ep", "imdbid", "tvdbid", "rid" }},
|
||||||
{"movie-search", new List<string>{ "q", "imdbid", "tmdbid" }},
|
{"movie-search", new List<string>{ "q", "imdbid", "tmdbid" }},
|
||||||
{"music-search", new List<string>{ "q", "album", "artist", "label", "year" }},
|
{"music-search", new List<string>{ "q", "album", "artist", "label", "year" }},
|
||||||
{"book-search", new List<string>{ "q", "author", "title" }}
|
{"book-search", new List<string>{ "q", "title", "author" }}
|
||||||
},
|
},
|
||||||
Categories = new Dictionary<string, string>()
|
Categories = new Dictionary<string, string>()
|
||||||
},
|
},
|
||||||
@@ -343,22 +355,52 @@ namespace Jackett.Test.Torznab
|
|||||||
indexer = new CardigannIndexer(null, null, null, null, definition);
|
indexer = new CardigannIndexer(null, null, null, null, definition);
|
||||||
|
|
||||||
Assert.True(indexer.TorznabCaps.SearchAvailable);
|
Assert.True(indexer.TorznabCaps.SearchAvailable);
|
||||||
|
Assert.AreEqual(
|
||||||
|
new List<TvSearchParam>
|
||||||
|
{
|
||||||
|
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep, TvSearchParam.ImdbId, TvSearchParam.TvdbId, TvSearchParam.RId
|
||||||
|
},
|
||||||
|
indexer.TorznabCaps.TvSearchParams
|
||||||
|
);
|
||||||
Assert.True(indexer.TorznabCaps.TvSearchAvailable);
|
Assert.True(indexer.TorznabCaps.TvSearchAvailable);
|
||||||
|
Assert.True(indexer.TorznabCaps.TvSearchSeasonAvailable);
|
||||||
|
Assert.True(indexer.TorznabCaps.TvSearchEpAvailable);
|
||||||
// TODO: SupportsImdbTVSearch is disabled in Jackett.Common.Models.TorznabCapabilities.TvSearchImdbAvailable
|
// TODO: SupportsImdbTVSearch is disabled in Jackett.Common.Models.TorznabCapabilities.TvSearchImdbAvailable
|
||||||
Assert.False(indexer.TorznabCaps.TvSearchImdbAvailable);
|
Assert.False(indexer.TorznabCaps.TvSearchImdbAvailable);
|
||||||
Assert.True(indexer.TorznabCaps.TvSearchTvdbAvailable);
|
Assert.True(indexer.TorznabCaps.TvSearchTvdbAvailable);
|
||||||
Assert.True(indexer.TorznabCaps.TvSearchTvRageAvailable);
|
Assert.True(indexer.TorznabCaps.TvSearchTvRageAvailable);
|
||||||
Assert.AreEqual(
|
Assert.AreEqual(
|
||||||
new List<MovieSearchParam> { MovieSearchParam.Q, MovieSearchParam.ImdbId, MovieSearchParam.TmdbId },
|
new List<MovieSearchParam>
|
||||||
|
{
|
||||||
|
MovieSearchParam.Q, MovieSearchParam.ImdbId, MovieSearchParam.TmdbId
|
||||||
|
},
|
||||||
indexer.TorznabCaps.MovieSearchParams
|
indexer.TorznabCaps.MovieSearchParams
|
||||||
);
|
);
|
||||||
Assert.True(indexer.TorznabCaps.MovieSearchAvailable);
|
Assert.True(indexer.TorznabCaps.MovieSearchAvailable);
|
||||||
Assert.True(indexer.TorznabCaps.MovieSearchImdbAvailable);
|
Assert.True(indexer.TorznabCaps.MovieSearchImdbAvailable);
|
||||||
Assert.True(indexer.TorznabCaps.MovieSearchTmdbAvailable);
|
Assert.True(indexer.TorznabCaps.MovieSearchTmdbAvailable);
|
||||||
// TODO: improve this assert
|
Assert.AreEqual(
|
||||||
Assert.AreEqual(5, indexer.TorznabCaps.MusicSearchParams.Count);
|
new List<MusicSearchParam>
|
||||||
|
{
|
||||||
|
MusicSearchParam.Q, MusicSearchParam.Album, MusicSearchParam.Artist, MusicSearchParam.Label, MusicSearchParam.Year
|
||||||
|
},
|
||||||
|
indexer.TorznabCaps.MusicSearchParams
|
||||||
|
);
|
||||||
Assert.True(indexer.TorznabCaps.MusicSearchAvailable);
|
Assert.True(indexer.TorznabCaps.MusicSearchAvailable);
|
||||||
|
Assert.True(indexer.TorznabCaps.MusicSearchAlbumAvailable);
|
||||||
|
Assert.True(indexer.TorznabCaps.MusicSearchArtistAvailable);
|
||||||
|
Assert.True(indexer.TorznabCaps.MusicSearchLabelAvailable);
|
||||||
|
Assert.True(indexer.TorznabCaps.MusicSearchYearAvailable);
|
||||||
|
Assert.AreEqual(
|
||||||
|
new List<BookSearchParam>
|
||||||
|
{
|
||||||
|
BookSearchParam.Q, BookSearchParam.Title, BookSearchParam.Author
|
||||||
|
},
|
||||||
|
indexer.TorznabCaps.BookSearchParams
|
||||||
|
);
|
||||||
Assert.True(indexer.TorznabCaps.BookSearchAvailable);
|
Assert.True(indexer.TorznabCaps.BookSearchAvailable);
|
||||||
|
Assert.True(indexer.TorznabCaps.BookSearchTitleAvailable);
|
||||||
|
Assert.True(indexer.TorznabCaps.BookSearchAuthorAvailable);
|
||||||
|
|
||||||
// test Jackett UI categories (internal JSON) => same code path as C# indexer
|
// test Jackett UI categories (internal JSON) => same code path as C# indexer
|
||||||
// test Torznab caps (XML) => same code path as C# indexer
|
// test Torznab caps (XML) => same code path as C# indexer
|
||||||
|
Reference in New Issue
Block a user