Exemple #1
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var qParams = new NameValueCollection
            {
                { "tor[text]", query.GetQueryString() },
                { "tor[srchIn][title]", "true" },
                { "tor[srchIn][author]", "true" },
                { "tor[searchType]", configData.ExcludeVip?.Value == true ? "nVIP" : "all" }, // exclude VIP torrents
                { "tor[searchIn]", "torrents" },
                { "tor[hash]", "" },
                { "tor[sortType]", "default" },
                { "tor[startNumber]", "0" },
                { "thumbnails", "1" }, // gives links for thumbnail sized versions of their posters
                //{ "posterLink", "1"}, // gives links for a full sized poster
                //{ "dlLink", "1"}, // include the url to download the torrent
                { "description", "1" } // include the description
                //{"bookmarks", "0"} // include if the item is bookmarked or not
            };

            // Exclude VIP torrents

            var catList = MapTorznabCapsToTrackers(query);

            if (catList.Any())
            {
                var index = 0;
                foreach (var cat in catList)
                {
                    qParams.Add("tor[cat][" + index + "]", cat);
                    index++;
                }
            }
            else
            {
                qParams.Add("tor[cat][]", "0");
            }

            var urlSearch = SearchUrl;

            if (qParams.Count > 0)
            {
                urlSearch += $"?{qParams.GetQueryString()}";
            }

            var response = await RequestStringWithCookiesAndRetry(urlSearch);

            if (response.Content.StartsWith("Error"))
            {
                throw new Exception(response.Content);
            }

            try
            {
                var jsonContent = JObject.Parse(response.Content);
                var sitelink    = new Uri(SiteLink);

                var error = jsonContent.Value <string>("error");
                if (error != null && error == "Nothing returned, out of 0")
                {
                    return(releases);
                }

                foreach (var item in jsonContent.Value <JArray>("data"))
                {
                    //TODO shift to ReleaseInfo object initializer for consistency
                    var release = new ReleaseInfo();

                    var id = item.Value <long>("id");
                    release.Title = item.Value <string>("title");

                    release.Description = item.Value <string>("description");

                    var    authorInfo = item.Value <string>("author_info");
                    string author     = null;
                    if (!string.IsNullOrWhiteSpace(authorInfo))
                    {
                        authorInfo = Regex.Unescape(authorInfo);
                        var authorInfoJson = JObject.Parse(authorInfo);
                        author = authorInfoJson.First.Last.Value <string>();
                    }
                    if (author != null)
                    {
                        release.Title += " by " + author;
                    }

                    var flags = new List <string>();

                    var langCode = item.Value <string>("lang_code");
                    if (!string.IsNullOrEmpty(langCode))
                    {
                        flags.Add(langCode);
                    }

                    var filetype = item.Value <string>("filetype");
                    if (!string.IsNullOrEmpty(filetype))
                    {
                        flags.Add(filetype);
                    }

                    if (flags.Count > 0)
                    {
                        release.Title += " [" + string.Join(" / ", flags) + "]";
                    }

                    if (item.Value <int>("vip") == 1)
                    {
                        release.Title += " [VIP]";
                    }

                    var category = item.Value <string>("category");
                    release.Category = MapTrackerCatToNewznab(category);

                    release.Link     = new Uri(sitelink, "/tor/download.php?tid=" + id);
                    release.Comments = new Uri(sitelink, "/t/" + id);
                    release.Guid     = release.Comments;

                    var dateStr  = item.Value <string>("added");
                    var dateTime = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                    release.PublishDate = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc).ToLocalTime();

                    release.Grabs   = item.Value <long>("times_completed");
                    release.Files   = item.Value <long>("numfiles");
                    release.Seeders = item.Value <int>("seeders");
                    release.Peers   = item.Value <int>("leechers") + release.Seeders;
                    var size = item.Value <string>("size");
                    release.Size = ReleaseInfo.GetBytes(size);

                    release.DownloadVolumeFactor = item.Value <int>("free") == 1 ? 0 : 1;
                    release.UploadVolumeFactor   = 1;

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.Content, ex);
            }

            return(releases);
        }
Exemple #2
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchUrl    = BrowseUrl;
            var searchString = query.GetQueryString();

            var    cats = MapTorznabCapsToTrackers(query);
            string cat  = "0";

            if (cats.Count == 1)
            {
                cat = cats[0];
            }

            var queryCollection = new NameValueCollection();

            if (query.ImdbID != null)
            {
                queryCollection.Add("search", query.ImdbID);
            }
            else if (!string.IsNullOrWhiteSpace(searchString))
            {
                queryCollection.Add("search", searchString);
            }

            queryCollection.Add("cat", cat);
            queryCollection.Add("searchin", "1");
            queryCollection.Add("sort", "2");

            searchUrl += "?" + queryCollection.GetQueryString();

            var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);

            // Occasionally the cookies become invalid, login again if that happens
            if (response.IsRedirect)
            {
                await ApplyConfiguration(null);

                response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
            }

            var results = response.Content;

            try
            {
                CQ  dom             = results;
                var globalFreeLeech = dom.Find("div.globalFreeLeech").Any();
                var rows            = dom[".torrentrow"];
                foreach (var row in rows)
                {
                    var release    = new ReleaseInfo();
                    var qRow       = row.Cq();
                    var qTitleLink = qRow.Find(".torrenttable:eq(1) a").First();
                    release.Title = qRow.Find(".torrenttable:eq(1) b").Text();
                    var longtitle = qRow.Find(".torrenttable:eq(1) a[title]").Attr("title");
                    if (!string.IsNullOrEmpty(longtitle) && !longtitle.Contains("<")) // releases with cover image have no full title
                    {
                        release.Title = longtitle;
                    }

                    if (query.ImdbID == null && !query.MatchQueryStringAND(release.Title))
                    {
                        continue;
                    }

                    release.Description = qRow.Find(".torrenttable:eq(1) > span > font.small").First().Text();

                    var tooltip = qTitleLink.Attr("title");
                    if (!string.IsNullOrEmpty(tooltip))
                    {
                        var ImgRegexp      = new Regex("src='(.*?)'");
                        var ImgRegexpMatch = ImgRegexp.Match(tooltip);
                        if (ImgRegexpMatch.Success)
                        {
                            release.BannerUrl = new Uri(ImgRegexpMatch.Groups[1].Value);
                        }
                    }

                    release.Guid     = new Uri(SiteLink + qTitleLink.Attr("href"));
                    release.Comments = release.Guid;

                    //22:05:3716/02/2013
                    var dateStr = qRow.Find(".torrenttable:eq(5)").Text().Trim() + " +0200";
                    release.PublishDate = DateTime.ParseExact(dateStr, "H:mm:ssdd/MM/yyyy zzz", CultureInfo.InvariantCulture);

                    var qLink = qRow.Find("a[href^=\"download.php?id=\"]").First();
                    release.Link = new Uri(SiteLink + qLink.Attr("href").Replace("&usetoken=1", ""));

                    var sizeStr = qRow.Find(".torrenttable:eq(6)").Text().Trim();
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(8)").Text().Trim());
                    release.Peers   = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(9)").Text().Trim()) + release.Seeders;

                    var catId = qRow.Find(".torrenttable:eq(0) a").First().Attr("href").Substring(15);
                    release.Category = MapTrackerCatToNewznab(catId);

                    var grabs = qRow.Find(".torrenttable:eq(7)").First().Get(0).FirstChild;
                    release.Grabs = ParseUtil.CoerceLong(catId);

                    if (globalFreeLeech || row.Cq().Find("img[alt=\"FreeLeech\"]").Any())
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

                    // Skip Romanian releases
                    if (release.Category.Contains(TorznabCatType.MoviesForeign.ID) && !configData.IncludeRomanianReleases.Value)
                    {
                        continue;
                    }

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results, ex);
            }

            return(releases);
        }
Exemple #3
0
        protected override 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, WebUtility.UrlEncode(query.GetQueryString()));
            var results          = await RequestStringWithCookiesAndRetry(episodeSearchUrl);

            if (results.IsRedirect)
            {
                throw new ExceptionWithConfigData("Unexpected redirect to " + results.RedirectingTo + ". Check your credentials.", configData);
            }

            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 (string.IsNullOrWhiteSpace(dateStr) ||
                            dateStr == "Sponsored links" ||
                            dateStr.StartsWith("!function") ||
                            dateStr.StartsWith("atOptions"))
                        {
                            continue; // ignore ads
                        }
                        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 catUrl = rowA.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href");
                    var catId  = QueryHelpers.ParseQuery(catUrl)["category"].First();
                    release.Category = MapTrackerCatToNewznab(catId);

                    var qLink = rowA.ChildElements.ElementAt(1).FirstElementChild.Cq();
                    release.Title       = qLink.Text().Trim();
                    release.Description = rowB.ChildElements.ElementAt(0).Cq().Text();

                    if (release.Category != null && release.Category.Contains(TorznabCatType.Audio.ID))
                    {
                        if (release.Description.Contains("Lossless"))
                        {
                            release.Category = new List <int> {
                                TorznabCatType.AudioLossless.ID
                            }
                        }
                        ;
                        else if (release.Description.Contains("MP3"))
                        {
                            release.Category = new List <int> {
                                TorznabCatType.AudioMP3.ID
                            }
                        }
                        ;
                        else
                        {
                            release.Category = new List <int> {
                                TorznabCatType.AudioOther.ID
                            }
                        };
                    }

                    release.Comments = new Uri(new Uri(SiteLink), qLink.Attr("href"));
                    release.Guid     = release.Comments;
                    release.Link     = release.Comments; // indirect download see Download() method

                    var sizeStr = rowB.ChildElements.ElementAt(2).Cq().Text();
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

                    release.Seeders = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(5).Cq().Text());
                    release.Peers   = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders;

                    var grabs = rowB.Cq().Find("td:nth-child(5)").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);
        }
Exemple #4
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var pairs = new Dictionary <string, string>
            {
                { "do", "search" },
                { "search_type", query.IsImdbQuery ? "t_genre" : "t_name" },
                { "keywords", query.IsImdbQuery ? query.ImdbID : query.GetQueryString() },
                { "category", "0" } // multi cat search not supported
            };

            var results = await RequestWithCookiesAsync(BrowseUrl, method : RequestType.POST, data : pairs);

            if (results.IsRedirect)
            {
                // re-login
                await ApplyConfiguration(null);

                results = await RequestWithCookiesAsync(BrowseUrl, method : RequestType.POST, data : pairs);
            }

            try
            {
                var lastDate = DateTime.Now;

                var parser = new HtmlParser();
                var doc    = parser.ParseDocument(results.ContentString);
                var rows   = doc.QuerySelectorAll("table[id='sortabletable'] > tbody > tr");

                foreach (var row in rows.Skip(1))
                {
                    if (row.Children.Length != 9)
                    {
                        continue; // not a torrent line
                    }
                    var cat            = row.Children[0].QuerySelector("a").GetAttribute("href").Split('=')[1];
                    var title          = row.Children[1].QuerySelector("a").TextContent;
                    var qLinks         = row.Children[2].QuerySelectorAll("a");
                    var link           = new Uri(configData.TorrentHTTPSMode.Value ? qLinks[1].GetAttribute("href") : qLinks[0].GetAttribute("href"));
                    var comments       = new Uri(row.Children[1].QuerySelector("a").GetAttribute("href"));
                    var size           = row.Children[4].TextContent;
                    var grabs          = row.Children[5].QuerySelector("a").TextContent;
                    var seeders        = ParseUtil.CoerceInt(row.Children[6].QuerySelector("a").TextContent);
                    var leechers       = ParseUtil.CoerceInt(row.Children[7].QuerySelector("a").TextContent);
                    var qTags          = row.Children[1].QuerySelector("div:has(span[style=\"float: right;\"])");
                    var dlVolumeFactor = 1.0;
                    if (qTags.QuerySelector("img[alt^=\"TORRENT GRATUIT\"]") != null)
                    {
                        dlVolumeFactor = 0.0;
                    }
                    else if (qTags.QuerySelector("img[alt^=\"TORRENT SILVER\"]") != null)
                    {
                        dlVolumeFactor = 0.5;
                    }

                    var upVolumeFactor = qTags.QuerySelector("img[alt^=\"TORRENT X2\"]") != null ? 2.0 : 1.0;
                    var release        = new ReleaseInfo
                    {
                        MinimumRatio         = 1,
                        MinimumSeedTime      = 172800,
                        Category             = MapTrackerCatToNewznab(cat),
                        Title                = title,
                        Link                 = link,
                        Comments             = comments,
                        Size                 = ReleaseInfo.GetBytes(size),
                        Seeders              = seeders,
                        Grabs                = ParseUtil.CoerceLong(grabs),
                        DownloadVolumeFactor = dlVolumeFactor,
                        UploadVolumeFactor   = upVolumeFactor,
                        Peers                = leechers + seeders,
                        Guid                 = link
                    };

                    var qTooltip = row.Children[1].QuerySelector("div.tooltip-content");
                    if (qTooltip != null)
                    {
                        var banner = qTooltip.QuerySelector("img");
                        if (banner != null)
                        {
                            release.BannerUrl = new Uri(banner.GetAttribute("src"));
                            banner.Remove();
                        }

                        qTooltip.QuerySelector("div:contains(\"Total Hits\")").Remove();

                        var qLongTitle = qTooltip.QuerySelector("div");
                        release.Title = qLongTitle.TextContent;
                        qLongTitle.Remove();

                        var description = qTooltip.TextContent.Trim();
                        if (!string.IsNullOrWhiteSpace(description))
                        {
                            release.Description = description;
                        }
                    }

                    // issue #5064 replace multi keyword
                    if (!string.IsNullOrEmpty(configData.ReplaceMulti.Value))
                    {
                        var regex = new Regex("(?i)([\\.\\- ])MULTI([\\.\\- ])");
                        release.Title = regex.Replace(release.Title, "$1" + configData.ReplaceMulti.Value + "$2");
                    }

                    // issue #6855 Replace VOSTFR with ENGLISH
                    if (configData.Vostfr.Value)
                    {
                        release.Title = release.Title.Replace("VOSTFR", "ENGLISH").Replace("SUBFRENCH", "ENGLISH");
                    }

                    var qPretime = qTags.QuerySelector("font.mkprettytime");
                    if (qPretime != null)
                    {
                        if (release.Description == null)
                        {
                            release.Description = qPretime.TextContent;
                        }
                        else
                        {
                            release.Description += "<br>\n" + qPretime.TextContent;
                        }
                        release.PublishDate = lastDate;
                    }
                    else
                    {
                        release.PublishDate = DateTime.ParseExact(qTags.TextContent.Trim(), "dd-MM-yyyy HH:mm", CultureInfo.InvariantCulture);
                        lastDate            = release.PublishDate;
                    }

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.ContentString, ex);
            }

            return(releases);
        }
