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

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

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

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

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

            try
            {
                var lastDate = DateTime.Now;

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

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

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

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

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

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

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

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

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

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

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

            return(releases);
        }
示例#2
0
        private async Task <List <ReleaseInfo> > ParseUserSearchAsync(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var searchUrl       = BrowseUrl;
            var isSearchAnime   = query.Categories.Any(s => s == TorznabCatType.TVAnime.ID);
            var searchTerm      = FixSearchTerm(query);
            var queryCollection = new NameValueCollection
            {
                { "searchstr", StripSearchString(searchTerm, isSearchAnime) },
                { "order_by", "time" },
                { "order_way", "desc" },
                { "group_results", "1" },
                { "action", "basic" },
                { "searchsubmit", "1" }
            };

            foreach (var cat in MapTorznabCapsToTrackers(query))
            {
                queryCollection.Add("filter_cat[" + cat + "]", "1");
            }
            searchUrl += "?" + queryCollection.GetQueryString();
            var results = await RequestWithCookiesAsync(searchUrl);

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

                results = await RequestWithCookiesAsync(searchUrl);
            }

            try
            {
                const string      rowsSelector         = "table.torrent_table > tbody > tr:not(tr.colhead)";
                var               searchResultParser   = new HtmlParser();
                var               searchResultDocument = searchResultParser.ParseDocument(results.ContentString);
                var               rows          = searchResultDocument.QuerySelectorAll(rowsSelector);
                ICollection <int> groupCategory = null;
                string            groupTitle    = null;
                string            groupYearStr  = null;
                var               categoryStr   = "";
                foreach (var row in rows)
                {
                    try
                    {
                        // ignore sub groups info row, it's just an row with an info about the next section, something like "Dual Áudio" or "Legendado"
                        if (row.QuerySelector(".edition_info") != null)
                        {
                            continue;
                        }

                        // some torrents has more than one link, and the one with .tooltip is the wrong one in that case,
                        // so let's try to pick up first without the .tooltip class,
                        // if nothing is found, then we try again without that filter
                        var qDetailsLink = row.QuerySelector("a[href^=\"torrents.php?id=\"]:not(.tooltip)");
                        if (qDetailsLink == null)
                        {
                            qDetailsLink = row.QuerySelector("a[href^=\"torrents.php?id=\"]");
                            // if still can't find the right link, skip it
                            if (qDetailsLink == null)
                            {
                                logger.Error($"{Id}: Error while parsing row '{row.OuterHtml}': Can't find the right details link");
                                continue;
                            }
                        }
                        var title = StripSearchString(qDetailsLink.TextContent, false);

                        var    seasonEl = row.QuerySelector("a[href^=\"torrents.php?torrentid=\"]");
                        string seasonEp = null;
                        if (seasonEl != null)
                        {
                            var seasonMatch = _EpisodeRegex.Match(seasonEl.TextContent);
                            seasonEp = seasonMatch.Success ? seasonMatch.Value : null;
                        }
                        seasonEp ??= _EpisodeRegex.Match(qDetailsLink.TextContent).Value;

                        ICollection <int> category = null;
                        string            yearStr  = null;
                        if (row.ClassList.Contains("group") || row.ClassList.Contains("torrent")) // group/ungrouped headers
                        {
                            var qCatLink = row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
                            categoryStr = qCatLink.GetAttribute("href").Split('=')[1].Split('&')[0];
                            category    = MapTrackerCatToNewznab(categoryStr);

                            var torrentInfoEl = row.QuerySelector("div.torrent_info");
                            if (torrentInfoEl != null)
                            {
                                // valid for torrent grouped but that has only 1 episode yet
                                yearStr = torrentInfoEl.GetAttribute("data-year");
                            }
                            yearStr ??= qDetailsLink.NextSibling.TextContent.Trim().TrimStart('[').TrimEnd(']');

                            if (row.ClassList.Contains("group")) // group headers
                            {
                                groupCategory = category;
                                groupTitle    = title;
                                groupYearStr  = yearStr;
                                continue;
                            }
                        }

                        var release = new ReleaseInfo
                        {
                            MinimumRatio    = 1,
                            MinimumSeedTime = 0
                        };
                        var qDlLink    = row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
                        var qSize      = row.QuerySelector("td:nth-last-child(4)");
                        var qGrabs     = row.QuerySelector("td:nth-last-child(3)");
                        var qSeeders   = row.QuerySelector("td:nth-last-child(2)");
                        var qLeechers  = row.QuerySelector("td:nth-last-child(1)");
                        var qFreeLeech = row.QuerySelector("strong[title=\"Free\"]");
                        if (row.ClassList.Contains("group_torrent")) // torrents belonging to a group
                        {
                            release.Description = Regex.Match(qDetailsLink.TextContent, @"\[.*?\]").Value;
                            release.Title       = ParseTitle(groupTitle, seasonEp, groupYearStr, categoryStr);
                            release.Category    = groupCategory;
                        }
                        else if (row.ClassList.Contains("torrent")) // standalone/un grouped torrents
                        {
                            release.Description = row.QuerySelector("div.torrent_info").TextContent;
                            release.Title       = ParseTitle(title, seasonEp, yearStr, categoryStr);
                            release.Category    = category;
                        }

                        release.Description = release.Description.Replace(" / Free", "");         // Remove Free Tag
                        release.Description = release.Description.Replace("/ WEB ", "/ WEB-DL "); // Fix web/web-dl
                        release.Description = release.Description.Replace("Full HD", "1080p");
                        // Handles HDR conflict
                        release.Description = release.Description.Replace("/ HD /", "/ 720p /");
                        release.Description = release.Description.Replace("/ HD]", "/ 720p]");
                        release.Description = release.Description.Replace("4K", "2160p");
                        release.Description = release.Description.Replace("SD", "480p");
                        release.Description = release.Description.Replace("Dual Áudio", "Dual");

                        // Adjust the description in order to can be read by Radarr and Sonarr
                        var      cleanDescription = release.Description.Trim().TrimStart('[').TrimEnd(']');
                        string[] titleElements;

                        //Formats the title so it can be parsed later
                        var stringSeparators = new[]
                        {
                            " / "
                        };
                        titleElements = cleanDescription.Split(stringSeparators, StringSplitOptions.None);
                        // release.Title += string.Join(" ", titleElements);
                        release.Title = release.Title.Trim();
                        if (titleElements.Length < 6)
                        {
                            // Usually non movies / series could have less than 6 elements, eg: Books.
                            release.Title += " " + string.Join(" ", titleElements);
                        }
                        else
                        {
                            release.Title += " " + titleElements[5] + " " + titleElements[3] + " " + titleElements[1] + " " +
                                             titleElements[2] + " " + titleElements[4] + " " + string.Join(
                                " ", titleElements.Skip(6));
                        }

                        // This tracker does not provide an publish date to search terms (only on last 24h page)
                        release.PublishDate = DateTime.Today;

                        // check for previously stripped search terms
                        if (!query.IsImdbQuery && !query.MatchQueryStringAND(release.Title, null, searchTerm))
                        {
                            continue;
                        }
                        var size = qSize.TextContent;
                        release.Size    = ReleaseInfo.GetBytes(size);
                        release.Link    = new Uri(SiteLink + qDlLink.GetAttribute("href"));
                        release.Details = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
                        release.Guid    = release.Link;
                        release.Grabs   = ParseUtil.CoerceLong(qGrabs.TextContent);
                        release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
                        release.Peers   = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;
                        release.DownloadVolumeFactor = qFreeLeech != null ? 0 : 1;
                        release.UploadVolumeFactor   = 1;
                        releases.Add(release);
                    }
                    catch (Exception ex)
                    {
                        logger.Error($"{Id}: Error while parsing row '{row.OuterHtml}': {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.ContentString, ex);
            }

            return(releases);
        }
示例#3
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases         = new List <ReleaseInfo>();
            var trackerCats      = MapTorznabCapsToTrackers(query);
            var cat              = (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0");
            var episodeSearchUrl = string.Format(SearchUrl, cat, HttpUtility.UrlEncode(query.GetQueryString()));
            var results          = await RequestStringWithCookiesAndRetry(episodeSearchUrl);


            if (results.Content.Contains("No torrents found"))
            {
                return(releases);
            }

            try
            {
                CQ       dom          = results.Content;
                var      rows         = dom[".ctable_content_no_pad > table > tbody > tr"].ToArray();
                DateTime lastDateTime = default(DateTime);
                for (var i = 0; i < rows.Length; i++)
                {
                    var rowA   = rows[i];
                    var rAlign = rowA.Attributes["align"];
                    if (rAlign == "right" || rAlign == "center")
                    {
                        continue;
                    }
                    if (rAlign == "left")
                    {
                        // ex: "Monday, Jun 01, 2015", "Monday, Aug 03, 2015"
                        var dateStr = rowA.Cq().Text().Trim().Replace("Added on ", "");
                        if (dateStr.ToLowerInvariant().Contains("today"))
                        {
                            lastDateTime = DateTime.Now;
                        }
                        else
                        {
                            lastDateTime = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dddd, MMM dd, yyyy", CultureInfo.InvariantCulture), DateTimeKind.Utc).ToLocalTime();
                        }
                        continue;
                    }
                    if (rowA.ChildElements.Count() < 2)
                    {
                        continue;
                    }

                    var rowB = rows[++i];

                    var release = new ReleaseInfo();
                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800;

                    release.PublishDate = lastDateTime;

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

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

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

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

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

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }
            return(releases);
        }
示例#4
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchString = query.GetQueryString();
            var searchUrl    = SearchUrl;

            // If query is empty, use the RSS Feed
            if (string.IsNullOrWhiteSpace(searchString))
            {
                var rssPage = await RequestStringWithCookiesAndRetry(RSSUrl + configData.RSSKey.Value);

                var rssDoc = XDocument.Parse(rssPage.Content);

                foreach (var item in rssDoc.Descendants("item"))
                {
                    var title = item.Descendants("title").First().Value;
                    if (title.StartsWith("Support YOUR site!"))
                    {
                        continue;
                    }
                    var description = item.Descendants("description").First().Value;
                    var link        = item.Descendants("link").First().Value;
                    var date        = item.Descendants("pubDate").First().Value;

                    var torrentIdMatch = Regex.Match(link, "(?<=download\\.php/)([a-zA-z0-9]*)");
                    var torrentId      = torrentIdMatch.Success ? torrentIdMatch.Value : string.Empty;
                    if (string.IsNullOrWhiteSpace(torrentId))
                    {
                        throw new Exception("Missing torrent id");
                    }

                    var infoMatch = Regex.Match(description, @"Category:\W(?<cat>.*)\W\n\WSize:\W(?<size>.*)\n\WStatus:\W(?<seeders>.*)\Wseeder(.*)\Wand\W(?<leechers>.*)\Wleecher(.*)\n\WAdded:\W(?<added>.*)\n\WDescription:");
                    if (!infoMatch.Success)
                    {
                        throw new Exception("Unable to find info");
                    }

                    var  imdbMatch = Regex.Match(description, "(?<=www.imdb.com/title/tt)([0-9]*)");
                    long?imdbID    = null;
                    if (imdbMatch.Success)
                    {
                        long l;
                        if (long.TryParse(imdbMatch.Value, out l))
                        {
                            imdbID = l;
                        }
                    }
                    var Now              = DateTime.Now;
                    var PublishDate      = DateTime.ParseExact(date, "ddd, dd MMM yyyy HH:mm:ss zz00", CultureInfo.InvariantCulture);
                    var PublishDateLocal = PublishDate.ToLocalTime();
                    var diff             = Now - PublishDateLocal;

                    var release = new ReleaseInfo()
                    {
                        Title       = title,
                        Description = title,
                        Guid        = new Uri(string.Format(DetailsURL, torrentId)),
                        Comments    = new Uri(string.Format(DetailsURL, torrentId)),
                        //PublishDate = DateTime.ParseExact(infoMatch.Groups["added"].Value, "yyyy-MM-dd H:mm:ss", CultureInfo.InvariantCulture), //2015-08-08 21:20:31 TODO: correct timezone (always -4)
                        PublishDate = PublishDateLocal,
                        Link        = new Uri(link),
                        Seeders     = ParseUtil.CoerceInt(infoMatch.Groups["seeders"].Value == "no" ? "0" : infoMatch.Groups["seeders"].Value),
                        Peers       = ParseUtil.CoerceInt(infoMatch.Groups["leechers"].Value == "no" ? "0" : infoMatch.Groups["leechers"].Value),
                        Size        = ReleaseInfo.GetBytes(infoMatch.Groups["size"].Value),
                        Category    = MapTrackerCatToNewznab(infoMatch.Groups["cat"].Value),
                        Imdb        = imdbID
                    };

                    //  if unknown category, set to "other"
                    if (release.Category.Count() == 0)
                    {
                        release.Category.Add(7000);
                    }

                    release.Peers += release.Seeders;
                    releases.Add(release);
                }
            }
            else
            {
                searchUrl += "?titleonly=1&search=" + WebUtility.UrlEncode(searchString);
                string.Format(SearchUrl, WebUtility.UrlEncode(searchString));

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

                var results = await RequestStringWithCookiesAndRetry(searchUrl);

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

                    results = await RequestStringWithCookiesAndRetry(searchUrl);
                }

                try
                {
                    CQ dom = results.Content;

                    //  table header is the first <tr> in table body, get all rows except this
                    CQ qRows = dom["#torrents-table > tbody > tr:not(:first-child)"];

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

                        var qRow = row.Cq();

                        var debug = qRow.Html();

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

                        CQ qLink = qRow.Find(".br_right > a").First();
                        release.Guid        = new Uri(SiteLink + qLink.Attr("href"));
                        release.Comments    = new Uri(SiteLink + qLink.Attr("href"));
                        release.Title       = qLink.Find("b").Text();
                        release.Description = release.Title;

                        var releaseLinkURI = qRow.Find("td:nth-child(4) > a").Attr("href");
                        release.Link = new Uri(SiteLink + releaseLinkURI);
                        if (releaseLinkURI != null)
                        {
                            var dateString = qRow.Find("td:nth-child(6) nobr")[0].TextContent.Trim();
                            //"2015-04-25 23:38:12"
                            //"yyyy-MMM-dd hh:mm:ss"
                            release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture);

                            var sizeStr = qRow.Children().ElementAt(6).InnerHTML.Trim();
                            sizeStr      = sizeStr.Substring(0, sizeStr.IndexOf('<'));
                            release.Size = ReleaseInfo.GetBytes(sizeStr);

                            release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:nth-child(9)").Text());
                            release.Peers   = release.Seeders + ParseUtil.CoerceInt(qRow.Find("td:nth-child(10)").Text());

                            var grabsStr = qRow.Find("td:nth-child(8)").Text();
                            release.Grabs = ParseUtil.GetLongFromString(grabsStr);

                            var filesStr = qRow.Find("td:nth-child(7) > a").Text();
                            release.Files = ParseUtil.GetLongFromString(filesStr);

                            var category = qRow.Find(".br_type > a").Attr("href").Replace("browse.php?cat=", string.Empty);
                            release.Category = MapTrackerCatToNewznab(category);
                        }
                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnParseError(results.Content, ex);
                }
            }

            return(releases);
        }
