Example #1
0
        /// <summary>
        /// These tests ensure that the code run for any action (Cq_Start and Cq_End) are applied for either action we test.
        /// </summary>
        ///
        /// <param name="doc">
        /// The document.
        /// </param>

        protected void Common(CQ doc)
        {
            Assert.IsTrue(doc["#cq-footer-1"].HasClass("cq-start"), "the 1st footer should get classes applied by controller-specific startup code");
            Assert.IsTrue(doc["#cq-footer-1"].HasClass("cq-end"), "the 1st footer should get classes applied by controller-specific end code");

            Assert.IsFalse(doc["#cq-footer-2"][0].HasClasses, "The footer added should have no classes from the controller-specific code");
        }
Example #2
0
        /// <summary>
        /// [CsQuery] A simple function to turn a sequence of Key/Value pairs into a pick list
        /// </summary>
        /// <param name="select"></param>
        /// <param name="list"></param>
        private void MakePickList(CQ select, IEnumerable<KeyValuePair<string,string>> list) 
        {
            foreach (var item in list)
            {
                var opt = select["<option />"]
                    .Attr("value",item.Key)
                    .Text(item.Value);

                select.Append(opt);
            }

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

            NameValueCollection qParams = new NameValueCollection();

            if (!string.IsNullOrWhiteSpace(query.ImdbID))
            {
                qParams.Add("search", query.ImdbID);
                qParams.Add("d", "on");
            }
            else if (!string.IsNullOrEmpty(query.GetQueryString()))
            {
                qParams.Add("search", query.GetQueryString());
            }

            List <string> catList = MapTorznabCapsToTrackers(query);

            foreach (string cat in catList)
            {
                qParams.Add("c" + cat, "1");
            }

            string urlSearch = SearchUrl;

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

            var response = await RequestStringWithCookiesAndRetry(urlSearch);

            if (!response.Content.Contains("/logout.php"))
            {
                //Cookie appears to expire after a period of time or logging in to the site via browser
                await DoLogin();

                response = await RequestStringWithCookiesAndRetry(urlSearch);
            }

            try
            {
                CQ  dom  = response.Content;
                var rows = dom["div[id='torrentTable'] > div[class^='box torrentBox'] > div[class='boxContent'] > table > tbody > tr"];

                foreach (IDomObject row in rows)
                {
                    CQ torrentData = row.OuterHTML;
                    CQ cells       = row.Cq().Find("td");

                    string title    = torrentData.Find("td[class='lft'] > div > a").First().Text().Trim();
                    Uri    link     = new Uri(SiteLink + torrentData.Find("img[title='Download']").First().Parent().Attr("href").Trim());
                    Uri    guid     = link;
                    long   size     = ReleaseInfo.GetBytes(cells.Elements.ElementAt(4).Cq().Text());
                    int    grabs    = ParseUtil.CoerceInt(cells.Elements.ElementAt(5).Cq().Text());
                    int    seeders  = ParseUtil.CoerceInt(cells.Elements.ElementAt(6).Cq().Text());
                    int    leechers = ParseUtil.CoerceInt(cells.Elements.ElementAt(7).Cq().Text());

                    string   pubDateStr  = torrentData.Find("span[class^='elapsedDate']").First().Attr("title").Trim().Replace(" at", "");
                    DateTime publishDate = DateTime.ParseExact(pubDateStr, "dddd, MMMM d, yyyy h:mmtt", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();

                    long   category = 0;
                    string cat      = torrentData.Find("img[class^='Tcat']").First().Parent().Attr("href").Trim().Remove(0, 5);
                    long.TryParse(cat, out category);

                    var release = new ReleaseInfo();

                    release.Title           = title;
                    release.Guid            = guid;
                    release.Link            = link;
                    release.PublishDate     = publishDate;
                    release.Size            = size;
                    release.Grabs           = grabs;
                    release.Seeders         = seeders;
                    release.Peers           = seeders + leechers;
                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800;
                    release.Category        = MapTrackerCatToNewznab(category.ToString());
                    release.Comments        = guid;

                    if (torrentData.Find("span:contains(\"[Freeleech]\")").Any())
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.Content, ex);
            }
            return(releases);
        }
Example #4
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var queryUrl        = SearchUrl;
            var queryCollection = new NameValueCollection();
            var cats            = MapTorznabCapsToTrackers(query);
            var tags            = string.Empty;
            var catGroups       = new List <string>();

            foreach (var cat in cats)
            {
                //"cat[]=7&tags=x264"
                var cSplit = cat.Split('&');
                if (cSplit.Length > 0)
                {
                    var gsplit = cSplit[0].Split('=');
                    if (gsplit.Length > 1)
                    {
                        catGroups.Add(gsplit[1]);
                    }
                }

                if (cSplit.Length > 1)
                {
                    var gsplit = cSplit[1].Split('=');
                    if (gsplit.Length > 1)
                    {
                        if (tags != string.Empty)
                        {
                            tags += ",";
                        }
                        tags += gsplit[1];
                    }
                }
            }

            if (catGroups.Distinct().Count() == 1)
            {
                queryCollection.Add("cat[]", catGroups.First());
            }

            if (!string.IsNullOrWhiteSpace(query.GetQueryString()))
            {
                queryCollection.Add("st", "1");
                queryCollection.Add("search", query.GetQueryString());
            }

            // Do not include too many tags as it'll mess with their servers.
            if (tags.Split(',').Length < 7)
            {
                queryCollection.Add("tags", tags);
                if (!string.IsNullOrWhiteSpace(tags))
                {
                    // if tags are specified match any
                    queryCollection.Add("tf", "any");
                }
                else
                {
                    // if no tags are specified match all, with any we get random results
                    queryCollection.Add("tf", "all");
                }
            }

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

            var response = await RequestStringWithCookiesAndRetry(queryUrl);

            if (response.IsRedirect)
            {
                await ApplyConfiguration(null);

                response = await RequestStringWithCookiesAndRetry(queryUrl);
            }

            try
            {
                CQ  dom  = response.Content;
                var rows = dom["table > tbody > tr.browse"];
                foreach (var row in rows)
                {
                    CQ  qRow    = row.Cq();
                    var release = new ReleaseInfo();

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

                    var qLink = row.ChildElements.ElementAt(1).Cq().Find("a").First();
                    release.Title = qLink.Text().Trim();
                    if (qLink.Find("span").Count() == 1 && release.Title.StartsWith("NEW! |"))
                    {
                        release.Title = release.Title.Substring(6).Trim();
                    }

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

                    var qDownload = row.ChildElements.ElementAt(2).Cq().Find("a").First();
                    release.Link = new Uri(SiteLink + qDownload.Attr("href"));

                    var dateStr = row.ChildElements.ElementAt(5).InnerHTML.Replace("<br>", " ");
                    release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr);

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

                    release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(9).InnerText);
                    release.Peers   = ParseUtil.CoerceInt(row.ChildElements.ElementAt(10).InnerText) + release.Seeders;

                    var cat = row.ChildElements.ElementAt(0).ChildElements.ElementAt(0).GetAttribute("href").Replace("browse.php?", string.Empty);
                    release.Category = MapTrackerCatToNewznab(cat);

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

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

                    release.DownloadVolumeFactor = 0; // ratioless
                    release.UploadVolumeFactor   = 1;

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.Content, ex);
            }
            return(releases);
        }
Example #5
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
            TimeZoneInfo.TransitionTime endTransition   = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
            TimeSpan delta = new TimeSpan(1, 0, 0);

            TimeZoneInfo.AdjustmentRule   adjustment  = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
            TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments);

            var releases = new List <ReleaseInfo>();

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

            queryCollection.Add("strWebValue", "torrent");
            queryCollection.Add("strWebAction", "search");
            queryCollection.Add("sort", "torrent_added");
            queryCollection.Add("by", "d");
            queryCollection.Add("type", "0");
            queryCollection.Add("do_search", "suchen");
            queryCollection.Add("time", "0");
            queryCollection.Add("details", "title");

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

            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                queryCollection.Add("dirs" + cat, "1");
            }
            searchUrl += "?" + queryCollection.GetQueryString();
            logger.Error(searchUrl);
            logger.Error(CookieHeader);
            var response = await RequestBytesWithCookies(searchUrl);

            var results = Encoding.GetEncoding("iso-8859-1").GetString(response.Content);

            try
            {
                CQ  dom  = results;
                var rows = dom["table.torrenttable > tbody > tr"];

                foreach (var row in rows.Skip(1))
                {
                    var release = new ReleaseInfo();
                    release.MinimumRatio    = 0.8;
                    release.MinimumSeedTime = 0;
                    var qRow = row.Cq();

                    var qDetailsLink = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=details]").First();
                    release.Title = qDetailsLink.Text();

                    var qCatLink  = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=search&dir=]").First();
                    var qDLLink   = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=download&id=]").First();
                    var qSeeders  = qRow.Find("td.column1:eq(3)");
                    var qLeechers = qRow.Find("td.column2:eq(3)");
                    var qDateStr  = qRow.Find("font:has(a)").First();
                    var qSize     = qRow.Find("td.column2[align=center]").First();

                    var catStr = qCatLink.Attr("href").Split('=')[3].Split('#')[0];
                    release.Category = MapTrackerCatToNewznab(catStr);

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

                    var sizeStr = qSize.Text();
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

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

                    var      dateStr      = qDateStr.Text().Trim();
                    var      dateStrParts = dateStr.Split();
                    DateTime dateGerman;
                    if (dateStrParts[0] == "Heute")
                    {
                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStrParts[1]);
                    }
                    else if (dateStrParts[0] == "Gestern")
                    {
                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStrParts[1]) - TimeSpan.FromDays(1);
                    }
                    else
                    {
                        dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStrParts[0] + dateStrParts[1], "dd.MM.yyyyHH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
                    }

                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
                    release.PublishDate = pubDateUtc.ToLocalTime();

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

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

                    release.UploadVolumeFactor = 1;

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

            return(releases);
        }
Example #6
0
 /// <summary>
 /// Return a CQ object, treating the HTML as content
 /// </summary>
 /// <returns></returns>
 public CQ GetContent()
 {
     return(CQ.Create(Html));
 }