Exemple #5
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 3, 5, DayOfWeek.Sunday);
            TimeZoneInfo.TransitionTime endTransition   = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 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 denmarkTz = TimeZoneInfo.CreateCustomTimeZone("Denmark Time", new TimeSpan(1, 0, 0), "(GMT+01:00) Denmark Time", "Denmark Time", "Denmark DST", adjustments);

            var releasesPerPage = 100;
            var releases        = new List <ReleaseInfo>();

            var page = (query.Offset / releasesPerPage) + 1;

            string episodeSearchUrl;

            if (string.IsNullOrEmpty(query.GetQueryString()))
            {
                episodeSearchUrl = SearchUrl + "?page=" + page;
            }
            else
            {
                var cats        = MapTorznabCapsToTrackers(query);
                var catsUrlPart = string.Join("&", cats.Select(c => $"filter_{c}=on"));
                episodeSearchUrl = $"{SearchUrl}?page={page}&group=0&{catsUrlPart}&search={HttpUtility.UrlEncode(query.GetQueryString())}&pre_type=torrents&type=";
            }
            var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);

            if (string.IsNullOrEmpty(results.Content))
            {
                CookieHeader = string.Empty;
                var pairs = new Dictionary <string, string>
                {
                    { "username", configData.Username.Value },
                    { "password", configData.Password.Value },
                    { "langlang", null },
                    { "login", "login" }
                };
                var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, CookieHeader, true, null, LoginUrl);

                await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("logout.php"), () =>
                {
                    CQ dom           = response.Content;
                    var messageEl    = dom["#loginform .warning"];
                    var errorMessage = messageEl.Text().Trim();
                    throw new ExceptionWithConfigData(errorMessage, configData);
                });

                results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
            }
            try
            {
                CQ  dom  = results.Content;
                var rows = dom["#torrent_table tr.torrent"];
                foreach (var row in rows)
                {
                    var qRow    = row.Cq();
                    var release = new ReleaseInfo
                    {
                        MinimumRatio    = 1,
                        MinimumSeedTime = 172800
                    };

                    var catAnchor        = row.FirstChild.FirstChild;
                    var catUrl           = catAnchor.GetAttribute("href");
                    var catStr           = Regex.Match(catUrl, "filter_(?<catNo>[0-9]+)=on").Groups["catNo"].Value;
                    var catNo            = int.Parse(catStr);
                    var moviesCatsDanish = new[] { 2, 3, 10, 28, 29, 31 };
                    var moviesCatsIntl   = new[] { 8, 9, 11, 22, 24 };
                    var moviesCats       = configData.OnlyDanishCategories.Value
                        ? moviesCatsDanish
                        : moviesCatsDanish.Concat(moviesCatsIntl);
                    var seriesCatsDanish = new[] { 1, 4, 30 };
                    var seriesCatsIntl   = new[] { 20, 21 };
                    var seriesCats       = configData.OnlyDanishCategories.Value
                        ? seriesCatsDanish
                        : seriesCatsDanish.Concat(seriesCatsIntl);
                    if (moviesCats.Contains(catNo))
                    {
                        release.Category = TorznabCatType.Movies.ID;
                    }
                    else if (seriesCats.Contains(catNo))
                    {
                        release.Category = TorznabCatType.TV.ID;
                    }
                    else if (catNo == 12)
                    {
                        release.Category = TorznabCatType.BooksEbook.ID;
                    }
                    else if (catNo == 6)
                    {
                        release.Category = TorznabCatType.AudioAudiobook.ID;
                    }
                    else
                    {
                        continue;
                    }

                    var titleAnchor = qRow.Find("div.croptorrenttext a").FirstElement();
                    var title       = titleAnchor.GetAttribute("title");
                    release.Title = title;

                    var dlUrlAnchor = qRow.Find("span.right a[title=\"Direkte download link\"]").FirstElement();
                    var dlUrl       = dlUrlAnchor.GetAttribute("href");
                    release.Link = new Uri(SiteLink + dlUrl);

                    var torrentLink = titleAnchor.GetAttribute("href");
                    release.Guid     = new Uri(SiteLink + torrentLink);
                    release.Comments = new Uri(SearchUrl + torrentLink);

                    var addedElement = qRow.Find("span.time").FirstElement();
                    var addedStr     = addedElement.GetAttribute("title");
                    release.PublishDate = TimeZoneInfo.ConvertTimeToUtc(DateTime.ParseExact(addedStr, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture), denmarkTz).ToLocalTime();

                    var columns        = qRow.Children();
                    var seedersElement = columns.Reverse().Skip(1).First();
                    release.Seeders = int.Parse(seedersElement.InnerText);

                    var leechersElement = columns.Last().FirstElement();
                    release.Peers = release.Seeders + int.Parse(leechersElement.InnerText);

                    var sizeElement = columns.Skip(2).First();
                    var sizeStr     = sizeElement.InnerText;
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

                    var imdbAnchor = qRow.Find(".torrentnotes a")
                                     .FirstOrDefault(a => a.GetAttribute("href").Contains("imdb.com"));
                    if (imdbAnchor != null)
                    {
                        var referrerUrl = imdbAnchor.GetAttribute("href");
                        release.Imdb = long.Parse(Regex.Match(referrerUrl, "tt(?<imdbId>[0-9]+)").Groups["imdbId"].Value);
                    }

                    var Files = qRow.Find("td:nth-child(3) > div");
                    release.Files = ParseUtil.CoerceLong(Files.Text().Split(' ')[0]);

                    var Grabs = qRow.Find("td:nth-child(6)");
                    release.Grabs = ParseUtil.CoerceLong(Grabs.Text());

                    if (qRow.Find("span.freeleech, img[src=\"/static/common/torrents/gratis.png\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    if (qRow.Find("img[src=\"/static/common/torrents/toxupload.png\"]").Length >= 1)
                    {
                        release.UploadVolumeFactor = 2;
                    }
                    else
                    {
                        release.UploadVolumeFactor = 1;
                    }

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }
            return(releases);
        }
Exemple #6
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var searchString = query.GetQueryString();

            // if the search string is empty use the "last 24h torrents" view
            if (string.IsNullOrWhiteSpace(searchString))
            {
                var results = await RequestStringWithCookies(TodayUrl);

                try
                {
                    string RowsSelector = "table.torrent_table > tbody > tr:not(tr.colhead)";

                    var SearchResultParser   = new HtmlParser();
                    var SearchResultDocument = SearchResultParser.Parse(results.Content);
                    var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
                    foreach (var Row in Rows)
                    {
                        try
                        {
                            var release = new ReleaseInfo();

                            release.MinimumRatio    = 1;
                            release.MinimumSeedTime = 0;

                            var qDetailsLink = Row.QuerySelector("a.BJinfoBox");
                            var qTitle       = qDetailsLink.QuerySelector("font");
                            release.Title = qTitle.TextContent;

                            var qBJinfoBox = qDetailsLink.QuerySelector("span");
                            var qCatLink   = Row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
                            var qDLLink    = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
                            var qSeeders   = Row.QuerySelector("td:nth-child(4)");
                            var qLeechers  = Row.QuerySelector("td:nth-child(5)");
                            var qFreeLeech = Row.QuerySelector("font[color=\"green\"]:contains(Free)");

                            release.Description = "";
                            foreach (var Child in qBJinfoBox.ChildNodes)
                            {
                                var type = Child.NodeType;
                                if (type != NodeType.Text)
                                {
                                    continue;
                                }

                                var line = Child.TextContent;
                                if (line.StartsWith("Tamanho:"))
                                {
                                    string Size = line.Substring("Tamanho: ".Length);;
                                    release.Size = ReleaseInfo.GetBytes(Size);
                                }
                                else if (line.StartsWith("Lançado em: "))
                                {
                                    string PublishDateStr = line.Substring("Lançado em: ".Length).Replace("às ", "");
                                    PublishDateStr += " +0";
                                    var PublishDate = DateTime.SpecifyKind(DateTime.ParseExact(PublishDateStr, "dd/MM/yyyy HH:mm z", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
                                    release.PublishDate = PublishDate.ToLocalTime();
                                }
                                else
                                {
                                    release.Description += line + "\n";
                                }
                            }


                            var catStr = qCatLink.GetAttribute("href").Split('=')[1];
                            release.Category = MapTrackerCatToNewznab(catStr);

                            release.Link     = new Uri(SiteLink + qDLLink.GetAttribute("href"));
                            release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
                            release.Guid     = release.Link;

                            release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
                            release.Peers   = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;


                            if (qFreeLeech != null)
                            {
                                release.DownloadVolumeFactor = 0;
                            }
                            else
                            {
                                release.DownloadVolumeFactor = 1;
                            }

                            release.UploadVolumeFactor = 1;

                            releases.Add(release);
                        }
                        catch (Exception ex)
                        {
                            logger.Error(string.Format("{0}: Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
                        }
                    }
                }
                catch (Exception ex)
                {
                    OnParseError(results.Content, ex);
                }
            }
            else // use search
            {
                var searchUrl = BrowseUrl;

                var queryCollection = new NameValueCollection();
                queryCollection.Add("searchstr", StripSearchString(searchString));
                queryCollection.Add("order_by", "time");
                queryCollection.Add("order_way", "desc");
                queryCollection.Add("group_results", "1");
                queryCollection.Add("action", "basic");
                queryCollection.Add("searchsubmit", "1");

                foreach (var cat in MapTorznabCapsToTrackers(query))
                {
                    queryCollection.Add("filter_cat[" + cat + "]", "1");
                }

                searchUrl += "?" + queryCollection.GetQueryString();

                var results = await RequestStringWithCookies(searchUrl);

                try
                {
                    string RowsSelector = "table.torrent_table > tbody > tr:not(tr.colhead)";

                    var SearchResultParser   = new HtmlParser();
                    var SearchResultDocument = SearchResultParser.Parse(results.Content);
                    var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);

                    int    GroupCategory = 0;
                    string GroupTitle    = null;
                    string GroupYearStr  = null;
                    Nullable <DateTime> GroupPublishDate = null;

                    foreach (var Row in Rows)
                    {
                        try
                        {
                            var    qDetailsLink = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
                            string Title        = qDetailsLink.TextContent;
                            int    Category     = 0;
                            string YearStr      = null;
                            Nullable <DateTime> YearPublishDate = null;

                            if (Row.ClassList.Contains("group") || Row.ClassList.Contains("torrent")) // group/ungrouped headers
                            {
                                var    qCatLink    = Row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
                                string CategoryStr = qCatLink.GetAttribute("href").Split('=')[1].Split('&')[0];
                                Category        = MapTrackerCatToNewznab(CategoryStr);
                                YearStr         = qDetailsLink.NextSibling.TextContent.Trim().TrimStart('[').TrimEnd(']');
                                YearPublishDate = DateTime.SpecifyKind(DateTime.ParseExact(YearStr, "yyyy", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);

                                if (Row.ClassList.Contains("group")) // group headers
                                {
                                    GroupCategory    = Category;
                                    GroupTitle       = Title;
                                    GroupYearStr     = YearStr;
                                    GroupPublishDate = YearPublishDate;
                                    continue;
                                }
                            }

                            var release = new ReleaseInfo();

                            release.MinimumRatio    = 1;
                            release.MinimumSeedTime = 0;

                            var qDLLink    = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
                            var qSize      = Row.QuerySelector("td:nth-last-child(4)");
                            var qSeeders   = Row.QuerySelector("td:nth-last-child(3)");
                            var qLeechers  = Row.QuerySelector("td:nth-last-child(2)");
                            var qFreeLeech = Row.QuerySelector("strong[title=\"Free\"]");

                            if (Row.ClassList.Contains("group_torrent")) // torrents belonging to a group
                            {
                                release.Description = qDetailsLink.TextContent;
                                release.Title       = GroupTitle + " " + GroupYearStr;
                                release.PublishDate = GroupPublishDate.Value;
                                release.Category    = GroupCategory;
                            }
                            else if (Row.ClassList.Contains("torrent")) // standalone/un grouped torrents
                            {
                                var qDescription = Row.QuerySelector("div.torrent_info");
                                release.Description = qDescription.TextContent;
                                release.Title       = Title + " " + YearStr;
                                release.PublishDate = YearPublishDate.Value;
                                release.Category    = Category;
                            }

                            release.Description = release.Description.Replace(" / Free", ""); // Remove Free Tag
                            release.Title      += " " + release.Description;                  // add year and Description to the release Title to add some meaning to it

                            // check for previously stripped search terms
                            if (!query.MatchQueryStringAND(release.Title))
                            {
                                continue;
                            }

                            var Size = qSize.TextContent;
                            release.Size = ReleaseInfo.GetBytes(Size);

                            release.Link     = new Uri(SiteLink + qDLLink.GetAttribute("href"));
                            release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
                            release.Guid     = release.Link;

                            release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
                            release.Peers   = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;

                            if (qFreeLeech != null)
                            {
                                release.DownloadVolumeFactor = 0;
                            }
                            else
                            {
                                release.DownloadVolumeFactor = 1;
                            }

                            release.UploadVolumeFactor = 1;

                            releases.Add(release);
                        }
                        catch (Exception ex)
                        {
                            logger.Error(string.Format("{0}: Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
                        }
                    }
                }
                catch (Exception ex)
                {
                    OnParseError(results.Content, ex);
                }
            }

            return(releases);
        }
Exemple #7
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var qc = new List <KeyValuePair <string, string> > // NameValueCollection don't support cat[]=19&cat[]=6
            {
                { "st", "1" } // search in title
            };

            if (query.IsImdbQuery)
            {
                qc.Add("search", query.ImdbID);
                qc.Add("sd", "1"); // search in description
            }
            else
            {
                qc.Add("search", query.GetQueryString());
            }

            // parse categories and tags
            var catGroups = new HashSet <string>(); // HashSet instead of List to avoid duplicates
            var tagGroups = new HashSet <string>();
            var cats      = MapTorznabCapsToTrackers(query);

            foreach (var cat in cats)
            {
                // "cat[]=7&tags=x264"
                var cSplit = cat.Split('&');

                var gSplit = cSplit[0].Split('=');
                if (gSplit.Length > 1)
                {
                    catGroups.Add(gSplit[1]); // category = 7
                }
                if (cSplit.Length > 1)
                {
                    var tSplit = cSplit[1].Split('=');
                    if (tSplit.Length > 1)
                    {
                        tagGroups.Add(tSplit[1]); // tag = x264
                    }
                }
            }

            // add categories
            foreach (var cat in catGroups)
            {
                qc.Add("cat[]", cat);
            }

            // do not include too many tags as it'll mess with their servers
            if (tagGroups.Count < 7)
            {
                qc.Add("tags", string.Join(",", tagGroups));
                // if tags are specified match any
                // if no tags are specified match all, with any we get random results
                qc.Add("tf", tagGroups.Any() ? "any" : "all");
            }

            var searchUrl = SearchUrl + "?" + qc.GetQueryString();
            var response  = await RequestStringWithCookiesAndRetry(searchUrl);

            if (response.IsRedirect) // re-login
            {
                await ApplyConfiguration(null);

                response = await RequestStringWithCookiesAndRetry(searchUrl);
            }

            try
            {
                var parser = new HtmlParser();
                var dom    = parser.ParseDocument(response.Content);
                var rows   = dom.QuerySelectorAll("table > tbody > tr.browse");
                foreach (var row in rows)
                {
                    var qLink = row.Children[1].QuerySelector("a");
                    var title = qLink.GetAttribute("title");
                    if (qLink.QuerySelectorAll("span").Length == 1 && title.StartsWith("NEW! |"))
                    {
                        title = title.Substring(6).Trim();
                    }

                    if (!query.MatchQueryStringAND(title))
                    {
                        continue; // we have to skip bad titles due to tags + any word search
                    }
                    var comments    = new Uri(SiteLink + qLink.GetAttribute("href"));
                    var link        = new Uri(SiteLink + row.Children[2].QuerySelector("a").GetAttribute("href"));
                    var dateStr     = Regex.Replace(row.Children[5].InnerHtml, @"\<br[\s]{0,1}[\/]{0,1}\>", " ");
                    var publishDate = DateTimeUtil.FromTimeAgo(dateStr);
                    var files       = ParseUtil.CoerceInt(row.Children[3].TextContent);
                    var size        = ReleaseInfo.GetBytes(row.Children[7].TextContent);
                    var grabs       = ParseUtil.CoerceInt(row.Children[8].TextContent);
                    var seeders     = ParseUtil.CoerceInt(row.Children[9].TextContent);
                    var leechers    = ParseUtil.CoerceInt(row.Children[10].TextContent);
                    var cat         = row.FirstElementChild.FirstElementChild.GetAttribute("href").Replace("browse.php?", string.Empty);

                    var release = new ReleaseInfo
                    {
                        Title                = title,
                        Comments             = comments,
                        Guid                 = comments,
                        Link                 = link,
                        PublishDate          = publishDate,
                        Size                 = size,
                        Category             = MapTrackerCatToNewznab(cat),
                        Files                = files,
                        Grabs                = grabs,
                        Seeders              = seeders,
                        Peers                = leechers + seeders,
                        MinimumRatio         = 1,
                        MinimumSeedTime      = 172800, // 48 hours
                        DownloadVolumeFactor = 0,      // ratioless
                        UploadVolumeFactor   = 1
                    };

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.Content, ex);
            }
            return(releases);
        }
Exemple #8
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var  releases = new List <ReleaseInfo>();
            bool configGoldenPopcornOnly = configData.FilterString.Value.ToLowerInvariant().Contains("goldenpopcorn");
            bool configSceneOnly         = configData.FilterString.Value.ToLowerInvariant().Contains("scene");
            bool configCheckedOnly       = configData.FilterString.Value.ToLowerInvariant().Contains("checked");
            bool configFreeOnly          = configData.FilterString.Value.ToLowerInvariant().Contains("free");


            string movieListSearchUrl = SearchUrl;
            var    queryCollection    = new NameValueCollection();

            queryCollection.Add("json", "noredirect");

            if (!string.IsNullOrEmpty(query.ImdbID))
            {
                queryCollection.Add("searchstr", query.ImdbID);
            }
            else if (!string.IsNullOrEmpty(query.GetQueryString()))
            {
                queryCollection.Add("searchstr", query.GetQueryString());
            }

            if (configFreeOnly)
            {
                queryCollection.Add("freetorrent", "1");
            }

            if (queryCollection.Count > 0)
            {
                movieListSearchUrl += "?" + queryCollection.GetQueryString();
            }

            var results = await RequestStringWithCookiesAndRetry(movieListSearchUrl);

            if (results.IsRedirect) // untested
            {
                // re-login
                await DoLogin();

                results = await RequestStringWithCookiesAndRetry(movieListSearchUrl);
            }
            try
            {
                //Iterate over the releases for each movie
                JObject js_results = JObject.Parse(results.Content);
                foreach (var movie in js_results["Movies"])
                {
                    string movie_title      = (string)movie["Title"];
                    string Year             = (string)movie["Year"];
                    var    movie_imdbid_str = (string)movie["ImdbId"];
                    var    coverStr         = (string)movie["Cover"];
                    Uri    coverUri         = null;
                    if (!string.IsNullOrEmpty(coverStr))
                    {
                        coverUri = new Uri(coverStr);
                    }
                    long?movie_imdbid = null;
                    if (!string.IsNullOrEmpty(movie_imdbid_str))
                    {
                        movie_imdbid = long.Parse(movie_imdbid_str);
                    }
                    string movie_groupid = (string)movie["GroupId"];
                    foreach (var torrent in movie["Torrents"])
                    {
                        var    release      = new ReleaseInfo();
                        string release_name = (string)torrent["ReleaseName"];
                        release.Title       = release_name;
                        release.Description = string.Format("Title: {0}", movie_title);
                        release.BannerUrl   = coverUri;
                        release.Imdb        = movie_imdbid;
                        release.Comments    = new Uri(string.Format("{0}?id={1}", SearchUrl, WebUtility.UrlEncode(movie_groupid)));
                        release.Size        = long.Parse((string)torrent["Size"]);
                        release.Grabs       = long.Parse((string)torrent["Snatched"]);
                        release.Seeders     = int.Parse((string)torrent["Seeders"]);
                        release.Peers       = release.Seeders + int.Parse((string)torrent["Leechers"]);
                        release.PublishDate = DateTime.ParseExact((string)torrent["UploadTime"], "yyyy-MM-dd HH:mm:ss",
                                                                  CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
                        release.Link = new Uri(string.Format("{0}?action=download&id={1}&authkey={2}&torrent_pass={3}",
                                                             SearchUrl, WebUtility.UrlEncode((string)torrent["Id"]), WebUtility.UrlEncode(AuthKey), WebUtility.UrlEncode(configData.Passkey.Value)));
                        release.Guid                 = release.Link;
                        release.MinimumRatio         = 1;
                        release.MinimumSeedTime      = 345600;
                        release.DownloadVolumeFactor = 1;
                        release.UploadVolumeFactor   = 1;
                        release.Category             = new List <int> {
                            2000
                        };

                        bool golden, scene, check;
                        bool.TryParse((string)torrent["GoldenPopcorn"], out golden);
                        bool.TryParse((string)torrent["Scene"], out scene);
                        bool.TryParse((string)torrent["Checked"], out check);

                        if (configGoldenPopcornOnly && !golden)
                        {
                            continue; //Skip release if user only wants GoldenPopcorn
                        }
                        if (configSceneOnly && !scene)
                        {
                            continue; //Skip release if user only wants Scene
                        }
                        if (configCheckedOnly && !check)
                        {
                            continue; //Skip release if user only wants Checked
                        }

                        var    titletags  = new List <string>();
                        string Quality    = (string)torrent["Quality"];
                        string Container  = (string)torrent["Container"];
                        string Codec      = (string)torrent["Codec"];
                        string Resolution = (string)torrent["Resolution"];
                        string Source     = (string)torrent["Source"];

                        if (Year != null)
                        {
                            release.Description += string.Format("<br>\nYear: {0}", Year);
                        }
                        if (Quality != null)
                        {
                            release.Description += string.Format("<br>\nQuality: {0}", Quality);
                        }
                        if (Resolution != null)
                        {
                            titletags.Add(Resolution);
                            release.Description += string.Format("<br>\nResolution: {0}", Resolution);
                        }
                        if (Source != null)
                        {
                            titletags.Add(Source);
                            release.Description += string.Format("<br>\nSource: {0}", Source);
                        }
                        if (Codec != null)
                        {
                            titletags.Add(Codec);
                            release.Description += string.Format("<br>\nCodec: {0}", Codec);
                        }
                        if (Container != null)
                        {
                            titletags.Add(Container);
                            release.Description += string.Format("<br>\nContainer: {0}", Container);
                        }
                        if (scene)
                        {
                            titletags.Add("Scene");
                            release.Description += "<br>\nScene";
                        }
                        if (check)
                        {
                            titletags.Add("Checked");
                            release.Description += "<br>\nChecked";
                        }
                        if (golden)
                        {
                            titletags.Add("Golden Popcorn");
                            release.Description += "<br>\nGolden Popcorn";
                        }

                        if (titletags.Count() > 0)
                        {
                            release.Title += " [" + string.Join(" / ", titletags) + "]";
                        }

                        bool freeleech;
                        bool.TryParse((string)torrent["FreeleechType"], out freeleech);
                        if (freeleech)
                        {
                            release.DownloadVolumeFactor = 0;
                        }

                        releases.Add(release);
                    }
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }

            return(releases);
        }
Exemple #9
0
 // hook to adjust the search term
 protected virtual string GetSearchTerm(TorznabQuery query)
 {
     return(query.GetQueryString());
 }
 // hook to adjust the search term
 protected virtual string GetSearchTerm(TorznabQuery query) => query.GetQueryString();
Exemple #11
0
        public ManualSearchResult Search([FromBody] AdminSearch value)
        {
            var results = new List <TrackerCacheResult>();
            var query   = new TorznabQuery()
            {
                SearchTerm = value.Query,
                Categories = value.Category == 0 ? new int[0] : new int[1] {
                    value.Category
                }
            };

            query.ExpandCatsToSubCats();

            var trackers = indexerService.GetAllIndexers().Where(t => t.IsConfigured).ToList();

            if (!string.IsNullOrWhiteSpace(value.Tracker))
            {
                trackers = trackers.Where(t => t.ID == value.Tracker).ToList();
            }

            if (value.Category != 0)
            {
                trackers = trackers.Where(t => t.TorznabCaps.Categories.Select(c => c.ID).Contains(value.Category)).ToList();
            }

            Parallel.ForEach(trackers.ToList(), indexer =>
            {
                try
                {
                    var searchResults = indexer.PerformQuery(query).Result;
                    searchResults     = indexer.CleanLinks(searchResults);
                    cacheService.CacheRssResults(indexer, searchResults);
                    searchResults = indexer.FilterResults(query, searchResults);

                    lock (results)
                    {
                        foreach (var result in searchResults)
                        {
                            var item       = Mapper.Map <TrackerCacheResult>(result);
                            item.Tracker   = indexer.DisplayName;
                            item.TrackerId = indexer.ID;
                            item.Peers     = item.Peers - item.Seeders; // Use peers as leechers
                            results.Add(item);
                        }
                    }
                }
                catch (Exception e)
                {
                    logger.Error(e, "An error occured during manual search on " + indexer.DisplayName + ":  " + e.Message);
                }
            });

            ConfigureCacheResults(results);

            if (trackers.Count > 1)
            {
                results = results.OrderByDescending(d => d.PublishDate).ToList();
            }

            var manualResult = new ManualSearchResult()
            {
                Results  = results,
                Indexers = trackers.Select(t => t.DisplayName).ToList()
            };


            if (manualResult.Indexers.Count == 0)
            {
                manualResult.Indexers = new List <string>()
                {
                    "None"
                }
            }
            ;

            logger.Info(string.Format("Manual search for \"{0}\" on {1} with {2} results.", query.GetQueryString(), string.Join(", ", manualResult.Indexers), manualResult.Results.Count));
            return(manualResult);
        }
    }
Exemple #12
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var searchString    = query.GetQueryString();
            var searchUrl       = BrowseUrl;
            var queryCollection = new NameValueCollection();

            if (!string.IsNullOrWhiteSpace(searchString))
            {
                queryCollection.Add("q", searchString);
            }

            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                queryCollection.Add(cat, string.Empty);
            }

            if (queryCollection.Count > 0)
            {
                searchUrl += "?" + queryCollection.GetQueryString();
            }

            var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);

            var results = response.Content;

            try
            {
                CQ dom = results;

                var rows = dom["table[id='torrents'] > tbody > tr"];
                foreach (var row in rows.Skip(1))
                {
                    var release    = new ReleaseInfo();
                    var qRow       = row.Cq();
                    var qTitleLink = qRow.Find("a.t_title").First();
                    release.Title = qTitleLink.Text().Trim();

                    // If we search an get no results, we still get a table just with no info.
                    if (string.IsNullOrWhiteSpace(release.Title))
                    {
                        break;
                    }

                    release.Description = release.Title;
                    release.Guid        = new Uri(UseLink + qTitleLink.Attr("href").Substring(1));
                    release.Comments    = release.Guid;

                    var descString = qRow.Find(".t_ctime").Text();
                    var dateString = descString.Split('|').Last().Trim();
                    dateString          = dateString.Split(new string[] { " by " }, StringSplitOptions.None)[0];
                    release.PublishDate = DateTimeUtil.FromTimeAgo(dateString);

                    var qLink = row.ChildElements.ElementAt(3).Cq().Children("a");
                    release.Link = new Uri(UseLink + HttpUtility.UrlEncode(qLink.Attr("href").TrimStart('/')));

                    var sizeStr = row.ChildElements.ElementAt(5).Cq().Text();
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".t_seeders").Text().Trim());
                    release.Peers   = ParseUtil.CoerceInt(qRow.Find(".t_leechers").Text().Trim()) + release.Seeders;

                    var cat = row.Cq().Find("td:eq(0) a").First().Attr("href").Substring(1);
                    release.Category = MapTrackerCatToNewznab(cat);

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results, ex);
            }

            return(releases);
        }
