public List <ReleaseInfo> ParseResponse(string htmlResponse) { List <ReleaseInfo> releases = new List <ReleaseInfo>(); try { var parser = new HtmlParser(); var document = parser.Parse(htmlResponse); var rows = document.QuerySelectorAll(".torrent_table > tbody > tr[class^='torrent row']"); foreach (var row in rows) { var release = new ReleaseInfo(); string title = row.QuerySelector("a[data-src]").GetAttribute("data-src"); if (string.IsNullOrEmpty(title) || title == "0") { title = row.QuerySelector("a[data-src]").TextContent; title = Regex.Replace(title, @"[\[\]\/]", ""); } else { if (title.Length > 5 && title.Substring(title.Length - 5).Contains(".")) { title = title.Remove(title.LastIndexOf(".")); } } release.Title = title; release.Description = release.Title; release.Guid = new Uri(SiteLink + row.QuerySelector("a[data-src]").GetAttribute("href")); release.Comments = release.Guid; release.Link = new Uri(SiteLink + row.QuerySelector("a[href*='action=download']").GetAttribute("href")); release.Category = TvCategoryParser.ParseTvShowQuality(release.Title); var timeAnchor = row.QuerySelector("span[class='time']"); release.PublishDate = DateTime.ParseExact(timeAnchor.GetAttribute("title"), "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal); release.Seeders = ParseUtil.CoerceInt(timeAnchor.ParentElement.NextElementSibling.NextElementSibling.TextContent.Trim()); release.Peers = ParseUtil.CoerceInt(timeAnchor.ParentElement.NextElementSibling.NextElementSibling.NextElementSibling.TextContent.Trim()) + release.Seeders; release.Size = ReleaseInfo.GetBytes(timeAnchor.ParentElement.PreviousElementSibling.TextContent); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; releases.Add(release); } } catch (Exception ex) { OnParseError(htmlResponse, ex); } return(releases); }
public void should_parse_quality_from_title(string title, int quality) => Assert.That(TvCategoryParser.ParseTvShowQuality(title), Is.EqualTo(quality));
/// <summary> /// Parses the torrents from the content /// </summary> /// <returns>The parsed torrents.</returns> /// <param name="results">The result of the query</param> /// <param name="alreadyFound">Number of the already found torrents.(used for limit)</param> /// <param name="limit">The limit to the number of torrents to download </param> /// <param name="previouslyParsedOnPage">Current position in parsed results</param> private async Task <List <ReleaseInfo> > ParseTorrentsAsync(WebResult results, int alreadyFound, int limit, int previouslyParsedOnPage) { var releases = new List <ReleaseInfo>(); var queryParams = new NameValueCollection { { "func", "getToggle" }, { "w", "F" }, { "pg", "0" } }; try { /* Content Looks like this * 2\15\2\1\1727\207244\1x08 \[WebDL-720p - Eng - AJP69]\gb\2018-03-09 08:11:53\akció, kaland, sci-fi \0\0\1\191170047\1\0\Anonymous\50\0\0\\0\4\0\174\0\ * 1\ 0\0\1\1727\207243\1x08 \[WebDL-1080p - Eng - AJP69]\gb\2018-03-09 08:11:49\akció, kaland, sci-fi \0\0\1\305729738\1\0\Anonymous\50\0\0\\0\8\0\102\0\0\0\0\1\\\ * First 3 items per page are total results, results per page, and results this page * There is also a tail of ~4 items after the results for some reason. Looks like \1\\\ */ var parameters = results.ContentString.Split('\\'); var torrentsThisPage = int.Parse(parameters[2]); var maxTorrents = Math.Min(torrentsThisPage, limit - alreadyFound); var rows = parameters.Skip(3) //Skip pages info .Select((str, index) => (index, str)) //Index each string for grouping .GroupBy(n => n.index / 27) // each torrent is divided into 27 parts .Skip(previouslyParsedOnPage).Take(maxTorrents) // only parse the rows we want //Convert above query into a List<string>(27) in prep for parsing .Select(entry => entry.Select(item => item.str).ToList()); foreach (var row in rows) { var torrentId = row[(int)TorrentParts.TorrentId]; var downloadLink = new Uri(DownloadUrl + "?id=" + torrentId); var imdbId = _imdbLookup.TryGetValue(int.Parse(row[(int)TorrentParts.InternalId]), out var imdb) ? (long?)imdb : null; var files = int.Parse(row[(int)TorrentParts.Files]); var size = long.Parse(row[(int)TorrentParts.SizeBytes]); var seeders = int.Parse(row[(int)TorrentParts.Seeders]); var leechers = int.Parse(row[(int)TorrentParts.Leechers]); var grabs = int.Parse(row[(int)TorrentParts.Grabs]); var publishDate = DateTime.Parse(row[(int)TorrentParts.PublishDate]); var isSeasonPack = row[(int)TorrentParts.EpisodeInfo].Contains("évad"); queryParams["id"] = torrentId; queryParams["now"] = DateTimeUtil.DateTimeToUnixTimestamp(DateTime.UtcNow) .ToString(CultureInfo.InvariantCulture); var filesList = (await RequestWithCookiesAndRetryAsync(SearchUrl + "?" + queryParams.GetQueryString())) .ContentString; var firstFileName = filesList.Split( new[] { @"\\" }, StringSplitOptions.None)[1]; // Delete the file extension. Many first files are either mkv or nfo. // Cannot confirm these are the only extensions, so generic remove all 3 char extensions at end of section. firstFileName = Regex.Replace(firstFileName, @"\.\w{3}$", string.Empty); if (isSeasonPack) { firstFileName = Regex.Replace( firstFileName, @"(?<=S\d+)E\d{2,3}", string.Empty, RegexOptions.IgnoreCase); } var category = new[] { TvCategoryParser.ParseTvShowQuality(firstFileName) }; var release = new ReleaseInfo { Title = firstFileName, Link = downloadLink, Guid = downloadLink, PublishDate = publishDate, Files = files, Size = size, Category = category, Seeders = seeders, Peers = leechers + seeders, Grabs = grabs, MinimumRatio = 1, MinimumSeedTime = 172800, // 48 hours DownloadVolumeFactor = 1, UploadVolumeFactor = UploadFactorCalculator(publishDate, isSeasonPack), Imdb = imdbId }; releases.Add(release); } } catch (Exception ex) { OnParseError(results.ContentString, ex); } return(releases); }
public List <ReleaseInfo> ParseResponse(string htmlResponse) { var releases = new List <ReleaseInfo>(); try { var globalFreeleech = false; var parser = new HtmlParser(); var document = parser.ParseDocument(htmlResponse); if (document.QuerySelector("div.nicebar > span:contains(\"Personal Freeleech\")") != null) { globalFreeleech = true; } var rows = document.QuerySelectorAll(".torrent_table > tbody > tr[class^='torrent row']"); foreach (var row in rows) { var release = new ReleaseInfo(); var title = row.QuerySelector("a[data-src]").GetAttribute("data-src"); if (string.IsNullOrEmpty(title) || title == "0") { title = row.QuerySelector("a[data-src]").TextContent; title = Regex.Replace(title, @"[\[\]\/]", ""); } else { if (title.Length > 5 && title.Substring(title.Length - 5).Contains(".")) { title = title.Remove(title.LastIndexOf(".")); } } release.Title = title; release.Description = release.Title; release.Guid = new Uri(SiteLink + row.QuerySelector("a[data-src]").GetAttribute("href")); release.Comments = release.Guid; release.Link = new Uri(SiteLink + row.QuerySelector("a[href*='action=download']").GetAttribute("href")); release.Category = new List <int> { TvCategoryParser.ParseTvShowQuality(release.Title) }; var timeAnchor = row.QuerySelector("span[class='time']"); var publishdate = timeAnchor.GetAttribute("title"); release.PublishDate = !string.IsNullOrEmpty(publishdate) && publishdate.Contains(",") ? DateTime.ParseExact(publishdate, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal) : DateTime.ParseExact(timeAnchor.TextContent.Trim(), "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal); release.Seeders = ParseUtil.CoerceInt(timeAnchor.ParentElement.NextElementSibling.NextElementSibling.TextContent.Trim()); release.Peers = ParseUtil.CoerceInt(timeAnchor.ParentElement.NextElementSibling.NextElementSibling.NextElementSibling.TextContent.Trim()) + release.Seeders; release.Size = ReleaseInfo.GetBytes(timeAnchor.ParentElement.PreviousElementSibling.TextContent); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; // 48 hours release.Files = ParseUtil.CoerceLong(row.QuerySelector("td > div:contains(\"Files:\")").TextContent.Split(':')[1].Trim()); release.Grabs = ParseUtil.CoerceLong(row.QuerySelector("td:nth-last-child(3)").TextContent); if (globalFreeleech) { release.DownloadVolumeFactor = 0; } else if (row.QuerySelector("img[alt=\"Freeleech\"]") != null) { release.DownloadVolumeFactor = 0; } else { release.DownloadVolumeFactor = 1; } release.UploadVolumeFactor = 1; releases.Add(release); } } catch (Exception ex) { OnParseError(htmlResponse, ex); } return(releases); }
public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 3, 2, DayOfWeek.Sunday); TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 11, 1, DayOfWeek.Sunday); TimeSpan delta = new TimeSpan(1, 0, 0); TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition); TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment }; TimeZoneInfo easternTz = TimeZoneInfo.CreateCustomTimeZone("Eastern Time", new TimeSpan(-5, 0, 0), "(GMT-05:00) Eastern Time", "Eastern Standard Time", "Eastern Daylight Time", adjustments); var releases = new List <ReleaseInfo>(); var categoryMapping = MapTorznabCapsToTrackers(query).Distinct(); string category = "0"; // Aka all if (categoryMapping.Count() == 1) { category = categoryMapping.First(); } var episodeSearchUrl = string.Format(SearchUrl, category, HttpUtility.UrlEncode(query.GetQueryString())); var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { CQ dom = response.Content; var rows = dom["table.table-condensed.table-striped.table-bordered:first"].Find("tbody > tr"); foreach (var row in rows) { CQ qRow = row.Cq(); var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.Title = qRow.Find("a[class='torrent-filename']").Text().Trim(); release.Comments = new Uri(qRow.Find("a[class='torrent-filename']").Attr("href")); release.Guid = release.Comments; release.Link = new Uri(qRow.Find("a[class='torrent-download-icon']").Attr("href")); //05 Aug 2016 01:08 var dateString = row.ChildElements.ElementAt(3).Cq().Find("span").Attr("title"); DateTime pubDateSite = DateTime.SpecifyKind(DateTime.ParseExact(dateString, "dd MMM yyyy HH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); release.PublishDate = TimeZoneInfo.ConvertTimeToUtc(pubDateSite, easternTz).ToLocalTime(); var sizeStr = row.ChildElements.ElementAt(5).Cq().Text().Trim(); release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(6).Cq().Text().Trim()); release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text().Trim()) + release.Seeders; int cat = 0; var catElement = qRow.Find("i[class$='torrent-icon']"); if (catElement.Length == 1) { string catName = catElement.Attr("title").Trim(); if (catName.StartsWith("TV")) { cat = TvCategoryParser.ParseTvShowQuality(release.Title); } if (catName.StartsWith("Music")) { cat = TorznabCatType.Audio.ID; } if (catName.StartsWith("Movie")) { cat = TorznabCatType.Movies.ID; } } release.Category = cat; releases.Add(release); } } catch (Exception ex) { OnParseError(response.Content, ex); } return(releases); }
/// <summary> /// Parses the torrents from the content /// </summary> /// <returns>The parsed torrents.</returns> /// <param name="results">The result of the query</param> /// <param name="query">Query.</param> /// <param name="already_found">Number of the already found torrents.(used for limit)</param> /// <param name="limit">The limit to the number of torrents to download </param> async Task <List <ReleaseInfo> > ParseTorrents(WebClientStringResult results, TorznabQuery query, int already_found, int limit) { var releases = new List <ReleaseInfo>(); try { String content = results.Content; /* Content Looks like this * 2\15\2\1\1727\207244\1x08 \[WebDL-720p - Eng - AJP69]\gb\2018-03-09 08:11:53\akció, kaland, sci-fi \0\0\1\191170047\1\0\Anonymous\50\0\0\\0\4\0\174\0\ * 1\ 0\0\1\1727\207243\1x08 \[WebDL-1080p - Eng - AJP69]\gb\2018-03-09 08:11:49\akció, kaland, sci-fi \0\0\1\305729738\1\0\Anonymous\50\0\0\\0\8\0\102\0\0\0\0\1\\\ */ var splits = content.Split('\\'); int i = 0; ReleaseInfo release = new ReleaseInfo(); /* Split the releases by '\' and go through them. * 26 element belongs to one torrent */ foreach (var s in splits) { switch (i) { case 4: //ID of the series //Get IMDB id form site series database SeriesDetail seriesinfo = series.Find(x => x.id.Contains(s)); if (seriesinfo != null && !s.Equals("")) { release.Imdb = long.Parse(seriesinfo.imdbid); } goto default; case 5: //ID of the torrent Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; string fileinfoURL = SearchUrl + "?func=getToggle&id=" + s + "&w=F&pg=0&now=" + unixTimestamp; string fileinfo = (await RequestStringWithCookiesAndRetry(fileinfoURL)).Content; release.Link = new Uri(DownloadUrl + "?id=" + s); release.Guid = release.Link; release.Comments = release.Link; string[] fileinf = fileinfo.Split(new string[] { "\\\\" }, StringSplitOptions.None); if (fileinf.Length > 1) { release.Title = fileinf[1]; } goto default; /*case 6: * Console.WriteLine("Series season/ep =" + s); --> 9x10 * goto default;*/ /*case 7: * Console.WriteLine("Releaseinfo =" + s); --->Releaseinfo =[HDTV - Rip - Eng - SVA] * goto default;*/ case 9: release.PublishDate = DateTime.Parse(s, CultureInfo.InvariantCulture); goto default; case 13: release.Files = int.Parse(s); goto default; case 14: release.Size = long.Parse(s); goto default; case 23: release.Seeders = int.Parse(s); goto default; case 24: release.Peers = (int.Parse(s) + release.Seeders); goto default; case 25: release.Grabs = int.Parse(s); goto default; case 26: /* This is the last element for the torrent. So add it to releases and start parsing to new torrent */ i = 0; release.Category = new List <int> { TvCategoryParser.ParseTvShowQuality(release.Title) }; //todo Added some basic configuration need to improve it release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.DownloadVolumeFactor = 1; release.UploadVolumeFactor = 1; if ((already_found + releases.Count) < limit) { releases.Add(release); } else { return(releases); } release = new ReleaseInfo(); break; default: i++; break; } } } catch (Exception ex) { OnParseError(results.Content, ex); } return(releases); }
protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { var releases = new List <ReleaseInfo>(); var qc = new NameValueCollection { { "action", "basic" }, { "order_by", "time" }, { "order_way", "desc" }, { "searchtext", query.GetQueryString() } }; var searchUrl = SearchUrl + "?" + qc.GetQueryString(); var response = await RequestWithCookiesAsync(searchUrl); if (!response.ContentString.Contains("logout.php")) // re-login { await DoLogin(); response = await RequestWithCookiesAsync(searchUrl); } try { var parser = new HtmlParser(); var document = parser.ParseDocument(response.ContentString); var rows = document.QuerySelectorAll(".torrent_table > tbody > tr[class^='torrent row']"); foreach (var row in rows) { var title = row.QuerySelector("a[data-src]").GetAttribute("data-src"); if (string.IsNullOrEmpty(title) || title == "0") { title = row.QuerySelector("a[data-src]").TextContent; title = Regex.Replace(title, @"[\[\]\/]", ""); } else { if (title.Length > 5 && title.Substring(title.Length - 5).Contains(".")) { title = title.Remove(title.LastIndexOf(".", StringComparison.Ordinal)); } } var posterStr = row.QuerySelector("img")?.GetAttribute("src"); var poster = !string.IsNullOrWhiteSpace(posterStr) ? new Uri(posterStr) : null; var details = new Uri(SiteLink + row.QuerySelector("a[data-src]").GetAttribute("href")); var link = new Uri(SiteLink + row.QuerySelector("a[href*='action=download']").GetAttribute("href")); var qColSize = row.QuerySelector("td:nth-child(3)"); var size = ReleaseInfo.GetBytes(qColSize.Children[0].TextContent); var files = ParseUtil.CoerceLong(qColSize.Children[1].TextContent.Split(':')[1].Trim()); var qPublishdate = row.QuerySelector("td:nth-child(4) span"); var publishDateStr = qPublishdate.GetAttribute("title"); var publishDate = !string.IsNullOrEmpty(publishDateStr) && publishDateStr.Contains(",") ? DateTime.ParseExact(publishDateStr, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture) : DateTime.ParseExact(qPublishdate.TextContent.Trim(), "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture); var grabs = ParseUtil.CoerceLong(row.QuerySelector("td:nth-child(5)").TextContent); var seeds = ParseUtil.CoerceLong(row.QuerySelector("td:nth-child(6)").TextContent); var leechers = ParseUtil.CoerceLong(row.QuerySelector("td:nth-child(7)").TextContent); var release = new ReleaseInfo { Title = title, Guid = details, Details = details, Link = link, Category = new List <int> { TvCategoryParser.ParseTvShowQuality(title) }, Size = size, Files = files, PublishDate = publishDate, Grabs = grabs, Seeders = seeds, Peers = seeds + leechers, Poster = poster, MinimumRatio = 0, // ratioless MinimumSeedTime = 86400, // 24 hours DownloadVolumeFactor = 0, // ratioless tracker UploadVolumeFactor = 1 }; releases.Add(release); } } catch (Exception e) { OnParseError(response.ContentString, e); } return(releases); }
public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday); TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday); TimeSpan delta = new TimeSpan(1, 0, 0); TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition); TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment }; TimeZoneInfo romaniaTz = TimeZoneInfo.CreateCustomTimeZone("Romania Time", new TimeSpan(2, 0, 0), "(GMT+02:00) Romania Time", "Romania Time", "Romania Daylight Time", adjustments); var releases = new List <ReleaseInfo>(); string episodeSearchUrl; if (string.IsNullOrEmpty(query.GetQueryString())) { episodeSearchUrl = SearchUrl; } else { episodeSearchUrl = $"{SearchUrl}?search={HttpUtility.UrlEncode(query.GetQueryString())}&cat=0"; } var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { CQ dom = results.Content; var rows = dom["#highlight > tbody > tr"]; foreach (var row in rows.Skip(1)) { var release = new ReleaseInfo(); var qRow = row.Cq(); var qLink = qRow.Find("a.torrent_name_link").First(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.Title = qLink.Attr("title"); release.Description = release.Title; release.Guid = new Uri(SiteLink + qLink.Attr("href")); release.Comments = release.Guid; release.Link = new Uri(SiteLink + qRow.Find("td.table_links > a").First().Attr("href")); release.Category = TvCategoryParser.ParseTvShowQuality(release.Title); release.Seeders = ParseUtil.CoerceInt(qRow.Find("td.table_seeders").Text().Trim()); release.Peers = ParseUtil.CoerceInt(qRow.Find("td.table_leechers").Text().Trim()) + release.Seeders; var sizeStr = qRow.Find("td.table_size")[0].Cq().Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); DateTime pubDateRomania; var dateString = qRow.Find("td.table_added").Text().Trim(); if (dateString.StartsWith("Today ")) { pubDateRomania = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateString.Split(' ')[1]); } else if (dateString.StartsWith("Yesterday ")) { pubDateRomania = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateString.Split(' ')[1]) - TimeSpan.FromDays(1); } else { pubDateRomania = DateTime.SpecifyKind(DateTime.ParseExact(dateString, "d-MMM-yyyy HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); } DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(pubDateRomania, romaniaTz); release.PublishDate = pubDateUtc.ToLocalTime(); releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return(releases); }
protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { var releases = new List <ReleaseInfo>(); var searchString = query.GetQueryString(); var searchUrl = BrowseUrl; var queryCollection = new NameValueCollection(); queryCollection.Add("searchstr", StripSearchString(searchString)); queryCollection.Add("order_by", "s3"); queryCollection.Add("order_way", "desc"); queryCollection.Add("disablegrouping", "1"); searchUrl += "?" + queryCollection.GetQueryString(); var results = await RequestStringWithCookies(searchUrl); try { string RowsSelector = "table.torrent_table > tbody > tr.torrent"; var SearchResultParser = new HtmlParser(); var SearchResultDocument = SearchResultParser.Parse(results.Content); var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector); foreach (var Row in Rows) { var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 0; var qDetailsLink = Row.QuerySelector("a[href^=\"torrents.php?id=\"]"); var DescStr = qDetailsLink.NextSibling; var Files = Row.QuerySelector("td:nth-child(3)"); var Added = Row.QuerySelector("td:nth-child(4)"); var Size = Row.QuerySelector("td:nth-child(5)").FirstChild; var Grabs = Row.QuerySelector("td:nth-child(6)"); var Seeders = Row.QuerySelector("td:nth-child(7)"); var Leechers = Row.QuerySelector("td:nth-child(8)"); var FreeLeech = Row.QuerySelector("strong.freeleech_normal"); var TorrentIdParts = qDetailsLink.GetAttribute("href").Split('='); var TorrentId = TorrentIdParts[TorrentIdParts.Length - 1]; var DLLink = "torrents.php?action=download&id=" + TorrentId.ToString(); release.Description = DescStr.TextContent.Trim(); release.Title = qDetailsLink.TextContent + " " + release.Description; release.PublishDate = DateTimeUtil.FromTimeAgo(Added.TextContent); release.Category = new List <int> { TvCategoryParser.ParseTvShowQuality(release.Description) }; release.Link = new Uri(SiteLink + DLLink); release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href")); release.Guid = release.Link; release.Seeders = ParseUtil.CoerceInt(Seeders.TextContent); release.Peers = ParseUtil.CoerceInt(Leechers.TextContent) + release.Seeders; release.Size = ReleaseInfo.GetBytes(Size.TextContent); release.Grabs = ReleaseInfo.GetBytes(Grabs.TextContent); release.Files = ReleaseInfo.GetBytes(Files.TextContent); if (FreeLeech != null) { release.DownloadVolumeFactor = 0; } else { release.DownloadVolumeFactor = 1; } release.UploadVolumeFactor = 1; releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return(releases); }
/// <summary> /// Parses the torrents from the content /// </summary> /// <returns>The parsed torrents.</returns> /// <param name="results">The result of the query</param> /// <param name="query">Query.</param> /// <param name="already_found">Number of the already found torrents.(used for limit)</param> /// <param name="limit">The limit to the number of torrents to download </param> private async Task <List <ReleaseInfo> > ParseTorrents(WebClientStringResult results, TorznabQuery query, int already_found, int limit, int previously_parsed_on_page) { var releases = new List <ReleaseInfo>(); try { var content = results.Content; /* Content Looks like this * 2\15\2\1\1727\207244\1x08 \[WebDL-720p - Eng - AJP69]\gb\2018-03-09 08:11:53\akció, kaland, sci-fi \0\0\1\191170047\1\0\Anonymous\50\0\0\\0\4\0\174\0\ * 1\ 0\0\1\1727\207243\1x08 \[WebDL-1080p - Eng - AJP69]\gb\2018-03-09 08:11:49\akció, kaland, sci-fi \0\0\1\305729738\1\0\Anonymous\50\0\0\\0\8\0\102\0\0\0\0\1\\\ */ var parameters = content.Split(new string[] { "\\" }, StringSplitOptions.None); var type = "normal"; /* * Split the releases by '\' and go through them. * 27 element belongs to one torrent */ for (var j = previously_parsed_on_page * 27; (j + 27 < parameters.Length && ((already_found + releases.Count) < limit)); j = j + 27) { var release = new ReleaseInfo(); var imdb_id = 4 + j; var torrent_id = 5 + j; var is_season_id = 6 + j; var publish_date_id = 9 + j; var files_id = 13 + j; var size_id = 14 + j; var seeders_id = 23; var peers_id = 24 + j; var grabs_id = 25 + j; type = "normal"; //IMDB id of the series var seriesinfo = series.Find(x => x.id.Contains(parameters[imdb_id])); if (seriesinfo != null && !parameters[imdb_id].Equals("")) { release.Imdb = long.Parse(seriesinfo.imdbid); } //ID of the torrent var unixTimestamp = (int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; var fileinfoURL = SearchUrl + "?func=getToggle&id=" + parameters[torrent_id] + "&w=F&pg=0&now=" + unixTimestamp; var fileinfo = (await RequestStringWithCookiesAndRetry(fileinfoURL)).Content; release.Link = new Uri(DownloadUrl + "?id=" + parameters[torrent_id]); release.Guid = release.Link; release.Comments = release.Link; var fileinf = fileinfo.Split(new string[] { "\\\\" }, StringSplitOptions.None); if (fileinf.Length > 1) { release.Title = fileinf[1]; if (fileinf[1].Length > 5 && fileinf[1].Substring(fileinf[1].Length - 4).Contains(".")) { release.Title = fileinf[1].Substring(0, fileinf[1].Length - 4); } } // SeasonPack check if (parameters[is_season_id].Contains("évad/")) { type = "season"; // If this is a seasonpack, remove episode nunmber from title. release.Title = Regex.Replace(release.Title, "s0?(\\d+)(e0?(\\d+))", "S$1", RegexOptions.IgnoreCase); } release.PublishDate = DateTime.Parse(parameters[publish_date_id], CultureInfo.InvariantCulture); release.Files = int.Parse(parameters[files_id]); release.Size = long.Parse(parameters[size_id]); release.Seeders = int.Parse(parameters[seeders_id]); release.Peers = (int.Parse(parameters[peers_id]) + release.Seeders); release.Grabs = int.Parse(parameters[grabs_id]); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; // 48 hours release.DownloadVolumeFactor = 1; release.UploadVolumeFactor = UploadFactorCalculator(release.PublishDate, type); release.Category = new List <int> { TvCategoryParser.ParseTvShowQuality(release.Title) }; if ((already_found + releases.Count) < limit) { releases.Add(release); } else { return(releases); } } } catch (Exception ex) { OnParseError(results.Content, ex); } return(releases); }