Example #7
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();
            var searchUrl    = SearchUrl;

            if (!string.IsNullOrWhiteSpace(searchString))
            {
                searchUrl += "&search=" + WebUtilityHelpers.UrlEncode(searchString, Encoding);
            }
            string.Format(SearchUrl, WebUtilityHelpers.UrlEncode(searchString, Encoding));

            var cats = MapTorznabCapsToTrackers(query);

            if (cats.Count > 0)
            {
                foreach (var cat in cats)
                {
                    searchUrl += "&c" + cat + "=1";
                }
            }

            var response = await RequestStringWithCookies(searchUrl);

            try
            {
                CQ dom = response.Content;

                CQ qRows = dom[".browse > div > div"];

                foreach (var row in qRows)
                {
                    var release = new ReleaseInfo();

                    var qRow = row.Cq();

                    var debug = qRow.Html();

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

                    var titleParts = qRow.Find(".bTitle").Text().Split('/');
                    if (titleParts.Length >= 2)
                    {
                        release.Title = titleParts[1].Trim();
                    }
                    else
                    {
                        release.Title = titleParts[0].Trim();
                    }

                    var qDetailsLink = qRow.Find("a[title][href^=\"details.php\"]");
                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
                    release.Link     = new Uri(SiteLink + qRow.Find("a[href^=\"download.php\"]").Attr("href"));
                    release.Guid     = release.Link;

                    var dateString = qRow.Find("div:last-child").Text().Trim();
                    var pattern    = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}";
                    var match      = Regex.Match(dateString, pattern);
                    if (match.Success)
                    {
                        release.PublishDate = DateTime.ParseExact(match.Value, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                    }

                    var sizeStr = qRow.Find(".bSize").Text();
                    release.Size    = ReleaseInfo.GetBytes(sizeStr);
                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".bUping").Text().Trim());
                    release.Peers   = release.Seeders + ParseUtil.CoerceInt(qRow.Find(".bDowning").Text().Trim());

                    var files = qRow.Find("div.bFiles").Get(0).LastChild.ToString();
                    release.Files = ParseUtil.CoerceInt(files);

                    var grabs = qRow.Find("div.bFinish").Get(0).LastChild.ToString();
                    release.Grabs = ParseUtil.CoerceInt(grabs);

                    if (qRow.Find("img[src=\"/pic/free.jpg\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    if (qRow.Find("img[src=\"/pic/triple.jpg\"]").Length >= 1)
                    {
                        release.UploadVolumeFactor = 3;
                    }
                    else if (qRow.Find("img[src=\"/pic/double.jpg\"]").Length >= 1)
                    {
                        release.UploadVolumeFactor = 2;
                    }
                    else
                    {
                        release.UploadVolumeFactor = 1;
                    }

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

            return(releases);
        }
Example #8
0
        protected async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query, String seasonep)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();
            var pairs        = new List <KeyValuePair <string, string> >();

            if (seasonep != null)
            {
                searchString = query.SanitizedSearchTerm;
            }

            pairs.Add(new KeyValuePair <string, string>("nyit_sorozat_resz", "true"));
            pairs.Add(new KeyValuePair <string, string>("miben", "name"));
            pairs.Add(new KeyValuePair <string, string>("tipus", "kivalasztottak_kozott"));
            pairs.Add(new KeyValuePair <string, string>("submit.x", "1"));
            pairs.Add(new KeyValuePair <string, string>("submit.y", "1"));
            pairs.Add(new KeyValuePair <string, string>("submit", "Ok"));
            pairs.Add(new KeyValuePair <string, string>("mire", searchString));

            var cats = MapTorznabCapsToTrackers(query);

            if (cats.Count == 0)
            {
                cats = GetAllTrackerCategories();
            }

            foreach (var lcat in LanguageCats)
            {
                if (!configData.Hungarian.Value)
                {
                    cats.Remove(lcat + "_hun");
                }
                if (!configData.English.Value)
                {
                    cats.Remove(lcat);
                }
            }

            foreach (var cat in cats)
            {
                pairs.Add(new KeyValuePair <string, string>("kivalasztott_tipus[]", cat));
            }

            var results = await PostDataWithCookiesAndRetry(SearchUrl, pairs);

            try
            {
                CQ dom = results.Content;

                ReleaseInfo release;
                var         rows = dom[".box_torrent_all"].Find(".box_torrent");

                foreach (var row in rows)
                {
                    CQ qRow = row.Cq();

                    var key = dom["link[rel=alternate]"].First().Attr("href").Split('=').Last();

                    release = new ReleaseInfo();
                    var torrentTxt = qRow.Find(".torrent_txt, .torrent_txt2").Find("a").Get(0);
                    //if (torrentTxt == null) continue;
                    release.Title                = torrentTxt.GetAttribute("title");
                    release.Description          = qRow.Find("div.siterank").Text();
                    release.MinimumRatio         = 1;
                    release.MinimumSeedTime      = 172800;
                    release.DownloadVolumeFactor = 0;
                    release.UploadVolumeFactor   = 1;

                    string downloadLink = SiteLink + torrentTxt.GetAttribute("href");
                    string downloadId   = downloadLink.Substring(downloadLink.IndexOf("&id=") + 4);

                    release.Link     = new Uri(SiteLink.ToString() + "torrents.php?action=download&id=" + downloadId + "&key=" + key);
                    release.Comments = new Uri(SiteLink.ToString() + "torrents.php?action=details&id=" + downloadId);
                    release.Guid     = new Uri(release.Comments.ToString() + "#comments");;
                    release.Seeders  = ParseUtil.CoerceInt(qRow.Find(".box_s2").Find("a").First().Text());
                    release.Peers    = ParseUtil.CoerceInt(qRow.Find(".box_l2").Find("a").First().Text()) + release.Seeders;
                    var imdblink = qRow.Find("a[href*=\".imdb.com/title\"]").Attr("href");
                    release.Imdb = ParseUtil.GetLongFromString(imdblink);
                    var banner = qRow.Find("img.infobar_ico").Attr("onmouseover");
                    if (banner != null)
                    {
                        Regex BannerRegEx = new Regex(@"mutat\('(.*?)', '", RegexOptions.Compiled);
                        var   BannerMatch = BannerRegEx.Match(banner);
                        var   bannerurl   = BannerMatch.Groups[1].Value;
                        release.BannerUrl = new Uri(bannerurl);
                    }
                    release.PublishDate = DateTime.Parse(qRow.Find(".box_feltoltve2").Get(0).InnerHTML.Replace("<br />", " "), CultureInfo.InvariantCulture);
                    string[] sizeSplit = qRow.Find(".box_meret2").Get(0).InnerText.Split(' ');
                    release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
                    string catlink = qRow.Find("a:has(img[class='categ_link'])").First().Attr("href");
                    string cat     = ParseUtil.GetArgumentFromQueryString(catlink, "tipus");
                    release.Category = MapTrackerCatToNewznab(cat);
                    if (seasonep == null)
                    {
                        releases.Add(release);
                    }

                    else
                    {
                        if (query.MatchQueryStringAND(release.Title, null, seasonep))
                        {
                            /* For sonnar if the search querry was english the title must be english also so we need to change the Description and Title */
                            var temp = release.Title;

                            // releasedata everithing after Name.S0Xe0X
                            String releasedata = release.Title.Split(new[] { seasonep }, StringSplitOptions.None)[1].Trim();

                            /* if the release name not contains the language we add it because it is know from category */
                            if (cat.Contains("hun") && !releasedata.Contains("hun"))
                            {
                                releasedata += ".hun";
                            }

                            // release description contains [imdb: ****] but we only need the data before it for title
                            String[] description = { release.Description, "" };
                            if (release.Description.Contains("[imdb:"))
                            {
                                description    = release.Description.Split('[');
                                description[1] = "[" + description[1];
                            }
                            else
                            {
                                release.Title = (description[0].Trim() + "." + seasonep.Trim() + "." + releasedata.Trim('.')).Replace(' ', '.');
                            }

                            // if search is done for S0X than we dont want to put . between S0X and E0X
                            Match match = Regex.Match(releasedata, @"^E\d\d?");
                            if (seasonep.Length == 3 && match.Success)
                            {
                                release.Title = (description[0].Trim() + "." + seasonep.Trim() + releasedata.Trim('.')).Replace(' ', '.');
                            }

                            // add back imdb points to the description [imdb: 8.7]
                            release.Description = temp + " " + description[1];
                            release.Description = release.Description.Trim();
                            releases.Add(release);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }

            return(releases);
        }
Example #9
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);
        }