示例#5
0
        private List <NewpctRelease> ParseSearchJsonContent(string content, string year)
        {
            var releases = new List <NewpctRelease>();

            if (string.IsNullOrWhiteSpace(content))
            {
                return(releases);
            }

            try
            {
                var jo = JObject.Parse(content);

                var numItems = int.Parse(jo["data"]["items"].ToString());
                for (var i = 0; i < numItems; i++)
                {
                    var item = jo["data"]["torrents"]["0"][i.ToString()];

                    var title      = item["torrentName"].ToString();
                    var detailsUrl = SiteLink + item["guid"];
                    var quality    = item["calidad"].ToString();
                    var sizeString = item["torrentSize"].ToString();
                    var size       = !sizeString.Contains("NAN") ? ReleaseInfo.GetBytes(sizeString) : 0;
                    DateTime.TryParseExact(item["torrentDateAdded"].ToString(), "dd/MM/yyyy", null, DateTimeStyles.None, out var publishDate);
                    var poster = SiteLink + item["imagen"].ToString().TrimStart('/');

                    // we have another search for series
                    var titleLower = title.ToLower();
                    var isSeries   = quality != null && quality.ToLower().Contains("hdtv");
                    var isGame     = titleLower.Contains("pcdvd");
                    if (isSeries || isGame)
                    {
                        continue;
                    }

                    // at this point we assume that this is a movie release, we need to parse the title. examples:
                    // Quien Es Harry Crumb (1989) [BluRay 720p X264 MKV][AC3 5.1 Castellano][www.descargas2020.ORG]
                    // Harry Potter y la orden del Fenix [4K UHDrip][2160p][HDR][AC3 5.1 Castellano DTS 5.1-Ingles+Subs][ES-EN]
                    // Harry Potter Y El Misterio Del Principe [DVDFULL][Spanish][2009]
                    // Harry Potter 2 Y La Camara Secreta [DVD9 FULL][Spanish_English][Inc Subs.]
                    // The Avengers [DVDRIP][VOSE English_Subs. Español][2012]
                    // Harry Potter y las Reliquias de la Muerte Parte I.DVD5  [ DVDR] [AC3 5.1] [Multilenguaje] [2010]
                    // Joker (2019) 720p [Web Screener 720p ][Castellano][www.descargas2020.ORG][www.pctnew.ORG]

                    // remove quality and language from the title
                    var titleParts = title.Split('[');
                    title = titleParts[0].Replace("720p", "").Trim();

                    // quality in the field quality/calidad is wrong in many cases
                    if (!string.IsNullOrWhiteSpace(quality))
                    {
                        if (titleLower.Contains("720") && !quality.Contains("720"))
                        {
                            quality += " 720p";
                        }
                        if (titleLower.Contains("265") || titleLower.Contains("hevc"))
                        {
                            quality += " x265";
                        }
                        if (titleLower.Contains("dvdfull") || titleLower.Contains("dvd5") || titleLower.Contains("dvd9"))
                        {
                            quality = "DVDR";
                        }
                        if (titleLower.Contains("[web screener]") || titleLower.Contains("[hd-tc]"))
                        {
                            quality = "TS Screener";
                        }
                    }
                    else if (titleParts.Length > 2)
                    {
                        quality = titleParts[1].Replace("]", "").Replace("MKV", "").Trim();
                    }

                    // we have to guess the language (words DUAL or MULTI are not supported in Radarr)
                    var language = "spanish";
                    if (titleLower.Contains("latino"))
                    {
                        language += " latino";
                    }
                    if ((titleLower.Contains("castellano") && titleLower.Contains("ingles")) ||
                        (titleLower.Contains("spanish") && titleLower.Contains("english")) ||
                        titleLower.Contains("[es-en]") || titleLower.Contains("multilenguaje"))
                    {
                        language += " english";
                    }
                    else if (titleLower.Contains("vose"))
                    {
                        language = "english vose";
                    }

                    // remove the movie year if the user chooses (the year in the title is wrong in many cases)
                    if (_removeMovieYear)
                    {
                        title = _titleYearRegex.Replace(title, "");
                    }

                    // we add the year from search if it's not in the title
                    if (!string.IsNullOrWhiteSpace(year) && !_titleYearRegex.Match(title).Success)
                    {
                        title += " " + year;
                    }

                    var release = GetReleaseFromData(ReleaseType.Movie, title, detailsUrl, quality, language, size, publishDate, poster);
                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(content, ex);
            }

            return(releases);
        }
示例#6
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();

            if (!string.IsNullOrWhiteSpace(searchString))
            {
                Regex ReplaceRegex = new Regex("[^a-zA-Z0-9]+");
                searchString = "%" + ReplaceRegex.Replace(searchString, "%") + "%";
                searchString = Regex.Replace(searchString, @"(%\d{3,4})[ip](%)", "$1$2"); // remove i/p from resolution tags (see #835)
                queryCollection.Add("search", searchString);
            }

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

            searchUrl += queryCollection.GetQueryString();

            var results = await RequestStringWithCookiesAndRetry(searchUrl);

            await FollowIfRedirect(results);

            try
            {
                CQ  dom  = results.Content;
                var rows = dom["table.torrenttable > tbody > tr.browse_color"];
                foreach (var row in rows)
                {
                    var release = new ReleaseInfo();
                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800;

                    var qRow = row.Cq();

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

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

                    var descCol      = row.ChildElements.ElementAt(3);
                    var qCommentLink = descCol.FirstChild.Cq();
                    release.Title    = qCommentLink.Text();
                    release.Comments = new Uri(SiteLink + "/" + qCommentLink.Attr("href"));
                    release.Guid     = release.Comments;
                    release.Link     = new Uri($"{SiteLink}download.php?torrent={torrentId}");

                    var dateStr = descCol.ChildElements.Last().Cq().Text().Split('|').Last().ToLowerInvariant().Replace("ago.", "").Trim();
                    release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr);

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

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

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

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

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

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

            return(releases);
        }
示例#7
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var searchurls      = new List <string>();
            var searchUrl       = SearchUrl;// string.Format(SearchUrl, HttpUtility.UrlEncode()));
            var queryCollection = new NameValueCollection();
            var searchString    = query.GetQueryString();


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


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



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

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


            var results = await RequestStringWithCookiesAndRetry(searchUrl);

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

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

                    release = new ReleaseInfo();

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

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

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



                    int seeders, peers;
                    if (ParseUtil.TryCoerceInt(qRow.Find("td").Get(9).FirstChild.FirstChild.InnerText, out seeders))
                    {
                        release.Seeders = seeders;
                        if (ParseUtil.TryCoerceInt(qRow.Find("td").Get(10).FirstChild.FirstChild.InnerText, out peers))
                        {
                            release.Peers = peers + release.Seeders;
                        }
                    }

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

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

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

                    string[] dateSplit  = qRow.Find("td.mainblockcontent").Get(5).InnerHTML.Split(',');
                    string   dateString = dateSplit[1].Substring(0, dateSplit[1].IndexOf('>'));
                    release.PublishDate = DateTime.Parse(dateString, CultureInfo.InvariantCulture);

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

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

                    release.UploadVolumeFactor = 1;

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

            return(releases);
        }