Exemple #13
0
        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();

            if (!string.IsNullOrWhiteSpace(searchString))
            {
                queryCollection.Add("searchstr", searchString);
            }

            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                queryCollection.Add("filter_cat[" + cat + "]", "1");
            }

            searchUrl += queryCollection.GetQueryString();

            var results = await RequestStringWithCookiesAndRetry(searchUrl);

            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;

                    var catStr = row.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href").Split(new char[] { '[', ']' })[1];
                    release.Category = MapTrackerCatToNewznab(catStr);

                    var qLink   = row.ChildElements.ElementAt(1).Cq().Children("a")[0].Cq();
                    var linkStr = qLink.Attr("href");
                    release.Title    = qLink.Text();
                    release.Comments = new Uri(BaseUrl + "/" + linkStr);
                    release.Guid     = release.Comments;

                    var qDownload = row.ChildElements.ElementAt(1).Cq().Find("a[title='Download']")[0].Cq();
                    release.Link = new Uri(BaseUrl + "/" + qDownload.Attr("href"));

                    var dateStr = row.ChildElements.ElementAt(3).Cq().Text().Trim().Replace(" and", "");
                    release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr);

                    var sizeStr = row.ChildElements.ElementAt(4).Cq().Text();
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

                    release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text().Trim());
                    release.Peers   = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text().Trim()) + release.Seeders;

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }
            return(releases);
        }