Example #10
0
        private async Task <IEnumerable <ReleaseInfo> > performRegularQuery(TorznabQuery query, string hebName = null)
        {
            var releases        = new List <ReleaseInfo>();
            var searchurls      = new List <string>();
            var searchUrl       = SearchUrl;
            var queryCollection = new NameValueCollection();
            var searchString    = query.GetQueryString();

            if (hebName != null)
            {
                searchString = hebName + " - עונה " + query.Season + " פרק " + query.Episode;
            }

            int categoryCounter = 1;

            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                searchUrl += "c" + categoryCounter.ToString() + "=" + cat + "&";
                categoryCounter++;
            }


            if (string.IsNullOrWhiteSpace(searchString))
            {
                searchUrl = SiteLink + "index.php?name=torrents";
            }
            else
            {
                var strEncoded = HttpUtility.UrlEncode(searchString, Encoding.GetEncoding("Windows-1255"));
                searchUrl += "text=" + strEncoded + "&category=0&search=1";
            }

            var data = await RequestStringWithCookiesAndRetry(searchUrl);

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

                int rowCount = 0;
                var rows     = dom["#collapseobj_module_17 > tr"];
                foreach (var row in rows)
                {
                    CQ qRow = row.Cq();
                    if (rowCount < 1 || qRow.Children().Count() != 9) //skip 1 row because there's an empty row
                    {
                        rowCount++;
                        continue;
                    }

                    release             = new ReleaseInfo();
                    release.Description = qRow.Find("td:nth-child(2) > a").Text();;

                    if (hebName != null)
                    {
                        release.Title = query.SearchTerm + " " + release.Description.Substring(release.Description.IndexOf(string.Format("S{0:D2}E{1:D2}", query.Season, int.Parse(query.Episode))));
                    }
                    else
                    {
                        const string DELIMITER = " | ";
                        release.Title = release.Description.Substring(release.Description.IndexOf(DELIMITER) + DELIMITER.Length);
                    }

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

                    int seeders, peers;
                    if (ParseUtil.TryCoerceInt(qRow.Find("td:nth-child(7) > div").Text(), out seeders))
                    {
                        release.Seeders = seeders;
                        if (ParseUtil.TryCoerceInt(qRow.Find("td:nth-child(8) > div").Text(), out peers))
                        {
                            release.Peers = peers + release.Seeders;
                        }
                    }

                    string fullSize = qRow.Find("td:nth-child(5) > div").Text();
                    release.Size = ReleaseInfo.GetBytes(fullSize);

                    release.Guid     = new Uri(qRow.Find("td:nth-child(2) > a").Attr("href"));
                    release.Link     = new Uri(SiteLink + qRow.Find("td:nth-child(3) > a").Attr("href"));
                    release.Comments = release.Guid;

                    string[] dateSplit  = qRow.Find("td:nth-child(2) > span.torrentstime").Text().Split(' ');
                    string   dateString = dateSplit[1] + " " + dateSplit[3];
                    release.PublishDate = DateTime.ParseExact(dateString, "dd-MM-yy HH:mm", CultureInfo.InvariantCulture);

                    string category = qRow.Find("script:nth-child(1)").Text();
                    int    index    = category.IndexOf("category=");
                    if (index == -1)
                    {
                        /// Other type
                        category = "17";
                    }
                    else
                    {
                        category = category.Substring(index + "category=".Length, 2);
                        if (category[1] == '\\')
                        {
                            category = category[0].ToString();
                        }
                    }

                    release.Category = MapTrackerCatToNewznab(category);

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

                    if (qRow.Find("img[src=\"/images/FL.png\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

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

            return(releases);
        }
Example #11
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            // This tracker only deals with full seasons so chop off the episode/season number if we have it D:
            if (!string.IsNullOrWhiteSpace(query.SearchTerm))
            {
                var splitindex = query.SearchTerm.LastIndexOf(' ');
                if (splitindex > -1)
                {
                    query.SearchTerm = query.SearchTerm.Substring(0, splitindex);
                }
            }

            var releases         = new List <ReleaseInfo>();
            var searchString     = query.SanitizedSearchTerm;
            var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);
            var response         = await RequestStringWithCookiesAndRetry(episodeSearchUrl);

            try
            {
                CQ  dom  = response.Content;
                var rows = dom[".torrents tr.torrent"];

                foreach (var row in rows)
                {
                    var qRow       = row.Cq();
                    var qTitleLink = qRow.Find("a.title").First();
                    var title      = qTitleLink.Text().Trim();

                    // Insert before the release info
                    var taidx = title.IndexOf('(');
                    var tbidx = title.IndexOf('[');

                    if (taidx == -1)
                    {
                        taidx = title.Length;
                    }

                    if (tbidx == -1)
                    {
                        tbidx = title.Length;
                    }
                    var titleSplit  = Math.Min(taidx, tbidx);
                    var titleSeries = title.Substring(0, titleSplit);
                    var releaseInfo = title.Substring(titleSplit);

                    // For each over each pipe deliminated name
                    foreach (var name in titleSeries.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
                    {
                        var release = new ReleaseInfo();

                        release.Title = (name + releaseInfo).Trim();
                        // Ensure the season is defined as this tracker only deals with full seasons
                        if (release.Title.IndexOf("Season") == -1)
                        {
                            // Insert before the release info
                            var aidx = release.Title.IndexOf('(');
                            var bidx = release.Title.IndexOf('[');

                            if (aidx == -1)
                            {
                                aidx = release.Title.Length;
                            }

                            if (bidx == -1)
                            {
                                bidx = release.Title.Length;
                            }

                            var insertPoint = Math.Min(aidx, bidx);
                            release.Title = release.Title.Substring(0, insertPoint) + "Season 1 " + release.Title.Substring(insertPoint);
                        }

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

                        release.Link = new Uri(SiteLink + qRow.Find(".peers a").First().Attr("href"));

                        release.Seeders = int.Parse(qRow.Find(".peers a").Get(0).InnerText);
                        release.Peers   = release.Seeders + int.Parse(qRow.Find(".peers a").Get(1).InnerText);

                        release.MinimumRatio = 1;

                        var size = qRow.Find(".size").First().Text();
                        release.Size = ReleaseInfo.GetBytes(size);

                        //22 Jul 15
                        var dateStr = qRow.Find(".added").First().Text().Replace("'", string.Empty);
                        if (dateStr.Split(' ')[0].Length == 1)
                        {
                            dateStr = "0" + dateStr;
                        }

                        if (string.Equals(dateStr, "yesterday", StringComparison.InvariantCultureIgnoreCase))
                        {
                            release.PublishDate = DateTime.Now.AddDays(-1);
                        }
                        else if (string.Equals(dateStr, "today", StringComparison.InvariantCultureIgnoreCase))
                        {
                            release.PublishDate = DateTime.Now;
                        }
                        else
                        {
                            release.PublishDate = DateTime.ParseExact(dateStr, "dd MMM yy", CultureInfo.InvariantCulture);
                        }

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

            return(releases);
        }
Example #12
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
            TimeZoneInfo.TransitionTime endTransition   = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
            TimeSpan delta = new TimeSpan(1, 0, 0);

            TimeZoneInfo.AdjustmentRule   adjustment  = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
            TimeZoneInfo romaniaTz = TimeZoneInfo.CreateCustomTimeZone("Romania Time", new TimeSpan(2, 0, 0), "(GMT+02:00) Romania Time", "Romania Time", "Romania Daylight Time", adjustments);

            var    releases = new List <ReleaseInfo>();
            string episodeSearchUrl;

            if (string.IsNullOrEmpty(query.GetQueryString()))
            {
                episodeSearchUrl = SearchUrl;
            }
            else
            {
                episodeSearchUrl = $"{SearchUrl}?search={HttpUtility.UrlEncode(query.GetQueryString())}&cat=0";
            }

            var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);

            try
            {
                CQ dom = results.Content;

                var rows = dom["#highlight > tbody > tr"];

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

                    var qRow  = row.Cq();
                    var qLink = qRow.Find("a.torrent_name_link").First();

                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800;
                    release.Title           = qLink.Attr("title");
                    if (!query.MatchQueryStringAND(release.Title))
                    {
                        continue;
                    }

                    release.Description = release.Title;
                    release.Guid        = new Uri(SiteLink + qLink.Attr("href").TrimStart('/'));
                    release.Comments    = release.Guid;
                    release.Link        = new Uri(SiteLink + qRow.Find("td.table_links > a").First().Attr("href").TrimStart('/'));
                    release.Category    = TvCategoryParser.ParseTvShowQuality(release.Title);

                    release.Seeders = ParseUtil.CoerceInt(qRow.Find("td.table_seeders").Text().Trim());
                    release.Peers   = ParseUtil.CoerceInt(qRow.Find("td.table_leechers").Text().Trim()) + release.Seeders;

                    var sizeStr = qRow.Find("td.table_size")[0].Cq().Text();
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

                    DateTime pubDateRomania;
                    var      dateString = qRow.Find("td.table_added").Text().Trim();
                    if (dateString.StartsWith("Today "))
                    {
                        pubDateRomania = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateString.Split(' ')[1]);
                    }
                    else if (dateString.StartsWith("Yesterday "))
                    {
                        pubDateRomania = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateString.Split(' ')[1]) - TimeSpan.FromDays(1);
                    }
                    else
                    {
                        pubDateRomania = DateTime.SpecifyKind(DateTime.ParseExact(dateString, "d-MMM-yyyy HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
                    }

                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(pubDateRomania, romaniaTz);
                    release.PublishDate = pubDateUtc.ToLocalTime();

                    var grabs = row.Cq().Find("td.table_snatch").Get(0).FirstChild.ToString();
                    release.Grabs = ParseUtil.CoerceInt(grabs);

                    if (row.Cq().Find("img[alt=\"100% Free\"]").Any())
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else if (row.Cq().Find("img[alt=\"50% Free\"]").Any())
                    {
                        release.DownloadVolumeFactor = 0.5;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

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

            return(releases);
        }
Example #13
0
        public static Page Get(String url)
        {
            try {
                if (url == null || url.Length > 100 || url.Length < 8)
                {
                    return(null);
                }
                Page page = new Page();
                page.url = url;


                CQ doc = CQ.CreateFromUrl(url);
                //Console.WriteLine(doc.Html());
                doc ["script"].Remove();
                doc ["style"].Remove();
                doc ["Script"].Remove();
                doc ["Style"].Remove();

                page.title = doc ["title"].Text();
                if (page.title == null)
                {
                    page.title = doc ["Title"].Text();
                }
                if (page.title == null)
                {
                    page.title = url;
                }
                page.title = page.title.Trim();
                if (page.title.Length < 2)
                {
                    page.title = url;
                }
                if (page.title.Length > 80)
                {
                    page.title = page.title.Substring(0, 80);
                }
                page.title = page.title.Replace("<", " ")
                             .Replace(">", " ").Replace("$", " ");

                page.description = doc ["meta[name='description']"].Attr("content");
                if (page.description == null)
                {
                    page.description = doc ["meta[name='Description']"].Attr("content");
                }
                if (page.description == null)
                {
                    page.description = "";
                }
                if (page.description.Length > 200)
                {
                    page.description = page.description.Substring(0, 200);
                }
                page.description = page.description.Replace("<", " ")
                                   .Replace(">", " ").Replace("$", " ");

                doc = CQ.Create(doc.Text().Replace("&lt;", "<")
                                .Replace("&gt;", ">"));
                doc ["script"].Remove();
                doc ["style"].Remove();
                doc ["Script"].Remove();
                doc ["Style"].Remove();

                String content = doc.Text().Trim();
                content = content.Replace("\r", " ")
                          .Replace("\n", " ")
                          .Replace(" ", " ")
                          .Replace("   ", " ")
                          .Replace("   ", " ")
                          .Replace("  ", " ")
                          .Replace("  ", " ").Trim();
                if (content.Length < 50)
                {
                    return(null);
                }
                if (content.Length > 5000)
                {
                    content = content.Substring(0, 5000);
                }

                page.content = ((content
                                 + " " + page.url
                                 + " " + page.description)
                                .Replace("<", " ")
                                .Replace(">", " ").Replace("$", " ")
                                .Replace(" ", " "));

                return(page);
            } catch (Exception ex) {
                Console.WriteLine(ex.ToString());
                return(null);
            }
        }
Example #14
0
        public void CharEncoding()
        {
            var res = CQ.Create("<div><span>x…</span></div>");

            Assert.AreEqual(res["div span"].Text(), "x" + (char)8230);
        }
Example #15
0
        private static async Task GetContent(Uri inputUrl, string outputFolder, bool isRecursive, int depth, bool isVerbose,
                                             bool allowDifferentDomain, string recursivePageName = "")
        {
            if (isRecursive && depth == -1)
            {
                return;
            }
            using (var client = new HttpClient())
            {
                HttpResponseMessage response = await client.GetAsync(inputUrl.OriginalString);

                if (isVerbose)
                {
                    Console.Write(_rm.GetString("DownloadingMessage") + inputUrl.OriginalString + "..." + "\n");
                }
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    string filepath;
                    if (inputUrl.Equals(_userInputUrl))
                    {
                        var fileName = "index.html";
                        filepath = Path.Combine(outputFolder, fileName);
                    }
                    else
                    {
                        Debugger.Launch();
                        filepath = Path.Combine(outputFolder, recursivePageName);
                    }
                    CQ dom = response.Content.ReadAsStringAsync().Result;
                    dom = await GetResources(inputUrl, dom, "img", "src", isVerbose, allowDifferentDomain, outputFolder);

                    dom = await GetResources(inputUrl, dom, "link[href]", "href", isVerbose, allowDifferentDomain, outputFolder);

                    dom = await GetResources(inputUrl, dom, "script[src]", "src", isVerbose, allowDifferentDomain, outputFolder);

                    if (isRecursive)
                    {
                        foreach (var link in dom["a[href]"])
                        {
                            Debugger.Launch();
                            Uri url = new Uri(link.Attributes.GetAttribute("href"), UriKind.RelativeOrAbsolute);
                            if (!url.IsAbsoluteUri)
                            {
                                url = new Uri(inputUrl, url.OriginalString);
                            }
                            if (IsSameDomain(inputUrl, url) || allowDifferentDomain)
                            {
                                var
                                    pageName = Path.GetFileName(url.AbsolutePath);
                                if (pageName.IsNullOrEmpty())
                                {
                                    continue;
                                }
                                Debugger.Launch();
                                var outputFolderNew = outputFolder +
                                                      inputUrl.AbsolutePath.Replace("/" + pageName, "");
                                pageName = pageName.Replace(".html", "").Replace(".htm", "");
                                pageName = pageName + ".html";

                                await GetContent(url, outputFolderNew, true, depth - 1, isVerbose,
                                                 allowDifferentDomain, pageName);

                                link.Attributes.SetAttribute("href", url.OriginalString.Replace(url.Host, "/"));
                            }
                        }
                    }
                    var fileContent = dom.Render();
                    File.WriteAllText(filepath, string.Empty);
                    var isDir = (File.GetAttributes(filepath) & FileAttributes.Directory) == FileAttributes.Directory;
                    if (isDir)
                    {
                        filepath = Path.Combine(filepath, "index.html");
                    }
                    File.WriteAllText(filepath, fileContent);
                }
            }
        }
Example #16
0
        /// <summary>
        /// Manage scripts.
        /// </summary>
        ///
        /// <param name="cqDoc">
        /// The cq document.
        /// </param>
        /// <param name="viewPage">
        /// The view page.
        /// </param>
        /// <param name="viewContext">
        /// The active view context
        /// </param>


        private void ManageScripts(CQ cqDoc, WebViewPage viewPage, ViewContext viewContext) {
            ScriptManager mgr = new ScriptManager(new ScriptEnvironment
            {
                  LibraryPath = LibraryPath,
                  RelativePathRoot =viewContext.RequestContext.HttpContext.Request.AppRelativeCurrentExecutionFilePath,
                  MapPath = viewContext.RequestContext.HttpContext.Server.MapPath
            });

            mgr.Options = Options;

            mgr.ResolveScriptDependencies(cqDoc);
            
        }
Example #17
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.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);
        }
Example #18
0
 private void ManageScripts(CQ cqDoc, WebViewPage viewPage) {
     ScriptManager mgr = new ScriptManager();
     mgr.Options = Options;
     mgr.LibraryPath = LibraryPath;
     mgr.ResolveScriptDependencies(cqDoc);
     
 }
Example #19
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();

            //  replace any space, special char, etc. with % (wildcard)
            Regex ReplaceRegex = new Regex("[^a-zA-Z0-9]+");

            searchString = ReplaceRegex.Replace(searchString, "%");

            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("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;

            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.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.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");
                    if (qLink.Length != 0) // newbie users don't see DL links
                    {
                        release.Link = new Uri(qLink.Attr("href"));
                    }
                    else
                    {
                        // use comments link as placeholder
                        // null causes errors during export to torznab
                        // skipping the release prevents newbie users from adding the tracker (empty result)
                        release.Link = release.Comments;
                    }

                    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;
                    release.Grabs   = ParseUtil.CoerceLong(connections[2].Trim());

                    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);

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

                    var ULFactorImg = qRow.Find("img[alt*=\"x Multiplier Torrent\"]");
                    if (ULFactorImg.Length >= 1)
                    {
                        release.UploadVolumeFactor = ParseUtil.CoerceDouble(ULFactorImg.Attr("alt").Split('x')[0]);
                    }
                    else
                    {
                        release.UploadVolumeFactor = 1;
                    }

                    qTitleLink.Remove();
                    release.Description = qRow.Find("td:eq(1)").Text();

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

            return(releases);
        }
