public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var results = await RequestStringWithCookiesAndRetry(string.Format(SearchUrl, query.GetQueryString())); try { CQ dom = results.Content; var rows = dom["#torrents-table > tbody > tr.tt_row"]; foreach (var row in rows) { CQ qRow = row.Cq(); var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 129600; release.Title = qRow.Find(".ttr_name > a").Text(); release.Description = release.Title; release.Guid = new Uri(SiteLink + "/" + qRow.Find(".ttr_name > a").Attr("href")); release.Comments = release.Guid; release.Link = new Uri(SiteLink + "/" + qRow.Find(".td_dl > a").Attr("href")); var sizeStr = qRow.Find(".ttr_size").Contents()[0].NodeValue; release.Size = ReleaseInfo.GetBytes(sizeStr); var timeStr = qRow.Find(".ttr_added").Text(); DateTime time; if (DateTime.TryParseExact(timeStr, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out time)) { release.PublishDate = time; } release.Seeders = ParseUtil.CoerceInt(qRow.Find(".ttr_seeders").Text()); release.Peers = ParseUtil.CoerceInt(qRow.Find(".ttr_leechers").Text()) + release.Seeders; var cat = qRow.Find(".ttr_type a").Attr("href"); if (cat == "?cat=27") { release.Category = TorznabCatType.TVHD.ID; } else if (cat == "?cat=17") { release.Category = TorznabCatType.TVSD.ID; } releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var results = response.Content; try { CQ dom = results; var rows = dom["table.lista > tbody > tr"]; foreach (var row in rows) { // this tracker has horrible markup, find the result rows by looking for the style tag before each one var prev = row.PreviousElementSibling; if (prev == null || prev.NodeName.ToLowerInvariant() != "style") continue; CQ qRow = row.Cq(); var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; var qLink = row.ChildElements.ElementAt(1).FirstElementChild.Cq(); release.Title = qLink.Text().Trim(); release.Comments = new Uri(SiteLink + qLink.Attr("href")); release.Guid = release.Comments; var qDownload = row.ChildElements.ElementAt(3).FirstElementChild.Cq(); release.Link = new Uri(SiteLink + qDownload.Attr("href")); //"July 11, 2015, 13:34:09", "Today at 20:04:23" var dateStr = row.ChildElements.ElementAt(4).Cq().Text().Trim(); if (dateStr.StartsWith("Today")) release.PublishDate = DateTime.Today + TimeSpan.ParseExact(dateStr.Replace("Today at ", ""), "hh\\:mm\\:ss", CultureInfo.InvariantCulture); else if (dateStr.StartsWith("Yesterday")) release.PublishDate = DateTime.Today - TimeSpan.FromDays(1) + TimeSpan.ParseExact(dateStr.Replace("Yesterday at ", ""), "hh\\:mm\\:ss", CultureInfo.InvariantCulture); else release.PublishDate = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MMMM dd, yyyy, HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Local); var sizeStr = row.ChildElements.ElementAt(5).Cq().Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text()); release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text()) + release.Seeders; releases.Add(release); } } catch (Exception ex) { OnParseError(results, ex); } return releases; }
private void FillReleaseInfoFromJson(ReleaseInfo release, JObject r) { var id = r["torrentId"]; release.Size = (long)r["size"]; release.Seeders = (int)r["seeders"]; release.Peers = (int)r["leechers"] + release.Seeders; release.Guid = new Uri(GuidUrl + id); release.Comments = release.Guid; release.Link = new Uri(DownloadUrl + id); }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { CQ dom = results.Content; CQ qRows = dom["#torrenttable > tbody > tr"]; foreach (var row in qRows) { var release = new ReleaseInfo(); var qRow = row.Cq(); var debug = qRow.Html(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; CQ qLink = qRow.Find(".title > a").First(); release.Guid = new Uri(SiteLink + qLink.Attr("href")); release.Comments = release.Guid; release.Title = qLink.Text(); release.Description = release.Title; release.Link = new Uri(SiteLink + qRow.Find(".quickdownload > a").Attr("href")); var dateString = qRow.Find(".name")[0].InnerText.Trim().Replace(" ", string.Empty).Replace("Addedinon", string.Empty); //"2015-04-25 23:38:12" //"yyyy-MMM-dd hh:mm:ss" release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture); var sizeStr = qRow.Children().ElementAt(4).InnerText; release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seeders").Text()); release.Peers = release.Seeders + ParseUtil.CoerceInt(qRow.Find(".leechers").Text()); releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { List<ReleaseInfo> releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); await FollowIfRedirect(results); try { CQ dom = results.Content; var rows = dom["table.torrenttable > tbody > tr.browse_color"]; foreach (var row in rows) { var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; var qRow = row.Cq(); 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(); release.Description = release.Title; release.Comments = new Uri(SiteLink + "/" + qCommentLink.Attr("href")); release.Guid = release.Comments; 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; releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { List<ReleaseInfo> releases = new List<ReleaseInfo>(); var searchTerm = string.IsNullOrEmpty(query.SanitizedSearchTerm) ? "2015" : query.SanitizedSearchTerm; var searchString = searchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim())); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty); try { var jResults = JObject.Parse(results.Content); foreach (JObject result in (JArray)jResults["torrents"]) { var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.Title = (string)result["torrent_title"]; release.Description = release.Title; release.Seeders = (int)result["seeds"]; release.Peers = (int)result["leeches"] + release.Seeders; release.Size = (long)result["size"]; // "Apr 2, 2015", "Apr 12, 2015" (note the spacing) // some are unix timestamps, some are not.. :/ var dateString = string.Join(" ", ((string)result["upload_date"]).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); float dateVal; if (ParseUtil.TryCoerceFloat(dateString, out dateVal)) release.PublishDate = DateTimeUtil.UnixTimestampToDateTime(dateVal); else release.PublishDate = DateTime.ParseExact(dateString, "MMM d, yyyy", CultureInfo.InvariantCulture); release.Guid = new Uri((string)result["page"]); release.Comments = release.Guid; release.InfoHash = (string)result["torrent_hash"]; release.MagnetUri = new Uri((string)result["magnet_uri"]); release.Link = new Uri(string.Format(DownloadUrl, release.InfoHash)); releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, string baseUrl) { var releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim())); var xmlDoc = new XmlDocument(); string xml = string.Empty; var result = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { xmlDoc.LoadXml(result.Content); ReleaseInfo release; TorrentzHelper td; string serie_title; foreach (XmlNode node in xmlDoc.GetElementsByTagName("item")) { release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; serie_title = node.SelectSingleNode("title").InnerText; release.Title = serie_title; release.Comments = new Uri(node.SelectSingleNode("link").InnerText); int category = 0; int.TryParse(node.SelectSingleNode("category").InnerText, out category); release.Category = category; release.Guid = new Uri(node.SelectSingleNode("guid").InnerText); release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture); td = new TorrentzHelper(node.SelectSingleNode("description").InnerText); release.Description = td.Description; release.InfoHash = td.hash; release.Size = td.Size; release.Seeders = td.Seeders; release.Peers = td.Peers + release.Seeders; release.MagnetUri = TorrentzHelper.createMagnetLink(td.hash, serie_title); releases.Add(release); } } catch (Exception ex) { OnParseError(xml, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var results = await PostDataWithCookiesAndRetry(SearchUrl, GetSearchFormData(searchString)); try { CQ dom = results.Content; var rows = dom["tr.browse"]; foreach (var row in rows) { var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; var descCol = row.ChildElements.ElementAt(1); var qDescCol = descCol.Cq(); var qLink = qDescCol.Find("a"); release.Title = qLink.Text(); release.Description = release.Title; release.Comments = new Uri(SiteLink + "/" + qLink.Attr("href")); release.Guid = release.Comments; var torrentId = qLink.Attr("href").Split('=')[1]; release.Link = new Uri(string.Format(DownloadUrl, torrentId)); var dateStr = descCol.ChildNodes.Last().NodeValue.Trim(); var euDate = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); var timezoneString = Environment.OSVersion.Platform == PlatformID.Unix ? "Europe/Berlin" : "Central European Standard Time"; var localDate = TimeZoneInfo.ConvertTimeToUtc(euDate, TimeZoneInfo.FindSystemTimeZoneById(timezoneString)).ToLocalTime(); release.PublishDate = localDate; var sizeStr = row.ChildElements.ElementAt(5).Cq().Text(); 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; releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { CQ dom = results.Content; dom["#needseed"].Remove(); var rows = dom["table[width='750'] > tbody"].Children(); foreach (var row in rows.Skip(1)) { var release = new ReleaseInfo(); var qRow = row.Cq(); var qLink = qRow.Children().ElementAt(2).Cq().Children("a").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(string.Format(DownloadUrl, qLink.Attr("href").Split('=')[1])); var dateString = qRow.Children().ElementAt(5).Cq().Text().Trim(); var pubDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); release.PublishDate = DateTime.SpecifyKind(pubDate, DateTimeKind.Local); var sizeStr = qRow.Children().ElementAt(6).Cq().Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Trim()); release.Peers = ParseUtil.CoerceInt(qRow.Children().ElementAt(9).Cq().Text().Trim()) + release.Seeders; releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { CQ dom = response.Content; var rows = dom["table > tbody > tr"]; foreach (var row in rows) { CQ qRow = row.Cq(); var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; var qLink = row.ChildElements.ElementAt(1).FirstElementChild.Cq(); release.Title = qLink.Text().Trim(); release.Comments = new Uri(qLink.Attr("href")); release.Guid = release.Comments; var qDownload = row.ChildElements.ElementAt(3).FirstElementChild.Cq(); release.Link = new Uri(qDownload.Attr("href")); var dateStr = row.ChildElements.ElementAt(5).Cq().Text().Trim(); release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr); var sizeStr = row.ChildElements.ElementAt(6).Cq().Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text()); release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(9).Cq().Text()) + release.Seeders; releases.Add(release); } } catch (Exception ex) { OnParseError(response.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var formData = HttpUtility.ParseQueryString(SearchFormData); var formDict = formData.AllKeys.ToDictionary(t => t, t => formData[t]); formDict.Add("search", query.SanitizedSearchTerm); var response = await PostDataWithCookiesAndRetry(SearchUrl, formDict); try { var jsonResult = JObject.Parse(response.Content); var resultArray = ((JArray)jsonResult["Fs"])[0]["Cn"]["torrents"]; foreach (var jobj in resultArray) { var release = new ReleaseInfo(); var id = (int)jobj["id"]; release.Comments = new Uri(string.Format(CommentsUrl, id)); release.Guid = release.Comments; release.Link = new Uri(string.Format(DownloadUrl, id)); release.Title = Regex.Replace((string)jobj["name"], "<.*?>", String.Empty); var SizeStr = ((string)jobj["size"]); release.Size = ReleaseInfo.GetBytes(SizeStr); release.Seeders = ParseUtil.CoerceInt((string)jobj["seed"]); release.Peers = ParseUtil.CoerceInt((string)jobj["leech"]) + release.Seeders; // ex: Tuesday, May 26, 2015 at 6:00pm var dateStr = new Regex("title=\"(.*?)\"").Match((string)jobj["added"]).Groups[1].ToString(); dateStr = dateStr.Replace(" at", ""); var dateTime = DateTime.ParseExact(dateStr, "dddd, MMMM d, yyyy h:mmtt", CultureInfo.InvariantCulture); release.PublishDate = dateTime; releases.Add(release); } } catch (Exception ex) { OnParseError(response.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { CQ dom = results.Content; var rows = dom["#torrentTable > tbody > tr.browse"]; foreach (var row in rows) { CQ qRow = row.Cq(); var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.Title = qRow.Find(".torrentName").Text(); release.Description = release.Title; release.Guid = new Uri(SiteLink + "/" + qRow.Find(".torrentName").Attr("href")); release.Comments = release.Guid; release.Link = new Uri(SiteLink + "/" + qRow.Find(".dlLinksInfo > a").Attr("href")); var sizeStr = qRow.Find(".sizeInfo").Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); var dateStr = qRow.Find(".ulInfo").Text().Split('|').Last().Trim(); release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr); release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seedersInfo").Text()); release.Peers = ParseUtil.CoerceInt(qRow.Find(".leechersInfo").Text()) + release.Seeders; releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var results = await PostDataWithCookiesAndRetry(SearchUrl, GetSearchFormData(query.GetQueryString())); try { CQ dom = results.Content; var rows = dom["tr.browse"]; foreach (var row in rows) { var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; var descCol = row.ChildElements.ElementAt(1); var qDescCol = descCol.Cq(); var qLink = qDescCol.Find("a"); release.Title = qLink.Text(); release.Description = release.Title; release.Comments = new Uri(SiteLink + "/" + qLink.Attr("href")); release.Guid = release.Comments; var torrentId = qLink.Attr("href").Split('=')[1]; release.Link = new Uri(string.Format(DownloadUrl, torrentId)); release.PublishDate = DateTimeUtil.FromTimeAgo(descCol.ChildNodes.Last().InnerText); var sizeStr = row.ChildElements.ElementAt(5).Cq().Text(); 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; releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
private void FillReleaseInfoFromJson(ReleaseInfo release, JObject r) { var id = r["torrentId"]; release.Size = (long)r["size"]; release.Seeders = (int)r["seeders"]; release.Peers = (int)r["leechers"] + release.Seeders; release.Guid = new Uri(GuidUrl + id); release.Comments = release.Guid; if ((string)r["category"] == "TV") { release.Category = TorznabCatType.TV.ID; } else if ((string)r["category"] == "Movies") { release.Category = TorznabCatType.Movies.ID; } release.Link = new Uri(DownloadUrl + id); }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { List<ReleaseInfo> releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { CQ dom = response.Cookies; var rows = dom[".results_index ul"]; foreach (var row in rows) { var release = new ReleaseInfo(); CQ qRow = row.Cq(); CQ qLink = qRow.Find("li.torrents_name > .torrents_name_link").First(); CQ qDlLink = qRow.Find("li.torrents_download > a").First(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.Title = qLink.Text().Trim(); release.Description = release.Title; release.Comments = new Uri(SiteLink + "/" + qLink.Attr("href").TrimStart('/')); release.Guid = release.Comments; release.Link = new Uri(SiteLink + "/" + qDlLink.Attr("href").TrimStart('/')); release.PublishDate = DateTime.Now; release.Seeders = ParseUtil.CoerceInt(qRow.Find("li.torrents_seeders").Text()); release.Peers = ParseUtil.CoerceInt(qRow.Find("li.torrents_leechers").Text()) + release.Seeders; var sizeParts = qRow.Find("li.torrents_size").Text(); release.Size = ReleaseInfo.GetBytes(sizeParts); releases.Add(release); } } catch (Exception ex) { OnParseError(response.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchString = query.GetQueryString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { CQ dom = results.Content; var rows = dom["#torrent_table > tbody > tr.torrent"]; foreach (var row in rows) { CQ qRow = row.Cq(); var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.Title = qRow.Find(".torrent_name_link").Text(); release.Description = release.Title; release.Guid = new Uri(SiteLink + "/" + qRow.Find(".torrent_name_link").Parent().Attr("href")); release.Comments = release.Guid; release.Link = new Uri(SiteLink + "/" + qRow.Find(".torrent_handle_links > a").First().Attr("href")); var dateStr = qRow.Find(".time").Text().Trim(); release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr); var sizeStr = qRow.Find(".size")[0].ChildNodes[0].NodeValue; release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(qRow.Children().ElementAt(6).InnerText.Trim()); release.Peers = ParseUtil.CoerceInt(qRow.Children().ElementAt(7).InnerText.Trim()) + release.Seeders; releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
public void CacheRssResults(string trackerId, ReleaseInfo[] releases) { lock (cache) { var trackerCache = cache.Where(c => c.TrackerId == trackerId).FirstOrDefault(); if (trackerCache == null) { trackerCache = new TrackerCache(); trackerCache.TrackerId = trackerId; cache.Add(trackerCache); } foreach(var release in releases.OrderByDescending(i=>i.PublishDate)) { // Skip old releases if(release.PublishDate-DateTime.Now> AGE_LIMIT) { continue; } var existingItem = trackerCache.Results.Where(i => i.Result.Guid == release.Guid).FirstOrDefault(); if (existingItem == null) { existingItem = new CachedResult(); existingItem.Created = DateTime.Now; trackerCache.Results.Add(existingItem); } existingItem.Result = release; } // Prune cache foreach(var tracker in cache) { tracker.Results = tracker.Results.OrderByDescending(i => i.Created).Take(MAX_RESULTS_PER_TRACKER).ToList(); } } }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(query.GetQueryString()); WebClientStringResult response = null; response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { var json = JObject.Parse(response.Content); foreach (JObject r in json["response"]["results"]) { DateTime pubDate = DateTime.MinValue; double dateNum; if (double.TryParse((string)r["groupTime"], out dateNum)) { pubDate = DateTimeUtil.UnixTimestampToDateTime(dateNum); pubDate = DateTime.SpecifyKind(pubDate, DateTimeKind.Utc).ToLocalTime(); } var groupName = (string)r["groupName"]; if (r["torrents"] is JArray) { foreach (JObject t in r["torrents"]) { var release = new ReleaseInfo(); release.PublishDate = pubDate; release.Title = groupName; release.Description = groupName; FillReleaseInfoFromJson(release, t); releases.Add(release); } } else { var release = new ReleaseInfo(); release.PublishDate = pubDate; release.Title = groupName; release.Description = groupName; FillReleaseInfoFromJson(release, r); releases.Add(release); } } } catch (Exception ex) { OnParseError(response.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { List<ReleaseInfo> releases = new List<ReleaseInfo>(); var searchString = query.GetQueryString(); var searchUrl = SearchUrl; var queryCollection = new NameValueCollection(); queryCollection.Add("action", "torrentstable"); queryCollection.Add("viewtype", "0"); queryCollection.Add("visiblecategories", "Action,Adventure,Animation,Biography,Comedy,Crime,Documentary,Drama,Eastern,Family,Fantasy,History,Holiday,Horror,Kids,Musical,Mystery,Romance,Sci-Fi,Short,Sports,Thriller,War,Western"); queryCollection.Add("page", "1"); queryCollection.Add("visibility", "showall"); queryCollection.Add("compression", "showall"); queryCollection.Add("sort", "added"); queryCollection.Add("order", "DESC"); queryCollection.Add("titleonly", "true"); queryCollection.Add("packs", "showall"); queryCollection.Add("bookmarks", "showall"); queryCollection.Add("subscriptions", "showall"); queryCollection.Add("skw", "showall"); queryCollection.Add("advancedsearchparameters", ""); if (!string.IsNullOrWhiteSpace(searchString)) { // search keywords use OR by default and it seems like there's no way to change it, expect unwanted results queryCollection.Add("searchstring", searchString); } var cats = MapTorznabCapsToTrackers(query); var hiddenqualities = ""; if (cats.Count > 0) { hiddenqualities = String.Join(",", categories.Where(cat => !cats.Contains(cat))); } queryCollection.Add("hiddenqualities", hiddenqualities); searchUrl += "?" + queryCollection.GetQueryString(); var results = await RequestStringWithCookiesAndRetry(searchUrl); try { CQ dom = results.Content; /* // parse logic for viewtype=1, unfortunately it's missing the release time so we can't use it var movieBlocks = dom["table.main"]; foreach (var movieBlock in movieBlocks) { var qMovieBlock = movieBlock.Cq(); var movieLink = qMovieBlock.Find("tr > td[class=colhead] > a").First(); var movieName = movieLink.Text(); var qDetailsBlock = qMovieBlock.Find("tr > td.torrentstd > table > tbody > tr"); var qDetailsHeader = qDetailsBlock.ElementAt(0); var qDetailsTags = qDetailsBlock.ElementAt(1); var qTorrents = qDetailsBlock.Find("td.moviestorrentstd > table > tbody > tr:eq(0)"); foreach (var torrent in qTorrents) { var qTorrent = torrent.Cq(); var qCatIcon = qTorrent.Find("td:eq(0) > img"); var qDetailsLink = qTorrent.Find("td:eq(1) > a:eq(0)"); var qSeeders = qTorrent.Find("td:eq(1) > b > a[alt=\"Number of Seeders\"]"); var qLeechers = qTorrent.Find("td:eq(1) > span[alt=\"Number of Leechers\"]"); var qDownloadLink = qTorrent.Find("td:eq(1) > a:has(img[alt=\"Download Torrent\"])"); } } */ var rows = dom["table.main > tbody > tr"]; foreach (var row in rows.Skip(1)) { var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 72 * 60 * 60; var qRow = row.Cq(); var qDetailsLink = qRow.Find("td:eq(1) > a:eq(0)"); // link to the movie, not the actual torrent release.Title = qDetailsLink.Attr("alt"); var qCatIcon = qRow.Find("td:eq(0) > img"); var qSeeders = qRow.Find("td:eq(8)"); var qLeechers = qRow.Find("td:eq(9)"); var qDownloadLink = qRow.Find("td > a:has(img[alt=\"Download Torrent\"])"); var qPudDate = qRow.Find("td:eq(5) > nobr"); var qSize = qRow.Find("td:eq(6)"); var catStr = qCatIcon.Attr("alt"); release.Category = MapTrackerCatToNewznab(catStr); release.Link = new Uri(SiteLink + qDownloadLink.Attr("href").Substring(1)); release.Title = qDetailsLink.Attr("alt"); release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href")); release.Guid = release.Link; var dateStr = qPudDate.Text().Trim(); DateTime pubDateUtc; var Timeparts = dateStr.Split(new char[] { ' ' }, 2)[1]; if (dateStr.StartsWith("Today ")) pubDateUtc = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + DateTime.ParseExact(dateStr.Split(new char[] { ' ' }, 2)[1], "hh:mm tt", System.Globalization.CultureInfo.InvariantCulture).TimeOfDay; else if (dateStr.StartsWith("Yesterday ")) pubDateUtc = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + DateTime.ParseExact(dateStr.Split(new char[] { ' ' }, 2)[1], "hh:mm tt", System.Globalization.CultureInfo.InvariantCulture).TimeOfDay - TimeSpan.FromDays(1); else pubDateUtc = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MMM d yyyy hh:mm tt", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); release.PublishDate = pubDateUtc.ToLocalTime(); var sizeStr = qSize.Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(qSeeders.Text()); release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders; var files = qRow.Find("td:nth-child(4)").Text(); release.Files = ParseUtil.CoerceInt(files); var grabs = qRow.Find("td:nth-child(8)").Text(); release.Grabs = ParseUtil.CoerceInt(grabs); release.DownloadVolumeFactor = 0; // ratioless release.UploadVolumeFactor = 1; releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var trackerCats = MapTorznabCapsToTrackers(query); var cat = (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0"); var episodeSearchUrl = string.Format(SearchUrl, cat, HttpUtility.UrlEncode(query.GetQueryString())); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); if (results.Content.Contains("No torrents found")) { return releases; } try { CQ dom = results.Content; var rows = dom[".ctable_content_no_pad > table > tbody > tr"].ToArray(); DateTime lastDateTime = default(DateTime); for (var i = 0; i < rows.Length; i++) { var rowA = rows[i]; var rAlign = rowA.Attributes["align"]; if (rAlign == "right" || rAlign == "center") continue; if (rAlign == "left") { // ex: "Monday, Jun 01, 2015", "Monday, Aug 03, 2015" var dateStr = rowA.Cq().Text().Trim().Replace("Added on ", ""); if (dateStr.ToLowerInvariant().Contains("today")) lastDateTime = DateTime.Now; else lastDateTime = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dddd, MMM dd, yyyy", CultureInfo.InvariantCulture), DateTimeKind.Utc).ToLocalTime(); continue; } if (rowA.ChildElements.Count() < 2) continue; var rowB = rows[++i]; var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.PublishDate = lastDateTime; var qLink = rowA.ChildElements.ElementAt(1).FirstElementChild.Cq(); release.Title = qLink.Text().Trim(); release.Description = release.Title; release.Comments = new Uri(SiteLink + qLink.Attr("href")); release.Guid = release.Comments; var qDownload = rowB.ChildElements.ElementAt(2).ChildElements.ElementAt(0).Cq(); release.Link = new Uri(SiteLink + qDownload.Attr("href")); var sizeStr = rowB.ChildElements.ElementAt(3).Cq().Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(6).Cq().Text()); release.Peers = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders; var grabs = rowB.Cq().Find("td:nth-child(6)").Text(); release.Grabs = ParseUtil.CoerceInt(grabs); release.DownloadVolumeFactor = 0; // ratioless release.UploadVolumeFactor = 1; releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchUrl = BrowsePage; if (!string.IsNullOrWhiteSpace(searchString)) { searchUrl += string.Format(QueryString, HttpUtility.UrlEncode(searchString)); } var results = await RequestStringWithCookiesAndRetry(searchUrl); try { CQ dom = results.Content; var rows = dom["#sortabletable tr"]; foreach (var row in rows.Skip(1)) { var release = new ReleaseInfo(); var qRow = row.Cq(); release.Title = qRow.Find(".tooltip-content div").First().Text(); if (string.IsNullOrWhiteSpace(release.Title)) continue; release.Description = qRow.Find(".tooltip-content div").Get(1).InnerText.Trim(); var qLink = row.Cq().Find("td:eq(2) a:eq(1)"); release.Link = new Uri(qLink.Attr("href")); release.Guid = release.Link; release.Comments = new Uri(qRow.Find(".tooltip-target a").First().Attr("href")); // 07-22-2015 11:08 AM var dateString = qRow.Find("td:eq(1) div").Last().Children().Remove().End().Text().Trim(); release.PublishDate = DateTime.ParseExact(dateString, "MM-dd-yyyy hh:mm tt", CultureInfo.InvariantCulture); var sizeStr = qRow.Find("td:eq(4)").Text().Trim(); release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:eq(6)").Text().Trim()); release.Peers = ParseUtil.CoerceInt(qRow.Find("td:eq(7)").Text().Trim()) + release.Seeders; var catLink = row.Cq().Find("td:eq(0) a").First().Attr("href"); var catSplit = catLink.IndexOf("category="); if (catSplit > -1) { catLink = catLink.Substring(catSplit + 9); } release.Category = MapTrackerCatToNewznab(catLink); releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchTerm = string.IsNullOrEmpty(query.SanitizedSearchTerm) ? "%20" : query.SanitizedSearchTerm; var searchString = searchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var message = new HttpRequestMessage(); message.Method = HttpMethod.Get; message.RequestUri = new Uri(episodeSearchUrl); message.Headers.TryAddWithoutValidation("Authorization", await GetAuthToken()); var response = await client.SendAsync(message); var results = await response.Content.ReadAsStringAsync(); var jsonResult = JObject.Parse(results); try { var items = (JArray)jsonResult["torrents"]; foreach (var item in items) { var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; var torrentId = (string)item["id"]; release.Link = new Uri(string.Format(DownloadUrl, torrentId)); release.Title = (string)item["name"]; release.Description = release.Title; release.Comments = new Uri(string.Format(CommentsUrl, (string)item["rewritename"])); release.Guid = release.Comments; var dateUtc = DateTime.ParseExact((string)item["added"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); release.PublishDate = DateTime.SpecifyKind(dateUtc, DateTimeKind.Utc).ToLocalTime(); release.Seeders = ParseUtil.CoerceInt((string)item["seeders"]); release.Peers = ParseUtil.CoerceInt((string)item["leechers"]) + release.Seeders; release.Size = ParseUtil.CoerceLong((string)item["size"]); release.Category = MapTrackerCatToNewznab((string)item["categoryname"]); releases.Add(release); } } catch (Exception ex) { OnParseError(results, ex); } return releases; }
public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query) { // This tracker only deals with full seasons so chop off the episode/season number if we have it D: if (!string.IsNullOrWhiteSpace(query.SanitizedSearchTerm)) { var splitindex = query.SanitizedSearchTerm.LastIndexOf(' '); if (splitindex > -1) query.SanitizedSearchTerm = query.SanitizedSearchTerm.Substring(0, splitindex); } var releases = new List<ReleaseInfo>(); var searchString = query.SanitizedSearchTerm; var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString); var response = await webclient.GetString(new Utils.Clients.WebRequest() { Url = episodeSearchUrl, Cookies = cookieHeader }); try { CQ dom = response.Content; var rows = dom[".torrents tr.torrent"]; foreach (var row in rows) { var qRow = row.Cq(); var qTitleLink = qRow.Find("a.title").First(); var title = qTitleLink.Text().Trim(); // Insert before the release info var taidx = title.IndexOf('('); var tbidx = title.IndexOf('['); if (taidx == -1) taidx = title.Length; if (tbidx == -1) tbidx = title.Length; var titleSplit = Math.Min(taidx, tbidx); var titleSeries = title.Substring(0, titleSplit); var releaseInfo = title.Substring(titleSplit); // For each over each pipe deliminated name foreach (var name in titleSeries.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) { var release = new ReleaseInfo(); release.Title = (name + releaseInfo).Trim(); // Ensure the season is defined as this tracker only deals with full seasons if (release.Title.IndexOf("Season") == -1) { // Insert before the release info var aidx = release.Title.IndexOf('('); var bidx = release.Title.IndexOf('['); if (aidx == -1) aidx = release.Title.Length; if (bidx == -1) bidx = release.Title.Length; var insertPoint = Math.Min(aidx, bidx); release.Title = release.Title.Substring(0, insertPoint) + "Season 1 " + release.Title.Substring(insertPoint); } release.Description = release.Title; release.Guid = new Uri(SiteLink + qTitleLink.Attr("href")); release.Comments = release.Guid; release.Link = new Uri(SiteLink + qRow.Find(".peers a").First().Attr("href")); release.Seeders = int.Parse(qRow.Find(".peers a").Get(0).InnerText); release.Peers = release.Seeders + int.Parse(qRow.Find(".peers a").Get(1).InnerText); release.MinimumRatio = 1; var size = qRow.Find(".size").First().Text(); release.Size = ReleaseInfo.GetBytes(size); //22 Jul 15 var dateStr = qRow.Find(".added . datetime").First().Text().Replace("'", string.Empty); if (dateStr.Split(' ')[0].Length == 1) dateStr = "0" + dateStr; if (string.Equals(dateStr, "yesterday", StringComparison.InvariantCultureIgnoreCase)) { release.PublishDate = DateTime.Now.AddDays(-1); } else if (string.Equals(dateStr, "today", StringComparison.InvariantCultureIgnoreCase)) { release.PublishDate = DateTime.Now; } else { release.PublishDate = DateTime.ParseExact(dateStr, "dd MMM yy", CultureInfo.InvariantCulture); } releases.Add(release); } } } catch (Exception ex) { OnParseError(response.Content, ex); } return releases.ToArray(); }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchString = query.GetQueryString(); var queryCollection = new NameValueCollection(); if (!string.IsNullOrWhiteSpace(searchString)) { queryCollection.Add("search", searchString); } var searchUrl = SearchUrl + queryCollection.GetQueryString(); var trackerCats = MapTorznabCapsToTrackers(query, mapChildrenCatsToParent: true); var results = await RequestStringWithCookiesAndRetry(searchUrl); try { CQ dom = results.Content; dom["#needseed"].Remove(); var rows = dom["table[width='750'] > tbody"].Children(); foreach (var row in rows.Skip(1)) { var release = new ReleaseInfo(); var qRow = row.Cq(); var qLink = qRow.Children().ElementAt(2).Cq().Children("a").First(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.Title = qLink.Attr("title"); release.Description = release.Title; release.Guid = new Uri(SiteLink + qLink.Attr("href").TrimStart('/')); release.Comments = release.Guid; release.Link = new Uri(string.Format(DownloadUrl, qLink.Attr("href").Split('=')[1])); var catUrl = qRow.Children().ElementAt(1).FirstElementChild.Cq().Attr("href"); var catNum = catUrl.Split(new char[] { '=', '&' })[1]; release.Category = MapTrackerCatToNewznab(catNum); // This tracker cannot search multiple cats at a time, so search all cats then filter out results from different cats if (trackerCats.Count > 0 && !trackerCats.Contains(catNum)) continue; var dateString = qRow.Children().ElementAt(5).Cq().Text().Trim(); var pubDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); release.PublishDate = DateTime.SpecifyKind(pubDate, DateTimeKind.Local); var sizeStr = qRow.Children().ElementAt(6).Cq().Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Trim()); release.Peers = ParseUtil.CoerceInt(qRow.Children().ElementAt(9).Cq().Text().Trim()) + release.Seeders; releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return releases; }
void FillReleaseInfoFromJson(ReleaseInfo release, JObject r) { var id = r["torrentId"]; release.Size = (long)r["size"]; release.Seeders = (int)r["seeders"]; release.Peers = (int)r["leechers"] + release.Seeders; release.Guid = new Uri(GuidUrl + id); release.Comments = release.Guid; release.Link = new Uri(DownloadUrl + id); release.Category = MapTrackerCatToNewznab(CategoryReverseMapper((string)r["category"])); release.Files = (int)r["fileCount"]; release.Grabs = (int)r["snatches"]; release.DownloadVolumeFactor = 1; release.UploadVolumeFactor = 1; if ((bool)r["isFreeleech"]) { release.DownloadVolumeFactor = 0; } if ((bool)r["isPersonalFreeleech"]) { release.DownloadVolumeFactor = 0; } if ((bool)r["isNeutralLeech"]) { release.DownloadVolumeFactor = 0; release.UploadVolumeFactor = 0; } }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var searchString = query.GetQueryString(); var searchUrl = SearchUrl; var queryCollection = new NameValueCollection(); if (!string.IsNullOrWhiteSpace(searchString)) { queryCollection.Add("searchstr", searchString); } foreach (var cat in MapTorznabCapsToTrackers(query)) { queryCollection.Add("filter_cat[" + cat + "]", "1"); } searchUrl += queryCollection.GetQueryString(); var response = await RequestStringWithCookiesAndRetry(searchUrl); if (response.IsRedirect) { await ApplyConfiguration(null); response = await RequestStringWithCookiesAndRetry(searchUrl); } try { var json = JObject.Parse(response.Content); foreach (JObject r in json["response"]["results"]) { DateTime pubDate = DateTime.MinValue; double dateNum; if (double.TryParse((string)r["groupTime"], out dateNum)) pubDate = UnixTimestampToDateTime(dateNum); var groupName = (string)r["groupName"]; if (r["torrents"] is JArray) { foreach (JObject t in r["torrents"]) { var release = new ReleaseInfo(); release.PublishDate = pubDate; release.Title = groupName; release.Description = groupName; FillReleaseInfoFromJson(release, t); releases.Add(release); } } else { var release = new ReleaseInfo(); release.PublishDate = pubDate; release.Title = groupName; release.Description = groupName; FillReleaseInfoFromJson(release, r); releases.Add(release); } } } catch (Exception ex) { OnParseError(response.Content, ex); } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var loggedInCheck = await RequestStringWithCookies(SearchUrl); if (!loggedInCheck.Content.Contains("/logout.php")) { //Cookie appears to expire after a period of time or logging in to the site via browser await DoLogin(); } var releases = new List<ReleaseInfo>(); NameValueCollection qParams = new NameValueCollection(); if (!string.IsNullOrEmpty(query.GetQueryString())) { qParams.Add("search", query.GetQueryString()); } List<string> catList = MapTorznabCapsToTrackers(query); foreach (string cat in catList) { qParams.Add("c" + cat, "1"); } string urlSearch = SearchUrl; if (qParams.Count > 0) { urlSearch += $"?{qParams.GetQueryString()}"; } var response = await RequestStringWithCookiesAndRetry(urlSearch); try { CQ dom = response.Content; var rows = dom["div[id='torrentTable'] > div[class='box torrentBox'] > div[class='boxContent'] > table > tbody > tr"]; foreach (IDomObject row in rows) { CQ torrentData = row.OuterHTML; CQ cells = row.Cq().Find("td"); string title = torrentData.Find("a[class='torrent']").First().Text().Trim(); Uri link = new Uri(SiteLink + torrentData.Find("img[class='icos save']").First().Parent().Attr("href").Trim()); Uri guid = new Uri(SiteLink + torrentData.Find("a[class='torrent']").First().Attr("href").Trim().TrimStart('/')); long size = ReleaseInfo.GetBytes(cells.Elements.ElementAt(4).Cq().Text()); int seeders = ParseUtil.CoerceInt(cells.Elements.ElementAt(5).Cq().Text()); int leechers = ParseUtil.CoerceInt(cells.Elements.ElementAt(6).Cq().Text()); string pubDateStr = torrentData.Find("span[class^='elapsedDate']").First().Attr("title").Trim().Replace(" at", ""); DateTime publishDate = DateTime.ParseExact(pubDateStr, "dddd, MMMM d, yyyy h:mmtt", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime(); long category = 0; string cat = torrentData.Find("a[class='cat']").First().Attr("id").Trim(); long.TryParse(cat, out category); var release = new ReleaseInfo(); release.Title = title; release.Guid = guid; release.Link = link; release.PublishDate = publishDate; release.Size = size; release.Description = release.Title; release.Seeders = seeders; release.Peers = seeders + leechers; release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.Category = MapTrackerCatToNewznab(category.ToString()); release.Comments = guid; releases.Add(release); } } catch (Exception ex) { OnParseError(response.Content, ex); } return releases; }
/// <summary> /// Execute our search query /// </summary> /// <param name="query">Query</param> /// <returns>Releases</returns> public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var torrentRowList = new List<CQ>(); var searchTerm = query.GetQueryString(); var searchUrl = SearchUrl; // Check login before performing a query await CheckLogin(); // Check cache first so we don't query the server (if search term used or not in dev mode) if (!DevMode && !string.IsNullOrEmpty(searchTerm)) { lock (cache) { // Remove old cache items CleanCache(); // Search in cache var cachedResult = cache.FirstOrDefault(i => i.Query == searchTerm); if (cachedResult != null) return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray(); } } // Build our query var request = BuildQuery(searchTerm, query, searchUrl); // Getting results & Store content var response = await RequestStringWithCookiesAndRetry(request, ConfigData.CookieHeader.Value); _fDom = response.Content; try { var firstPageRows = FindTorrentRows(); // Add them to torrents list torrentRowList.AddRange(firstPageRows.Select(fRow => fRow.Cq())); // If pagination available int nbResults; int pageLinkCount; nbResults = 1; pageLinkCount = 1; // Check if we have a minimum of one result if (firstPageRows.Length > 1) { // Retrieve total count on our alone page nbResults = firstPageRows.Count(); } else { // Check if no result if(torrentRowList.First().Find("td").Length == 1) { // No results found Output("\nNo result found for your query, please try another search term ...\n", "info"); // No result found for this query return releases; } } Output("\nFound " + nbResults + " result(s) (+/- " + firstPageRows.Length + ") in " + pageLinkCount + " page(s) for this query !"); Output("\nThere are " + firstPageRows.Length + " results on the first page !"); // Loop on results foreach (var tRow in torrentRowList) { Output("Torrent #" + (releases.Count + 1)); // ID var id = tRow.Find("td:eq(1) > a:eq(0)").Attr("href").Split('=').Last(); Output("ID: " + id); // Release Name var name = tRow.Find("td:eq(1) > a:eq(0)").Attr("title"); // Category var categoryId = tRow.Find("td:eq(0) > div > a:eq(0)").Attr("href").Split('?').Last(); var categoryName = tRow.Find("td:eq(0) > div > a:eq(0)").Attr("title"); var MainCat = tRow.Find("td:eq(0) > div > a:eq(0)").Attr("href").Split('?').Last(); var SubCat1 = "none"; var SubCat2 = "none"; var testcat = MainCat; if (tRow.Find("td:eq(0) > div > a:eq(1)").Length == 1) { SubCat1 = tRow.Find("td:eq(0) > div > a:eq(1)").Attr("href").Split('?').Last(); } if (tRow.Find("td:eq(0) > div > a:eq(2)").Length == 1) { SubCat2 = tRow.Find("td:eq(0) > div > a:eq(2)").Attr("href").Split('?').Last(); testcat = MainCat + '&' + SubCat2; } Output("Category: " + testcat + " - " + categoryName); // Seeders var seeders = 1; if (tRow.Find("td:eq(10) > a").Length > 0) { seeders = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(9) > a").Text(), @"\d+").Value); Output("Seeders: " + seeders); } else { seeders = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(9)").Text(), @"\d+").Value); Output("Seeders: " + seeders); } // Leechers var leechers = 1; if (tRow.Find("td:eq(10) > a").Length > 0) { leechers = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(10) > a").Text(), @"\d+").Value); Output("Leechers: " + leechers); } else { leechers = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(10)").Text(), @"\d+").Value); Output("Leechers: " + leechers); } // Completed Regex regexObj = new Regex(@"[^\d]"); var completed2 = tRow.Find("td:eq(7)").Text(); var completed = regexObj.Replace(completed2, ""); Output("Completed: " + completed); // Files var files = 1; if (tRow.Find("td:eq(2) > a").Length == 1) { files = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(2) > a").Text(), @"\d+").Value); } Output("Files: " + files); // Health var percent = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(8)").Text(), @"\d+").Value.Trim()); Output("Health: " + percent + "%"); // Size var humanSize = tRow.Find("td:eq(6)").Text().ToLowerInvariant(); var size = ReleaseInfo.GetBytes(humanSize); Output("Size: " + humanSize + " (" + size + " bytes)"); // --> Date var dateTimeOrig = tRow.Find("td:eq(4)").Text(); var dateTime = Regex.Replace(dateTimeOrig, @"<[^>]+>| ", "").Trim(); var date = DateTime.ParseExact(dateTime, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime(); Output("Released on: " + date); // Torrent Details URL var detailsLink = new Uri(TorrentDescriptionUrl.Replace("{id}", id.ToString())); Output("Details: " + detailsLink.AbsoluteUri); // Torrent Comments URL var commentsLink = new Uri(TorrentCommentUrl.Replace("{id}", id.ToString())); Output("Comments Link: " + commentsLink.AbsoluteUri); // Torrent Download URL var passkey = tRow.Find("td:eq(1) > a:eq(1)").Attr("href"); var key = Regex.Match(passkey, "(?<=passkey\\=)([a-zA-z0-9]*)"); Uri downloadLink = new Uri(TorrentDownloadUrl.Replace("{id}", id.ToString()).Replace("{passkey}", key.ToString())); Output("Download Link: " + downloadLink.AbsoluteUri); // Building release infos var release = new ReleaseInfo { Category = MapTrackerCatToNewznab(testcat.ToString()), Title = name, Seeders = seeders, Peers = seeders + leechers, MinimumRatio = 1, MinimumSeedTime = 172800, PublishDate = date, Size = size, Guid = detailsLink, Comments = commentsLink, Link = downloadLink }; releases.Add(release); } } catch (Exception ex) { OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex); } // Return found releases return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { var releases = new List<ReleaseInfo>(); var breakWhile = false; var page = 0; while (page < 3) { string episodeSearchUrl; if (string.IsNullOrEmpty(query.GetQueryString())) { episodeSearchUrl = SearchUrl + "?page=" + page; breakWhile = true; } else { var cats = MapTorznabCapsToTrackers(query); var catsUrlPart = string.Join("&", cats.Select(c => $"c{c}=1")); episodeSearchUrl = string.Format("{0}?search={1}&cat=0&incldead=0&{2}&page={3}", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()), catsUrlPart, page); } page++; var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); try { CQ dom = results.Content; var rows = dom["#torrent-table-wrapper > div"]; foreach (var row in rows.Skip(1)) { var release = new ReleaseInfo(); var qRow = row.Cq(); var qLink = qRow.Find("#torrent-udgivelse2-users > a").First(); var qDesc = qRow.Find("#torrent-udgivelse2-users > p").FirstOrDefault(); var moviesCats = new[] { 47, 38, 5, 23, 22, 33, 17, 9 }; var seriesCats = new[] { 46, 26, 43 }; var catUrl = qRow.Find(".torrent-icon > a").Attr("href"); var cat = catUrl.Substring(catUrl.LastIndexOf('=') + 1); var catNo = int.Parse(cat); if (moviesCats.Contains(catNo)) release.Category = TorznabCatType.Movies.ID; else if (seriesCats.Contains(catNo)) release.Category = TorznabCatType.TV.ID; else continue; releases.Add(release); var torrentUrl = qLink.Attr("href"); var torrentId = torrentUrl.Substring(torrentUrl.LastIndexOf('=') + 1); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; release.Title = qLink.Attr("title"); release.Description = qDesc != null ? qDesc.InnerText : release.Title; release.Guid = new Uri(SiteLink + torrentUrl); release.Comments = new Uri(release.Guid + "#startcomments"); var downloadUrl = $"{SiteLink}download.php?id={torrentId}&rss&passkey={configData.RSSKey.Value}"; release.Link = new Uri(downloadUrl); var qAdded = qRow.Find("#torrent-added").First(); var addedStr = qAdded.Text().Trim(); release.PublishDate = DateTime.ParseExact(addedStr, "dd-MM-yyyyHH:mm:ss", CultureInfo.InvariantCulture); release.Seeders = ParseUtil.CoerceInt(qRow.Find("#torrent-seeders").Text().Trim()); release.Peers = ParseUtil.CoerceInt(qRow.Find("#torrent-leechers").Text().Trim()) + release.Seeders; var sizeStr = qRow.Find("#torrent-size").First().Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); var infoLink = qRow.Find("#infolink"); var linkContainer = infoLink.Children().First().Children().First(); var url = linkContainer.Attr("href"); var img = linkContainer.Children().First(); var imgUrl = img.Attr("src"); if (imgUrl == "/pic/imdb.png") { release.Imdb = long.Parse(url.Substring(url.LastIndexOf('t') + 1)); } else if (imgUrl == "/pic/TV.png") { release.TVDBId = long.Parse(url.Substring(url.LastIndexOf('=') + 1)); } } var nextPage = dom["#torrent-table-wrapper + p[align=center]"].Children().Last(); if (!nextPage.Is("a")) breakWhile = true; } catch (Exception ex) { OnParseError(results.Content, ex); } if (breakWhile) break; } return releases; }
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { 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 > tbody > tr"]; foreach (var row in rows) { CQ qRow = row.Cq(); var release = new ReleaseInfo(); release.MinimumRatio = 1; release.MinimumSeedTime = 172800; var qLink = row.ChildElements.ElementAt(1).FirstElementChild.Cq(); release.Title = qLink.Text().Trim(); release.Comments = new Uri(qLink.Attr("href")); release.Guid = release.Comments; var qDownload = row.ChildElements.ElementAt(3).FirstElementChild.Cq(); release.Link = new Uri(qDownload.Attr("href")); var dateStr = row.ChildElements.ElementAt(5).Cq().Text().Trim(); release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr); var sizeStr = row.ChildElements.ElementAt(6).Cq().Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text()); release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(9).Cq().Text()) + release.Seeders; var cat = row.Cq().Find("td:eq(0) i").First().Attr("class") .Replace("gi gi-film", "1") .Replace("gi gi-tv", "2") .Replace("gi gi-music", "3") .Replace("text-pink", string.Empty); release.Category = MapTrackerCatToNewznab(cat.Trim()); releases.Add(release); } } catch (Exception ex) { OnParseError(response.Content, ex); } return releases; }