diff --git a/src/Jackett.Common/Definitions/beyond-hd.yml b/src/Jackett.Common/Definitions/beyond-hd.yml new file mode 100644 index 000000000..6d6f7df0c --- /dev/null +++ b/src/Jackett.Common/Definitions/beyond-hd.yml @@ -0,0 +1,128 @@ +--- + site: beyond-hd + name: Beyond-HD + description: "Without BeyondHD, your HDTV is just a TV" + language: en-us + type: private + encoding: UTF-8 + links: + - https://beyond-hd.me/ + + caps: + categorymappings: + - {id: 1, cat: Movies, desc: "Movies"} + - {id: 2, cat: TV, desc: "TV"} + + modes: + search: [q] + tv-search: [q, season, ep, imdbid] + movie-search: [q, imdbid] + + login: + path: login + method: form + inputs: + username: "{{ .Config.username }}" + password: "{{ .Config.password }}" + error: + - selector: div.has-error + test: + path: torrents + + search: + paths: + - path: filterTorrents + inputs: + $raw: "{{range .Categories}}categories[]={{.}}&{{end}}" + search: "{{if .Query.IMDBID}}{{else}}{{ .Keywords }}{{end}}" + description: "" + uploader: "" + imdb: "{{ .Query.IMDBIDShort }}" + tvdb: "" + tmdb: "" + mal: "" + sort: created_at + direction: desc + qty: 100 + rows: + selector: table > tbody > tr + fields: + category: + selector: a[href*="/categories/"] + attribute: href + filters: + - name: regexp + args: "/categories/.*?\\.(\\d+)" + title: + selector: a.torrent-name + download: + selector: a[href*="/download/"] + attribute: href + details: + selector: a.torrent-name + attribute: href + banner: + optional: true + selector: div.torrent-poster img + attribute: src + filters: + - name: replace + args: ["https://via.placeholder.com/600x900", ""] + size: + selector: td:nth-child(6) + seeders: + selector: td:nth-child(7) + leechers: + selector: td:nth-child(8) + grabs: + selector: td:nth-child(9) + filters: + - name: regexp + args: ([\d\.]+) + imdb: + optional: true + selector: a[href*="www.imdb.com/title/tt"] + attribute: href + date: + selector: td:nth-child(5) + filters: + - name: timeago + # translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portoguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch + - name: re_replace + args: ["(önce|tagasi|geleden|fa|temu|siden|atrás|nazpět|назад|acum|hace|il y a|vor|преди)", "ago"] + - name: re_replace + args: ["(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut)", "minute"] + - name: re_replace + args: ["(dakika|minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten)", "minutes"] + - name: re_replace + args: ["(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur)", "hour"] + - name: re_replace + args: ["(saat|tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden)", "hours"] + - name: re_replace + args: ["(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден)", "day"] + - name: re_replace + args: ["(gün|päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen)", "days"] + - name: re_replace + args: ["(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица)", "week"] + - name: re_replace + args: ["(hafta|nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken)", "weeks"] + - name: re_replace + args: [" (ay|kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|mois|Monat|месец|maand)", "month"] + - name: re_replace + args: [" (ay|kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden)", "months"] + downloadvolumefactor: + case: + "i[data-original-title=\"Personal Freeleech\"]": "0" # 24 Hour FreeLeech From BON Store + "i[data-original-title=\"Special Freeleech\"]": "0" # Special FreeLeech For Certain User Groups + "i[data-original-title=\"Freeleech Token\"]": "0" # Freeleech From Token + "i[data-original-title=\"Global FreeLeech\"]": "0" # Global Freeleech + "i[data-original-title=\"Freeleech\"]": "0" # Freeleech + "i[data-original-title=\"Featured Torrent\"]": "0" # Featured Torrent + "*": "1" + uploadvolumefactor: + case: + "i[data-original-title=\"Double Upload\"]": "2" # Single Torrent Double Upload + "i[data-original-title=\"Global Double Upload\"]": "2" # Global Double Upload + "i[data-original-title=\"Featured Torrent\"]": "2" # Featured Torrent + "*": "1" +# UNIT3D 1.9.2 diff --git a/src/Jackett.Common/Indexers/BeyondHD.cs b/src/Jackett.Common/Indexers/BeyondHD.cs deleted file mode 100644 index 691067afe..000000000 --- a/src/Jackett.Common/Indexers/BeyondHD.cs +++ /dev/null @@ -1,203 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using CsQuery; -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 -{ - public class BeyondHD : BaseWebIndexer - { - private string SearchUrl { get { return SiteLink + "browse.php?searchin=descr&incldead=1&"; } } - - private new ConfigurationDataLoginLink configData - { - get { return (ConfigurationDataLoginLink)base.configData; } - set { base.configData = value; } - } - - public BeyondHD(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) - : base(name: "BeyondHD", - description: "Without BeyondHD, your HDTV is just a TV", - link: "https://beyond-hd.me/", - caps: new TorznabCapabilities(), - configService: configService, - client: w, - logger: l, - p: ps, - configData: new ConfigurationDataLoginLink()) - { - Encoding = Encoding.UTF8; - Language = "en-us"; - Type = "private"; - - configData.DisplayText.Value = "Go to the general tab of your BeyondHD user profile and create/copy the Login Link."; - - TorznabCaps.SupportsImdbSearch = true; - - AddCategoryMapping(37, TorznabCatType.MoviesBluRay, "Movie / Blu-ray"); - AddCategoryMapping(71, TorznabCatType.Movies3D, "Movie / 3D"); - AddCategoryMapping(83, TorznabCatType.Movies3D, "FraMeSToR 3D"); - - AddCategoryMapping(77, TorznabCatType.MoviesHD, "Movie / 1080p/i"); - AddCategoryMapping(102, TorznabCatType.MoviesUHD, "Movie / 4K Disk"); - AddCategoryMapping(94, TorznabCatType.MoviesUHD, "Movie / 4K Other"); - AddCategoryMapping(103, TorznabCatType.MoviesUHD, "Movie / 4K Remux"); - AddCategoryMapping(78, TorznabCatType.MoviesHD, "Movie / 720p"); - AddCategoryMapping(54, TorznabCatType.MoviesHD, "Movie / MP4"); - AddCategoryMapping(17, TorznabCatType.MoviesHD, "Movie / Remux"); - AddCategoryMapping(38, TorznabCatType.MoviesHD, "Movie / WEB-DL"); - AddCategoryMapping(106, TorznabCatType.MoviesHD, "Internal / BHDStudio 1080p"); - AddCategoryMapping(105, TorznabCatType.MoviesHD, "Internal / BHDStudio 720p"); - AddCategoryMapping(50, TorznabCatType.MoviesHD, "Internal / FraMeSToR 1080p"); - AddCategoryMapping(75, TorznabCatType.MoviesHD, "Internal / FraMeSToR 720p"); - AddCategoryMapping(49, TorznabCatType.MoviesHD, "Internal / FraMeSToR REMUX"); - AddCategoryMapping(101, TorznabCatType.MoviesHD, "Internal / FraMeSToR 4K REMUX"); - AddCategoryMapping(61, TorznabCatType.MoviesHD, "Internal / HDX REMUX"); - AddCategoryMapping(86, TorznabCatType.MoviesHD, "Internal / SC4R"); - AddCategoryMapping(95, TorznabCatType.MoviesHD, "Nightripper 1080p"); - AddCategoryMapping(96, TorznabCatType.MoviesHD, "Nightripper 720p"); - AddCategoryMapping(98, TorznabCatType.MoviesHD, "Nightripper MicroHD"); - - AddCategoryMapping(104, TorznabCatType.TVUHD, "TV Show / 4K"); - AddCategoryMapping(40, TorznabCatType.TVHD, "TV Show / Blu-ray"); - AddCategoryMapping(44, TorznabCatType.TVHD, "TV Show / Encodes"); - AddCategoryMapping(48, TorznabCatType.TVHD, "TV Show / HDTV"); - AddCategoryMapping(89, TorznabCatType.TVHD, "TV Show / Packs"); - AddCategoryMapping(46, TorznabCatType.TVHD, "TV Show / Remux"); - AddCategoryMapping(99, TorznabCatType.TVHD, "TV Show / Sports"); - AddCategoryMapping(100, TorznabCatType.TVHD, "TV Show / Sports / WEB-DL"); - AddCategoryMapping(45, TorznabCatType.TVHD, "TV Show / WEB-DL"); - AddCategoryMapping(97, TorznabCatType.TVHD, "Nightripper TV Show Encodes"); - - AddCategoryMapping(36, TorznabCatType.AudioLossless, "Music / Lossless"); - AddCategoryMapping(69, TorznabCatType.AudioMP3, "Music / MP3"); - AddCategoryMapping(55, TorznabCatType.AudioVideo, "Music / 1080p/i"); - AddCategoryMapping(56, TorznabCatType.AudioVideo, "Music / 720p"); - AddCategoryMapping(42, TorznabCatType.AudioVideo, "Music / Blu-ray"); - AddCategoryMapping(41, TorznabCatType.AudioVideo, "Music / Movie OST"); - } - - public override async Task ApplyConfiguration(JToken configJson) - { - LoadValuesFromJson(configJson); - - var result = await RequestStringWithCookies(configData.LoginLink.Value); - await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("Welcome Back"), () => - { - var errorMessage = result.Content; - throw new ExceptionWithConfigData(errorMessage, configData); - }); - return IndexerConfigurationStatus.RequiresTesting; - } - - protected override async Task> PerformQuery(TorznabQuery query) - { - List releases = new List(); - Regex IMDBRegEx = new Regex(@"tt(\d+)", RegexOptions.Compiled); - - var searchString = query.GetQueryString(); - var searchUrl = SearchUrl; - var queryCollection = new NameValueCollection(); - var searchStringIsImdbQuery = (ParseUtil.GetImdbID(searchString) != null); - - if (query.IsImdbQuery) - { - queryCollection.Add("search", query.ImdbID); - } - else if (searchStringIsImdbQuery) - { - queryCollection.Add("search", searchString); - } - else if (!string.IsNullOrWhiteSpace(searchString)) - { - Regex ReplaceRegex = new Regex("[^a-zA-Z0-9]+"); - searchString = "%" + ReplaceRegex.Replace(searchString, "%") + "%"; - searchString = Regex.Replace(searchString, @"(%\d{3,4})[ip](%)", "$1$2"); // remove i/p from resolution tags (see #835) - queryCollection.Add("search", searchString); - } - - foreach (var cat in MapTorznabCapsToTrackers(query)) - { - queryCollection.Add("c" + cat, "1"); - } - - searchUrl += queryCollection.GetQueryString(); - - var results = await RequestStringWithCookiesAndRetry(searchUrl); - await FollowIfRedirect(results); - try - { - CQ dom = results.Content; - var rows = dom["table.torrenttable > tbody > tr.browse_color, table.torrenttable > tbody > tr.highlight"]; - foreach (var row in rows) - { - var release = new ReleaseInfo(); - release.MinimumRatio = 1; - release.MinimumSeedTime = 172800; - - var qRow = row.Cq(); - - var catStr = row.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href").Split('=')[1]; - release.Category = MapTrackerCatToNewznab(catStr); - - var qLink = row.ChildElements.ElementAt(2).FirstChild.Cq(); - release.Link = new Uri(SiteLink + qLink.Attr("href")); - var torrentId = qLink.Attr("href").Split('=').Last(); - - var descCol = row.ChildElements.ElementAt(3); - var qCommentLink = descCol.FirstChild.Cq(); - release.Title = qCommentLink.Text(); - if (!query.IsImdbQuery && !query.MatchQueryStringAND(release.Title)) - continue; - release.Comments = new Uri(SiteLink + qCommentLink.Attr("href")); - release.Guid = release.Comments; - release.Link = new Uri($"{SiteLink}download.php?torrent={torrentId}"); - - var dateStr = descCol.ChildElements.Last().Cq().Text().Split('|').Last().ToLowerInvariant().Replace("ago.", "").Trim(); - release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr); - - var sizeStr = row.ChildElements.ElementAt(7).Cq().Text(); - release.Size = ReleaseInfo.GetBytes(sizeStr); - - release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(9).Cq().Text()); - release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(10).Cq().Text()) + release.Seeders; - - var files = qRow.Find("td:nth-child(6)").Text(); - release.Files = ParseUtil.CoerceInt(files); - - var grabs = qRow.Find("td:nth-child(9) > a").Get(0).FirstChild.ToString(); - release.Grabs = ParseUtil.CoerceInt(grabs); - - var imdbLink = qRow.Find("a[href*=\"imdb.com/title/\"]").Attr("href"); - if (imdbLink != null) - { - var IMDBMatch = IMDBRegEx.Match(imdbLink); - release.Imdb = ParseUtil.CoerceLong(IMDBMatch.Groups[1].Value); - } - - release.DownloadVolumeFactor = 0; - release.UploadVolumeFactor = 1; - - releases.Add(release); - } - } - catch (Exception ex) - { - OnParseError(results.Content, ex); - } - - return releases; - } - } -}