Example #20
0
        /// <summary>
        /// Execute our search query
        /// </summary>
        /// <param name="query">Query</param>
        /// <returns>Releases</returns>
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases       = new List <ReleaseInfo>();
            var torrentRowList = new List <CQ>();
            var searchTerm     = query.GetQueryString();
            var searchUrl      = SearchUrl;
            int nbResults      = 0;
            int pageLinkCount  = 0;

            // Check cache first so we don't query the server (if search term used or not in dev mode)
            if (!DevMode && !string.IsNullOrEmpty(searchTerm))
            {
                lock (cache)
                {
                    // Remove old cache items
                    CleanCache();

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

            // Build our query
            var request = buildQuery(searchTerm, query, searchUrl);

            // Getting results & Store content
            WebClientStringResult results = await queryExec(request);

            fDom = results.Content;

            try
            {
                // Find torrent rows
                var firstPageRows = findTorrentRows();

                // Add them to torrents list
                torrentRowList.AddRange(firstPageRows.Select(fRow => fRow.Cq()));

                // Check if there are pagination links at bottom
                Boolean pagination = (fDom[".pager_align > a"].Length != 0);

                // If pagination available
                if (pagination)
                {
                    // Calculate numbers of pages available for this search query (Based on number results and number of torrents on first page)
                    pageLinkCount = ParseUtil.CoerceInt(Regex.Match(fDom[".pager_align > a:not(:last-child)"].Last().Attr("href").ToString(), @"\d+").Value) + 1;

                    // Calculate average number of results (based on torrents rows lenght on first page)
                    nbResults = firstPageRows.Count() * pageLinkCount;
                }
                else
                {
                    // Check if we have a minimum of one result
                    if (firstPageRows.Length >= 1)
                    {
                        // Retrieve total count on our alone page
                        nbResults     = firstPageRows.Count();
                        pageLinkCount = 1;
                    }
                    else
                    {
                        output("\nNo result found for your query, please try another search term ...\n", "info");
                        // No result found for this query
                        return(releases);
                    }
                }
                output("\nFound " + nbResults + " result(s) (+/- " + firstPageRows.Length + ") in " + pageLinkCount + " page(s) for this query !");
                output("\nThere are " + firstPageRows.Length + " results on the first page !");

                // If we have a term used for search and pagination result superior to one
                if (!string.IsNullOrWhiteSpace(query.GetQueryString()) && pageLinkCount > 1)
                {
                    // Starting with page #2
                    for (int i = 2; i <= Math.Min(Int32.Parse(ConfigData.Pages.Value), pageLinkCount); i++)
                    {
                        output("\nProcessing page #" + i);

                        // Request our page
                        latencyNow();

                        // Build our query
                        var pageRequest = buildQuery(searchTerm, query, searchUrl, (i - 1));

                        // Getting results & Store content
                        WebClientStringResult pageResults = await queryExec(pageRequest);

                        // Assign response
                        fDom = pageResults.Content;

                        // Process page results
                        var additionalPageRows = findTorrentRows();

                        // Add them to torrents list
                        torrentRowList.AddRange(additionalPageRows.Select(fRow => fRow.Cq()));
                    }
                }
                else
                {
                    // No search term, maybe testing... so registring passkey for future uses
                    string         infosData    = firstPageRows.First().Find("td:eq(2) > a").Attr("href");
                    IList <string> infosList    = infosData.Split('&').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
                    IList <string> infosTracker = infosList.Select(s => s.Split(new[] { '=' }, 2)[1].Trim()).ToList();

                    output("\nStoring Passkey for future uses... \"" + infosTracker[2] + "\"");
                    ConfigData.PassKey.Value = infosTracker[2];
                }

                // Loop on results
                foreach (CQ tRow in torrentRowList)
                {
                    output("\n=>> Torrent #" + (releases.Count + 1));

                    // ID
                    string row = tRow.Html().ToString();
                    int    id  = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(1) > a").Attr("href").ToString(), @"\d+").Value);
                    output("ID: " + id);

                    // Release Name
                    string name = tRow.Find("td:eq(1) > a").Attr("title").ToString();
                    output("Release: " + name);

                    // Category
                    string         infosDataCategory = firstPageRows.First().Find("td:eq(0) > a").Attr("href");
                    IList <string> infosListCategory = infosDataCategory.Split('&').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
                    IList <string> infosCategory     = infosListCategory.Select(s => s.Split(new[] { '=' }, 2)[0].Trim()).ToList();
                    string         categoryID        = infosCategory.Last().TrimStart('c');
                    output("Category: " + MapTrackerCatToNewznab(categoryID) + " (" + categoryID + ")");

                    // Seeders
                    int seeders = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(6)").Text(), @"\d+").Value);
                    output("Seeders: " + seeders);

                    // Leechers
                    int leechers = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(7)").Text(), @"\d+").Value);
                    output("Leechers: " + leechers);

                    // Completed
                    int completed = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(5)").Text(), @"\d+").Value);
                    output("Completed: " + completed);

                    // Size
                    string sizeStr = tRow.Find("td:eq(4)").Text().Trim().Replace("Go", "gb").Replace("Mo", "mb").Replace("Ko", "kb");
                    long   size    = ReleaseInfo.GetBytes(sizeStr);
                    output("Size: " + sizeStr + " (" + size + " bytes)");

                    // Health
                    int percent = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(8) > img").Attr("alt").ToString(), @"\d+").Value);
                    output("Health: " + percent + "%");

                    // Publish DateToString
                    //var date = agoToDate(null);
                    int      timestamp = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(1)").Attr("data-added").ToString(), @"\d+").Value);
                    DateTime date      = unixTimeStampToDateTime(timestamp);
                    output("Released on: " + date.ToLocalTime() + " (TS >> " + timestamp + ")");

                    // Torrent Details URL
                    Uri detailsLink = new Uri(TorrentDescriptionUrl + id);
                    output("Details: " + detailsLink.AbsoluteUri);

                    // Torrent Comments URL
                    Uri commentsLink = new Uri(TorrentCommentUrl + id);
                    output("Comments Link: " + commentsLink.AbsoluteUri);

                    // Torrent Download URL
                    Uri downloadLink = new Uri(TorrentDownloadUrl.Replace("{id}", id.ToString()).Replace("{passkey}", ConfigData.PassKey.Value));
                    output("Download Link: " + downloadLink.AbsoluteUri);

                    // Building release infos
                    var release = new ReleaseInfo();
                    release.Category        = MapTrackerCatToNewznab(categoryID.ToString());
                    release.Title           = name;
                    release.Seeders         = seeders;
                    release.Peers           = seeders + leechers;
                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 345600;
                    release.PublishDate     = date;
                    release.Size            = size;
                    release.Guid            = detailsLink;
                    release.Comments        = commentsLink;
                    release.Link            = downloadLink;
                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
            }

            // Return found releases
            return(releases);
        }
        public async Task <IHttpActionResult> CreateOneFromSteamAppId(int appId, bool fillExisted = false)
        {
            if (appId <= 0)
            {
                return(this.BadRequest(nameof(appId), Errors.Invalid));
            }
            var gamePoint = await _dbContext.NormalPoints.Where(p => p.SteamAppId == appId).SingleOrDefaultAsync();

            if (fillExisted)
            {
                if (!User.IsInRole(KeylolRoles.Operator))
                {
                    return(Unauthorized());
                }
                if (gamePoint == null)
                {
                    return(NotFound());
                }
            }
            else if (gamePoint != null)
            {
                return(this.BadRequest(nameof(appId), Errors.Duplicate));
            }
            else
            {
                gamePoint = _dbContext.NormalPoints.Create();
                _dbContext.NormalPoints.Add(gamePoint);
            }

            var cookieContainer = new CookieContainer();

            cookieContainer.Add(new Uri("http://store.steampowered.com/"), new Cookie("birthtime", "-473410799"));
            using (var httpClientHandler = new HttpClientHandler {
                CookieContainer = cookieContainer
            })
                using (var httpClient = new HttpClient(httpClientHandler)
                {
                    Timeout = TimeSpan.FromSeconds(30)
                })
                {
                    Task <HttpResponseMessage> picsAwaiter = null;
                    if (!fillExisted)
                    {
                        picsAwaiter = httpClient.GetAsync($"https://steampics-mckay.rhcloud.com/info?apps={appId}");
                    }
                    var response =
                        await httpClient.GetAsync($"http://store.steampowered.com/app/{appId}/?l=english&cc=us");

                    response.EnsureSuccessStatusCode();
                    Config.OutputFormatter = OutputFormatters.HtmlEncodingNone;
                    var dom      = CQ.Create(await response.Content.ReadAsStringAsync());
                    var navTexts = dom[".game_title_area .blockbg a"];
                    if (!navTexts.Any() ||
                        (navTexts[0].InnerText != "All Games" && navTexts[0].InnerText != "All Hardware"))
                    {
                        return(this.BadRequest(nameof(appId), Errors.SteamAppNotSupported));
                    }
                    if (dom[".game_area_dlc_bubble"].Any())
                    {
                        return(this.BadRequest(nameof(appId), Errors.SteamDlcNotSupported));
                    }
                    if (!fillExisted)
                    {
                        gamePoint.SteamAppId    = appId;
                        gamePoint.PreferredName = PreferredNameType.English;
                        gamePoint.Type          = navTexts[0].InnerText != "All Games"
                        ? NormalPointType.Game
                        : NormalPointType.Hardware;
                    }
                    if (string.IsNullOrWhiteSpace(gamePoint.BackgroundImage))
                    {
                        var backgroundResponse = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head,
                                                                                                   $"http://steamcdn-a.akamaihd.net/steam/apps/{appId}/page_bg_generated.jpg"));

                        if (backgroundResponse.IsSuccessStatusCode)
                        {
                            gamePoint.BackgroundImage = $"keylol://steam/app-backgrounds/{appId}";
                        }
                        else
                        {
                            var screenshots = dom[".highlight_strip_screenshot img"];
                            if (screenshots.Any())
                            {
                                var match = Regex.Match(screenshots[0].Attributes["src"], @"ss_([^\/]*)\.\d+x\d+\.jpg");
                                if (match.Success)
                                {
                                    gamePoint.BackgroundImage =
                                        $"keylol://steam/app-backgrounds/{appId}-{match.Groups[1].Value}";
                                }
                            }
                        }
                    }
                    if (string.IsNullOrWhiteSpace(gamePoint.CoverImage))
                    {
                        gamePoint.CoverImage = $"keylol://steam/app-capsules/{appId}";
                    }
                    gamePoint.Description = dom[".game_description_snippet"].Text().Trim();
                    var genreNames     = new List <string>();
                    var tags           = dom[".popular_tags a.app_tag"].Select(child => child.InnerText.Trim()).Take(5).ToList();
                    var developerNames = new List <string>();
                    var publisherNames = new List <string>();
                    foreach (var child in dom[".game_details .details_block"].First().Find("b"))
                    {
                        var key    = child.InnerText.Trim();
                        var values = new List <string>();
                        if (string.IsNullOrWhiteSpace(child.NextSibling.NodeValue))
                        {
                            var current = child;
                            do
                            {
                                current = current.NextElementSibling;
                                values.Add(current.InnerText.Trim());
                            } while (current.NextSibling.NodeType == NodeType.TEXT_NODE &&
                                     current.NextSibling.NodeValue.Trim() == ",");
                        }
                        else
                        {
                            values.Add(child.NextSibling.NodeValue.Trim());
                        }
                        if (!values.Any())
                        {
                            continue;
                        }
                        switch (key)
                        {
                        case "Title:":
                            if (!fillExisted)
                            {
                                gamePoint.EnglishName = values[0];
                            }
                            break;

                        case "Genre:":
                            genreNames.AddRange(values);
                            break;

                        case "Developer:":
                        case "Manufacturer:":
                            developerNames.AddRange(values);
                            break;

                        case "Publisher:":
                            publisherNames.AddRange(values);
                            break;

                        case "Release Date:":
                            DateTime releaseDate;
                            gamePoint.ReleaseDate = DateTime.TryParse(values[0], out releaseDate)
                                ? releaseDate
                                : Helpers.DateTimeFromTimeStamp(0);
                            break;
                        }
                    }
                    if (!fillExisted)
                    {
                        gamePoint.IdCode = await GenerateIdCode(gamePoint.EnglishName);
                    }
                    var genrePointsMap        = new Dictionary <string, Models.NormalPoint>();
                    var manufacturerPointsMap = new Dictionary <string, Models.NormalPoint>();
                    foreach (var pair in genreNames.Concat(tags).Distinct()
                             .Select(n => new KeyValuePair <NormalPointType, string>(NormalPointType.Genre, n))
                             .Concat(developerNames.Concat(publisherNames).Distinct()
                                     .Select(n => new KeyValuePair <NormalPointType, string>(NormalPointType.Manufacturer, n))))
                    {
                        var relatedPoint = await _dbContext.NormalPoints
                                           .Where(p => p.Type == pair.Key && p.SteamStoreNames.Select(n => n.Name).Contains(pair.Value))
                                           .SingleOrDefaultAsync();

                        if (relatedPoint == null)
                        {
                            relatedPoint             = _dbContext.NormalPoints.Create();
                            relatedPoint.EnglishName = pair.Value;
                            var name = await _dbContext.SteamStoreNames
                                       .Where(n => n.Name == pair.Value).SingleOrDefaultAsync();

                            if (name == null)
                            {
                                name      = _dbContext.SteamStoreNames.Create();
                                name.Name = pair.Value;
                                _dbContext.SteamStoreNames.Add(name);
                                await _dbContext.SaveChangesAsync();
                            }
                            relatedPoint.SteamStoreNames = new[] { name };
                            relatedPoint.Type            = pair.Key;
                            relatedPoint.PreferredName   = PreferredNameType.English;
                            relatedPoint.IdCode          = await GenerateIdCode(pair.Value);

                            _dbContext.NormalPoints.Add(relatedPoint);
                            await _dbContext.SaveChangesAsync();
                        }
                        switch (pair.Key)
                        {
                        case NormalPointType.Genre:
                            genrePointsMap[pair.Value] = relatedPoint;
                            break;

                        case NormalPointType.Manufacturer:
                            manufacturerPointsMap[pair.Value] = relatedPoint;
                            break;
                        }
                    }
                    if (fillExisted)
                    {
                        gamePoint.MajorPlatformPoints.Clear();
                        gamePoint.GenrePoints.Clear();
                        gamePoint.TagPoints.Clear();
                        gamePoint.DeveloperPoints.Clear();
                        gamePoint.PublisherPoints.Clear();
                    }
                    else
                    {
                        gamePoint.MajorPlatformPoints = new List <Models.NormalPoint>();
                        gamePoint.GenrePoints         = new List <Models.NormalPoint>();
                        gamePoint.TagPoints           = new List <Models.NormalPoint>();
                        gamePoint.DeveloperPoints     = new List <Models.NormalPoint>();
                        gamePoint.PublisherPoints     = new List <Models.NormalPoint>();
                    }
                    gamePoint.MajorPlatformPoints.Add(
                        await _dbContext.NormalPoints.SingleAsync(p => p.IdCode == "STEAM"));
                    gamePoint.GenrePoints.AddRange(genreNames.Select(n => genrePointsMap[n]).ToList());
                    gamePoint.TagPoints.AddRange(tags.Select(n => genrePointsMap[n]).ToList());
                    gamePoint.DeveloperPoints.AddRange(developerNames.Select(n => manufacturerPointsMap[n]).ToList());
                    gamePoint.PublisherPoints.AddRange(publisherNames.Select(n => manufacturerPointsMap[n]).ToList());
                    if (!fillExisted)
                    {
                        response = await picsAwaiter;
                        response.EnsureSuccessStatusCode();
                        var root = JObject.Parse(await response.Content.ReadAsStringAsync());
                        if ((bool)root["success"])
                        {
                            gamePoint.AvatarImage =
                                $"keylol://steam/app-icons/{appId}-{(string) root["apps"][appId.ToString()]["common"]["icon"]}";
                        }
                    }
                    await _dbContext.SaveChangesAsync();

                    return(Created($"normal-point/{gamePoint.Id}", new NormalPointDto(gamePoint, false, true)
                    {
                        Description = gamePoint.Description,
                        SteamAppId = gamePoint.SteamAppId,
                        DisplayAliases = gamePoint.DisplayAliases,
                        CoverImage = gamePoint.CoverImage,
                        ReleaseDate = gamePoint.ReleaseDate,
                        DeveloperPoints = gamePoint.DeveloperPoints.Select(p => new NormalPointDto(p, true)).ToList(),
                        PublisherPoints = gamePoint.PublisherPoints.Select(p => new NormalPointDto(p, true)).ToList(),
                        SeriesPoints = gamePoint.SeriesPoints.Select(p => new NormalPointDto(p, true)).ToList(),
                        GenrePoints = gamePoint.GenrePoints.Select(p => new NormalPointDto(p, true)).ToList(),
                        TagPoints = gamePoint.TagPoints.Select(p => new NormalPointDto(p, true)).ToList(),
                        MajorPlatformPoints =
                            gamePoint.MajorPlatformPoints.Select(p => new NormalPointDto(p, true)).ToList(),
                        MinorPlatformPoints =
                            gamePoint.MinorPlatformPoints.Select(p => new NormalPointDto(p, true)).ToList()
                    }));
                }
        }
