Add support for book-search (#9306)

This commit is contained in:
ta264
2020-08-16 22:44:12 +01:00
committed by GitHub
parent dfdbbad532
commit df91bd4573
8 changed files with 81 additions and 20 deletions

View File

@@ -18,6 +18,7 @@ caps:
modes: modes:
search: [q] search: [q]
book-search: [q, author, title]
settings: settings:
- name: username - name: username
@@ -51,14 +52,12 @@ settings:
login: login:
path: / path: /
method: form method: post
form: form#loginform
submitpath: /
inputs: inputs:
action: login
username: "{{ .Config.username }}" username: "{{ .Config.username }}"
password: "{{ .Config.password }}" password: "{{ .Config.password }}"
keeploggedin: 1 keeplogged: 1
login: "Log In!"
error: error:
- selector: center:first-of-type - selector: center:first-of-type
test: test:
@@ -69,7 +68,7 @@ search:
paths: paths:
- path: torrents/ - path: torrents/
inputs: inputs:
search: "{{ .Keywords }}" search: "{{ if .Query.Author }} @authors {{ .Query.Author }}{{else}}{{end}}{{ if .Query.Title }} @title {{ .Query.Title }}{{else}}{{end}}{{ .Keywords }}"
$raw: "{{ range .Categories }}cat[]={{.}}&{{end}}" $raw: "{{ range .Categories }}cat[]={{.}}&{{end}}"
orderby: "{{ .Config.orderby }}" orderby: "{{ .Config.orderby }}"
order: "{{ .Config.order }}" order: "{{ .Config.order }}"
@@ -86,39 +85,48 @@ search:
div[title="Comics"]: 4 div[title="Comics"]: 4
div[title="Ebooks"]: 5 div[title="Ebooks"]: 5
div[title="Magazines"]: 7 div[title="Magazines"]: 7
_author:
selector: .authorLink
optional: true
_editor:
selector: .editorLink
optional: true
author:
text: "{{ or (.Result._author) (.Result._editor) }}"
_year: _year:
selector: .torYear selector: .torYear
optional: true optional: true
_filetype: _filetype:
selector: .torFormat selector: .torFormat
optional: true optional: true
title: _retail:
selector: .torRetail
optional: true
booktitle:
selector: .title a selector: .title a
title:
text: "{{.Result.booktitle}}"
filters: filters:
- name: append - name: append
args: "{{ if .Result._year }} {{ .Result._year }}{{else}}{{end}}{{ if .Result._filetype }} {{ .Result._filetype }}{{else}}{{end}}" args: "{{ if .Result.author }} by {{ .Result.author }}{{else}}{{end}}{{ if .Result._year }} {{ .Result._year }}{{else}}{{end}}{{ if .Result._filetype }} {{ .Result._filetype }}{{else}}{{end}}{{ if .Result._retail }} {{ .Result._retail }}{{else}}{{end}}"
details: details:
selector: .title a selector: .title a
attribute: href attribute: href
date: date:
optional: true optional: true
selector: .t_files_size_added time selector: .t_files_size_added time
filters: attribute: datetime
- name: timeago
download: download:
selector: a[title="Download"] selector: a[title="Download"]
attribute: href attribute: href
# files: files:
# selector: .t_files_size_added
# filters:
# - name: regexp
# args: "^\\s*(\\d+)\\s*file"
size:
selector: .t_files_size_added selector: .t_files_size_added
filters: filters:
- name: split - name: regexp
args: [",", 1] args: "^\\s*(\\d+)\\s*file"
- name: trim size:
selector: .t_files_size_added span
attribute: data-bytecount
seeders: seeders:
text: 0 text: 0
seeders: seeders:

View File

@@ -299,6 +299,8 @@ namespace Jackett.Common.Indexers
return true; return true;
if (caps.MusicSearchAvailable && query.IsMusicSearch) if (caps.MusicSearchAvailable && query.IsMusicSearch)
return true; return true;
if (caps.BookSearchAvailable && query.IsBookSearch)
return true;
if (caps.SupportsTVRageSearch && query.IsTVRageSearch) if (caps.SupportsTVRageSearch && query.IsTVRageSearch)
return true; return true;
if (caps.SupportsImdbMovieSearch && query.IsImdbQuery) if (caps.SupportsImdbMovieSearch && query.IsImdbQuery)

View File

@@ -113,7 +113,8 @@ namespace Jackett.Common.Indexers
Type = Definition.Type; Type = Definition.Type;
TorznabCaps = new TorznabCapabilities TorznabCaps = new TorznabCapabilities
{ {
SupportsImdbMovieSearch = Definition.Caps.Modes.Any(c => c.Key == "movie-search" && c.Value.Contains("imdbid")) SupportsImdbMovieSearch = Definition.Caps.Modes.Any(c => c.Key == "movie-search" && c.Value.Contains("imdbid")),
BookSearchAvailable = Definition.Caps.Modes.Any(c => c.Key == "book-search" && c.Value.Contains("author") && c.Value.Contains("title"))
}; };
if (Definition.Caps.Modes.ContainsKey("music-search")) if (Definition.Caps.Modes.ContainsKey("music-search"))
TorznabCaps.SupportedMusicSearchParamsList = Definition.Caps.Modes["music-search"]; TorznabCaps.SupportedMusicSearchParamsList = Definition.Caps.Modes["music-search"];
@@ -1237,6 +1238,8 @@ namespace Jackett.Common.Indexers
variables[".Query.Track"] = query.Track; variables[".Query.Track"] = query.Track;
//variables[".Query.Genre"] = query.Genre ?? new List<string>(); //variables[".Query.Genre"] = query.Genre ?? new List<string>();
variables[".Query.Episode"] = query.GetEpisodeSearchString(); variables[".Query.Episode"] = query.GetEpisodeSearchString();
variables[".Query.Author"] = query.Author;
variables[".Query.Title"] = query.Title;
var mappedCategories = MapTorznabCapsToTrackers(query); var mappedCategories = MapTorznabCapsToTrackers(query);
if (mappedCategories.Count == 0) if (mappedCategories.Count == 0)
@@ -1325,6 +1328,8 @@ namespace Jackett.Common.Indexers
} }
var searchUrlUri = new Uri(searchUrl); var searchUrlUri = new Uri(searchUrl);
logger.Info($"Fetching: {searchUrl}");
// send HTTP request // send HTTP request
WebClientStringResult response = null; WebClientStringResult response = null;
Dictionary<string, string> headers = null; Dictionary<string, string> headers = null;
@@ -1570,6 +1575,12 @@ namespace Jackett.Common.Indexers
release.TVDBId = ParseUtil.CoerceLong(TVDBId); release.TVDBId = ParseUtil.CoerceLong(TVDBId);
value = release.TVDBId.ToString(); value = release.TVDBId.ToString();
break; break;
case "author":
release.Author = value;
break;
case "booktitle":
release.BookTitle = value;
break;
case "banner": case "banner":
if (!string.IsNullOrWhiteSpace(value)) if (!string.IsNullOrWhiteSpace(value))
{ {

View File

@@ -21,6 +21,8 @@ namespace Jackett.Common.Models.DTO
public string track { get; set; } public string track { get; set; }
public string year { get; set; } public string year { get; set; }
public string genre { get; set; } public string genre { get; set; }
public string author { get; set; }
public string title { get; set; }
public string configured { get; set; } public string configured { get; set; }
public static TorznabQuery ToTorznabQuery(TorznabRequest request) public static TorznabQuery ToTorznabQuery(TorznabRequest request)
@@ -72,6 +74,11 @@ namespace Jackett.Common.Models.DTO
if (!string.IsNullOrWhiteSpace(request.genre)) if (!string.IsNullOrWhiteSpace(request.genre))
query.Genre = request.genre.Split(','); query.Genre = request.genre.Split(',');
if (!string.IsNullOrWhiteSpace(request.title))
query.Title = request.title;
if (!string.IsNullOrWhiteSpace(request.author))
query.Author = request.author;
query.ExpandCatsToSubCats(); query.ExpandCatsToSubCats();
return query; return query;

View File

@@ -24,6 +24,8 @@ namespace Jackett.Common.Models
public long? TVDBId { get; set; } public long? TVDBId { get; set; }
public long? Imdb { get; set; } public long? Imdb { get; set; }
public long? TMDb { get; set; } public long? TMDb { get; set; }
public string Author { get; set; }
public string BookTitle { get; set; }
public int? Seeders { get; set; } public int? Seeders { get; set; }
public int? Peers { get; set; } public int? Peers { get; set; }
public Uri BannerUrl { get; set; } public Uri BannerUrl { get; set; }
@@ -59,6 +61,8 @@ namespace Jackett.Common.Models
RageID = copyFrom.RageID; RageID = copyFrom.RageID;
Imdb = copyFrom.Imdb; Imdb = copyFrom.Imdb;
TMDb = copyFrom.TMDb; TMDb = copyFrom.TMDb;
Author = copyFrom.Author;
BookTitle = copyFrom.BookTitle;
Seeders = copyFrom.Seeders; Seeders = copyFrom.Seeders;
Peers = copyFrom.Peers; Peers = copyFrom.Peers;
BannerUrl = copyFrom.BannerUrl; BannerUrl = copyFrom.BannerUrl;

View File

@@ -82,6 +82,8 @@ namespace Jackett.Common.Models
getTorznabElement("rageid", r.RageID), getTorznabElement("rageid", r.RageID),
getTorznabElement("thetvdb", r.TVDBId), getTorznabElement("thetvdb", r.TVDBId),
getTorznabElement("imdb", r.Imdb == null ? null : ((long)r.Imdb).ToString("D7")), getTorznabElement("imdb", r.Imdb == null ? null : ((long)r.Imdb).ToString("D7")),
getTorznabElement("author", r.Author),
getTorznabElement("booktitle", r.BookTitle),
getTorznabElement("seeders", r.Seeders), getTorznabElement("seeders", r.Seeders),
getTorznabElement("peers", r.Peers), getTorznabElement("peers", r.Peers),
getTorznabElement("infohash", r.InfoHash), getTorznabElement("infohash", r.InfoHash),

View File

@@ -26,6 +26,8 @@ namespace Jackett.Common.Models
public List<string> SupportedMusicSearchParamsList; public List<string> SupportedMusicSearchParamsList;
public bool BookSearchAvailable { get; set; }
public List<TorznabCategory> Categories { get; private set; } public List<TorznabCategory> Categories { get; private set; }
public TorznabCapabilities() public TorznabCapabilities()
@@ -38,6 +40,7 @@ namespace Jackett.Common.Models
SupportsImdbMovieSearch = false; SupportsImdbMovieSearch = false;
SupportsImdbTVSearch = false; SupportsImdbTVSearch = false;
SupportedMusicSearchParamsList = new List<string>(); SupportedMusicSearchParamsList = new List<string>();
BookSearchAvailable = false;
} }
public TorznabCapabilities(params TorznabCategory[] cats) public TorznabCapabilities(params TorznabCategory[] cats)
@@ -48,6 +51,7 @@ namespace Jackett.Common.Models
SupportsImdbMovieSearch = false; SupportsImdbMovieSearch = false;
SupportsImdbTVSearch = false; SupportsImdbTVSearch = false;
SupportedMusicSearchParamsList = new List<string>(); SupportedMusicSearchParamsList = new List<string>();
BookSearchAvailable = false;
Categories = new List<TorznabCategory>(); Categories = new List<TorznabCategory>();
Categories.AddRange(cats); Categories.AddRange(cats);
MovieSearchAvailable = Categories.Any(i => TorznabCatType.Movies.Contains(i)); MovieSearchAvailable = Categories.Any(i => TorznabCatType.Movies.Contains(i));
@@ -79,6 +83,17 @@ namespace Jackett.Common.Models
private string SupportedMusicSearchParams => string.Join(",", SupportedMusicSearchParamsList); private string SupportedMusicSearchParams => string.Join(",", SupportedMusicSearchParamsList);
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) public bool SupportsCategories(int[] categories)
{ {
var subCategories = Categories.SelectMany(c => c.SubCategories); var subCategories = Categories.SelectMany(c => c.SubCategories);
@@ -122,6 +137,10 @@ namespace Jackett.Common.Models
new XElement("audio-search", new XElement("audio-search",
new XAttribute("available", MusicSearchAvailable ? "yes" : "no"), new XAttribute("available", MusicSearchAvailable ? "yes" : "no"),
new XAttribute("supportedParams", SupportedMusicSearchParams) new XAttribute("supportedParams", SupportedMusicSearchParams)
),
new XElement("book-search",
new XAttribute("available", BookSearchAvailable ? "yes" : "no"),
new XAttribute("supportedParams", SupportedBookSearchParams)
) )
), ),
new XElement("categories", new XElement("categories",
@@ -149,6 +168,7 @@ namespace Jackett.Common.Models
lhs.SearchAvailable = lhs.SearchAvailable || rhs.SearchAvailable; lhs.SearchAvailable = lhs.SearchAvailable || rhs.SearchAvailable;
lhs.TVSearchAvailable = lhs.TVSearchAvailable || rhs.TVSearchAvailable; lhs.TVSearchAvailable = lhs.TVSearchAvailable || rhs.TVSearchAvailable;
lhs.MovieSearchAvailable = lhs.MovieSearchAvailable || rhs.MovieSearchAvailable; lhs.MovieSearchAvailable = lhs.MovieSearchAvailable || rhs.MovieSearchAvailable;
lhs.BookSearchAvailable = lhs.BookSearchAvailable || rhs.BookSearchAvailable;
lhs.SupportsTVRageSearch = lhs.SupportsTVRageSearch || rhs.SupportsTVRageSearch; lhs.SupportsTVRageSearch = lhs.SupportsTVRageSearch || rhs.SupportsTVRageSearch;
lhs.SupportsImdbMovieSearch = lhs.SupportsImdbMovieSearch || rhs.SupportsImdbMovieSearch; lhs.SupportsImdbMovieSearch = lhs.SupportsImdbMovieSearch || rhs.SupportsImdbMovieSearch;
lhs.SupportsImdbTVSearch = lhs.SupportsImdbTVSearch || rhs.SupportsImdbTVSearch; lhs.SupportsImdbTVSearch = lhs.SupportsImdbTVSearch || rhs.SupportsImdbTVSearch;

View File

@@ -29,6 +29,9 @@ namespace Jackett.Common.Models
public int? Year { get; set; } public int? Year { get; set; }
public ICollection<string> Genre { get; set; } public ICollection<string> Genre { get; set; }
public string Author { get; set; }
public string Title { get; set; }
public bool IsTest { get; set; } public bool IsTest { get; set; }
public string ImdbIDShort => ImdbID?.TrimStart('t'); public string ImdbIDShort => ImdbID?.TrimStart('t');
@@ -43,6 +46,8 @@ namespace Jackett.Common.Models
public bool IsMusicSearch => QueryType == "music"; public bool IsMusicSearch => QueryType == "music";
public bool IsBookSearch => QueryType == "book";
public bool IsTVRageSearch => RageID != null; public bool IsTVRageSearch => RageID != null;
public bool IsImdbQuery => ImdbID != null; public bool IsImdbQuery => ImdbID != null;
@@ -121,6 +126,8 @@ namespace Jackett.Common.Models
Label = Label, Label = Label,
Track = Track, Track = Track,
Year = Year, Year = Year,
Author = Author,
Title = Title,
RageID = RageID, RageID = RageID,
ImdbID = ImdbID ImdbID = ImdbID
}; };