mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
@@ -1,198 +0,0 @@
|
||||
---
|
||||
id: audiobookbay
|
||||
name: AudioBookBay
|
||||
description: "AudioBook Bay (ABB) is a public Torrent Tracker for AUDIOBOOKS"
|
||||
language: en-US
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
requestDelay: 2
|
||||
links:
|
||||
- https://audiobookbay.li/
|
||||
- https://audiobookbay.se/
|
||||
legacylinks:
|
||||
- https://audiobookbay.la/
|
||||
- http://audiobookbay.net/
|
||||
- https://audiobookbay.unblockit.tv/
|
||||
- http://audiobookbay.nl/
|
||||
- http://audiobookbay.ws/
|
||||
- https://audiobookbay.unblockit.how/
|
||||
- https://audiobookbay.unblockit.cam/
|
||||
- https://audiobookbay.unblockit.biz/
|
||||
- https://audiobookbay.unblockit.day/
|
||||
- https://audiobookbay.unblockit.llc/
|
||||
- https://audiobookbay.unblockit.blue/
|
||||
- https://audiobookbay.unblockit.name/
|
||||
- http://audiobookbay.fi/
|
||||
- http://audiobookbay.se/
|
||||
- http://audiobookbayabb.com/
|
||||
- https://audiobookbay.unblockit.ist/
|
||||
- https://audiobookbay.unblockit.bet/
|
||||
- https://audiobookbay.unblockit.cat/
|
||||
- https://audiobookbay.unblockit.nz/
|
||||
- https://audiobookbay.fi/
|
||||
- https://audiobookbay.unblockit.page/
|
||||
- https://audiobookbay.unblockit.pet/
|
||||
- https://audiobookbay.unblockit.ink/
|
||||
- https://audiobookbay.unblockit.bio/ # error 502
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: "(Post)apocalyptic", cat: Audio/Audiobook, desc: "(Post)apocalyptic"}
|
||||
- {id: Action, cat: Audio/Audiobook, desc: "Action"}
|
||||
- {id: Adults, cat: Audio/Audiobook, desc: "Adults"}
|
||||
- {id: Adventure, cat: Audio/Audiobook, desc: "Adventure"}
|
||||
- {id: Anthology, cat: Audio/Audiobook, desc: "Anthology"}
|
||||
- {id: Art, cat: Audio/Audiobook, desc: "Art"}
|
||||
- {id: Autobiography, cat: Audio/Audiobook, desc: "Autobiography & Biographies"}
|
||||
- {id: Bestsellers, cat: Audio/Audiobook, desc: "Bestsellers"}
|
||||
- {id: Business, cat: Audio/Audiobook, desc: "Business"}
|
||||
- {id: Children, cat: Audio/Audiobook, desc: "Children"}
|
||||
- {id: Classic, cat: Audio/Audiobook, desc: "Classic"}
|
||||
- {id: Computer, cat: Audio/Audiobook, desc: "Computer"}
|
||||
- {id: Contemporary, cat: Audio/Audiobook, desc: "Contemporary"}
|
||||
- {id: Crime, cat: Audio/Audiobook, desc: "Crime"}
|
||||
- {id: Detective, cat: Audio/Audiobook, desc: "Detective"}
|
||||
- {id: Doctor, cat: Audio/Audiobook, desc: "Doctor Who"}
|
||||
- {id: Documentary, cat: Audio/Audiobook, desc: "Documentary"}
|
||||
- {id: Education, cat: Audio/Audiobook, desc: "Education"}
|
||||
- {id: Fantasy, cat: Audio/Audiobook, desc: "Fantasy"}
|
||||
- {id: Full, cat: Audio/Audiobook, desc: "Full Cast"}
|
||||
- {id: Gay, cat: Audio/Audiobook, desc: "Gay"}
|
||||
- {id: General, cat: Audio/Audiobook, desc: "General Fiction"}
|
||||
- {id: Historical, cat: Audio/Audiobook, desc: "Historical Fiction"}
|
||||
- {id: History, cat: Audio/Audiobook, desc: "History"}
|
||||
- {id: Horror, cat: Audio/Audiobook, desc: "Horror"}
|
||||
- {id: Humor, cat: Audio/Audiobook, desc: "Humor"}
|
||||
- {id: Lecture, cat: Audio/Audiobook, desc: "Lecture"}
|
||||
- {id: Lesbian, cat: Audio/Audiobook, desc: "Lesbian"}
|
||||
- {id: LGBT, cat: Audio/Audiobook, desc: "LGBT"}
|
||||
- {id: Libertarian, cat: Audio/Audiobook, desc: "Libertarian"}
|
||||
- {id: Literature, cat: Audio/Audiobook, desc: "Literature"}
|
||||
- {id: LitRPG, cat: Audio/Audiobook, desc: "LitRPG"}
|
||||
- {id: Military, cat: Audio/Audiobook, desc: "Military"}
|
||||
- {id: Misc., cat: Audio/Audiobook, desc: "Misc. Non-fiction"}
|
||||
- {id: Mystery, cat: Audio/Audiobook, desc: "Mystery"}
|
||||
- {id: Novel, cat: Audio/Audiobook, desc: "Novel"}
|
||||
- {id: Other, cat: Audio/Audiobook, desc: "Other"}
|
||||
- {id: Paranormal, cat: Audio/Audiobook, desc: "Paranormal"}
|
||||
- {id: Plays, cat: Audio/Audiobook, desc: "Plays & Theater"}
|
||||
- {id: Poetry, cat: Audio/Audiobook, desc: "Poetry"}
|
||||
- {id: Political, cat: Audio/Audiobook, desc: "Political"}
|
||||
- {id: Radio, cat: Audio/Audiobook, desc: "Radio Productions"}
|
||||
- {id: Romance, cat: Audio/Audiobook, desc: "Romance"}
|
||||
- {id: Sci-Fi, cat: Audio/Audiobook, desc: "Sci-Fi"}
|
||||
- {id: Science, cat: Audio/Audiobook, desc: "Science"}
|
||||
- {id: Self-help, cat: Audio/Audiobook, desc: "Self-help"}
|
||||
- {id: Sex, cat: Audio/Audiobook, desc: "Sex Scenes"}
|
||||
- {id: Short, cat: Audio/Audiobook, desc: "Short Story"}
|
||||
- {id: Spiritual, cat: Audio/Audiobook, desc: "Spiritual & Religious"}
|
||||
- {id: Sport, cat: Audio/Audiobook, desc: "Sport & Recreation"}
|
||||
- {id: Suspense, cat: Audio/Audiobook, desc: "Suspense"}
|
||||
- {id: Teen, cat: Audio/Audiobook, desc: "Teen & Young Adult"}
|
||||
- {id: Thriller, cat: Audio/Audiobook, desc: "Thriller"}
|
||||
- {id: "True", cat: Audio/Audiobook, desc: "True Crime"}
|
||||
- {id: Tutorial, cat: Audio/Audiobook, desc: "Tutorial"}
|
||||
- {id: Violence, cat: Audio/Audiobook, desc: "Violence"}
|
||||
- {id: Westerns, cat: Audio/Audiobook, desc: "Westerns"}
|
||||
- {id: Zombies, cat: Audio/Audiobook, desc: "Zombies"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
book-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
infohash:
|
||||
hash:
|
||||
selector: td:contains("Info Hash:") ~ td
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([A-F|a-f|0-9]{40})
|
||||
title:
|
||||
selector: h1
|
||||
filters:
|
||||
- name: trim
|
||||
- name: validfilename
|
||||
|
||||
search:
|
||||
paths:
|
||||
# with just 7 results per page, try to grab up to 35 results
|
||||
# http://audiobookbay.nl/?s=teeth
|
||||
# http://audiobookbay.nl/page/2/?s=teeth
|
||||
- path: "{{ if .Keywords }}?s={{ .Keywords }}&tt=1{{ else }}{{ end }}"
|
||||
- path: "page/2/{{ if .Keywords }}?s={{ .Keywords }}&tt=1{{ else }}{{ end }}"
|
||||
- path: "page/3/{{ if .Keywords }}?s={{ .Keywords }}&tt=1{{ else }}{{ end }}"
|
||||
- path: "page/4/{{ if .Keywords }}?s={{ .Keywords }}&tt=1{{ else }}{{ end }}"
|
||||
- path: "page/5/{{ if .Keywords }}?s={{ .Keywords }}&tt=1{{ else }}{{ end }}"
|
||||
|
||||
rows:
|
||||
selector: div.post:has(div[class="postTitle"])
|
||||
filters:
|
||||
- name: andmatch
|
||||
|
||||
fields:
|
||||
category:
|
||||
selector: div.postInfo
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "Category: (.+?)\\s"
|
||||
_format:
|
||||
optional: true
|
||||
selector: div.postContent
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "Format: (.+?) /"
|
||||
- name: replace
|
||||
args: ["?", ""]
|
||||
_bitrate:
|
||||
optional: true
|
||||
selector: div.postContent
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "Bitrate: (.+?)File"
|
||||
- name: replace
|
||||
args: ["?", ""]
|
||||
title:
|
||||
selector: div.postTitle
|
||||
filters:
|
||||
- name: append
|
||||
args: "{{ if .Result._format }} [{{ .Result._format }}]{{ else }}{{ end }}{{ if .Result._bitrate }} [{{ .Result._bitrate }}]{{ else }}{{ end }}"
|
||||
details:
|
||||
selector: div.postTitle h2 a
|
||||
attribute: href
|
||||
download:
|
||||
selector: div.postTitle h2 a
|
||||
attribute: href
|
||||
poster:
|
||||
selector: img
|
||||
attribute: src
|
||||
date_optional:
|
||||
optional: true
|
||||
selector: div.postContent
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "(\\d{1,2} \\D{3} \\d{4})"
|
||||
- name: dateparse
|
||||
args: "2 Jan 2006"
|
||||
date:
|
||||
text: "{{ if .Result.date_optional }}{{ .Result.date_optional }}{{ else }}now{{ end }}"
|
||||
size_optional:
|
||||
optional: true
|
||||
selector: div.postContent
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "File Size: (.+?)$"
|
||||
- name: replace
|
||||
args: ["s", ""]
|
||||
size:
|
||||
text: "{{ if .Result.size_optional }}{{ .Result.size_optional }}{{ else }}0 B{{ end }}"
|
||||
seeders:
|
||||
text: 1
|
||||
leechers:
|
||||
text: 1
|
||||
downloadvolumefactor:
|
||||
text: 0
|
||||
uploadvolumefactor:
|
||||
text: 1
|
||||
# engine n/a
|
296
src/Jackett.Common/Indexers/AudioBookBay.cs
Normal file
296
src/Jackett.Common/Indexers/AudioBookBay.cs
Normal file
@@ -0,0 +1,296 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Dom;
|
||||
using AngleSharp.Html.Dom;
|
||||
using AngleSharp.Html.Parser;
|
||||
using Jackett.Common.Models;
|
||||
using Jackett.Common.Models.IndexerConfig;
|
||||
using Jackett.Common.Services.Interfaces;
|
||||
using Jackett.Common.Utils;
|
||||
using Jackett.Common.Utils.Clients;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
|
||||
namespace Jackett.Common.Indexers
|
||||
{
|
||||
[ExcludeFromCodeCoverage]
|
||||
public class AudioBookBay : BaseWebIndexer
|
||||
{
|
||||
public override string[] AlternativeSiteLinks { get; protected set; } = {
|
||||
"https://audiobookbay.li/",
|
||||
"https://audiobookbay.se/"
|
||||
};
|
||||
|
||||
public override string[] LegacySiteLinks { get; protected set; } =
|
||||
{
|
||||
"https://audiobookbay.la/",
|
||||
"http://audiobookbay.net/",
|
||||
"https://audiobookbay.unblockit.tv/",
|
||||
"http://audiobookbay.nl/",
|
||||
"http://audiobookbay.ws/",
|
||||
"https://audiobookbay.unblockit.how/",
|
||||
"https://audiobookbay.unblockit.cam/",
|
||||
"https://audiobookbay.unblockit.biz/",
|
||||
"https://audiobookbay.unblockit.day/",
|
||||
"https://audiobookbay.unblockit.llc/",
|
||||
"https://audiobookbay.unblockit.blue/",
|
||||
"https://audiobookbay.unblockit.name/",
|
||||
"http://audiobookbay.fi/",
|
||||
"http://audiobookbay.se/",
|
||||
"http://audiobookbayabb.com/",
|
||||
"https://audiobookbay.unblockit.ist/",
|
||||
"https://audiobookbay.unblockit.bet/",
|
||||
"https://audiobookbay.unblockit.cat/",
|
||||
"https://audiobookbay.unblockit.nz/",
|
||||
"https://audiobookbay.fi/",
|
||||
"https://audiobookbay.unblockit.page/",
|
||||
"https://audiobookbay.unblockit.pet/",
|
||||
"https://audiobookbay.unblockit.ink/",
|
||||
"https://audiobookbay.unblockit.bio/" // error 502
|
||||
};
|
||||
|
||||
public AudioBookBay(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, ICacheService cs)
|
||||
: base(id: "audiobookbay",
|
||||
name: "AudioBook Bay",
|
||||
description: "AudioBook Bay (ABB) is a public Torrent Tracker for AUDIOBOOKS",
|
||||
link: "https://audiobookbay.li/",
|
||||
caps: new TorznabCapabilities
|
||||
{
|
||||
BookSearchParams = new List<BookSearchParam>
|
||||
{
|
||||
BookSearchParam.Q
|
||||
}
|
||||
},
|
||||
configService: configService,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
cacheService: cs,
|
||||
configData: new ConfigurationData())
|
||||
{
|
||||
Encoding = Encoding.UTF8;
|
||||
Language = "en-US";
|
||||
Type = "public";
|
||||
|
||||
// requestDelay for API Limit (1 request per 2 seconds)
|
||||
webclient.requestDelay = 2.1;
|
||||
|
||||
// Age
|
||||
AddCategoryMapping("children", TorznabCatType.AudioAudiobook, "Children");
|
||||
AddCategoryMapping("teen-young-adult", TorznabCatType.AudioAudiobook, "Teen & Young Adult");
|
||||
AddCategoryMapping("adults", TorznabCatType.AudioAudiobook, "Adults");
|
||||
|
||||
// Category
|
||||
AddCategoryMapping("postapocalyptic", TorznabCatType.AudioAudiobook, "(Post)apocalyptic");
|
||||
AddCategoryMapping("action", TorznabCatType.AudioAudiobook, "Action");
|
||||
AddCategoryMapping("adventure", TorznabCatType.AudioAudiobook, "Adventure");
|
||||
AddCategoryMapping("art", TorznabCatType.AudioAudiobook, "Art");
|
||||
AddCategoryMapping("autobiography-biographies", TorznabCatType.AudioAudiobook, "Autobiography & Biographies");
|
||||
AddCategoryMapping("business", TorznabCatType.AudioAudiobook, "Business");
|
||||
AddCategoryMapping("computer", TorznabCatType.AudioAudiobook, "Computer");
|
||||
AddCategoryMapping("contemporary", TorznabCatType.AudioAudiobook, "Contemporary");
|
||||
AddCategoryMapping("crime", TorznabCatType.AudioAudiobook, "Crime");
|
||||
AddCategoryMapping("detective", TorznabCatType.AudioAudiobook, "Detective");
|
||||
AddCategoryMapping("doctor-who-sci-fi", TorznabCatType.AudioAudiobook, "Doctor Who");
|
||||
AddCategoryMapping("education", TorznabCatType.AudioAudiobook, "Education");
|
||||
AddCategoryMapping("fantasy", TorznabCatType.AudioAudiobook, "Fantasy");
|
||||
AddCategoryMapping("general-fiction", TorznabCatType.AudioAudiobook, "General Fiction");
|
||||
AddCategoryMapping("historical-fiction", TorznabCatType.AudioAudiobook, "Historical Fiction");
|
||||
AddCategoryMapping("history", TorznabCatType.AudioAudiobook, "History");
|
||||
AddCategoryMapping("horror", TorznabCatType.AudioAudiobook, "Horror");
|
||||
AddCategoryMapping("humor", TorznabCatType.AudioAudiobook, "Humor");
|
||||
AddCategoryMapping("lecture", TorznabCatType.AudioAudiobook, "Lecture");
|
||||
AddCategoryMapping("lgbt", TorznabCatType.AudioAudiobook, "LGBT");
|
||||
AddCategoryMapping("literature", TorznabCatType.AudioAudiobook, "Literature");
|
||||
AddCategoryMapping("litrpg", TorznabCatType.AudioAudiobook, "LitRPG");
|
||||
AddCategoryMapping("general-non-fiction", TorznabCatType.AudioAudiobook, "Misc. Non-fiction");
|
||||
AddCategoryMapping("mystery", TorznabCatType.AudioAudiobook, "Mystery");
|
||||
AddCategoryMapping("paranormal", TorznabCatType.AudioAudiobook, "Paranormal");
|
||||
AddCategoryMapping("plays-theater", TorznabCatType.AudioAudiobook, "Plays & Theater");
|
||||
AddCategoryMapping("poetry", TorznabCatType.AudioAudiobook, "Poetry");
|
||||
AddCategoryMapping("political", TorznabCatType.AudioAudiobook, "Political");
|
||||
AddCategoryMapping("radio-productions", TorznabCatType.AudioAudiobook, "Radio Productions");
|
||||
AddCategoryMapping("romance", TorznabCatType.AudioAudiobook, "Romance");
|
||||
AddCategoryMapping("sci-fi", TorznabCatType.AudioAudiobook, "Sci-Fi");
|
||||
AddCategoryMapping("science", TorznabCatType.AudioAudiobook, "Science");
|
||||
AddCategoryMapping("self-help", TorznabCatType.AudioAudiobook, "Self-help");
|
||||
AddCategoryMapping("spiritual", TorznabCatType.AudioAudiobook, "Spiritual & Religious");
|
||||
AddCategoryMapping("sports", TorznabCatType.AudioAudiobook, "Sport & Recreation");
|
||||
AddCategoryMapping("suspense", TorznabCatType.AudioAudiobook, "Suspense");
|
||||
AddCategoryMapping("thriller", TorznabCatType.AudioAudiobook, "Thriller");
|
||||
AddCategoryMapping("true-crime", TorznabCatType.AudioAudiobook, "True Crime");
|
||||
AddCategoryMapping("tutorial", TorznabCatType.AudioAudiobook, "Tutorial");
|
||||
AddCategoryMapping("westerns", TorznabCatType.AudioAudiobook, "Westerns");
|
||||
AddCategoryMapping("zombies", TorznabCatType.AudioAudiobook, "Zombies");
|
||||
|
||||
// Category Modifiers
|
||||
AddCategoryMapping("anthology", TorznabCatType.AudioAudiobook, "Anthology");
|
||||
AddCategoryMapping("bestsellers", TorznabCatType.AudioAudiobook, "Bestsellers");
|
||||
AddCategoryMapping("classic", TorznabCatType.AudioAudiobook, "Classic");
|
||||
AddCategoryMapping("documentary", TorznabCatType.AudioAudiobook, "Documentary");
|
||||
AddCategoryMapping("full-cast", TorznabCatType.AudioAudiobook, "Full Cast");
|
||||
AddCategoryMapping("libertarian", TorznabCatType.AudioAudiobook, "Libertarian");
|
||||
AddCategoryMapping("military", TorznabCatType.AudioAudiobook, "Military");
|
||||
AddCategoryMapping("novel", TorznabCatType.AudioAudiobook, "Novel");
|
||||
AddCategoryMapping("short-story", TorznabCatType.AudioAudiobook, "Short Story");
|
||||
}
|
||||
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
LoadValuesFromJson(configJson);
|
||||
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
await ConfigureIfOK(string.Empty, releases.Any(), () => throw new Exception("Could not find releases from this URL"));
|
||||
|
||||
return IndexerConfigurationStatus.Completed;
|
||||
}
|
||||
|
||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
var urls = new HashSet<string>
|
||||
{
|
||||
SiteLink,
|
||||
SiteLink + "page/2/",
|
||||
SiteLink + "page/3/"
|
||||
};
|
||||
|
||||
foreach (var url in urls)
|
||||
{
|
||||
var searchUrl = url;
|
||||
|
||||
var parameters = new NameValueCollection();
|
||||
|
||||
var searchString = query.GetQueryString().Trim();
|
||||
if (!string.IsNullOrWhiteSpace(searchString))
|
||||
{
|
||||
searchString = Regex.Replace(searchString, @"[\W]+", " ").Trim();
|
||||
parameters.Set("s", searchString);
|
||||
parameters.Set("tt", "1");
|
||||
}
|
||||
|
||||
if (parameters.Count > 0)
|
||||
searchUrl += $"?{parameters.GetQueryString()}";
|
||||
|
||||
var response = await RequestWithCookiesAsync(searchUrl);
|
||||
|
||||
var pageReleases = ParseReleases(response);
|
||||
releases.AddRange(pageReleases);
|
||||
|
||||
// Stop fetching the next page when less than 15 results are found.
|
||||
if (pageReleases.Count < 15)
|
||||
break;
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
public override async Task<byte[]> Download(Uri link)
|
||||
{
|
||||
var response = await RequestWithCookiesAsync(link.ToString());
|
||||
|
||||
var parser = new HtmlParser();
|
||||
var dom = parser.ParseDocument(response.ContentString);
|
||||
|
||||
var hash = dom.QuerySelector("td:contains(\"Info Hash:\") ~ td")?.TextContent.Trim();
|
||||
if (hash == null)
|
||||
throw new Exception($"Failed to fetch hash from {link}");
|
||||
|
||||
var title = dom.QuerySelector("div.postTitle h1")?.TextContent.Trim();
|
||||
if (title == null)
|
||||
throw new Exception($"Failed to fetch title from {link}");
|
||||
|
||||
title = StringUtil.MakeValidFileName(title, '_', false);
|
||||
|
||||
var magnet = MagnetUtil.InfoHashToPublicMagnet(hash, title);
|
||||
|
||||
return await base.Download(magnet);
|
||||
}
|
||||
|
||||
private List<ReleaseInfo> ParseReleases(WebResult response)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
var dom = ParseHtmlDocument(response.ContentString);
|
||||
|
||||
var rows = dom.QuerySelectorAll("div.post:has(div[class=\"postTitle\"])");
|
||||
foreach (var row in rows)
|
||||
{
|
||||
var detailsLink = row.QuerySelector("div.postTitle h2 a")?.GetAttribute("href")?.Trim().TrimStart('/');
|
||||
var details = new Uri(SiteLink + detailsLink);
|
||||
|
||||
var title = row.QuerySelector("div.postTitle")?.TextContent.Trim();
|
||||
|
||||
var infoString = row.QuerySelector("div.postContent")?.TextContent.Trim() ?? string.Empty;
|
||||
|
||||
var matchFormat = Regex.Match(infoString, @"Format: (.+) \/", RegexOptions.IgnoreCase);
|
||||
if (matchFormat.Groups[1].Success && matchFormat.Groups[1].Value.Length > 0 && matchFormat.Groups[1].Value != "?")
|
||||
title += $" [{matchFormat.Groups[1].Value.Trim()}]";
|
||||
|
||||
var matchBitrate = Regex.Match(infoString, @"Bitrate: (.+)File", RegexOptions.IgnoreCase);
|
||||
if (matchBitrate.Groups[1].Success && matchBitrate.Groups[1].Value.Length > 0 && matchBitrate.Groups[1].Value != "?")
|
||||
title += $" [{matchBitrate.Groups[1].Value.Trim()}]";
|
||||
|
||||
var matchSize = Regex.Match(infoString, @"File Size: (.+?)s?$", RegexOptions.IgnoreCase);
|
||||
var size = matchSize.Groups[1].Success ? ReleaseInfo.GetBytes(matchSize.Groups[1].Value) : 0;
|
||||
|
||||
var matchDateAdded = Regex.Match(infoString, @"Posted: (\d{1,2} \D{3} \d{4})", RegexOptions.IgnoreCase);
|
||||
var publishDate = matchDateAdded.Groups[1].Success && DateTime.TryParseExact(matchDateAdded.Groups[1].Value, "d MMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var parsedDate) ? parsedDate : DateTime.Now;
|
||||
|
||||
var postInfo = row.QuerySelector("div.postInfo")?.FirstChild?.TextContent.Trim().Replace("\xA0", ";") ?? string.Empty;
|
||||
var matchCategory = Regex.Match(postInfo, @"Category: (.+)$", RegexOptions.IgnoreCase);
|
||||
var category = matchCategory.Groups[1].Success ? matchCategory.Groups[1].Value.Split(';').Select(c => c.Trim()).ToList() : new List<string>();
|
||||
var categories = category.SelectMany(MapTrackerCatDescToNewznab).Distinct().ToList();
|
||||
|
||||
var release = new ReleaseInfo
|
||||
{
|
||||
Guid = details,
|
||||
Details = details,
|
||||
Link = details,
|
||||
Title = title,
|
||||
Category = categories,
|
||||
Size = size,
|
||||
Seeders = 1,
|
||||
Peers = 1,
|
||||
PublishDate = publishDate,
|
||||
DownloadVolumeFactor = 0,
|
||||
UploadVolumeFactor = 1
|
||||
};
|
||||
|
||||
var cover = row.QuerySelector("img[src]")?.GetAttribute("src")?.Trim();
|
||||
if (!string.IsNullOrEmpty(cover))
|
||||
release.Poster = cover.StartsWith("http") ? new Uri(cover) : new Uri(SiteLink + cover);
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
private static IHtmlDocument ParseHtmlDocument(string response)
|
||||
{
|
||||
var parser = new HtmlParser();
|
||||
var dom = parser.ParseDocument(response);
|
||||
|
||||
var hidden = dom.QuerySelectorAll("div.post.re-ab");
|
||||
foreach (var element in hidden)
|
||||
{
|
||||
var body = dom.CreateElement<IHtmlDivElement>();
|
||||
body.ClassList.Add("post");
|
||||
body.InnerHtml = Encoding.UTF8.GetString(Convert.FromBase64String(element.TextContent));
|
||||
element.Parent.ReplaceChild(body, element);
|
||||
}
|
||||
|
||||
return dom;
|
||||
}
|
||||
}
|
||||
}
|
@@ -278,6 +278,7 @@ namespace Jackett.Updater
|
||||
"Definitions/asgaard.yml",
|
||||
"Definitions/ast4u.yml", // renamed to animeworld #10578
|
||||
"Definitions/asylumshare.yml",
|
||||
"Definitions/audiobookbay.yml", // migrated to C#
|
||||
"Definitions/audiobooktorrents.yml", // renamed to abtorrents
|
||||
"Definitions/avg.yml",
|
||||
"Definitions/awesomehd.yml", // migrated to C#
|
||||
|
Reference in New Issue
Block a user