Example #22
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();

            // search in normal + gems view
            foreach (var view in new string[] { "0", "1" })
            {
                var queryCollection = new NameValueCollection();

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

                foreach (var cat in MapTorznabCapsToTrackers(query))
                {
                    queryCollection.Add(string.Format("c{0}", cat), "1");
                }

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

                var results = await RequestStringWithCookiesAndRetry(searchUrl);

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

                    results = await RequestStringWithCookiesAndRetry(searchUrl);
                }

                try
                {
                    CQ  dom  = results.Content;
                    var rows = dom["#torrentBrowse > table > tbody > tr"];
                    foreach (var row in rows.Skip(1))
                    {
                        var release = new ReleaseInfo();
                        CQ  qRow    = row.Cq();

                        release.MinimumRatio    = 0;
                        release.MinimumSeedTime = 2 * 24 * 60 * 60;

                        var qLink = qRow.Find("a[title][href^=\"details.php?id=\"]");
                        release.Title    = qLink.Attr("title");
                        release.Guid     = new Uri(SiteLink + qLink.Attr("href").TrimStart('/'));
                        release.Comments = release.Guid;

                        qLink        = qRow.Children().ElementAt(3).Cq().Children("a").First();
                        release.Link = new Uri(string.Format("{0}{1}", SiteLink, qLink.Attr("href")));

                        var catUrl = qRow.Children().ElementAt(0).FirstElementChild.Cq().Attr("href");
                        var catNum = catUrl.Split(new char[] { '=', '&' })[2].Replace("c", "");
                        release.Category = MapTrackerCatToNewznab(catNum);

                        var dateString = qRow.Children().ElementAt(6).Cq().Text().Trim();
                        if (dateString.Contains("ago"))
                        {
                            release.PublishDate = DateTimeUtil.FromTimeAgo(dateString);
                        }
                        else
                        {
                            release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture);
                        }

                        var sizeStr = qRow.Children().ElementAt(7).Cq().Text().Split(new char[] { '/' })[0];
                        release.Size = ReleaseInfo.GetBytes(sizeStr);

                        release.Seeders = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Split(new char[] { '/' })[0].Trim());
                        release.Peers   = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Split(new char[] { '/' })[1].Trim()) + release.Seeders;
                        release.Files   = ParseUtil.CoerceLong(qRow.Find("td:nth-child(5)").Text());
                        release.Grabs   = ParseUtil.CoerceLong(qRow.Find("a[href^=\"snatches.php?id=\"]").Text().Split(' ')[0]);

                        release.DownloadVolumeFactor = 0;
                        release.UploadVolumeFactor   = 1;

                        var desc = qRow.Find("td:nth-child(2)");
                        desc.Find("a").Remove();
                        desc.Find("small").Remove(); // Remove release name (if enabled in the user cp)
                        release.Description = desc.Text().Trim(new char[] { '-', ' ' });

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

            return(releases);
        }