示例#8
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var searchString    = query.GetQueryString();
            var queryUrl        = SearchUrl;
            var queryCollection = new NameValueCollection();

            if (!string.IsNullOrWhiteSpace(query.ImdbID) && query.ImdbID.ToLower().StartsWith("tt"))
            {
                queryCollection.Add("search", query.ImdbID);
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(searchString))
                {
                    queryCollection.Add("search", searchString);
                }
            }

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

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

            var results = await RequestStringWithCookiesAndRetry(queryUrl);

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

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

                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800;
                    release.Title           = qRow.Find(".torrentName").Text();

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

                    release.Guid     = new Uri(SiteLink + qRow.Find(".torrentName").Attr("href"));
                    release.Comments = release.Guid;
                    release.Link     = new Uri(SiteLink + qRow.Find(".dlLinksInfo > a").Attr("href"));

                    var sizeStr = qRow.Find(".sizeInfo").Text();
                    release.Size = ReleaseInfo.GetBytes(sizeStr);

                    var dateStr = qRow.Find(".ulInfo").Text().Split('|').Last().Trim();
                    var agoIdx  = dateStr.IndexOf("ago");
                    if (agoIdx > -1)
                    {
                        dateStr = dateStr.Substring(0, agoIdx);
                    }
                    release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr);

                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seedersInfo").Text());
                    release.Peers   = ParseUtil.CoerceInt(qRow.Find(".leechersInfo").Text()) + release.Seeders;

                    var cat = qRow.Find("td:eq(0) a").First().Attr("href").Split('#')[0].Substring(15);//browse.php?cat=24
                    release.Category = MapTrackerCatToNewznab(cat);

                    if (qRow.Find("span.flTags").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(results.Content, ex);
            }
            return(releases);
        }
