Esempio n. 1
0
        /// <summary>
        /// Execute our search query
        /// </summary>
        /// <param name="query">Query</param>
        /// <returns>Releases</returns>
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases   = new List <ReleaseInfo>();
            var searchTerm = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();

            if (EnhancedAnimeSearch && query.HasSpecifiedCategories && (query.Categories.Contains(TorznabCatType.TVAnime.ID) || query.Categories.Contains(100032) || query.Categories.Contains(100101) || query.Categories.Contains(100110)))
            {
                var regex = new Regex(" ([0-9]+)");
                searchTerm = regex.Replace(searchTerm, " E$1");
            }

            searchTerm = searchTerm.Trim();
            searchTerm = searchTerm.ToLower();
            searchTerm = searchTerm.Replace(" ", ".");

            // Multiple page support
            var nextPage       = 1;
            var followingPages = true;

            do
            {
                // Build our query
                var request = BuildQuery(searchTerm, query, SearchUrl, nextPage);

                // Getting results
                logger.Info("\nAbnormal - Querying API page " + nextPage);
                var dom     = new HtmlParser().ParseDocument(await QueryExecAsync(request));
                var results = dom.QuerySelectorAll(".table-rows > tbody > tr:not(.mvc-grid-empty-row)");

                // Torrents Result Count
                var torrentsCount = results.Length;

                try
                {
                    // If contains torrents
                    if (torrentsCount > 0)
                    {
                        logger.Info("\nAbnormal - Found " + torrentsCount + " torrents on current page.");

                        // Adding each torrent row to releases
                        releases.AddRange(results.Select(torrent =>
                        {
                            // Selectors
                            var id         = torrent.QuerySelector("td.grid-release-column > a").GetAttribute("href");  // ID
                            var name       = torrent.QuerySelector("td.grid-release-column > a").TextContent;           // Release Name
                            var categoryId = torrent.QuerySelector("td.grid-cat-column > a").GetAttribute("href");      // Category
                            var completed  = torrent.QuerySelector("td:nth-of-type(3)").TextContent;                    // Completed
                            var seeders    = torrent.QuerySelector("td.text-green").TextContent;                        // Seeders
                            var leechers   = torrent.QuerySelector("td.text-red").TextContent;                          // Leechers
                            var size       = torrent.QuerySelector("td:nth-of-type(5)").TextContent;                    // Size

                            var release = new ReleaseInfo
                            {
                                // Mapping data
                                Category             = MapTrackerCatToNewznab(Regex.Match(categoryId, @"\d+").Value),
                                Title                = name,
                                Seeders              = int.Parse(Regex.Match(seeders, @"\d+").Value),
                                Peers                = int.Parse(Regex.Match(seeders, @"\d+").Value) + int.Parse(Regex.Match(leechers, @"\d+").Value),
                                Grabs                = int.Parse(Regex.Match(completed, @"\d+").Value) + int.Parse(Regex.Match(leechers, @"\d+").Value),
                                MinimumRatio         = 1,
                                MinimumSeedTime      = 172800,
                                Size                 = ReleaseInfo.GetBytes(size.Replace("Go", "gb").Replace("Mo", "mb").Replace("Ko", "kb")),
                                UploadVolumeFactor   = 1,
                                DownloadVolumeFactor = 1,
                                PublishDate          = DateTime.Now,
                                Guid                 = new Uri(TorrentDetailsUrl.Replace("{id}", Regex.Match(id, @"\d+").Value)),
                                Details              = new Uri(TorrentDetailsUrl.Replace("{id}", Regex.Match(id, @"\d+").Value)),
                                Link                 = new Uri(TorrentDownloadUrl.Replace("{id}", Regex.Match(id, @"\d+").Value))
                            };

                            // Multi Replacement
                            if (!string.IsNullOrEmpty(MultiReplacement))
                            {
                                var regex     = new Regex("(?i)([\\.\\- ])MULTI([\\.\\- ])");
                                release.Title = regex.Replace(release.Title, "$1" + MultiReplacement + "$2");
                            }

                            // Sub Replacement
                            if (SubReplacement)
                            {
                                release.Title = release.Title.Replace("VOSTFR", "ENGLISH").Replace("SUBFRENCH", "ENGLISH");
                            }

                            // Freeleech
                            if (torrent.QuerySelector("img[alt=\"Freeleech\"]") != null)
                            {
                                release.DownloadVolumeFactor = 0;
                            }

                            return(release);
                        }));
                        if (torrentsCount == 50)
                        {
                            // Is there more pages to follow ?
                            var morePages = dom.QuerySelectorAll("div.mvc-grid-pager > button").Last().GetAttribute("tabindex");
                            if (morePages == "-1")
                            {
                                followingPages = false;
                            }
                        }
                        nextPage++;
                    }
                    else
                    {
                        logger.Info("\nAbnormal - No results found on page  " + nextPage + ", stopping follow of next page.");
                        //  No results or no more results available
                        followingPages = false;
                        break;
                    }
                }
                catch (Exception ex)
                {
                    OnParseError("Unable to parse result \n" + ex.StackTrace, ex);
                }

                // Stop ?
                if (torrentsCount < int.Parse(dom.QuerySelector(".mvc-grid-pager-rows").GetAttribute("value")))
                {
                    logger.Info("\nAbnormal - Stopping follow of next page " + nextPage + " due max available results reached.");
                    break;
                }
                else if (nextPage > MaxPages)
                {
                    logger.Info("\nAbnormal - Stopping follow of next page " + nextPage + " due to page limit reached.");
                    break;
                }
                else if (query.IsTest)
                {
                    logger.Info("\nAbnormal - Stopping follow of next page " + nextPage + " due to index test query.");
                    break;
                }
            } while (followingPages);

            // Return found releases
            return(releases);
        }
Esempio n. 2
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[".linkbox > 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[".linkbox > a"].Last().Attr("href").ToString(), @"\d+").Value);

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

                        // 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 autkey and torrentpass for future uses
                    string         infosData    = firstPageRows.First().Find("td:eq(3) > 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 Authkey for future uses...");
                    ConfigData.AuthKey.Value = infosTracker[2];

                    output("\nStoring TorrentPass for future uses...");
                    ConfigData.TorrentPass.Value = infosTracker[3];
                }

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

                    // ID
                    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").Text().ToString();
                    output("Release: " + name);

                    // Category
                    string categoryID = tRow.Find("td:eq(0) > a").Attr("href").Replace("torrents.php?cat[]=", String.Empty);
                    output("Category: " + MapTrackerCatToNewznab(categoryID) + " (" + categoryID + ")");

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

                    // Leechers
                    int leechers = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(6)").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().Replace("Go", "gb").Replace("Mo", "mb").Replace("Ko", "kb");
                    long   size    = ReleaseInfo.GetBytes(sizeStr);
                    output("Size: " + sizeStr + " (" + size + " bytes)");

                    // Publish DateToString
                    IList <string> clockList = tRow.Find("td:eq(2) > span").Text().Replace("Il y a", "").Split(',').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
                    var            date      = agoToDate(clockList);
                    output("Released on: " + date.ToLocalTime());

                    // 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("{auth_key}", ConfigData.AuthKey.Value).Replace("{torrent_pass}", ConfigData.TorrentPass.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 = 172800;
                    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);
        }