Example #23
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();
            var pairs        = new List <KeyValuePair <string, string> >();

            pairs.Add(new KeyValuePair <string, string>("nyit_sorozat_resz", "true"));
            pairs.Add(new KeyValuePair <string, string>("miben", "name"));
            pairs.Add(new KeyValuePair <string, string>("tipus", "kivalasztottak_kozott"));
            pairs.Add(new KeyValuePair <string, string>("submit.x", "1"));
            pairs.Add(new KeyValuePair <string, string>("submit.y", "1"));
            pairs.Add(new KeyValuePair <string, string>("submit", "Ok"));
            pairs.Add(new KeyValuePair <string, string>("mire", searchString));

            var cats = MapTorznabCapsToTrackers(query);

            if (cats.Count == 0)
            {
                cats = GetAllTrackerCategories();
            }

            foreach (var lcat in LanguageCats)
            {
                if (!configData.Hungarian.Value)
                {
                    cats.Remove(lcat + "_hun");
                }
                if (!configData.English.Value)
                {
                    cats.Remove(lcat);
                }
            }

            foreach (var cat in cats)
            {
                pairs.Add(new KeyValuePair <string, string>("kivalasztott_tipus[]", cat));
            }

            var results = await PostDataWithCookiesAndRetry(SearchUrl, pairs);

            try
            {
                CQ dom = results.Content;

                ReleaseInfo release;
                var         rows = dom[".box_torrent_all"].Find(".box_torrent");

                foreach (var row in rows)
                {
                    CQ qRow = row.Cq();

                    var key = dom ["link[rel=alternate]"].First().Attr("href").Split('=').Last();

                    release = new ReleaseInfo();
                    var torrentTxt = qRow.Find(".torrent_txt, .torrent_txt2").Find("a").Get(0);
                    //if (torrentTxt == null) continue;
                    release.Title                = torrentTxt.GetAttribute("title");
                    release.Description          = qRow.Find("div.siterank").Text();
                    release.MinimumRatio         = 1;
                    release.MinimumSeedTime      = 172800;
                    release.DownloadVolumeFactor = 0;
                    release.UploadVolumeFactor   = 1;

                    string downloadLink = SiteLink + torrentTxt.GetAttribute("href");
                    string downloadId   = downloadLink.Substring(downloadLink.IndexOf("&id=") + 4);

                    release.Link     = new Uri(SiteLink.ToString() + "torrents.php?action=download&id=" + downloadId + "&key=" + key);
                    release.Comments = new Uri(SiteLink.ToString() + "torrents.php?action=details&id=" + downloadId);
                    release.Guid     = new Uri(release.Comments.ToString() + "#comments");;
                    release.Seeders  = ParseUtil.CoerceInt(qRow.Find(".box_s2").Find("a").First().Text());
                    release.Peers    = ParseUtil.CoerceInt(qRow.Find(".box_l2").Find("a").First().Text()) + release.Seeders;
                    var imdblink = qRow.Find("a[href*=\".imdb.com/title\"]").Attr("href");
                    release.Imdb = ParseUtil.GetLongFromString(imdblink);
                    var banner = qRow.Find("img.infobar_ico").Attr("onmouseover");
                    if (banner != null)
                    {
                        Regex BannerRegEx = new Regex(@"mutat\('(.*?)', '", RegexOptions.Compiled);
                        var   BannerMatch = BannerRegEx.Match(banner);
                        var   bannerurl   = BannerMatch.Groups[1].Value;
                        release.BannerUrl = new Uri(bannerurl);
                    }
                    release.PublishDate = DateTime.Parse(qRow.Find(".box_feltoltve2").Get(0).InnerHTML.Replace("<br />", " "), CultureInfo.InvariantCulture);
                    string[] sizeSplit = qRow.Find(".box_meret2").Get(0).InnerText.Split(' ');
                    release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
                    string catlink = qRow.Find("a:has(img[class='categ_link'])").First().Attr("href");
                    string cat     = ParseUtil.GetArgumentFromQueryString(catlink, "tipus");
                    release.Category = MapTrackerCatToNewznab(cat);

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

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

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

            queryCollection.Add("incldead", "1");
            queryCollection.Add("rel_type", "0"); // Alle

            if (query.ImdbID != null)
            {
                queryCollection.Add("searchin", "imdb");
                queryCollection.Add("search", query.ImdbID);
            }
            else
            {
                queryCollection.Add("searchin", "title");

                if (!string.IsNullOrWhiteSpace(searchString))
                {
                    // use AND+wildcard operator to avoid getting to many useless results
                    var searchStringArray = Regex.Split(searchString.Trim(), "[ _.-]+", RegexOptions.Compiled).ToList();
                    searchStringArray = searchStringArray.Where(x => x.Length >= 3).ToList();                                                      //  remove words with less than 3 characters
                    searchStringArray = searchStringArray.Where(x => !new string[] { "der", "die", "das", "the" }.Contains(x.ToLower())).ToList(); //  remove words with less than 3 characters
                    searchStringArray = searchStringArray.Select(x => "+" + x + "*").ToList();                                                     // add AND operators+wildcards
                    var searchStringFinal = String.Join(" ", searchStringArray);
                    queryCollection.Add("search", searchStringFinal);
                }
            }
            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                queryCollection.Add("c" + cat, "1");
            }

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

            var results = await RequestStringWithCookiesAndRetry(searchUrl);

            if (results.IsRedirect)
            {
                await ApplyConfiguration(null);

                results = await RequestStringWithCookiesAndRetry(searchUrl);
            }

            try
            {
                CQ  dom             = results.Content;
                var rows            = dom["table.torrent_table > tbody > tr"];
                var globalFreeleech = dom.Find("legend:contains(\"Freeleech\")+ul > li > b:contains(\"Freeleech\")").Any();
                foreach (var row in rows.Skip(1))
                {
                    var release = new ReleaseInfo();
                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 96 * 60 * 60;

                    var qRow = row.Cq();

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

                    var qLink = row.ChildElements.ElementAt(2).FirstElementChild.Cq();
                    release.Link = new Uri(SiteLink + qLink.Attr("href"));
                    var torrentId = qLink.Attr("href").Split('=').Last();

                    var descCol      = row.ChildElements.ElementAt(1);
                    var qCommentLink = descCol.FirstElementChild.Cq();
                    var torrentTag   = descCol.Cq().Find("span.torrent-tag");
                    var torrentTags  = torrentTag.Elements.Select(x => x.InnerHTML).ToList();
                    release.Title       = qCommentLink.Attr("title");
                    release.Description = String.Join(", ", torrentTags);
                    release.Comments    = new Uri(SiteLink + qCommentLink.Attr("href").Replace("&hit=1", ""));
                    release.Guid        = release.Comments;

                    var      torrent_details = descCol.Cq().Find(".torrent_details").Get(0);
                    var      rawDateStr      = torrent_details.ChildNodes.ElementAt(torrent_details.ChildNodes.Length - 3).Cq().Text();
                    var      dateStr         = rawDateStr.Trim().Replace("von", "").Trim();
                    DateTime dateGerman;
                    if (dateStr.StartsWith("Heute "))
                    {
                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStr.Split(' ')[1]);
                    }
                    else if (dateStr.StartsWith("Gestern "))
                    {
                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStr.Split(' ')[1]) - TimeSpan.FromDays(1);
                    }
                    else
                    {
                        dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
                    }

                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
                    release.PublishDate = pubDateUtc.ToLocalTime();

                    var imdbLink = descCol.Cq().Find("a[href*=\"&searchin=imdb\"]");
                    if (imdbLink.Any())
                    {
                        release.Imdb = ParseUtil.GetLongFromString(imdbLink.Attr("href"));
                    }

                    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(7)").Text();
                    release.Grabs = ParseUtil.CoerceInt(grabs);

                    if (globalFreeleech)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else if (qRow.Find("span.torrent-tag-free").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

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

            return(releases);
        }
Example #25
0
        public void AttributeEqualsSelector()
        {
            CQ res = Dom.Find("span[name=badge_span_bronze]");

            Assert.AreEqual("13", res[0].InnerHTML, "InnerHtml of element id=badge_span_bronze did not match");
        }
Example #26
0
 /// <summary>
 /// Return a CQ object, treating the HTML as a complete document
 /// </summary>
 public CQ GetDocument()
 {
     return(CQ.CreateDocument(Html));
 }
Example #27
0
        /// <summary>
        /// Resolve all script dependencies in the bound CQ document. Scripts that cotain a "data-
        /// location='head'" attribute will be moved to the head.
        /// </summary>
        ///
        /// <param name="doc">
        /// The document to resolve.
        /// </param>

        public void ResolveScriptDependencies(CQ doc)
        {
           

            string scriptSelector = "script[src][type='text/javascript'], script[src]:not([type]), link[type='text/css']";

            CQ scripts = doc[scriptSelector];

            if (scripts.Length == 0)
            {
                return;
            }
            
            // move scripts first
            // TODO: Optimize using a query caching mechanism so
                
            foreach (var item in scripts.Filter("[data-moveto]"))
            {
                var target = doc.Select(item["data-moveto"]);
                if (target.Length>0) {
                    target.First().Append(item);
                    item.RemoveAttribute("data-moveto");
                }
            }
            

            // resolve dependencies

            ScriptCollection coll = new ScriptCollection(ScriptEnvironment);
            coll.Options= Options;

            // identify the insertion point for the script bundle. AddFromCq returns the first script with dependencies,
            // so scripts should be added right before that one. Otherwise they should be added
            // at the end of head.
            
            var firstScriptEl = coll.AddFromCq(scripts);
            CQ firstScript=null;

            if (firstScriptEl != null)
            {
                firstScript = firstScriptEl.Cq();
            }
           
            string bundleUrl;
            List<ScriptRef> dependencies = coll.GetDependencies()
                .Where(item=>!coll.Contains(item))
                .ToList();

            // Now add scripts directly for dependencies marked as NoCombine.

            
            var inlineScripts = Options.HasFlag(ViewEngineOptions.NoBundle) ?
                dependencies :
                dependencies.Where(item => item.NoCombine);


            foreach (var item in inlineScripts)
            {
                var script = GetScriptHtml(item.Path, item.ScriptHash);
                if (firstScript != null)
                {
                    firstScript.Before(script);
                }
                else
                {
                    firstScript = script;
                    doc["body"].Append(script);
                }
           }

            // Before creating the bundle, remove any duplicates of the same script on the page


            if (!Options.HasFlag(ViewEngineOptions.NoBundle))
            {

                bool hasBundle = Bundles.TryGetValue(coll, out bundleUrl);

                if (hasBundle)
                {
                    // when nocache is set, we will regenerate the bundle, but not change the script ID. The v=
                    // flag will be changed by BundleTable. 
                    
                    if (Options.HasFlag(ViewEngineOptions.NoCache))
                    {
                        string removeUrl = "~" + bundleUrl.Before("?");
                        BundleTable.Bundles.Remove(BundleTable.Bundles.GetBundleFor(removeUrl));
                        hasBundle = false;
                        ScriptID++;
                        
                        // this code attempts to un-cache the bundle, it doesn't work.
                        // leaving it here until some permanent solution is found as a reminder
                        // 
                        // http://stackoverflow.com/questions/12317391/how-to-force-bundlecollection-to-flush-cached-script-bundles-in-mvc4
                        // 
                        //var bundleList = BundleTable.Bundles.ToList();
                        //BundleTable.Bundles.Clear();
                        //BundleTable.Bundles.ResetAll();
                        //BundleTable.EnableOptimizations = false;

                        //foreach (var oldBundle in bundleList)
                        //{
                        //    BundleTable.Bundles.Add(oldBundle);
                        //}

                    }
                }
                else
                {
                    ScriptID++;
                }

                if (!hasBundle)
                {
                    var activeDependencies = dependencies.Where(item => !item.NoCombine).ToList();
                    if (activeDependencies.Count > 0)
                    {
                        string bundleAlias = "~/cqbundle" + ScriptID;
                        var bundle = GetScriptBundle(bundleAlias);



                        foreach (var item in activeDependencies)
                        {
                            bundle.Include(item.Path);
                        }


                        BundleTable.Bundles.Add(bundle);
                        if (HttpContext.Current != null)
                        {
                            bundleUrl = BundleTable.Bundles.ResolveBundleUrl(bundleAlias, true);
                        }
                        else
                        {
                            bundleUrl = bundleAlias + "_no_http_context";
                        }
                        Bundles[coll] = bundleUrl;
                    }
                }

                var scriptPlaceholder = scripts.First();



                // add bundle after all noncombined scripts
                if (!String.IsNullOrEmpty(bundleUrl))
                {
                    firstScript.Before(GetScriptHtml(bundleUrl));
                }
            }
               
            
        }
Example #28
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var searchString    = query.GetQueryString();
            var queryCollection = new NameValueCollection();

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

            var searchUrl = SearchUrl + queryCollection.GetQueryString();

            var trackerCats = MapTorznabCapsToTrackers(query, mapChildrenCatsToParent: true);

            var results = await RequestStringWithCookiesAndRetry(searchUrl);

            try
            {
                CQ dom = results.Content;
                dom["#needseed"].Remove();
                var rows = dom["table[width='750'] > tbody"].Children();
                foreach (var row in rows.Skip(1))
                {
                    var release = new ReleaseInfo();

                    var qRow  = row.Cq();
                    var qLink = qRow.Children().ElementAt(2).Cq().Children("a").First();

                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800;
                    release.Title           = qLink.Attr("title");
                    release.Description     = release.Title;
                    release.Guid            = new Uri(SiteLink + qLink.Attr("href").TrimStart('/'));
                    release.Comments        = release.Guid;
                    release.Link            = new Uri(string.Format(DownloadUrl, qLink.Attr("href").Split('=')[1]));

                    var catUrl = qRow.Children().ElementAt(1).FirstElementChild.Cq().Attr("href");
                    var catNum = catUrl.Split(new char[] { '=', '&' })[1];
                    release.Category = MapTrackerCatToNewznab(catNum);

                    // This tracker cannot search multiple cats at a time, so search all cats then filter out results from different cats
                    if (trackerCats.Count > 0 && !trackerCats.Contains(catNum))
                    {
                        continue;
                    }

                    var dateString = qRow.Children().ElementAt(5).Cq().Text().Trim();
                    var pubDate    = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                    release.PublishDate = DateTime.SpecifyKind(pubDate, DateTimeKind.Local);

                    var sizeStr = qRow.Children().ElementAt(6).Cq().Text();
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

                    release.Seeders = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Trim());
                    release.Peers   = ParseUtil.CoerceInt(qRow.Children().ElementAt(9).Cq().Text().Trim()) + release.Seeders;

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

            return(releases);
        }
Example #29
0
        public void Cq_About__LogOnPartial(CQ doc)
        {
            doc["a"].Text("Link Text About Only");

        }
Example #30
0
        public void AttributeStartsWithSelector()
        {
            CQ res = Dom.Find("span[name^=badge_span]");

            Assert.AreEqual(2, res.Length, "Expected two elements starting with badge_span");
        }
Example #31
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("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;

            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);
        }