示例#9
0
文件: FileList.cs 项目: slmovies/slp1
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases     = new List <ReleaseInfo>();
            var searchUrl    = BrowseUrl;
            var searchString = query.GetQueryString();

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

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

            var queryCollection = new NameValueCollection();

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

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

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

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

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

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

            var results = response.Content;

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

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

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

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

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

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

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

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

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

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

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

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

                    release.UploadVolumeFactor = 1;

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

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

            return(releases);
        }
示例#10
0
        /// <summary>
        /// Execute our search query
        /// </summary>
        /// <param name="query">Query</param>
        /// <returns>Releases</returns>
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases        = new List <ReleaseInfo>();
            var exactSearchTerm = query.GetQueryString();
            var searchUrl       = SearchUrl;

            // Check login before performing a query
            await CheckLogin();

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

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

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

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

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

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

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

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

                try
                {
                    var firstPageRows = FindTorrentRows(dom);

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

                    // Check if we have a minimum of one result
                    if (firstPageRows?.Length >= 1)
                    {
                        // Retrieve total count on our alone page
                        nbResults = firstPageRows.Count();
                    }
                    else
                    {
                        // No result found for this query
                        Output("\nNo result found for your query, please try another search term ...\n", "info");
                        break;
                    }

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

                    // Loop on results

                    foreach (var row in firstPageRows)
                    {
                        Output("Torrent #" + (releases.Count + 1));

                        // ID
                        var id = row.QuerySelector("td:nth-of-type(2) > a:nth-of-type(1)").GetAttribute("href").Split('=').Last();
                        Output("ID: " + id);

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

                        // Category
                        var categoryName = row.QuerySelector("td:nth-of-type(1) > div > a:nth-of-type(1)").GetAttribute("title");
                        var mainCat      = row.QuerySelector("td:nth-of-type(1) > div > a:nth-of-type(1)").GetAttribute("href").Split('?').Last();
                        var qSubCat2     = row.QuerySelector("td:nth-of-type(1) > div > a[href^=\"/browse.php?sub2_cat[]=\"]");

                        var cat = mainCat;
                        if (qSubCat2 != null)
                        {
                            cat += '&' + qSubCat2.GetAttribute("href").Split('?').Last();
                        }

                        Output("Category: " + cat + " - " + categoryName);

                        // Seeders
                        var seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-of-type(9)").TextContent);
                        Output("Seeders: " + seeders);

                        // Leechers
                        var leechers = ParseUtil.CoerceInt(row.QuerySelector("td:nth-of-type(10)").TextContent);
                        Output("Leechers: " + leechers);

                        // Completed
                        var regexObj   = new Regex(@"[^\d]");
                        var completed2 = row.QuerySelector("td:nth-of-type(8)").TextContent;
                        var completed  = ParseUtil.CoerceLong(regexObj.Replace(completed2, ""));
                        Output("Completed: " + completed);

                        // Files
                        var qFiles = row.QuerySelector("td:nth-of-type(3) > a");
                        var files  = qFiles != null?ParseUtil.CoerceInt(Regex.Match(qFiles.TextContent, @"\d+").Value) : 1;

                        Output("Files: " + files);

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

                        // --> Date
                        var dateTimeOrig = row.QuerySelector("td:nth-of-type(5)").TextContent;
                        var dateTime     = Regex.Replace(dateTimeOrig, @"<[^>]+>|&nbsp;", "").Trim();
                        var date         = DateTime.ParseExact(dateTime, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
                        Output("Released on: " + date);

                        // Torrent Details URL
                        var details = new Uri(TorrentDetailsUrl.Replace("{id}", id.ToString()));
                        Output("Details: " + details.AbsoluteUri);

                        // Torrent Download URL
                        var passkey      = row.QuerySelector("td:nth-of-type(2) > a:nth-of-type(2)").GetAttribute("href");
                        var key          = Regex.Match(passkey, "(?<=passkey\\=)([a-zA-z0-9]*)");
                        var downloadLink = new Uri(TorrentDownloadUrl.Replace("{id}", id.ToString()).Replace("{passkey}", key.ToString()));
                        Output("Download Link: " + downloadLink.AbsoluteUri);

                        // Building release infos
                        var release = new ReleaseInfo
                        {
                            Category        = MapTrackerCatToNewznab(cat),
                            Title           = name,
                            Seeders         = seeders,
                            Peers           = seeders + leechers,
                            PublishDate     = date,
                            Size            = size,
                            Files           = files,
                            Grabs           = completed,
                            Guid            = details,
                            Details         = details,
                            Link            = downloadLink,
                            MinimumRatio    = 1,
                            MinimumSeedTime = 172800 // 48 hours
                        };

                        var genres = row.QuerySelector("span.genres")?.TextContent;
                        if (!string.IsNullOrEmpty(genres))
                        {
                            release.Description = genres;
                        }

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

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

                        release.UploadVolumeFactor = 1;

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
                }
            }
            // Return found releases
            return(releases);
        }