Exemple #14
0
        /// <summary>
        /// Execute our search query
        /// </summary>
        /// <param name="query">Query</param>
        /// <returns>Releases</returns>
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var exactSearchTerm = 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(exactSearchTerm))
            {
                lock (cache)
                {
                    // Remove old cache items
                    CleanCache();

                    // Search in cache
                    var cachedResult = cache.FirstOrDefault(i => i.Query == exactSearchTerm);
                    if (cachedResult != null)
                    {
                        return(cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray());
                    }
                }
            }

            var SearchTerms = new List <string> {
                exactSearchTerm
            };

            // duplicate search without diacritics
            var baseSearchTerm = StringUtil.RemoveDiacritics(exactSearchTerm);

            if (baseSearchTerm != exactSearchTerm)
            {
                SearchTerms.Add(baseSearchTerm);
            }

            foreach (var searchTerm in SearchTerms)
            {
                // Build our query
                var request = BuildQuery(searchTerm, query, searchUrl);

                // Getting results & Store content
                var response = await RequestWithCookiesAndRetryAsync(request, ConfigData.CookieHeader.Value);

                var parser = new HtmlParser();
                var dom    = parser.ParseDocument(response.ContentString);

                try
                {
                    var firstPageRows = FindTorrentRows(dom);

                    // If pagination available
                    int nbResults;
                    int pageLinkCount;
                    pageLinkCount = 1;

                    // Check if we have a minimum of one result
                    if (firstPageRows?.Length > 1)
                    {
                        // Retrieve total count on our alone page
                        nbResults = firstPageRows.Length;
                    }
                    else
                    {
                        // No result found for this query
                        Output("\nNo result found for your query, please try another search term or change the theme you're currently using on the site as this is an unsupported solution...\n", "info");
                        break;
                    }

                    Output("\nFound " + nbResults + " result(s) (+/- " + firstPageRows.Length + ") in " + pageLinkCount + " page(s) for this query !");
                    Output("\nThere are " + (firstPageRows.Length - 2) + " results on the first page !");

                    // Loop on results

                    foreach (var row in firstPageRows.Skip(1).Take(firstPageRows.Length - 2))
                    {
                        Output("Torrent #" + (releases.Count + 1));

                        // ID
                        var idOrig = row.QuerySelector("td:nth-of-type(2) > a:nth-of-type(1)").GetAttribute("href").Split('=')[1];
                        var id     = idOrig.Substring(0, idOrig.Length - 4);
                        Output("ID: " + id);

                        // Release Name
                        var name = row.QuerySelector("td:nth-of-type(2) > a:nth-of-type(1)").TextContent.Trim();

                        // Category
                        var categoryId = row.QuerySelector("td:nth-of-type(1) > a:nth-of-type(1)").GetAttribute("href").Split('?').Last();
                        var newznab    = MapTrackerCatToNewznab(categoryId);
                        Output("Category: " + (newznab.Count > 0 ? newznab.First().ToString() : "unknown category") + " (" + categoryId + ")");

                        // Seeders
                        var seeders = ParseUtil.CoerceInt(Regex.Match(row.QuerySelector("td:nth-of-type(10)").TextContent, @"\d+").Value);
                        Output("Seeders: " + seeders);

                        // Leechers
                        var leechers = ParseUtil.CoerceInt(Regex.Match(row.QuerySelector("td:nth-of-type(11)").TextContent, @"\d+").Value);
                        Output("Leechers: " + leechers);

                        // Files
                        var files = 1;
                        files = ParseUtil.CoerceInt(Regex.Match(row.QuerySelector("td:nth-of-type(5)").TextContent, @"\d+").Value);
                        Output("Files: " + files);

                        // Completed
                        var completed = ParseUtil.CoerceInt(Regex.Match(row.QuerySelector("td:nth-of-type(9)").TextContent, @"\d+").Value);
                        Output("Completed: " + completed);

                        // Size
                        var humanSize = row.QuerySelector("td:nth-of-type(8)").TextContent.ToLowerInvariant();
                        var size      = ReleaseInfo.GetBytes(humanSize);
                        Output("Size: " + humanSize + " (" + size + " bytes)");

                        // Publish DateToString
                        var dateTimeOrig = row.QuerySelector("td:nth-of-type(7)").TextContent;
                        var datestr      = Regex.Replace(dateTimeOrig, @"<[^>]+>|&nbsp;", "").Trim();
                        datestr = Regex.Replace(datestr, "Today", DateTime.Now.ToString("MMM dd yyyy"), RegexOptions.IgnoreCase);
                        datestr = Regex.Replace(datestr, "Yesterday", DateTime.Now.Date.AddDays(-1).ToString("MMM dd yyyy"), RegexOptions.IgnoreCase);
                        var date = DateTimeUtil.FromUnknown(datestr, "DK");
                        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      = row.QuerySelector("td:nth-of-type(3) > a:nth-of-type(1)").GetAttribute("href");
                        var key          = Regex.Match(passkey, "(?<=torrent_pass\\=)([a-zA-z0-9]*)");
                        var 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        = newznab,
                            Title           = name,
                            Seeders         = seeders,
                            Peers           = seeders + leechers,
                            PublishDate     = date,
                            Size            = size,
                            Files           = files,
                            Grabs           = completed,
                            Guid            = detailsLink,
                            Comments        = commentsLink,
                            Link            = downloadLink,
                            MinimumRatio    = 1,
                            MinimumSeedTime = 172800 // 48 hours
                        };

                        // IMDB
                        var imdbLink = row.QuerySelector("a[href*=\"imdb.com/title/tt\"]")?.GetAttribute("href");
                        release.Imdb = ParseUtil.GetLongFromString(imdbLink);

                        if (row.QuerySelector("img[title=\"Free Torrent\"]") != null)
                        {
                            release.DownloadVolumeFactor = 0;
                        }
                        else if (row.QuerySelector("img[title=\"Halfleech\"]") != null)
                        {
                            release.DownloadVolumeFactor = 0.5;
                        }
                        else if (row.QuerySelector("img[title=\"90% Freeleech\"]") != null)
                        {
                            release.DownloadVolumeFactor = 0.1;
                        }
                        else
                        {
                            release.DownloadVolumeFactor = 1;
                        }

                        release.UploadVolumeFactor = 1;

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
                }
            }
            // Return found releases
            return(releases);
        }
Exemple #15
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var searchString = "--";
            var maxPages     = 2; // we scrape only 2 pages for recent torrents

            if (!string.IsNullOrWhiteSpace(query.GetQueryString()))
            {
                searchString = Uri.EscapeUriString(query.GetQueryString());
                maxPages     = MaxSearchPageLimit;
            }

            var lastPublishDate = DateTime.Now;

            for (var page = 0; page < maxPages; page++)
            {
                var searchUrl = string.Format(SearchUrl, page * MaxItemsPerPage, searchString);
                var result    = await RequestWithCookiesAsync(searchUrl, headers : _apiHeaders);

                try
                {
                    var json   = JsonConvert.DeserializeObject <dynamic>(result.ContentString);
                    var parser = new HtmlParser();
                    var doc    = parser.ParseDocument((string)json["contenido"]);

                    var rows = doc.QuerySelectorAll("div.span2");
                    foreach (var row in rows)
                    {
                        var title = row.QuerySelector("h2").TextContent + " - " +
                                    row.QuerySelector("h1").TextContent;
                        if (!CheckTitleMatchWords(query.GetQueryString(), title))
                        {
                            continue; // skip if it doesn't contain all words
                        }
                        var poster  = new Uri(row.QuerySelector("img[id=catalog]").GetAttribute("src"));
                        var qLink   = row.QuerySelector("a");
                        var details = new Uri(qLink.GetAttribute("href"));

                        var qTooltip = parser.ParseDocument(qLink.GetAttribute("data-content"));
                        // we get the language from the last class tag => class="pull-right sprite idioma_5"
                        var languageId = qTooltip.QuerySelector("div.pull-right").GetAttribute("class").Split('_')[1];
                        title += $" [{_languages[languageId]}] [epub]";
                        var qDesc       = qTooltip.QuerySelectorAll("div.row-fluid > div");
                        var description = $"Rev: {qDesc[0].TextContent} Páginas: {qDesc[1].TextContent} Puntación: {qDesc[2].TextContent} Likes: {qDesc[3].TextContent}";

                        // publish date is not available in the torrent list, but we add a relative date so we can sort
                        lastPublishDate = lastPublishDate.AddMinutes(-1);
                        var release = new ReleaseInfo
                        {
                            Title       = title,
                            Details     = details,
                            Link        = details,
                            Guid        = details,
                            PublishDate = lastPublishDate,
                            Poster      = poster,
                            Description = description,
                            Category    = new List <int> {
                                TorznabCatType.BooksEBook.ID
                            },
                            Size    = 5242880, // 5 MB
                            Seeders = 1,
                            Peers   = 2,
                            DownloadVolumeFactor = 0,
                            UploadVolumeFactor   = 1
                        };
                        releases.Add(release);
                    }

                    if (rows.Length < MaxItemsPerPage)
                    {
                        break; // this is the last page
                    }
                }
                catch (Exception ex)
                {
                    OnParseError(result.ContentString, ex);
                }
            }

            return(releases);
        }