Example #32
0
        /// <summary>   Cq log on partial. </summary>
        ///
        /// <remarks>   James Treworgy, 7/1/2012. </remarks>

        public void Cq__LogOnPartial(CQ doc)
        {
            doc["a"].Text("Link Text Always");
        }
Example #33
0
        public void CssSelector()
        {
            CQ res = Dom.Find(".badgecount");

            Assert.AreEqual(2, res.Length, "Expected 2 .badgecount items");
        }
Example #34
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var searchString    = query.GetQueryString();
            var searchUrl       = BrowseUrl;
            var queryCollection = new NameValueCollection();

            if (!string.IsNullOrWhiteSpace(query.ImdbID))
            {
                queryCollection.Add("q", query.ImdbID);
            }
            else 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[href^=\"/details.php?id=\"]").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.Guid     = new Uri(SiteLink + 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(SiteLink + WebUtility.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 catIcon = row.Cq().Find("td:eq(0) a");
                    if (catIcon.Length >= 1) // Torrents - Category column == Icons
                    {
                        release.Category = MapTrackerCatToNewznab(catIcon.First().Attr("href").Substring(1));
                    }
                    else // Torrents - Category column == Text (Code is not supported)
                    {
                        release.Category = MapTrackerCatDescToNewznab(row.Cq().Find("td:eq(0)").Text());
                    }

                    var filesElement = row.Cq().Find("a[href*=\"/files\"]"); // optional
                    if (filesElement.Length == 1)
                    {
                        release.Files = ParseUtil.CoerceLong(filesElement.Text());
                    }

                    var grabs = row.Cq().Find("td:nth-last-child(3)").Text();
                    release.Grabs = ParseUtil.CoerceInt(grabs);

                    if (row.Cq().Find("span.t_tag_free_leech").Any())
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

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

            return(releases);
        }
        protected override void ProcessJob(Guid targetInstanceId)
        {
            // check whether there are running instances of timerjob
            // if there is - the work stops
            if ((from SPRunningJob job in WebApplication.RunningJobs
                 where String.CompareOrdinal(job.JobDefinition.Name, Name) == 0
                 select job).Count() > 1)
            {
                Logger.WriteMessage(string.Format("You can not run multiple instances of the same timer job. Name: {0}, Time start attempt: {1}", Title,
                                                  DateTime.Now.ToString("dd:MM:yyyy:hh:mm:ss")));
                return;
            }

            using (var site = new SPSite(SiteUrl, SPUserToken.SystemAccount))
            {
                using (SPWeb web = site.OpenWeb(WebUrl))
                {
                    try
                    {
                        SPList officesList  = web.GetList(Constants.Lists.OfficesListUrl);
                        SPList officesList2 = web.GetList(Constants.Lists.Offices2ListUrl);

                        // prepare spquery ti get not copied items by 'iscopied' flag
                        string query   = CQ.Where(CQ.Neq.FieldRef(new Guid(Constants.Fields.FieldIsCopiedFieldInternalNameId)).Value(true));
                        var    spQuery = new SPQuery
                        {
                            Query      = query,
                            ViewFields =
                                CQ.ViewFields(CQ.FieldRef(new Guid(Constants.Fields.NameFieldInternalNameId)),
                                              CQ.FieldRef(new Guid(Constants.Fields.DirectorFieldInternalNameId)),
                                              CQ.FieldRef(new Guid(Constants.Fields.FieldIsCopiedFieldInternalNameId)),
                                              CQ.FieldRef(SPBuiltInFieldId.Title))
                        };

                        // get not copied items
                        SPListItemCollection itemsToCopy = officesList.GetItems(spQuery);
                        SPListItem           destItem    = officesList2.Items.Add();

                        foreach (SPListItem srcItem in itemsToCopy)
                        {
                            // set additional title field
                            destItem[SPBuiltInFieldId.Title] = srcItem[SPBuiltInFieldId.Title];

                            // Copy fields
                            srcItem.CopyItemTo(destItem,
                                               new List <string>
                            {
                                Constants.Fields.NameFieldInternalName,
                                Constants.Fields.DirectorFieldInternalName,
                            });

                            // set flag copied to 'true' at source item
                            srcItem[new Guid(Constants.Fields.FieldIsCopiedFieldInternalNameId)] = true;
                            srcItem.Update();
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.WriteError(
                            string.Format("Failed to copy the elements of the list {0} to the list {1}.", Constants.Lists.OfficesListUrl, Constants.Lists.Offices2ListUrl),
                            ex,
                            TraceSeverity.Unexpected);
                    }
                }
            }
        }
Example #36
0
        /// <summary>
        /// Resolve all script dependencies in the bound CQ document. Scripts that cotain a "data-
        /// location='head'" attribute will be moved to the head.
        /// </summary>
        ///
        /// <param name="doc">
        /// The document to resolve.
        /// </param>

        public void ResolveScriptDependencies(CQ doc)
        {
           

            string scriptSelector = "script[src][type='text/javascript'], link[type='text/css']";
                
            //+ (Options.HasFlag(ViewEngineOptions.ProcessAllScripts) ?
            //        "" : ".csquery-script")
            //        + "[src]";

            // Filter out non-relative paths (remote URLs)
            CQ scripts = doc[scriptSelector].Filter(item =>
            {
                return !PathList.IsRemoteUrl(item.UrlSource());
            });



            if (scripts.Length == 0)
            {
                return;
            }
            
            // move scripts to head as needed first

            var toMove = scripts.Filter("[data-location='head']");
            var head = doc["head"];

            if (toMove.Length > 0)
            {
                
                foreach (var item in toMove)
                {
                    if (item.ParentNode != head)
                    {
                        head.Append(item);
                    }
                }
            }

            // resolve dependencies

            ScriptCollection coll = new ScriptCollection(LibraryPath,MapPath);
            coll.NoCache = Options.HasFlag(ViewEngineOptions.NoCache);
            coll.IgnoreErrors = Options.HasFlag(ViewEngineOptions.IgnoreMissingScripts);

            // identify the insertion point for the script bundle
            var firstScriptEl = coll.AddFromCq(scripts);
            var firstScript = firstScriptEl == null ? 
                head.Children().First() : 
                firstScriptEl.Cq();

            string bundleUrl;
            List<ScriptRef> dependencies = coll.GetDependencies()
                .Where(item=>!coll.Contains(item))
                .ToList();

            // find the first script with dependencies
            

            // Now add scripts directly for depenencies marked as NoCombine.

            foreach (var item in dependencies.Where(item => item.NoCombine))
            {
                firstScript.Before(GetScriptHtml(item.Path, item.ScriptHash));
            }

            // Before creating the bundle, remove any duplicates of the same script on the page
            
            


            bool hasBundle = Bundles.TryGetValue(coll, out bundleUrl);

            if (hasBundle) {
                // when nocache is set, we will regenerate the bundle, but not change the script ID. The v=
                // flag will be changed by BundleTable. 
                if (Options.HasFlag(ViewEngineOptions.NoCache))
                {
                    string removeUrl = "~" + bundleUrl.Before("?");
                    BundleTable.Bundles.Remove(BundleTable.Bundles.GetBundleFor(removeUrl));
                    hasBundle = false;
                    ScriptID++;
                    // 
                    //var bundleList = BundleTable.Bundles.ToList();
                    //BundleTable.Bundles.Clear();
                    //BundleTable.Bundles.ResetAll();
                    //BundleTable.EnableOptimizations = false;

                    //foreach (var oldBundle in bundleList)
                    //{
                    //    BundleTable.Bundles.Add(oldBundle);
                    //}

                }
            }
            else
            {
                ScriptID++;
            }

            if (!hasBundle) {

                string bundleAlias = "~/cqbundle" + ScriptID;
                var bundle = GetScriptBundle(bundleAlias);

                var activeDependencies = dependencies.Where(item => !item.NoCombine);
                foreach (var item in activeDependencies)
                {
                    bundle.Include(item.Path);
                }

               
                BundleTable.Bundles.Add(bundle);
                if (HttpContext.Current != null)
                {
                    bundleUrl = BundleTable.Bundles.ResolveBundleUrl(bundleAlias, true);
                }
                else
                {
                    bundleUrl = bundleAlias + "_no_http_context";
                }
                Bundles[coll] = bundleUrl;
            }

            var scriptPlaceholder = scripts.First();

          

            // add bundle after all noncombined scripts

            firstScript.Before(GetScriptHtml(bundleUrl));

               
            
        }
Example #37
0
        /// <summary>
        /// Configure our Provider
        /// </summary>
        /// <param name="configJson">Our params in Json</param>
        /// <returns>Configuration state</returns>
        public async Task <IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
        {
            // Retrieve config values set by Jackett's user
            ConfigData.LoadValuesFromJson(configJson);

            // Check & Validate Config
            validateConfig();

            // Setting our data for a better emulated browser (maximum security)
            // TODO: Encoded Content not supported by Jackett at this time
            // emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");

            // If we want to simulate a browser
            if (ConfigData.Browser.Value)
            {
                // Clean headers
                emulatedBrowserHeaders.Clear();

                // Inject headers
                emulatedBrowserHeaders.Add("Accept", ConfigData.HeaderAccept.Value);
                emulatedBrowserHeaders.Add("Accept-Language", ConfigData.HeaderAcceptLang.Value);
                emulatedBrowserHeaders.Add("DNT", Convert.ToInt32(ConfigData.HeaderDNT.Value).ToString());
                emulatedBrowserHeaders.Add("Upgrade-Insecure-Requests", Convert.ToInt32(ConfigData.HeaderUpgradeInsecure.Value).ToString());
                emulatedBrowserHeaders.Add("User-Agent", ConfigData.HeaderUserAgent.Value);
            }


            // Getting login form to retrieve CSRF token

            /*var myRequest = new Utils.Clients.WebRequest()
             * {
             *  Url = LoginUrl
             * };*/

            // Add our headers to request
            //myRequest.Headers = emulatedBrowserHeaders;

            // Building login form data
            var pairs = new Dictionary <string, string> {
                { "username", ConfigData.Username.Value },
                { "password", ConfigData.Password.Value }
            };

            // Do the login
            var request = new Utils.Clients.WebRequest()
            {
                PostData = pairs,
                Referer  = LoginUrl,
                Type     = RequestType.POST,
                Url      = LoginUrl,
                Headers  = emulatedBrowserHeaders
            };

            // Perform loggin
            latencyNow();
            output("\nPerform loggin.. with " + LoginUrl);
            var response = await webclient.GetString(request);

            // Test if we are logged in
            await ConfigureIfOK(response.Cookies, !response.Cookies.Contains("deleted"), () =>
            {
                // Parse error page
                CQ dom         = response.Content;
                string message = dom[".error"].Text().Trim().Replace("X\n\t\t", "").Replace("\n\t\tX", "");

                // Oops, unable to login
                output("-> Login failed: \"" + message + "\".", "error");
                throw new ExceptionWithConfigData("Login failed: << " + message + " >>", configData);
            });

            output("-> Login Success");

            return(IndexerConfigurationStatus.RequiresTesting);
        }
Example #38
0
 public SelectorCache(CQ cqSource)
 {
     CqSource = cqSource;
 }
Example #39
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
            TimeZoneInfo.TransitionTime endTransition   = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
            TimeSpan delta = new TimeSpan(1, 0, 0);

            TimeZoneInfo.AdjustmentRule   adjustment  = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
            TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments);

            var releases = new List <ReleaseInfo>();

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

            queryCollection.Add("incldead", "1");
            queryCollection.Add("_by", "0");
            queryCollection.Add("sort", "4");
            queryCollection.Add("type", "desc");

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

            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                queryCollection.Add("c" + cat, "1");
            }
            searchUrl += "?" + queryCollection.GetQueryString();

            var response = await RequestStringWithCookies(searchUrl);

            var results = response.Content;

            try
            {
                CQ  dom  = results;
                var rows = dom["table[border=1] > tbody > tr:has(td.torrenttable)"];

                foreach (var row in rows)
                {
                    var release = new ReleaseInfo();
                    release.MinimumRatio    = 0.8;
                    release.MinimumSeedTime = 48 * 60 * 60;

                    var qRow = row.Cq();

                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
                    var qTitle       = qDetailsLink.Find("b").First();
                    release.Title = qTitle.Text();

                    var qCatLink  = qRow.Find("a[href^=browse.php?cat=]").First();
                    var qDLLink   = qRow.Find("a.download").First();
                    var qSeeders  = qRow.Find("td.torrenttable:eq(7)");
                    var qLeechers = qRow.Find("td.torrenttable:eq(8)");
                    var qDateStr  = qRow.Find("td.torrenttable:eq(4)").First();
                    var qSize     = qRow.Find("td.torrenttable:eq(5)").First();

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

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

                    var sizeStr = qSize.Text();
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

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

                    var      dateStr    = qDateStr.Text().Trim();
                    DateTime dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MMM d yyyy HH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);

                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
                    release.PublishDate = pubDateUtc.ToLocalTime();

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

                    var grabs = qRow.Find("td:nth-child(8)").Get(0).FirstChild.ToString();
                    release.Grabs = ParseUtil.CoerceInt(grabs);

                    if (qRow.Find("img[src=\"pic/torrent_ou.gif\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else if (qRow.Find("font[color=\"gray\"]:contains(50% Down)").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0.5;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

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

            return(releases);
        }