diff --git a/src/Jackett.Common/Indexers/Hebits.cs b/src/Jackett.Common/Indexers/Hebits.cs index ef5d45117..78c0a2009 100644 --- a/src/Jackett.Common/Indexers/Hebits.cs +++ b/src/Jackett.Common/Indexers/Hebits.cs @@ -20,8 +20,7 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class Hebits : BaseWebIndexer { - private string LoginPostUrl => SiteLink + "takeloginAjax.php"; - private string SearchUrl => SiteLink + "browse.php?sort=4&type=desc"; + private string SearchUrl => SiteLink + "torrents.php?order_way=desc&order_by=time"; private new ConfigurationDataCookie configData => (ConfigurationDataCookie)base.configData; public Hebits(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, @@ -54,37 +53,22 @@ namespace Jackett.Common.Indexers logger: l, p: ps, cacheService: cs, - downloadBase: "https://hebits.net/", configData: new ConfigurationDataCookie("Easily find the cookie under the 'Cookie' header in the index.php GET request. HeBits Cookie usually look like: hebits=hebits; uid=12345; pass=[...]")) { - Encoding = Encoding.GetEncoding("windows-1255"); + Encoding = Encoding.GetEncoding("UTF-8"); Language = "he-il"; Type = "private"; - AddCategoryMapping(21, TorznabCatType.PCGames, "משחקים - PC (PC Games)"); - AddCategoryMapping(33, TorznabCatType.Console, "משחקים - קונסולות (Console Games)"); - AddCategoryMapping(19, TorznabCatType.MoviesSD, "סרטי SD (Movies SD)"); - AddCategoryMapping(25, TorznabCatType.MoviesOther, "סרטים ישראלי (Movies ISR)"); - AddCategoryMapping(20, TorznabCatType.MoviesDVD, "סרטים - DVD-R (Movies DVD"); - AddCategoryMapping(36, TorznabCatType.MoviesBluRay, "Bluray / Remux"); - AddCategoryMapping(27, TorznabCatType.MoviesHD, "סרטי HD (Movies HD)"); - AddCategoryMapping(34, TorznabCatType.Movies, "טופ IMDB (Top IMDB)"); - AddCategoryMapping(7, TorznabCatType.TVSD, "סדרות ישראליות (TV SD ISR)"); - AddCategoryMapping(24, TorznabCatType.TVSD, "סדרות לועזיות - עם תרגום מובנה (TV with subs)"); - AddCategoryMapping(1, TorznabCatType.TVHD, "סדרות HD לועזיות (TV HD)"); - AddCategoryMapping(37, TorznabCatType.TVHD, "סדרות HD ישראליות (TV HD ISR)"); - AddCategoryMapping(23, TorznabCatType.TVAnime, "אנימציה - מצויירים (Anime)"); - AddCategoryMapping(28, TorznabCatType.Audio, "מוזיקה לועזית (Music)"); - AddCategoryMapping(6, TorznabCatType.Audio, "מוזיקה ישראלית (Music ISR)"); - AddCategoryMapping(28, TorznabCatType.AudioLossless, "מוזיקה - Flac (Music Flac)"); - AddCategoryMapping(35, TorznabCatType.AudioVideo, "הופעות (Music Concerts)"); - AddCategoryMapping(30, TorznabCatType.Audio, "פסי קול (Music OST)"); - AddCategoryMapping(32, TorznabCatType.PCMobileOther, "סלולאר (Mobile)"); - AddCategoryMapping(26, TorznabCatType.Books, "ספרים (Books)"); - AddCategoryMapping(22, TorznabCatType.PC, "תוכנות (Apps)"); - AddCategoryMapping(29, TorznabCatType.Other, "שונות (Other)"); - AddCategoryMapping(9, TorznabCatType.XXX, "פורנו XXX (3X)"); - AddCategoryMapping(41, TorznabCatType.TVSport, "ספורט (Sport)"); + AddCategoryMapping(1, TorznabCatType.Movies, "סרטים (Movies)"); + AddCategoryMapping(2, TorznabCatType.TV, "סדרות (TV)"); + AddCategoryMapping(3, TorznabCatType.TVOther, "הצגות והופעות (Theater)"); + AddCategoryMapping(4, TorznabCatType.PC, "תוכנות (Apps)"); + AddCategoryMapping(5, TorznabCatType.Console, "משחקים (Games)"); + AddCategoryMapping(6, TorznabCatType.Audio, "מוזיקה (Music)"); + AddCategoryMapping(7, TorznabCatType.Books, "ספרים (Books)"); + AddCategoryMapping(8, TorznabCatType.MoviesOther, "חבילות סרטים (Movies Packs)"); + AddCategoryMapping(9, TorznabCatType.XXX, "פורנו (Porn)"); + AddCategoryMapping(10, TorznabCatType.Other, "שונות (Other)"); } public override async Task ApplyConfiguration(JToken configJson) @@ -115,50 +99,73 @@ namespace Jackett.Common.Indexers var searchString = query.GetQueryString(); var searchUrl = SearchUrl; if (!string.IsNullOrWhiteSpace(searchString)) - searchUrl += "&search=" + WebUtilityHelpers.UrlEncode(searchString, Encoding); + searchUrl += "&action=advanced&searchsubmit=1&filelist=" + WebUtilityHelpers.UrlEncode(searchString, Encoding); var cats = MapTorznabCapsToTrackers(query); if (cats.Count > 0) - searchUrl = cats.Aggregate(searchUrl, (url, cat) => $"{url}&c{cat}=1"); + searchUrl = cats.Aggregate(searchUrl, (url, cat) => $"{url}&filter_cat[{cat}]=1"); var response = await RequestWithCookiesAsync(searchUrl); try { var parser = new HtmlParser(); var dom = parser.ParseDocument(response.ContentString); - var rows = dom.QuerySelectorAll(".browse > div > div"); + var rows = dom.QuerySelectorAll("table#torrent_table > tbody > tr.torrent"); foreach (var row in rows) { - var release = new ReleaseInfo(); - release.MinimumRatio = 0.8; - release.MinimumSeedTime = 259200; // 72 hours - var qCatLink = row.QuerySelector("a[href^=\"browse.php?cat=\"]"); - var catStr = qCatLink.GetAttribute("href").Split('=')[1]; - release.Category = MapTrackerCatToNewznab(catStr); - var qTitle = row.QuerySelector(".bTitle"); - var titleParts = qTitle.TextContent.Split('/'); - release.Title = titleParts.Length >= 2 ? titleParts[1].Trim() : titleParts[0].Trim(); - var qDetailsLink = qTitle.QuerySelector("a[href^=\"details.php\"]"); + var release = new ReleaseInfo + { + MinimumRatio = 0.8, + MinimumSeedTime = 259200 // 72 hours + }; + var qCat = row.QuerySelector("div[class*=\"cats_\"]"); + var catStr = qCat.GetAttribute("class").Split('_')[1]; + release.Category = catStr switch + { + "movies" => MapTrackerCatToNewznab("1"), + "tv" => MapTrackerCatToNewznab("2"), + "theater" => MapTrackerCatToNewznab("3"), + "software" => MapTrackerCatToNewznab("4"), + "games" => MapTrackerCatToNewznab("5"), + "music" => MapTrackerCatToNewznab("6"), + "books" => MapTrackerCatToNewznab("7"), + "moviespacks" => MapTrackerCatToNewznab("8"), + "porno" => MapTrackerCatToNewznab("9"), + "other" => MapTrackerCatToNewznab("10"), + _ => throw new Exception("Error parsing category! Unknown cat=" + catStr), + }; + var qTitle = row.QuerySelector("div.torrent_info"); + release.Title = qTitle.TextContent.Trim(); + var qDetailsLink = row.QuerySelector("a.torrent_name"); + // I don't understand, I correctly build the poster as + // https://hebits.net/images/oRbJr/3776T8DeNsKbyUM3tsV0LBY_v_JfdfmkhShh_LguTP.jpg + // yet the dashboard shows a broken icon symbol! No idea why this does not work. + //if (!string.IsNullOrEmpty(qDetailsLink.GetAttribute("data-cover"))) + //{ + // release.Poster = new Uri(SiteLink.TrimEnd('/') + qDetailsLink.GetAttribute("data-cover")); + // logger.Debug("poster=" + release.Poster); + //} release.Details = new Uri(SiteLink + qDetailsLink.GetAttribute("href")); - release.Link = new Uri(SiteLink + row.QuerySelector("a[href^=\"download.php\"]").GetAttribute("href")); + release.Link = new Uri(SiteLink + row.QuerySelector("a[href^=\"torrents.php?action=download&id=\"]").GetAttribute("href")); release.Guid = release.Link; - var dateString = row.QuerySelector("div:last-child").TextContent.Trim(); - var match = Regex.Match(dateString, @"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}"); - if (match.Success) - release.PublishDate = DateTime.ParseExact(match.Value, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); - var sizeStr = row.QuerySelector(".bSize").TextContent.Trim(); - release.Size = ReleaseInfo.GetBytes(sizeStr); - release.Seeders = ParseUtil.CoerceInt(row.QuerySelector(".bUping").TextContent.Trim()); - release.Peers = release.Seeders + ParseUtil.CoerceInt(row.QuerySelector(".bDowning").TextContent.Trim()); - var files = row.QuerySelector("div.bFiles").ChildNodes.Last().TextContent.Trim(); - release.Files = ParseUtil.CoerceInt(files); - var grabs = row.QuerySelector("div.bFinish").ChildNodes.Last().TextContent.Trim(); - release.Grabs = ParseUtil.CoerceInt(grabs); - release.DownloadVolumeFactor = row.QuerySelector("img[src=\"/pic/free.jpg\"]") != null ? 0 : 1; - if (row.QuerySelector("img[src=\"/pic/triple.jpg\"]") != null) - release.UploadVolumeFactor = 3; - else if (row.QuerySelector("img[src=\"/pic/double.jpg\"]") != null) - release.UploadVolumeFactor = 2; - else - release.UploadVolumeFactor = 1; + var qDate = row.QuerySelector("span.time").GetAttribute("title"); + release.PublishDate = DateTime.ParseExact(qDate, "dd/MM/yyyy, HH:mm", CultureInfo.InvariantCulture); + var qSize = row.QuerySelector("td:nth-last-child(4)").TextContent.Trim(); + release.Size = ReleaseInfo.GetBytes(qSize); + release.Seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(2)").TextContent.Trim()); + release.Peers = release.Seeders + ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(1)").TextContent.Trim()); + release.Files = ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(6)").TextContent.Trim()); + release.Grabs = ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(3)").TextContent.Trim()); + release.DownloadVolumeFactor = release.Title.Contains("פריליץ") + ? 0 + : release.Title.Contains("חצי פריליץ") + ? 0.5 + : release.Title.Contains("75% פריליץ") + ? 0.25 + : 1; + release.UploadVolumeFactor = release.Title.Contains("העלאה משולשת") + ? 3 + : release.Title.Contains("העלאה כפולה") + ? 2 + : 1; releases.Add(release); } }