예제 #1
0
        private List <ReleaseInfo> ParseTorrents(WebResult results, string episodeString, TorznabQuery query,
                                                 int alreadyFound, int limit, int previouslyParsedOnPage)
        {
            var releases = new List <ReleaseInfo>();

            try
            {
                var parser = new HtmlParser();
                var dom    = parser.ParseDocument(results.ContentString);
                var rows   = dom.QuerySelectorAll(".box_torrent").Skip(previouslyParsedOnPage).Take(limit - alreadyFound);

                var key = ParseUtil.GetArgumentFromQueryString(
                    dom.QuerySelector("link[rel=alternate]").GetAttribute("href"), "key");
                // Check torrents only till we reach the query Limit
                foreach (var row in rows)
                {
                    try
                    {
                        var torrentTxt = row.QuerySelector(".torrent_txt, .torrent_txt2").QuerySelector("a");
                        //if (torrentTxt == null) continue;
                        var infoLink = row.QuerySelector("a.infolink");
                        var imdbId   = ParseUtil.GetLongFromString(infoLink?.GetAttribute("href"));
                        var desc     = row.QuerySelector("span")?.GetAttribute("title") + " " +
                                       infoLink?.TextContent;
                        var torrentLink = SiteLink + torrentTxt.GetAttribute("href");
                        var downloadId  = ParseUtil.GetArgumentFromQueryString(torrentLink, "id");

                        //Build site links
                        var baseLink     = SiteLink + "torrents.php?action=details&id=" + downloadId;
                        var downloadLink = SiteLink + "torrents.php?action=download&id=" + downloadId;
                        var commentsUri  = new Uri(baseLink + "#comments");
                        var guidUri      = new Uri(baseLink);
                        var linkUri      = new Uri(QueryHelpers.AddQueryString(downloadLink, "key", key));

                        var seeders     = ParseUtil.CoerceInt(row.QuerySelector(".box_s2 a").TextContent);
                        var leechers    = ParseUtil.CoerceInt(row.QuerySelector(".box_l2 a").TextContent);
                        var publishDate = DateTime.Parse(
                            row.QuerySelector(".box_feltoltve2").InnerHtml.Replace("<br>", " "),
                            CultureInfo.InvariantCulture);
                        var sizeSplit = row.QuerySelector(".box_meret2").TextContent.Split(' ');
                        var size      = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
                        var catLink   = row.QuerySelector("a:has(img[class='categ_link'])").GetAttribute("href");
                        var cat       = ParseUtil.GetArgumentFromQueryString(catLink, "tipus");
                        var title     = torrentTxt.GetAttribute("title");
                        // if the release name does not contain the language we add from the category
                        if (cat.Contains("hun") && !title.ToLower().Contains("hun"))
                        {
                            title += ".hun";
                        }

                        // Minimum seed time is 48 hours + 24 minutes (.4 hours) per GB of torrent size if downloaded in full.
                        // Or a 1.0 ratio on the torrent
                        var seedTime = TimeSpan.FromHours(48) +
                                       TimeSpan.FromMinutes(24 * ReleaseInfo.GigabytesFromBytes(size).Value);

                        var release = new ReleaseInfo
                        {
                            Title                = title,
                            Description          = desc.Trim(),
                            MinimumRatio         = 1,
                            MinimumSeedTime      = (long)seedTime.TotalSeconds,
                            DownloadVolumeFactor = 0,
                            UploadVolumeFactor   = 1,
                            Link        = linkUri,
                            Comments    = commentsUri,
                            Guid        = guidUri,
                            Seeders     = seeders,
                            Peers       = leechers + seeders,
                            Imdb        = imdbId,
                            PublishDate = publishDate,
                            Size        = size,
                            Category    = MapTrackerCatToNewznab(cat)
                        };
                        var banner = row.QuerySelector("img.infobar_ico")?.GetAttribute("onmouseover");
                        if (banner != null)
                        {
                            // static call to Regex.Match caches the pattern, so we aren't recompiling every loop.
                            var bannerMatch = Regex.Match(banner, @"mutat\('(.*?)', '", RegexOptions.Compiled);
                            release.BannerUrl = new Uri(bannerMatch.Groups[1].Value);
                        }

                        //TODO there is room for improvement here.
                        if (episodeString != null &&
                            query.MatchQueryStringAND(release.Title, queryStringOverride: episodeString) &&
                            !query.IsImdbQuery)
                        {
                            // For Sonarr if the search query was english the title must be english also
                            // The description holds the alternate language name
                            // so we need to swap title and description names
                            var tempTitle = release.Title;

                            // releaseData everything after Name.S0Xe0X
                            var releaseIndex = tempTitle.IndexOf(episodeString, StringComparison.OrdinalIgnoreCase) +
                                               episodeString.Length;
                            var releaseData = tempTitle.Substring(releaseIndex).Trim();

                            // release description contains [imdb: ****] but we only need the data before it for title
                            var description = new[]
                            {
                                release.Description,
                                ""
                            };
                            if (release.Description.Contains("[imdb:"))
                            {
                                description    = release.Description.Split('[');
                                description[1] = "[" + description[1];
                            }

                            var match = Regex.Match(releaseData, @"^E\d\d?");
                            // if search is done for S0X than we don't want to put . between S0X and E0X
                            var episodeSeparator = episodeString.Length == 3 && match.Success ? null : ".";
                            release.Title =
                                (description[0].Trim() + "." + episodeString.Trim() + episodeSeparator +
                                 releaseData.Trim('.')).Replace(' ', '.');

                            // add back imdb points to the description [imdb: 8.7]
                            release.Description = tempTitle + " " + description[1];
                            release.Description = release.Description.Trim();
                        }

                        releases.Add(release);
                    }
                    catch (FormatException ex)
                    {
                        logger.Error("Problem of parsing Torrent:" + row.InnerHtml);
                        logger.Error("Exception was the following:" + ex);
                    }
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.ContentString, ex);
            }

            return(releases);
        }