示例#11
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("showsearch", "1");
            queryCollection.Add("incldead", "1");
            queryCollection.Add("orderby", "added");
            queryCollection.Add("sort", "desc");

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

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

            if (cats.Count == 1)
            {
                cat = cats[0];
            }
            queryCollection.Add("cat", cat);

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

            var response = await RequestBytesWithCookies(searchUrl);

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

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

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

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

                    if (!query.MatchQueryStringAND(release.Title))
                    {
                        continue;
                    }

                    var qCatLink      = qRow.Find("a[href^=browse.php?cat=]").First();
                    var qSeeders      = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(3)");
                    var qLeechers     = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(4)");
                    var qDateStr      = qRow.Find("td > table.testtable > tbody > tr > td:eq(6)");
                    var qSize         = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(1)");
                    var qDownloadLink = qRow.Find("a[href*=download]").First();

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

                    var dlLink = qDownloadLink.Attr("href");
                    if (dlLink.Contains("javascript")) // depending on the user agent the DL link is a javascript call
                    {
                        var dlLinkParts = dlLink.Split(new char[] { '\'', ',' });
                        dlLink = SiteLink + "download/" + dlLinkParts[3] + "/" + dlLinkParts[5];
                    }
                    release.Link     = new Uri(dlLink);
                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
                    release.Guid     = release.Link;

                    var sizeStr = qSize.Text();
                    logger.Error(sizeStr);
                    release.Size = ReleaseInfo.GetBytes(sizeStr.Replace(".", "").Replace(",", "."));

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

                    var      dateStr    = qDateStr.Text().Replace('\xA0', ' ');
                    var      dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
                    release.PublishDate = pubDateUtc;

                    var files = qRow.Find("td:contains(Datei) > strong ~ strong").Text();
                    release.Files = ParseUtil.CoerceInt(files);

                    if (qRow.Find("img[title=\"OnlyUpload\"]").Length >= 1)
                    {
                        release.DownloadVolumeFactor = 0;
                    }
                    else
                    {
                        release.DownloadVolumeFactor = 1;
                    }

                    release.UploadVolumeFactor = 1;

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

            return(releases);
        }