Exemple #16
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();

            queryCollection.Add("order_by", "time");
            queryCollection.Add("order_way", "desc");

            if (!string.IsNullOrWhiteSpace(searchString))
            {
                queryCollection.Add("searchstr", searchString);
            }

            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                queryCollection.Add("filter_cat[" + cat + "]", "1");
            }

            searchUrl += "?" + queryCollection.GetQueryString();
            var results = await RequestStringWithCookiesAndRetry(searchUrl);

            if (results.Content.Contains("Din søgning gav intet resultat."))
            {
                return(releases);
            }
            try
            {
                CQ dom = results.Content;

                var rows = dom["#torrent_table > tbody > tr"].ToArray();

                foreach (var row in rows.Skip(1))
                {
                    var release = new ReleaseInfo();
                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800;

                    var qCat   = row.ChildElements.ElementAt(0).ChildElements.ElementAt(0).Cq();
                    var catUrl = qCat.Attr("href");
                    var cat    = catUrl.Substring(catUrl.LastIndexOf('[') + 1).Trim(']');
                    release.Category = MapTrackerCatToNewznab(cat);

                    var qAdded   = row.ChildElements.ElementAt(4).ChildElements.ElementAt(0).Cq();
                    var addedStr = qAdded.Attr("title");
                    release.PublishDate = DateTime.ParseExact(addedStr, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture);

                    var qLink = row.ChildElements.ElementAt(1).ChildElements.ElementAt(2).Cq();
                    release.Title       = qLink.Text().Trim();
                    release.Description = release.Title;

                    release.Comments = new Uri(SiteLink + qLink.Attr("href"));
                    release.Guid     = release.Comments;

                    var qDownload = row.ChildElements.ElementAt(1).ChildElements.ElementAt(1).ChildElements.ElementAt(0).Cq();
                    release.Link = new Uri(SiteLink + qDownload.Attr("href"));

                    var sizeStr = row.ChildElements.ElementAt(5).Cq().Text();
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

                    release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(6).Cq().Text());
                    release.Peers   = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text()) + release.Seeders;

                    var files = row.Cq().Find("td:nth-child(4)").Text();
                    release.Files = ParseUtil.CoerceInt(files);

                    if (row.Cq().Find("img[src=\"/static//common/browse/freeleech.png\"]").Any())
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }

            return(releases);
        }
Exemple #17
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            List <ReleaseInfo> releases      = new List <ReleaseInfo>();
            List <string>      searchStrings = new List <string>(new string[] { query.GetQueryString() });

            if (string.IsNullOrEmpty(query.Episode) && (query.Season > 0))
            {
                // Tracker naming rules: If query is for a whole season, "Season #" instead of "S##".
                searchStrings.Add((query.SanitizedSearchTerm + " " + string.Format("\"Season {0}\"", query.Season)).Trim());
            }

            List <string> categories   = MapTorznabCapsToTrackers(query);
            List <string> request_urls = new List <string>();

            foreach (var searchString in searchStrings)
            {
                var queryCollection = new NameValueCollection();
                queryCollection.Add("action", "basic");

                if (!string.IsNullOrWhiteSpace(searchString))
                {
                    queryCollection.Add("searchstr", searchString);
                }

                foreach (var cat in categories)
                {
                    queryCollection.Add("filter_cat[" + cat + "]", "1");
                }

                request_urls.Add(SearchUrl + queryCollection.GetQueryString());
            }
            IEnumerable <Task <WebClientStringResult> > downloadTasksQuery =
                from url in request_urls select RequestStringWithCookiesAndRetry(url);

            WebClientStringResult[] responses = await Task.WhenAll(downloadTasksQuery.ToArray());

            for (int i = 0; i < searchStrings.Count(); i++)
            {
                var results = responses[i];
                // Occasionally the cookies become invalid, login again if that happens
                if (results.IsRedirect)
                {
                    await ApplyConfiguration(null);

                    results = await RequestStringWithCookiesAndRetry(request_urls[i]);
                }
                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;

                        var catStr = row.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href").Split(new char[] { '[', ']' })[1];
                        release.Category = MapTrackerCatToNewznab(catStr);

                        var qLink   = row.ChildElements.ElementAt(1).Cq().Children("a")[0].Cq();
                        var linkStr = qLink.Attr("href");
                        release.Comments = new Uri(BaseUrl + "/" + linkStr);
                        release.Guid     = release.Comments;

                        var qDownload = row.ChildElements.ElementAt(1).Cq().Find("a[title='Download']")[0].Cq();
                        release.Link = new Uri(BaseUrl + "/" + qDownload.Attr("href"));

                        var dateStr = row.ChildElements.ElementAt(3).Cq().Text().Trim().Replace(" and", "");
                        release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr);

                        var sizeStr = row.ChildElements.ElementAt(4).Cq().Text();
                        release.Size = ReleaseInfo.GetBytes(sizeStr);

                        release.Files   = ParseUtil.CoerceInt(row.ChildElements.ElementAt(2).Cq().Text().Trim());
                        release.Grabs   = ParseUtil.CoerceInt(row.ChildElements.ElementAt(6).Cq().Text().Trim());
                        release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text().Trim());
                        release.Peers   = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text().Trim()) + release.Seeders;

                        var grabs = qRow.Find("td:nth-child(6)").Text();
                        release.Grabs = ParseUtil.CoerceInt(grabs);

                        if (qRow.Find("strong:contains(\"Freeleech!\")").Length >= 1)
                        {
                            release.DownloadVolumeFactor = 0;
                        }
                        else
                        {
                            release.DownloadVolumeFactor = 1;
                        }

                        release.UploadVolumeFactor = 1;

                        var title = qRow.Find("td:nth-child(2)");
                        title.Find("span, strong, div, br").Remove();

                        release.Title = ParseUtil.NormalizeMultiSpaces(title.Text().Replace(" - ]", "]"));

                        if (catStr == "10") //change "Season #" to "S##" for TV shows
                        {
                            release.Title = Regex.Replace(release.Title, @"Season (\d+)",
                                                          m => string.Format("S{0:00}", Int32.Parse(m.Groups[1].Value)));
                        }

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnParseError(results.Content, ex);
                }
            }
            return(releases);
        }
Exemple #18
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var qc = new List <KeyValuePair <string, string> > // NameValueCollection don't support cat[]=19&cat[]=6
            {
                { "tpage", "1" }
            };

            if (query.IsImdbQuery)
            {
                qc.Add("search", query.ImdbID);
                qc.Add("nfo", "true");
            }
            else if (!string.IsNullOrWhiteSpace(query.GetQueryString()))
            {
                qc.Add("search", query.GetQueryString());
            }

            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                qc.Add("cat[]", cat);
            }

            var searchUrl = SearchUrl + "?" + qc.GetQueryString();
            var result    = await RequestWithCookiesAndRetryAsync(searchUrl, referer : SearchUrl);

            if (result.IsRedirect)
            {
                throw new Exception($"Your cookie did not work. Please, configure the tracker again. Message: {result.ContentString}");
            }

            if (!result.ContentString.StartsWith("{")) // not JSON => error
            {
                throw new ExceptionWithConfigData(result.ContentString, configData);
            }

            var json = JsonConvert.DeserializeObject <dynamic>(result.ContentString);

            try
            {
                var torrents = json["torrents"]; // latest torrents
                if (json["hits"] != null)        // is search result
                {
                    torrents = json.SelectTokens("$.hits[?(@._type == 'torrent')]._source");
                }
                foreach (var torrent in torrents)
                {
                    var torrentId   = (long)torrent.id;
                    var details     = new Uri(SiteLink + "torrents/" + torrentId);
                    var link        = new Uri(SiteLink + "download/" + torrentId);
                    var publishDate = DateTime.Parse(torrent.added.ToString());
                    var imdbId      = ParseUtil.GetImdbID(torrent.imdb_id.ToString());

                    Uri poster = null;
                    if ((bool)torrent.poster)
                    {
                        if (torrent["imdb_id"] != null)
                        {
                            poster = new Uri(CdnUrl + "images/torrents/poster/imd/l/" + torrent["imdb_id"] + ".jpg");
                        }
                        else if (torrent["cdu_id"] != null)
                        {
                            poster = new Uri(CdnUrl + "images/torrents/poster/cdu/b/" + torrent["cdu_id"] + "_front.jpg");
                        }
                        else if (torrent["steam_id"] != null)
                        {
                            poster = new Uri(CdnUrl + "images/torrents/poster/ste/l/" + torrent["steam_id"] + ".jpg");
                        }
                    }

                    var title = torrent.name.ToString();

                    var descriptions = new List <string>();
                    var language     = (string)torrent.language;
                    if (!string.IsNullOrEmpty(language))
                    {
                        descriptions.Add("Language: " + language);
                    }
                    else if ((bool?)torrent.polish == true)
                    {
                        descriptions.Add("Language: pl");
                    }

                    if (language == "pl" && (((BoolConfigurationItem)configData.GetDynamic("LanguageTitle")).Value))
                    {
                        title += " POLISH";
                    }

                    var description = descriptions.Any() ? string.Join("<br />\n", descriptions) : null;

                    var release = new ReleaseInfo
                    {
                        Title                = title,
                        Details              = details,
                        Guid                 = details,
                        Link                 = link,
                        PublishDate          = publishDate,
                        Category             = MapTrackerCatToNewznab(torrent.category.ToString()),
                        Size                 = (long)torrent.size,
                        Grabs                = (long)torrent.completed,
                        Seeders              = (int)torrent.seeders,
                        Peers                = (int)torrent.seeders + (int)torrent.leechers,
                        Imdb                 = imdbId,
                        Poster               = poster,
                        Description          = description,
                        MinimumRatio         = 1,
                        MinimumSeedTime      = 259200, // 72 hours (I can't verify this, but this is a safe value in most trackers)
                        UploadVolumeFactor   = 1,
                        DownloadVolumeFactor = 1
                    };

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(result.ToString(), ex);
            }

            return(releases);
        }
Exemple #19
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var searchString    = query.GetQueryString();
            var queryCollection = new NameValueCollection();

            queryCollection.Add("order_by", "time");
            queryCollection.Add("order_way", "desc");

            if (!string.IsNullOrWhiteSpace(query.ImdbID))
            {
                queryCollection.Add("imdbid", query.ImdbID);
            }
            else if (!string.IsNullOrWhiteSpace(searchString))
            {
                queryCollection.Add("groupname", searchString);
            }

            queryCollection.Add("groupname", searchString);

            var searchUrl = BrowseUrl + "?" + queryCollection.GetQueryString();

            var results = await RequestStringWithCookies(searchUrl);

            if (results.IsRedirect)
            {
                // re login
                await GetConfigurationForSetup();
                await ApplyConfiguration(null);

                results = await RequestStringWithCookies(searchUrl);
            }

            Regex IMDBRegEx      = new Regex(@"tt(\d+)", RegexOptions.Compiled);
            var   hParser        = new HtmlParser();
            var   ResultDocument = hParser.Parse(results.Content);

            try
            {
                var Groups = ResultDocument.QuerySelectorAll("div.browsePoster");

                foreach (var Group in Groups)
                {
                    var groupPoster = Group.QuerySelector("img.classBrowsePoster");
                    var bannerURL   = new Uri(SiteLink + groupPoster.GetAttribute("src"));

                    long?IMDBId   = null;
                    var  imdbLink = Group.QuerySelector("a[href^=\"http://anonym.to/?http://www.imdb.com/title/tt\"]");
                    if (imdbLink != null)
                    {
                        var IMDBMatch = IMDBRegEx.Match(imdbLink.GetAttribute("href"));
                        IMDBId = ParseUtil.CoerceLong(IMDBMatch.Groups[1].Value);
                    }

                    var GroupTitle = Group.QuerySelector("strong:has(a[title=\"View Torrent\"])").TextContent.Replace(" ]", "]");

                    var Rows = Group.QuerySelectorAll("tr.group_torrent:has(a[href^=\"torrents.php?id=\"])");
                    foreach (var Row in Rows)
                    {
                        var release = new ReleaseInfo();
                        release.MinimumRatio    = 1;
                        release.MinimumSeedTime = 72 * 60 * 60;

                        var title    = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
                        var link     = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
                        var added    = Row.QuerySelector("td:nth-child(3)");
                        var Size     = Row.QuerySelector("td:nth-child(4)");
                        var Grabs    = Row.QuerySelector("td:nth-child(6)");
                        var Seeders  = Row.QuerySelector("td:nth-child(7)");
                        var Leechers = Row.QuerySelector("td:nth-child(8)");

                        release.Title    = GroupTitle + " " + title.TextContent;
                        release.Category = new List <int> {
                            TorznabCatType.MoviesHD.ID
                        };
                        release.Link        = new Uri(SiteLink + link.GetAttribute("href"));
                        release.Comments    = new Uri(SiteLink + title.GetAttribute("href"));
                        release.Guid        = release.Link;
                        release.Size        = ReleaseInfo.GetBytes(Size.TextContent);
                        release.Seeders     = ParseUtil.CoerceInt(Seeders.TextContent);
                        release.Peers       = ParseUtil.CoerceInt(Leechers.TextContent) + release.Seeders;
                        release.Grabs       = ParseUtil.CoerceLong(Grabs.TextContent);
                        release.PublishDate = DateTimeUtil.FromTimeAgo(added.TextContent);
                        release.BannerUrl   = bannerURL;
                        release.Imdb        = IMDBId;

                        releases.Add(release);
                    }
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }

            return(releases);
        }