示例#12
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases                = new List <ReleaseInfo>();
            var searchString            = query.GetQueryString();
            var prevCook                = CookieHeader + "";
            var searchStringIsImdbQuery = (ParseUtil.GetImdbID(searchString) != null);

            // If we have no query use the RSS Page as their server is slow enough at times!
            // ~15.01.2019 they removed the description tag making the RSS feed almost useless, we don't use it for now. See #4458
            // if (false && query.IsTest || string.IsNullOrWhiteSpace(searchString))

            /*
             * if (false)
             * {
             *  var rssPage = await RequestStringWithCookiesAndRetry(string.Format(RSSUrl, configData.RSSKey.Value));
             *  try
             *  {
             *      if (rssPage.Content.EndsWith("\0"))
             *      {
             *          rssPage.Content = rssPage.Content.Substring(0, rssPage.Content.Length - 1);
             *      }
             *      rssPage.Content = RemoveInvalidXmlChars(rssPage.Content);
             *      var rssDoc = XDocument.Parse(rssPage.Content);
             *
             *      foreach (var item in rssDoc.Descendants("item"))
             *      {
             *          var title = item.Descendants("title").First().Value;
             *          var description = item.Descendants("description").First().Value;
             *          var link = item.Descendants("link").First().Value;
             *          var category = item.Descendants("category").First().Value;
             *          var date = item.Descendants("pubDate").First().Value;
             *
             *          var torrentIdMatch = Regex.Match(link, "(?<=id=)(\\d)*");
             *          var torrentId = torrentIdMatch.Success ? torrentIdMatch.Value : string.Empty;
             *          if (string.IsNullOrWhiteSpace(torrentId))
             *              throw new Exception("Missing torrent id");
             *
             *          var infoMatch = Regex.Match(description, @"Category:\W(?<cat>.*)\W\/\WSeeders:\W(?<seeders>[\d\,]*)\W\/\WLeechers:\W(?<leechers>[\d\,]*)\W\/\WSize:\W(?<size>[\d\.]*\W\S*)");
             *          if (!infoMatch.Success)
             *              throw new Exception("Unable to find info");
             *
             *          var release = new ReleaseInfo
             *          {
             *              Title = title,
             *              Description = title,
             *              Guid = new Uri(string.Format(DownloadUrl, torrentId)),
             *              Comments = new Uri(string.Format(CommentUrl, torrentId)),
             *              PublishDate = DateTime.ParseExact(date, "yyyy-MM-dd H:mm:ss", CultureInfo.InvariantCulture), //2015-08-08 21:20:31
             *              Link = new Uri(string.Format(DownloadUrl, torrentId)),
             *              Seeders = ParseUtil.CoerceInt(infoMatch.Groups["seeders"].Value),
             *              Peers = ParseUtil.CoerceInt(infoMatch.Groups["leechers"].Value),
             *              Size = ReleaseInfo.GetBytes(infoMatch.Groups["size"].Value),
             *              Category = MapTrackerCatToNewznab(category)
             *          };
             *
             *          release.Peers += release.Seeders;
             *          releases.Add(release);
             *      }
             *  }
             *  catch (Exception ex)
             *  {
             *      logger.Error("XSpeeds: Error while parsing the RSS feed:");
             *      logger.Error(rssPage.Content);
             *      throw ex;
             *  }
             * }
             */
            //if (query.IsTest || !string.IsNullOrWhiteSpace(searchString))

            /*
             * if (searchString.Length < 3 && !query.IsTest)
             * {
             *  OnParseError("", new Exception("Minimum search length is 3"));
             *  return releases;
             * }
             */
            var searchParams = new Dictionary <string, string> {
                { "do", "search" },
                { "category", "0" },
                { "include_dead_torrents", "no" }
            };

            if (query.IsImdbQuery)
            {
                searchParams.Add("keywords", query.ImdbID);
                searchParams.Add("search_type", "t_both");
            }
            else
            {
                searchParams.Add("keywords", searchString);
                if (searchStringIsImdbQuery)
                {
                    searchParams.Add("search_type", "t_both");
                }
                else
                {
                    searchParams.Add("search_type", "t_name");
                }
            }

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

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

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

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

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

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

                    var qBanner = qRow.Find("td:eq(1) .tooltip-content img").First();
                    if (qBanner.Length > 0)
                    {
                        release.BannerUrl = new Uri(qBanner.Attr("src"));
                    }

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

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

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

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

                    releases.Add(release);
                }
            }
            catch (Exception ex)
            {
                OnParseError(searchPage.Content, ex);
            }
            if (!CookieHeader.Trim().Equals(prevCook.Trim()))
            {
                SaveConfig();
            }
            return(releases);
        }
示例#13
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            var qc = new NameValueCollection();

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

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

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

            var results = response.ContentString;

            if (results == null || !results.Contains("/lout.php"))
            {
                throw new Exception("The user is not logged in. It is possible that the cookie has expired or you made a mistake when copying it. Please check the settings.");
            }

            if (string.IsNullOrWhiteSpace(query.ImdbID) && string.IsNullOrWhiteSpace(query.SearchTerm) && results.Contains("No Torrents Found!"))
            {
                throw new Exception("Got No Torrents Found! Make sure your IPTorrents profile config contain proper default category settings.");
            }

            try
            {
                var parser = new HtmlParser();
                var doc    = parser.ParseDocument(results);

                var rows = doc.QuerySelectorAll("table[id='torrents'] > tbody > tr");
                foreach (var row in rows.Skip(1))
                {
                    var qTitleLink = row.QuerySelector("a[href^=\"/details.php?id=\"]");
                    if (qTitleLink == null) // no results
                    {
                        continue;
                    }

                    // drop invalid char that seems to have cropped up in some titles. #6582
                    var title    = qTitleLink.TextContent.Trim().Replace("\u000f", "");
                    var comments = new Uri(SiteLink + qTitleLink.GetAttribute("href").TrimStart('/'));

                    var qLink = row.QuerySelector("a[href^=\"/download.php/\"]");
                    var link  = new Uri(SiteLink + qLink.GetAttribute("href").TrimStart('/'));

                    var descrSplit  = row.QuerySelector(".t_ctime").TextContent.Split('|');
                    var dateSplit   = descrSplit.Last().Trim().Split(new[] { " by " }, StringSplitOptions.None);
                    var publishDate = DateTimeUtil.FromTimeAgo(dateSplit.First());
                    var description = descrSplit.Length > 1 ? "Tags: " + descrSplit.First().Trim() : "";
                    if (dateSplit.Length > 1)
                    {
                        description += " Uploader: " + dateSplit.Last();
                    }
                    description = description.Trim();

                    var catIcon = row.QuerySelector("td:nth-of-type(1) a");
                    if (catIcon == null)
                    {
                        // Torrents - Category column == Text or Code
                        // release.Category = MapTrackerCatDescToNewznab(row.Cq().Find("td:eq(0)").Text()); // Works for "Text" but only contains the parent category
                        throw new Exception("Please, change the 'Torrents - Category column' option to 'Icons' in the website Settings. Wait a minute (cache) and then try again.");
                    }
                    // Torrents - Category column == Icons
                    var cat = MapTrackerCatToNewznab(catIcon.GetAttribute("href").Substring(1));

                    var size           = ReleaseInfo.GetBytes(row.Children[5].TextContent);
                    var grabs          = ParseUtil.CoerceInt(row.Children[6].TextContent);
                    var seeders        = ParseUtil.CoerceInt(row.QuerySelector(".t_seeders").TextContent.Trim());
                    var leechers       = ParseUtil.CoerceInt(row.QuerySelector(".t_leechers").TextContent.Trim());
                    var dlVolumeFactor = row.QuerySelector("span.t_tag_free_leech") != null ? 0 : 1;

                    var release = new ReleaseInfo
                    {
                        Title                = title,
                        Comments             = comments,
                        Guid                 = comments,
                        Link                 = link,
                        PublishDate          = publishDate,
                        Category             = cat,
                        Description          = description,
                        Size                 = size,
                        Grabs                = grabs,
                        Seeders              = seeders,
                        Peers                = seeders + leechers,
                        DownloadVolumeFactor = dlVolumeFactor,
                        UploadVolumeFactor   = 1,
                        MinimumRatio         = 1,
                        MinimumSeedTime      = 1209600 // 336 hours
                    };

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

            return(releases);
        }
示例#14
0
        public async Task <IEnumerable <ReleaseInfo> > GetResults(string searchTerm)
        {
            var cleanSearchTerm = HttpUtility.UrlEncode(searchTerm);

            // This tracker only deals with full seasons so chop off the episode/season number if we have it D:
            if (!string.IsNullOrWhiteSpace(searchTerm))
            {
                var splitindex = searchTerm.LastIndexOf(' ');
                if (splitindex > -1)
                {
                    searchTerm = searchTerm.Substring(0, splitindex);
                }
            }

            // The result list
            var releases = new List <ReleaseInfo>();

            // Check cache first so we don't query the server for each episode when searching for each episode in a series.
            lock (cache)
            {
                // Remove old cache items
                CleanCache();

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

            var queryUrl = SearchUrl;

            // Only include the query bit if its required as hopefully the site caches the non query page
            if (!string.IsNullOrWhiteSpace(searchTerm))
            {
                queryUrl += string.Format("searchstr={0}&action=advanced&search_type=title&year=&year2=&tags=&tags_type=0&sort=time_added&way=desc&hentai=2&releasegroup=&epcount=&epcount2=&artbooktitle=", cleanSearchTerm);
            }

            // Get the content from the tracker
            var response = await RequestStringWithCookiesAndRetry(queryUrl);

            CQ dom = response.Content;

            // Parse
            try
            {
                var releaseInfo = "S01";
                var root        = dom.Find(".group_cont");
                // We may have got redirected to the series page if we have none of these
                if (root.Count() == 0)
                {
                    root = dom.Find(".torrent_table");
                }

                foreach (var series in root)
                {
                    var seriesCq = series.Cq();

                    var synonyms  = new List <string>();
                    var mainTitle = seriesCq.Find(".group_title strong a").First().Text().Trim();

                    var yearStr   = seriesCq.Find(".group_title strong").First().Text().Trim().Replace("]", "").Trim();
                    int yearIndex = yearStr.LastIndexOf("[");
                    if (yearIndex > -1)
                    {
                        yearStr = yearStr.Substring(yearIndex + 1);
                    }

                    int year = 0;
                    if (!int.TryParse(yearStr, out year))
                    {
                        year = DateTime.Now.Year;
                    }

                    synonyms.Add(mainTitle);

                    // If the title contains a comma then we can't use the synonyms as they are comma seperated
                    if (!mainTitle.Contains(","))
                    {
                        var symnomnNames = string.Empty;
                        foreach (var e in seriesCq.Find(".group_statbox li"))
                        {
                            if (e.FirstChild.InnerText == "Synonyms:")
                            {
                                symnomnNames = e.InnerText;
                            }
                        }

                        if (!string.IsNullOrWhiteSpace(symnomnNames))
                        {
                            foreach (var name in symnomnNames.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
                            {
                                var theName = name.Trim();
                                if (!theName.Contains("&#") && !string.IsNullOrWhiteSpace(theName))
                                {
                                    synonyms.Add(theName);
                                }
                            }
                        }
                    }

                    foreach (var title in synonyms)
                    {
                        var releaseRows = seriesCq.Find(".torrent_group tr");

                        // Skip the first two info rows
                        for (int r = 1; r < releaseRows.Count(); r++)
                        {
                            var row   = releaseRows.Get(r);
                            var rowCq = row.Cq();
                            if (rowCq.HasClass("edition_info"))
                            {
                                releaseInfo = rowCq.Find("td").Text();

                                if (string.IsNullOrWhiteSpace(releaseInfo))
                                {
                                    // Single episodes alpha - Reported that this info is missing.
                                    // It should self correct when availible
                                    break;
                                }

                                releaseInfo = releaseInfo.Replace("Episode ", "");
                                releaseInfo = releaseInfo.Replace("Season ", "S");
                                releaseInfo = releaseInfo.Trim();
                            }
                            else if (rowCq.HasClass("torrent"))
                            {
                                var links = rowCq.Find("a");
                                // Protect against format changes
                                if (links.Count() != 2)
                                {
                                    continue;
                                }

                                var release = new ReleaseInfo();
                                release.MinimumRatio    = 1;
                                release.MinimumSeedTime = 259200;
                                var downloadLink = links.Get(0);

                                // We dont know this so try to fake based on the release year
                                release.PublishDate = new DateTime(year, 1, 1);
                                release.PublishDate = release.PublishDate.AddDays(Math.Min(DateTime.Now.DayOfYear, 365) - 1);

                                var infoLink = links.Get(1);
                                release.Comments = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href"));
                                release.Guid     = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href") + "&nh=" + StringUtil.Hash(title)); // Sonarr should dedupe on this url - allow a url per name.
                                release.Link     = new Uri(downloadLink.Attributes.GetAttribute("href"), UriKind.Relative);

                                var category = seriesCq.Find("a[title=\"View Torrent\"]").Text().Trim();
                                if (category == "TV Series")
                                {
                                    release.Category = TorznabCatType.TVAnime.ID;
                                }

                                // Ignore these categories as they'll cause hell with the matcher
                                // TV Special, OVA, ONA, DVD Special, BD Special

                                if (category == "Movie")
                                {
                                    release.Category = TorznabCatType.Movies.ID;
                                }

                                if (category == "Manga" || category == "Oneshot" || category == "Anthology" || category == "Manhwa" || category == "Manhua" || category == "Light Novel")
                                {
                                    release.Category = TorznabCatType.BooksComics.ID;
                                }

                                if (category == "Novel" || category == "Artbook")
                                {
                                    release.Category = TorznabCatType.BooksComics.ID;
                                }

                                if (category == "Game" || category == "Visual Novel")
                                {
                                    var description = rowCq.Find(".torrent_properties a:eq(1)").Text();
                                    if (description.Contains(" PSP "))
                                    {
                                        release.Category = TorznabCatType.ConsolePSP.ID;
                                    }
                                    if (description.Contains("PSX"))
                                    {
                                        release.Category = TorznabCatType.ConsoleOther.ID;
                                    }
                                    if (description.Contains(" NES "))
                                    {
                                        release.Category = TorznabCatType.ConsoleOther.ID;
                                    }
                                    if (description.Contains(" PC "))
                                    {
                                        release.Category = TorznabCatType.PCGames.ID;
                                    }
                                }



                                // We dont actually have a release name >.> so try to create one
                                var releaseTags = infoLink.InnerText.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
                                for (int i = releaseTags.Count - 1; i >= 0; i--)
                                {
                                    releaseTags[i] = releaseTags[i].Trim();
                                    if (string.IsNullOrWhiteSpace(releaseTags[i]))
                                    {
                                        releaseTags.RemoveAt(i);
                                    }
                                }

                                var group = releaseTags.Last();
                                if (group.Contains("(") && group.Contains(")"))
                                {
                                    // Skip raws if set
                                    if (group.ToLowerInvariant().StartsWith("raw") && !AllowRaws)
                                    {
                                        continue;
                                    }

                                    var start = group.IndexOf("(");
                                    group = "[" + group.Substring(start + 1, (group.IndexOf(")") - 1) - start) + "] ";
                                }
                                else
                                {
                                    group = string.Empty;
                                }

                                var infoString = "";

                                for (int i = 0; i + 1 < releaseTags.Count(); i++)
                                {
                                    if (releaseTags[i] == "Raw" && !AllowRaws)
                                    {
                                        continue;
                                    }
                                    infoString += "[" + releaseTags[i] + "]";
                                }

                                if (category == "Movie")
                                {
                                    release.Title = string.Format("{0} {1} {2}{3}", title, year, group, infoString);
                                }
                                else
                                {
                                    release.Title = string.Format("{0}{1} {2} {3}", group, title, releaseInfo, infoString);
                                }
                                release.Description = title;

                                var size = rowCq.Find(".torrent_size");
                                if (size.Count() > 0)
                                {
                                    release.Size = ReleaseInfo.GetBytes(size.First().Text());
                                }

                                //  Additional 5 hours per GB
                                release.MinimumSeedTime += (release.Size / 1000000000) * 18000;

                                // Peer info
                                release.Seeders = ParseUtil.CoerceInt(rowCq.Find(".torrent_seeders").Text());
                                release.Peers   = release.Seeders + ParseUtil.CoerceInt(rowCq.Find(".torrent_leechers").Text());

                                if (release.Category != 0)
                                {
                                    releases.Add(release);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                OnParseError(response.Content, ex);
            }

            // Add to the cache
            lock (cache)
            {
                cache.Add(new CachedQueryResult(searchTerm, releases));
            }

            return(releases.Select(s => (ReleaseInfo)s.Clone()));
        }
示例#15
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 3, 5, DayOfWeek.Sunday);
            TimeZoneInfo.TransitionTime endTransition   = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 10, 5, DayOfWeek.Sunday);
            TimeSpan delta = new TimeSpan(1, 0, 0);

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

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

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

            string episodeSearchUrl;

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

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

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

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

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

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

                    var dlUrlAnchor = qRow.Find("span.right a").FirstElement();
                    var dlUrl       = dlUrlAnchor.GetAttribute("href");
                    var authkey     = Regex.Match(dlUrl, "authkey=(?<authkey>[0-9a-zA-Z]+)").Groups["authkey"].Value;
                    var torrentPass = Regex.Match(dlUrl, "torrent_pass=(?<torrent_pass>[0-9a-zA-Z]+)").Groups["torrent_pass"].Value;
                    var torrentId   = Regex.Match(dlUrl, "id=(?<id>[0-9]+)").Groups["id"].Value;
                    release.Link = new Uri($"{SearchUrl}/{title}.torrent/?action=download&authkey={authkey}&torrent_pass={torrentPass}&id={torrentId}");

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

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

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

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

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

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

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

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

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

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

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