Exemple #20
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();
            var prevCook     = CookieHeader + "";

            // If we have no query use the RSS Page as their server is slow enough at times!
            if (query.IsTest || string.IsNullOrWhiteSpace(searchString))
            {
                var rssPage = await RequestStringWithCookiesAndRetry(string.Format(RSSUrl, configData.RSSKey.Value));

                try
                {
                    if (rssPage.Content.EndsWith("\0"))
                    {
                        rssPage.Content = rssPage.Content.Substring(0, rssPage.Content.Length - 1);
                    }
                    rssPage.Content = RemoveInvalidXmlChars(rssPage.Content);
                    var rssDoc = XDocument.Parse(rssPage.Content);

                    foreach (var item in rssDoc.Descendants("item"))
                    {
                        var title       = item.Descendants("title").First().Value;
                        var description = item.Descendants("description").First().Value;
                        var link        = item.Descendants("link").First().Value;
                        var category    = item.Descendants("category").First().Value;
                        var date        = item.Descendants("pubDate").First().Value;

                        var torrentIdMatch = Regex.Match(link, "(?<=id=)(\\d)*");
                        var torrentId      = torrentIdMatch.Success ? torrentIdMatch.Value : string.Empty;
                        if (string.IsNullOrWhiteSpace(torrentId))
                        {
                            throw new Exception("Missing torrent id");
                        }

                        var infoMatch = Regex.Match(description, @"Category:\W(?<cat>.*)\W\/\WSeeders:\W(?<seeders>[\d\,]*)\W\/\WLeechers:\W(?<leechers>[\d\,]*)\W\/\WSize:\W(?<size>[\d\.]*\W\S*)");
                        if (!infoMatch.Success)
                        {
                            throw new Exception("Unable to find info");
                        }

                        var release = new ReleaseInfo
                        {
                            Title       = title,
                            Description = title,
                            Guid        = new Uri(string.Format(DownloadUrl, torrentId)),
                            Comments    = new Uri(string.Format(CommentUrl, torrentId)),
                            PublishDate = DateTime.ParseExact(date, "yyyy-MM-dd H:mm:ss", CultureInfo.InvariantCulture), //2015-08-08 21:20:31
                            Link        = new Uri(string.Format(DownloadUrl, torrentId)),
                            Seeders     = ParseUtil.CoerceInt(infoMatch.Groups["seeders"].Value),
                            Peers       = ParseUtil.CoerceInt(infoMatch.Groups["leechers"].Value),
                            Size        = ReleaseInfo.GetBytes(infoMatch.Groups["size"].Value),
                            Category    = MapTrackerCatToNewznab(category)
                        };

                        release.Peers += release.Seeders;
                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    logger.Error("XSpeeds: Error while parsing the RSS feed:");
                    logger.Error(rssPage.Content);
                    throw ex;
                }
            }
            if (query.IsTest || !string.IsNullOrWhiteSpace(searchString))
            {
                if (searchString.Length < 3 && !query.IsTest)
                {
                    OnParseError("", new Exception("Minimum search length is 3"));
                    return(releases);
                }
                var searchParams = new Dictionary <string, string> {
                    { "do", "search" },
                    { "keywords", searchString },
                    { "search_type", "t_name" },
                    { "category", "0" },
                    { "include_dead_torrents", "no" }
                };
                var pairs = new Dictionary <string, string> {
                    { "username", configData.Username.Value },
                    { "password", configData.Password.Value }
                };

                var searchPage = await PostDataWithCookiesAndRetry(SearchUrl, searchParams, CookieHeader);

                // Occasionally the cookies become invalid, login again if that happens
                if (searchPage.IsRedirect)
                {
                    await ApplyConfiguration(null);

                    searchPage = await PostDataWithCookiesAndRetry(SearchUrl, searchParams, CookieHeader);
                }

                try
                {
                    CQ  dom  = searchPage.Content;
                    var rows = dom["table#sortabletable > tbody > tr:has(div > a[href*=\"details.php?id=\"])"];
                    foreach (var row in rows)
                    {
                        var release = new ReleaseInfo();
                        var qRow    = row.Cq();

                        var qDetails = qRow.Find("div > a[href*=\"details.php?id=\"]");  // details link, release name get's shortened if it's to long
                        var qTitle   = qRow.Find("td:eq(1) .tooltip-content div:eq(0)"); // use Title from tooltip
                        if (!qTitle.Any())                                               // fallback to Details link if there's no tooltip
                        {
                            qTitle = qDetails;
                        }
                        release.Title = qTitle.Text();

                        release.Guid        = new Uri(qRow.Find("td:eq(2) a").Attr("href"));
                        release.Link        = release.Guid;
                        release.Comments    = new Uri(qDetails.Attr("href"));
                        release.PublishDate = DateTime.ParseExact(qRow.Find("td:eq(1) div").Last().Text().Trim(), "dd-MM-yyyy H:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); //08-08-2015 12:51
                        release.Seeders     = ParseUtil.CoerceInt(qRow.Find("td:eq(6)").Text());
                        release.Peers       = release.Seeders + ParseUtil.CoerceInt(qRow.Find("td:eq(7)").Text().Trim());
                        release.Size        = ReleaseInfo.GetBytes(qRow.Find("td:eq(4)").Text().Trim());


                        var cat      = row.Cq().Find("td:eq(0) a").First().Attr("href");
                        var catSplit = cat.LastIndexOf('=');
                        if (catSplit > -1)
                        {
                            cat = cat.Substring(catSplit + 1);
                        }
                        release.Category = MapTrackerCatToNewznab(cat);

                        // If its not apps or audio we can only mark as general TV
                        if (release.Category == 0)
                        {
                            release.Category = 5030;
                        }

                        var grabs = qRow.Find("td:nth-child(6)").Text();
                        release.Grabs = ParseUtil.CoerceInt(grabs);

                        if (qRow.Find("img[alt^=\"Free Torrent\"]").Length >= 1)
                        {
                            release.DownloadVolumeFactor = 0;
                        }
                        else if (qRow.Find("img[alt^=\"Silver Torrent\"]").Length >= 1)
                        {
                            release.DownloadVolumeFactor = 0.5;
                        }
                        else
                        {
                            release.DownloadVolumeFactor = 1;
                        }

                        if (qRow.Find("img[alt^=\"x2 Torrent\"]").Length >= 1)
                        {
                            release.UploadVolumeFactor = 2;
                        }
                        else
                        {
                            release.UploadVolumeFactor = 1;
                        }

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnParseError(searchPage.Content, ex);
                }
            }
            if (!CookieHeader.Trim().Equals(prevCook.Trim()))
            {
                SaveConfig();
            }
            return(releases);
        }
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();

            var searchUrl       = APIUrl;
            var queryCollection = new NameValueCollection();

            queryCollection.Add("action", "browse");
            //queryCollection.Add("group_results", "0"); # results won't include all information
            queryCollection.Add("order_by", "time");
            queryCollection.Add("order_way", "desc");

            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 || query.IsTest)
            {
                // re-login
                await ApplyConfiguration(null);

                response = await RequestStringWithCookiesAndRetry(searchUrl);
            }

            try
            {
                var json = JObject.Parse(response.Content);
                foreach (JObject r in json["response"]["results"])
                {
                    var groupTime   = DateTimeUtil.UnixTimestampToDateTime(long.Parse((string)r["groupTime"]));
                    var groupName   = HttpUtility.HtmlDecode((string)r["groupName"]);
                    var artist      = (string)r["artist"];
                    var cover       = (string)r["cover"];
                    var tags        = r["tags"].ToList();
                    var groupYear   = (string)r["groupYear"];
                    var releaseType = (string)r["releaseType"];

                    var release = new ReleaseInfo();

                    release.PublishDate = groupTime;

                    if (!string.IsNullOrEmpty(cover))
                    {
                        release.BannerUrl = new Uri(cover);
                    }

                    release.Title = "";
                    if (!string.IsNullOrEmpty(artist))
                    {
                        release.Title += artist + " - ";
                    }
                    release.Title += groupName;
                    if (!string.IsNullOrEmpty(groupYear))
                    {
                        release.Title += " [" + groupYear + "]";
                    }
                    if (!string.IsNullOrEmpty(releaseType))
                    {
                        release.Title += " [" + releaseType + "]";
                    }

                    release.Description = "";
                    if (tags != null && tags.Count > 0 && (string)tags[0] != "")
                    {
                        release.Description += "Tags: " + string.Join(", ", tags) + "\n";
                    }

                    if (r["torrents"] is JArray)
                    {
                        foreach (JObject torrent in r["torrents"])
                        {
                            ReleaseInfo release2 = (ReleaseInfo)release.Clone();
                            FillReleaseInfoFromJson(release2, torrent);
                            if (ReleaseInfoPostParse(release2, torrent, r))
                            {
                                releases.Add(release2);
                            }
                        }
                    }
                    else
                    {
                        FillReleaseInfoFromJson(release, r);
                        if (ReleaseInfoPostParse(release, r, r))
                        {
                            releases.Add(release);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.Content, ex);
            }

            return(releases);
        }
Exemple #22
0
        private async Task <IEnumerable <ReleaseInfo> > PerformRegularQueryAsync(TorznabQuery query, string hebName = null)
        {
            var releases     = new List <ReleaseInfo>();
            var searchUrl    = SearchUrl;
            var searchString = query.GetQueryString();

            if (query.IsImdbQuery)
            {
                searchString = query.ImdbID;
            }
            if (hebName != null)
            {
                searchString = hebName + " - עונה " + query.Season + " פרק " + query.Episode;
            }
            searchUrl += "?";
            if (!string.IsNullOrWhiteSpace(searchString))
            {
                var strEncoded = WebUtilityHelpers.UrlEncode(searchString, Encoding);
                searchUrl += "&query=" + strEncoded + "&matchquery=any";
            }

            searchUrl = MapTorznabCapsToTrackers(query).Aggregate(searchUrl, (current, cat) => $"{current}&c[]={cat}");
            var data = await RequestWithCookiesAndRetryAsync(searchUrl);

            try
            {
                var parser = new HtmlParser();
                var dom    = parser.ParseDocument(data.ContentString);
                var rows   = dom.QuerySelectorAll("tr.box_torrent");
                foreach (var row in rows)
                {
                    var release       = new ReleaseInfo();
                    var mainTitleLink = row.QuerySelector("div.main_title > a");
                    release.Title = mainTitleLink.GetAttribute("longtitle");
                    if (string.IsNullOrWhiteSpace(release.Title))
                    {
                        release.Title = mainTitleLink.TextContent;
                    }
                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800; // 48 hours
                    release.Grabs           = ParseUtil.CoerceLong(row.QuerySelector("td:nth-child(5)").TextContent.Replace(",", ""));
                    release.Seeders         = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(6)").TextContent.Replace(",", ""));
                    release.Peers           = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(7)").TextContent.Replace(",", "")) +
                                              release.Seeders;
                    var fullSize = row.QuerySelector("td:nth-child(4)").TextContent;
                    release.Size    = ReleaseInfo.GetBytes(fullSize);
                    release.Details = new Uri(SiteLink + row.QuerySelector("a.threadlink[href]").GetAttribute("href"));
                    release.Link    = new Uri(SiteLink + row.QuerySelector("a:has(div.dlimg)").GetAttribute("href"));
                    release.Guid    = release.Details;
                    //some releases have invalid poster URLs, ignore the posters in this case
                    if (Uri.TryCreate(row.QuerySelector("a[imgsrc]").GetAttribute("imgsrc"),
                                      UriKind.Absolute, out var poster))
                    {
                        release.Poster = poster;
                    }
                    var dateStringAll = row.QuerySelector("div.up_info2").ChildNodes.Last().TextContent;
                    var dateParts     = dateStringAll.Split(' ');
                    var dateString    = dateParts[dateParts.Length - 2] + " " + dateParts[dateParts.Length - 1];
                    release.PublishDate = DateTime.ParseExact(dateString, "dd/MM/yy HH:mm", CultureInfo.InvariantCulture);
                    var categoryLink = row.QuerySelector("a[href^=\"/browse.php?cat=\"]").GetAttribute("href");
                    var catid        = ParseUtil.GetArgumentFromQueryString(categoryLink, "cat");
                    release.Category = MapTrackerCatToNewznab(catid);
                    if (row.QuerySelector("a[href^=\"?freeleech=1\"]") != null)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }
                    release.UploadVolumeFactor = 1;
                    var subTitle = row.QuerySelector("div.sub_title");
                    var imdbLink = subTitle.QuerySelector("span.imdb-inline > a");
                    if (imdbLink != null)
                    {
                        release.Imdb = ParseUtil.GetLongFromString(imdbLink.GetAttribute("href"));
                    }
                    release.Description = subTitle.FirstChild.TextContent;
                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(data.ContentString, ex);
            }

            return(releases);
        }
Exemple #23
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            // if the search string is empty use the "last 24h torrents" view
            if (string.IsNullOrWhiteSpace(query.SearchTerm))
            {
                var results = await RequestStringWithCookies(TodayUrl);

                try
                {
                    string RowsSelector = "table.torrent_table > tbody > tr:not(tr.colhead)";

                    var SearchResultParser   = new HtmlParser();
                    var SearchResultDocument = SearchResultParser.Parse(results.Content);
                    var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
                    foreach (var Row in Rows)
                    {
                        try
                        {
                            var release = new ReleaseInfo();

                            release.MinimumRatio    = 1;
                            release.MinimumSeedTime = 0;

                            var qDetailsLink = Row.QuerySelector("a.BJinfoBox");
                            var qTitle       = qDetailsLink.QuerySelector("font");
                            release.Title = qTitle.TextContent;

                            var qBJinfoBox = qDetailsLink.QuerySelector("span");
                            var qCatLink   = Row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
                            var qDLLink    = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
                            var qSeeders   = Row.QuerySelector("td:nth-child(4)");
                            var qLeechers  = Row.QuerySelector("td:nth-child(5)");
                            var qFreeLeech = Row.QuerySelector("font[color=\"green\"]:contains(Free)");

                            release.Description = "";
                            foreach (var Child in qBJinfoBox.ChildNodes)
                            {
                                var type = Child.NodeType;
                                if (type != NodeType.Text)
                                {
                                    continue;
                                }

                                var line = Child.TextContent;
                                if (line.StartsWith("Tamanho:"))
                                {
                                    string Size = line.Substring("Tamanho: ".Length);;
                                    release.Size = ReleaseInfo.GetBytes(Size);
                                }
                                else if (line.StartsWith("Lançado em: "))
                                {
                                    string PublishDateStr = line.Substring("Lançado em: ".Length).Replace("às ", "");
                                    PublishDateStr += " +0";
                                    var PublishDate = DateTime.SpecifyKind(DateTime.ParseExact(PublishDateStr, "dd/MM/yyyy HH:mm z", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
                                    release.PublishDate = PublishDate.ToLocalTime();
                                }
                                else
                                {
                                    release.Description += line + "\n";
                                }
                            }

                            var catStr = qCatLink.GetAttribute("href").Split('=')[1];
                            // if result is an anime, convert title from SXXEXX to EXX
                            if (catStr == "14")
                            {
                                release.Title = Regex.Replace(release.Title, @"(Ep[\.]?[ ]?)|([S]\d\d[Ee])", "E");
                            }
                            release.Category = MapTrackerCatToNewznab(catStr);

                            release.Link     = new Uri(SiteLink + qDLLink.GetAttribute("href"));
                            release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
                            release.Guid     = release.Link;

                            release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
                            release.Peers   = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;

                            if (qFreeLeech != null)
                            {
                                release.DownloadVolumeFactor = 0;
                            }
                            else
                            {
                                release.DownloadVolumeFactor = 1;
                            }

                            release.UploadVolumeFactor = 1;

                            releases.Add(release);
                        }
                        catch (Exception ex)
                        {
                            logger.Error(string.Format("{0}: Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
                        }
                    }
                }
                catch (Exception ex)
                {
                    OnParseError(results.Content, ex);
                }
            }
            else // use search
            {
                var searchUrl     = BrowseUrl;
                var isSearchAnime = query.Categories.Any(s => s == TorznabCatType.TVAnime.ID);

                query.SearchTerm = query.SearchTerm.Replace("Agents of SHIELD", "Agents of S.H.I.E.L.D.");
                var searchString = query.GetQueryString();

                var queryCollection = new NameValueCollection
                {
                    { "searchstr", StripSearchString(searchString, isSearchAnime) },
                    { "order_by", "time" },
                    { "order_way", "desc" },
                    { "group_results", "1" },
                    { "action", "basic" },
                    { "searchsubmit", "1" }
                };

                foreach (var cat in MapTorznabCapsToTrackers(query))
                {
                    queryCollection.Add("filter_cat[" + cat + "]", "1");
                }

                searchUrl += "?" + queryCollection.GetQueryString();

                var results = await RequestStringWithCookies(searchUrl);

                try
                {
                    string RowsSelector = "table.torrent_table > tbody > tr:not(tr.colhead)";

                    var SearchResultParser   = new HtmlParser();
                    var SearchResultDocument = SearchResultParser.Parse(results.Content);
                    var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);

                    ICollection <int>   GroupCategory    = null;
                    string              GroupTitle       = null;
                    string              GroupYearStr     = null;
                    Nullable <DateTime> GroupPublishDate = null;

                    foreach (var Row in Rows)
                    {
                        try
                        {
                            var                 qDetailsLink    = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
                            string              Title           = qDetailsLink.TextContent;
                            ICollection <int>   Category        = null;
                            string              YearStr         = null;
                            Nullable <DateTime> YearPublishDate = null;
                            string              CategoryStr     = "";

                            if (Row.ClassList.Contains("group") || Row.ClassList.Contains("torrent")) // group/ungrouped headers
                            {
                                var qCatLink = Row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
                                CategoryStr = qCatLink.GetAttribute("href").Split('=')[1].Split('&')[0];
                                Category    = MapTrackerCatToNewznab(CategoryStr);

                                YearStr         = qDetailsLink.NextSibling.TextContent.Trim().TrimStart('[').TrimEnd(']');
                                YearPublishDate = DateTime.SpecifyKind(DateTime.ParseExact(YearStr, "yyyy", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);

                                // if result is an anime, convert title from SXXEXX to EXX
                                if (CategoryStr == "14")
                                {
                                    Title = Regex.Replace(Title, @"(Ep[\.]?[ ]?)|([S]\d\d[Ee])", "E");
                                }

                                if (Row.ClassList.Contains("group")) // group headers
                                {
                                    GroupCategory    = Category;
                                    GroupTitle       = Title;
                                    GroupYearStr     = YearStr;
                                    GroupPublishDate = YearPublishDate;
                                    continue;
                                }
                            }

                            var release = new ReleaseInfo();

                            release.MinimumRatio    = 1;
                            release.MinimumSeedTime = 0;

                            var qDLLink    = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
                            var qSize      = Row.QuerySelector("td:nth-last-child(4)");
                            var qGrabs     = Row.QuerySelector("td:nth-last-child(3)");
                            var qSeeders   = Row.QuerySelector("td:nth-last-child(2)");
                            var qLeechers  = Row.QuerySelector("td:nth-last-child(1)");
                            var qFreeLeech = Row.QuerySelector("strong[title=\"Free\"]");

                            if (Row.ClassList.Contains("group_torrent")) // torrents belonging to a group
                            {
                                release.Description = qDetailsLink.TextContent;

                                string cleanTitle = Regex.Replace(GroupTitle, @" - S?(?<season>\d{1,2})?E?(?<episode>\d{1,4})?", "");
                                string seasonEp   = Regex.Replace(GroupTitle, @"^(.*?) - (S?(\d{1,2})?E?(\d{1,4})?)?", "$2");
                                release.Title = CategoryStr == "14" ? GroupTitle : cleanTitle + " " + GroupYearStr + " " + seasonEp;

                                release.PublishDate = GroupPublishDate.Value;
                                release.Category    = GroupCategory;
                            }
                            else if (Row.ClassList.Contains("torrent")) // standalone/un grouped torrents
                            {
                                var qDescription = Row.QuerySelector("div.torrent_info");
                                release.Description = qDescription.TextContent;

                                string cleanTitle = Regex.Replace(Title, @" - ((S(\d{1,2}))?E(\d{1,4}))", "");
                                string seasonEp   = Regex.Replace(Title, @"^(.*?) - ((S(\d{1,2}))?E(\d{1,4}))", "$2");
                                release.Title = CategoryStr == "14" ? Title : cleanTitle + " " + YearStr + " " + seasonEp;

                                release.PublishDate = YearPublishDate.Value;
                                release.Category    = Category;
                            }

                            release.Description = release.Description.Replace(" / Free", ""); // Remove Free Tag

                            release.Description = release.Description.Replace("Full HD", "1080p");
                            release.Description = release.Description.Replace("/ HD / ", "/ 720p /");
                            release.Description = release.Description.Replace(" / HD]", " / 720p]");
                            release.Description = release.Description.Replace("4K", "2160p");

                            int nBarra = release.Title.IndexOf("[");
                            if (nBarra != -1)
                            {
                                release.Title = release.Title.Substring(nBarra + 1);
                                release.Title = release.Title.Replace("]", "");
                            }

                            release.Title += " " + release.Description; // add year and Description to the release Title to add some meaning to it

                            // check for previously stripped search terms
                            if (!query.MatchQueryStringAND(release.Title))
                            {
                                continue;
                            }

                            var Size = qSize.TextContent;
                            release.Size = ReleaseInfo.GetBytes(Size);

                            release.Link     = new Uri(SiteLink + qDLLink.GetAttribute("href"));
                            release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
                            release.Guid     = release.Link;

                            release.Grabs   = ParseUtil.CoerceLong(qGrabs.TextContent);
                            release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
                            release.Peers   = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;

                            if (qFreeLeech != null)
                            {
                                release.DownloadVolumeFactor = 0;
                            }
                            else
                            {
                                release.DownloadVolumeFactor = 1;
                            }

                            release.UploadVolumeFactor = 1;

                            releases.Add(release);
                        }
                        catch (Exception ex)
                        {
                            logger.Error(string.Format("{0}: Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
                        }
                    }
                }
                catch (Exception ex)
                {
                    OnParseError(results.Content, ex);
                }
            }

            return(releases);
        }
Exemple #24
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var qc = new List <KeyValuePair <string, string> >(); // NameValueCollection don't support c[]=30&c[]=52

            if (query.IsImdbQuery)
            {
                qc.Add("search", query.ImdbID);
                qc.Add("d", "on");
            }
            else
            {
                qc.Add("search", query.GetQueryString());
            }

            var catList = MapTorznabCapsToTrackers(query);

            foreach (var cat in catList)
            {
                qc.Add("c[]", cat);
            }

            var searchUrl = SearchUrl + "?" + qc.GetQueryString();
            var response  = await RequestStringWithCookiesAndRetry(searchUrl);

            if (!response.Content.Contains("/logout.php")) // re-login
            {
                await DoLogin();

                response = await RequestStringWithCookiesAndRetry(searchUrl);
            }

            try
            {
                var parser = new HtmlParser();
                var dom    = parser.ParseDocument(response.Content);
                var rows   = dom.QuerySelectorAll("div.boxContent > table > tbody > tr");

                foreach (var row in rows)
                {
                    var cells = row.QuerySelectorAll("td");

                    var title    = row.QuerySelector("td[class='lft'] > div > a").TextContent.Trim();
                    var link     = new Uri(SiteLink + row.QuerySelector("img[title='Download']").ParentElement.GetAttribute("href").TrimStart('/'));
                    var comments = new Uri(SiteLink + row.QuerySelector("td[class='lft'] > div > a").GetAttribute("href").TrimStart('/'));
                    var size     = ReleaseInfo.GetBytes(cells[4].TextContent);
                    var grabs    = ParseUtil.CoerceInt(cells[5].TextContent);
                    var seeders  = ParseUtil.CoerceInt(cells[6].TextContent);
                    var leechers = ParseUtil.CoerceInt(cells[7].TextContent);

                    var pubDateStr  = row.QuerySelector("span[class^='elapsedDate']").GetAttribute("title").Replace(" at", "");
                    var publishDate = DateTime.ParseExact(pubDateStr, "dddd, MMMM d, yyyy h:mmtt", CultureInfo.InvariantCulture);

                    var cat = row.QuerySelector("a[href^='?c[]=']").GetAttribute("href").Replace("?c[]=", "");
                    var downloadVolumeFactor = row.QuerySelector("span:contains(\"[Freeleech]\")") != null ? 0 : 1;

                    var release = new ReleaseInfo
                    {
                        Title                = title,
                        Link                 = link,
                        Guid                 = link,
                        Comments             = comments,
                        PublishDate          = publishDate,
                        Category             = MapTrackerCatToNewznab(cat),
                        Size                 = size,
                        Grabs                = grabs,
                        Seeders              = seeders,
                        Peers                = seeders + leechers,
                        MinimumRatio         = 1,
                        MinimumSeedTime      = 172800, // 48 hours
                        DownloadVolumeFactor = downloadVolumeFactor,
                        UploadVolumeFactor   = 1
                    };

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.Content, ex);
            }
            return(releases);
        }
Exemple #25
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var searchurls      = new List <string>();
            var searchUrl       = SearchUrl;// string.Format(SearchUrl, HttpUtility.UrlEncode()));
            var queryCollection = new NameValueCollection();
            var searchString    = query.GetQueryString();


            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                searchUrl += "category%5B%5D=" + cat + "&";
            }


            if (query.ImdbID != null)
            {
                queryCollection.Add("search", query.ImdbID);
            }
            else if (!string.IsNullOrWhiteSpace(searchString))
            {
                queryCollection.Add("search", searchString);
            }



            queryCollection.Add("active", "0");
            queryCollection.Add("options", "0");

            searchUrl += queryCollection.GetQueryString().Replace("(", "%28").Replace(")", "%29"); // maually url encode brackets to prevent "hacking" detection


            var results = await RequestStringWithCookiesAndRetry(searchUrl);

            try
            {
                CQ          dom = results.Content;
                ReleaseInfo release;

                var rows = dom[".mainblockcontenttt > tbody > tr:has(a[href^=\"details.php?id=\"])"];
                foreach (var row in rows)
                {
                    CQ qRow = row.Cq();

                    release = new ReleaseInfo();

                    release.Title       = qRow.Find("td.mainblockcontent b a").Text();
                    release.Description = qRow.Find("td:nth-child(3) > span").Text();

                    if (0 != qRow.Find("td.mainblockcontent u").Length)
                    {
                        var  imdbStr = qRow.Find("td.mainblockcontent u").Parent().First().Attr("href").Replace("http://www.imdb.com/title/tt", "").Replace("/", "");
                        long imdb;
                        if (ParseUtil.TryCoerceLong(imdbStr, out imdb))
                        {
                            release.Imdb = imdb;
                        }
                    }

                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800;


                    // Sometimes the uploader column is missing
                    int seeders, peers;
                    if (ParseUtil.TryCoerceInt(qRow.Find("td:nth-last-child(3)").Text(), out seeders))
                    {
                        release.Seeders = seeders;
                        if (ParseUtil.TryCoerceInt(qRow.Find("td:nth-last-child(2)").Text(), out peers))
                        {
                            release.Peers = peers + release.Seeders;
                        }
                    }

                    release.Grabs = ParseUtil.CoerceLong(qRow.Find("td:nth-last-child(1)").Text());

                    string fullSize = qRow.Find("td.mainblockcontent").Get(6).InnerText;
                    release.Size = ReleaseInfo.GetBytes(fullSize);

                    release.Guid     = new Uri(SiteLink + qRow.Find("td.mainblockcontent b a").Attr("href"));
                    release.Link     = new Uri(SiteLink + qRow.Find("td.mainblockcontent").Get(3).FirstChild.GetAttribute("href"));
                    release.Comments = new Uri(SiteLink + qRow.Find("td.mainblockcontent b a").Attr("href"));

                    string[] dateSplit  = qRow.Find("td.mainblockcontent").Get(5).InnerHTML.Split(',');
                    string   dateString = dateSplit[1].Substring(0, dateSplit[1].IndexOf('>')).Trim();
                    release.PublishDate = DateTime.ParseExact(dateString, "dd MMM yyyy HH:mm:ss zz00", CultureInfo.InvariantCulture).ToLocalTime();

                    string category = qRow.Find("td:eq(0) a").Attr("href").Replace("torrents.php?category=", "");
                    release.Category = MapTrackerCatToNewznab(category);

                    release.UploadVolumeFactor = 1;

                    if (qRow.Find("img[alt=\"Free Torrent\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                        release.UploadVolumeFactor   = 0;
                    }
                    else if (qRow.Find("img[alt=\"Silver Torrent\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0.5;
                    }
                    else if (qRow.Find("img[alt=\"Bronze Torrent\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0.75;
                    }
                    else if (qRow.Find("img[alt=\"Blue Torrent\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0.25;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }

            return(releases);
        }
Exemple #26
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();

            queryCollection.Add("total", "146"); // Not sure what this is about but its required!

            var cat       = "0";
            var queryCats = MapTorznabCapsToTrackers(query);

            if (queryCats.Count == 1)
            {
                cat = queryCats.First().ToString();
            }

            queryCollection.Add("cat", cat);
            queryCollection.Add("dlable", "1");
            queryCollection.Add("searchin", "filename");
            queryCollection.Add("search", searchString);
            queryCollection.Add("page", "1");
            searchUrl += "?" + queryCollection.GetQueryString();

            var extraHeaders = new Dictionary <string, string>()
            {
                { "X-Requested-With", "XMLHttpRequest" }
            };

            var response = await RequestStringWithCookiesAndRetry(searchUrl, null, SearchUrlReferer, extraHeaders);

            var results = response.Content;

            if (!string.IsNullOrWhiteSpace(results))
            {
                try
                {
                    CQ dom = results;

                    var rows = dom["tr"];
                    foreach (var row in rows.Skip(1))
                    {
                        var release    = new ReleaseInfo();
                        var qRow       = row.Cq();
                        var qTitleLink = qRow.Find("td:eq(1) a:eq(0)").First();
                        release.Title = qTitleLink.Find("strong").Text().Trim();

                        // If we search an get no results, we still get a table just with no info.
                        if (string.IsNullOrWhiteSpace(release.Title))
                        {
                            break;
                        }

                        release.Description = release.Title;
                        release.Guid        = new Uri(qTitleLink.Attr("href"));
                        release.Comments    = release.Guid;

                        var dateString = qRow.Find("td:eq(4)").Text();
                        release.PublishDate = DateTime.ParseExact(dateString, "dd MMM yy", CultureInfo.InvariantCulture);

                        var qLink = qRow.Find("td:eq(2) a");
                        release.Link = new Uri(qLink.Attr("href"));

                        var sizeStr = qRow.Find("td:eq(5)").Text();
                        release.Size = ReleaseInfo.GetBytes(sizeStr);

                        var connections = qRow.Find("td:eq(7)").Text().Trim().Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

                        release.Seeders = ParseUtil.CoerceInt(connections[0].Trim());
                        release.Peers   = ParseUtil.CoerceInt(connections[1].Trim()) + release.Seeders;

                        var rCat    = row.Cq().Find("td:eq(0) a").First().Attr("href");
                        var rCatIdx = rCat.IndexOf("cat=");
                        if (rCatIdx > -1)
                        {
                            rCat = rCat.Substring(rCatIdx + 4);
                        }

                        release.Category = MapTrackerCatToNewznab(rCat);

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnParseError(results, ex);
                }
            }

            return(releases);
        }
Exemple #27
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query, int attempts = 0)
        {
            await CheckToken();

            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();

            var queryCollection = new NameValueCollection();

            queryCollection.Add("token", token);
            queryCollection.Add("format", "json_extended");
            queryCollection.Add("app_id", "jackett_v" + Engine.ConfigService.GetVersion());
            queryCollection.Add("limit", "100");
            queryCollection.Add("ranked", "0");

            if (query.ImdbID != null)
            {
                queryCollection.Add("mode", "search");
                queryCollection.Add("search_imdb", query.ImdbID);
            }
            else if (query.RageID != null)
            {
                queryCollection.Add("mode", "search");
                queryCollection.Add("search_tvrage", query.RageID.ToString());
            }

            /*else if (query.TvdbID != null)
             * {
             *  queryCollection.Add("mode", "search");
             *  queryCollection.Add("search_tvdb", query.TvdbID);
             * }*/
            else if (!string.IsNullOrWhiteSpace(searchString))
            {
                searchString = searchString.Replace("'", ""); // ignore ' (e.g. search for america's Next Top Model)
                queryCollection.Add("mode", "search");
                queryCollection.Add("search_string", searchString);
            }
            else
            {
                queryCollection.Add("mode", "list");
            }

            var cats = string.Join(";", MapTorznabCapsToTrackers(query));

            if (!string.IsNullOrEmpty(cats))
            {
                queryCollection.Add("category", cats);
            }

            var searchUrl = ApiEndpoint + "?" + queryCollection.GetQueryString();
            var response  = await RequestStringWithCookiesAndRetry(searchUrl, string.Empty);

            try
            {
                var jsonContent = JObject.Parse(response.Content);

                int errorCode = jsonContent.Value <int>("error_code");
                if (errorCode == 20) // no results found
                {
                    return(releases.ToArray());
                }

                if (errorCode > 0) // too many requests per second
                {
                    // we use the IwebClient rate limiter now, this shouldn't happen
                    throw new Exception(jsonContent.Value <string>("error"));

                    /*if (attempts < 3)
                     * {
                     *  await Task.Delay(TimeSpan.FromSeconds(2));
                     *  return await PerformQuery(query, ++attempts);
                     * }
                     * else
                     * {
                     *  throw new Exception(jsonContent.Value<string>("error"));
                     * }*/
                }

                foreach (var item in jsonContent.Value <JArray>("torrent_results"))
                {
                    var release = new ReleaseInfo();
                    release.Title    = item.Value <string>("title");
                    release.Category = MapTrackerCatDescToNewznab(item.Value <string>("category"));

                    release.MagnetUri = new Uri(item.Value <string>("download"));
                    release.InfoHash  = release.MagnetUri.ToString().Split(':')[3].Split('&')[0];

                    release.Comments = new Uri(item.Value <string>("info_page"));
                    release.Guid     = release.Comments;

                    var episode_info = item.Value <JToken>("episode_info");

                    if (episode_info.HasValues)
                    {
                        var imdb = episode_info.Value <string>("imdb");
                        release.Imdb   = ParseUtil.GetImdbID(imdb);
                        release.TVDBId = episode_info.Value <long?>("tvdb");
                        release.RageID = episode_info.Value <long?>("tvrage");
                        release.TMDb   = episode_info.Value <long?>("themoviedb");
                    }

                    // ex: 2015-08-16 21:25:08 +0000
                    var dateStr  = item.Value <string>("pubdate").Replace(" +0000", "");
                    var dateTime = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                    release.PublishDate = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc).ToLocalTime();

                    release.Seeders = item.Value <int>("seeders");
                    release.Peers   = item.Value <int>("leechers") + release.Seeders;
                    release.Size    = item.Value <long>("size");
                    release.DownloadVolumeFactor = 0;
                    release.UploadVolumeFactor   = 1;

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.Content, ex);
            }

            return(releases);
        }
Exemple #28
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var cats = MapTorznabCapsToTrackers(query);

            if (cats.Count == 0)
            {
                cats = GetAllTrackerCategories();
            }
            var catStr    = string.Join(";", cats);
            var searchUrl = SearchUrl + "?" + catStr;

            if (query.IsImdbQuery)
            {
                searchUrl += ";q=" + query.ImdbID;
            }
            else
            {
                searchUrl += ";q=" + WebUtilityHelpers.UrlEncode(query.GetQueryString(), Encoding);
            }

            var results = await RequestStringWithCookiesAndRetry(searchUrl);

            // Check for being logged out
            if (results.IsRedirect)
            {
                if (results.RedirectingTo.Contains("login.php"))
                {
                    throw new ExceptionWithConfigData("Login failed, please reconfigure the tracker to update the cookies", configData);
                }
                else
                {
                    throw new ExceptionWithConfigData($"Got a redirect to {results.RedirectingTo}, please adjust your the alternative link", configData);
                }
            }

            try
            {
                var rows = JsonConvert.DeserializeObject <dynamic>(results.Content);

                foreach (var row in rows)
                {
                    var title = (string)row.name;
                    if ((!query.IsImdbQuery || !TorznabCaps.SupportsImdbMovieSearch) && !query.MatchQueryStringAND(title))
                    {
                        continue;
                    }
                    var torrentId          = (long)row.t;
                    var comments           = new Uri(SiteLink + "details.php?id=" + torrentId);
                    var seeders            = (int)row.seeders;
                    var imdbId             = (string)row["imdb-id"];
                    var downloadMultiplier = (double?)row["download-multiplier"] ?? 1;
                    var link        = new Uri(SiteLink + "download.php/" + torrentId + "/" + torrentId + ".torrent");
                    var publishDate = DateTimeUtil.UnixTimestampToDateTime((long)row.ctime).ToLocalTime();
                    var imdb        = ParseUtil.GetImdbID(imdbId);

                    var release = new ReleaseInfo
                    {
                        Title                = title,
                        Comments             = comments,
                        Guid                 = comments,
                        Link                 = link,
                        PublishDate          = publishDate,
                        Category             = MapTrackerCatToNewznab(row.c.ToString()),
                        Size                 = (long)row.size,
                        Files                = (long)row.files,
                        Grabs                = (long)row.completed,
                        Seeders              = seeders,
                        Peers                = seeders + (int)row.leechers,
                        Imdb                 = imdb,
                        DownloadVolumeFactor = downloadMultiplier,
                        UploadVolumeFactor   = 1,
                        MinimumRatio         = 1,
                        MinimumSeedTime      = 172800 // 48 hours
                    };

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }
            return(releases);
        }
Exemple #29
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            // remove dashes at the beginning of keywords as they exclude search strings (see issue #3096)
            var searchString = query.GetQueryString();

            searchString = Regex.Replace(searchString, @"(^|\s)-", " ");

            var searchUrl = SearchUrl;

            if (query.IsImdbQuery)
            {
                searchUrl += "imdbID/" + query.ImdbID + "/";
            }
            else if (!string.IsNullOrWhiteSpace(searchString))
            {
                searchUrl += "query/" + WebUtility.UrlEncode(searchString) + "/";
            }

            var cats = MapTorznabCapsToTrackers(query);

            if (cats.Count > 0)
            {
                searchUrl += "categories/" + string.Join(",", cats);
            }
            else
            {
                searchUrl += "newfilter/2"; // include 0day and music
            }
            var results = await RequestStringWithCookiesAndRetry(searchUrl);

            if (results.Content.Contains("/user/account/login")) // re-login
            {
                await DoLogin();

                results = await RequestStringWithCookiesAndRetry(searchUrl);
            }

            try
            {
                var rows = (JArray)((JObject)JsonConvert.DeserializeObject(results.Content))["torrentList"];
                foreach (var row in rows)
                {
                    var title = row["name"].ToString();
                    if (!query.MatchQueryStringAND(title))
                    {
                        continue;
                    }

                    var torrentId   = row["fid"].ToString();
                    var comments    = new Uri(SiteLink + "torrent/" + torrentId);
                    var link        = new Uri(SiteLink + "download/" + torrentId + "/" + row["filename"]);
                    var publishDate = DateTime.ParseExact(row["addedTimestamp"].ToString(), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                    var seeders     = (int)row["seeders"];

                    // freeleech #6579 #6624 #7367
                    var dlMultiplier   = row["download_multiplier"].ToString();
                    var dlVolumeFactor = string.IsNullOrEmpty(dlMultiplier) ? 1 : ParseUtil.CoerceInt(dlMultiplier);

                    var release = new ReleaseInfo
                    {
                        Title                = title,
                        Comments             = comments,
                        Guid                 = comments,
                        Link                 = link,
                        PublishDate          = publishDate,
                        Category             = MapTrackerCatToNewznab(row["categoryID"].ToString()),
                        Size                 = (long)row["size"],
                        Grabs                = (int)row["completed"],
                        Seeders              = seeders,
                        Peers                = seeders + (int)row["leechers"],
                        Imdb                 = ParseUtil.GetImdbID(row["imdbID"].ToString()),
                        UploadVolumeFactor   = 1,
                        DownloadVolumeFactor = dlVolumeFactor,
                        MinimumRatio         = 1,
                        MinimumSeedTime      = 172800 // 48 hours
                    };

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }

            return(releases);
        }
Exemple #30
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var searchString    = query.GetQueryString();
            var searchUrl       = SearchUrl;
            var queryCollection = new NameValueCollection();

            queryCollection.Add("active", "0");
            queryCollection.Add("options", "0");
            queryCollection.Add("category", string.Join(";", MapTorznabCapsToTrackers(query)));

            if (!string.IsNullOrWhiteSpace(searchString))
            {
                queryCollection.Add("search", searchString);
            }

            searchUrl += queryCollection.GetQueryString();

            var response = await RequestStringWithCookiesAndRetry(searchUrl);

            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;

                    var grabs = qRow.Find("td:nth-child(10)").Text();
                    grabs         = grabs.Replace("---", "0");
                    release.Grabs = ParseUtil.CoerceInt(grabs);

                    if (qRow.Find("img[title=\"FreeLeech\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else if (qRow.Find("img[src=\"images/sf.png\"]").Length >= 1) // side freeleech
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else if (qRow.Find("img[title=\"Half FreeLeech\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0.5;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

                    var qCat = qRow.Find("a[href^=\"index.php?page=torrents&category=\"]");
                    var cat  = qCat.Attr("href").Split('=')[2];
                    release.Category = MapTrackerCatToNewznab(cat);

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results, ex);
            }
            return(releases);
        }