Exemple #1
0
        async Task <ReleaseInfo[]> PerformQuery(TorznabQuery query, string baseUrl)
        {
            List <ReleaseInfo> releases = new List <ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString     = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(searchAllUrl);

                XmlDocument xmlDoc = new XmlDocument();
                string      xml    = string.Empty;
                WebClient   wc     = getWebClient();

                try
                {
                    using (wc)
                    {
                        xml = wc.DownloadString(episodeSearchUrl);
                        xmlDoc.LoadXml(xml);
                    }

                    ReleaseInfo    release;
                    TorrentzHelper td;
                    string         serie_title;

                    foreach (XmlNode node in xmlDoc.GetElementsByTagName("item"))
                    {
                        release = new ReleaseInfo();

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

                        serie_title   = node.SelectSingleNode("title").InnerText;
                        release.Title = serie_title;

                        release.Comments = new Uri(node.SelectSingleNode("link").InnerText);
                        release.Category = node.SelectSingleNode("title").InnerText;
                        var test = node.SelectSingleNode("enclosure");
                        release.Guid        = new Uri(test.Attributes["url"].Value);
                        release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture);

                        release.Description = node.SelectSingleNode("description").InnerText;
                        release.InfoHash    = node.SelectSingleNode("description").InnerText;
                        release.Size        = 0;
                        release.Seeders     = 1;
                        release.Peers       = 1;
                        release.MagnetUri   = new Uri(node.SelectSingleNode("link").InnerText);
                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, xml, ex);
                    throw ex;
                }
            }

            return(releases.ToArray());
        }
Exemple #2
0
        private async Task ParseSeriesRelease(ICollection <ReleaseInfo> releases, string link, TorznabQuery query, string title, string quality)
        {
            var result = await RequestWithCookiesAsync(link);

            if (result.Status != HttpStatusCode.OK)
            {
                throw new ExceptionWithConfigData(result.ContentString, configData);
            }

            var searchResultParser = new HtmlParser();
            var doc = searchResultParser.ParseDocument(result.ContentString);

            var data = doc.QuerySelector("div.descargar > div.card > div.card-body");

            //var _title = data.QuerySelector("h2.descargarTitulo").TextContent;

            //var data2 = data.QuerySelectorAll("div.d-inline-block > p");

            //var quality = data2[0].TextContent; //"Formato: {0}" -- needs trimming
            //var episodes = data2[1].TextContent; //"Episodios: {0}" -- needs trimming, contains number of episodes available

            var data3 = data.QuerySelectorAll("div.d-inline-block > table.table > tbody > tr");

            foreach (var row in data3)
            {
                var episodeData = row.QuerySelectorAll("td");

                var episodeTitle      = episodeData[0].TextContent;                                        //it may contain two episodes divided by '&', eg '1x01 & 1x02'
                var downloadLink      = "https:" + episodeData[1].QuerySelector("a").GetAttribute("href"); // URL like "//cdn.pizza/"
                var episodePublishStr = episodeData[2].TextContent;
                var episodePublish    = TryToParseDate(episodePublishStr, DateTime.Now);

                // Convert the title to Scene format
                episodeTitle = ParseSeriesTitle(title, episodeTitle, query);

                // if the original query was in scene format, we filter the results to match episode
                // query.Episode != null means scene title
                if (query.Episode != null && !episodeTitle.Contains(query.GetEpisodeSearchString()))
                {
                    continue;
                }

                // guess size
                var size = 536870912L; // 512 MB
                if (episodeTitle.ToLower().Contains("720p"))
                {
                    size = 1073741824L; // 1 GB
                }
                if (episodeTitle.ToLower().Contains("1080p"))
                {
                    size = 4294967296L; // 4 GB
                }
                size *= GetEpisodeCountFromTitle(episodeTitle);

                var release = GenerateRelease(episodeTitle, link, downloadLink, GetCategory(title, link), episodePublish, size);
                releases.Add(release);
            }
        }
Exemple #3
0
        public async Task <ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List <ReleaseInfo> releases = new List <ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString     = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);
                var results          = await client.GetStringAsync(episodeSearchUrl);

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

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

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

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

                        var sizeCol  = qRow.Children().ElementAt(6);
                        var sizeVal  = sizeCol.ChildNodes[0].NodeValue;
                        var sizeUnit = sizeCol.ChildNodes[2].NodeValue;
                        release.Size = ReleaseInfo.GetBytes(sizeUnit, float.Parse(sizeVal));

                        release.Seeders = int.Parse(qRow.Children().ElementAt(8).Cq().Text().Trim(), NumberStyles.AllowThousands);
                        release.Peers   = int.Parse(qRow.Children().ElementAt(9).Cq().Text().Trim(), NumberStyles.AllowThousands) + release.Seeders;

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }

            return(releases.ToArray());
        }
Exemple #4
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var results = await PerformQuery(query, null);

            if (results.Count() == 0 && query.IsTVSearch) // if we search for a localized title ncore can't handle any extra S/E information, search without it and AND filter the results. See #1450
            {
                results = await PerformQuery(query, query.GetEpisodeSearchString());
            }

            return(results);
        }
Exemple #5
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases         = new List <ReleaseInfo>();
            var searchTerm       = string.IsNullOrEmpty(query.SanitizedSearchTerm) ? "%20" : query.SanitizedSearchTerm;
            var searchString     = searchTerm + " " + query.GetEpisodeSearchString();
            var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));

            var message = new HttpRequestMessage();

            message.Method     = HttpMethod.Get;
            message.RequestUri = new Uri(episodeSearchUrl);
            message.Headers.TryAddWithoutValidation("Authorization", await GetAuthToken());

            var response = await client.SendAsync(message);

            var results = await response.Content.ReadAsStringAsync();

            var jsonResult = JObject.Parse(results);

            try
            {
                var items = (JArray)jsonResult["torrents"];
                foreach (var item in items)
                {
                    var release = new ReleaseInfo();

                    release.MinimumRatio    = 1;
                    release.MinimumSeedTime = 172800;
                    var torrentId = (string)item["id"];
                    release.Link        = new Uri(string.Format(DownloadUrl, torrentId));
                    release.Title       = (string)item["name"];
                    release.Description = release.Title;
                    release.Comments    = new Uri(string.Format(CommentsUrl, (string)item["rewritename"]));
                    release.Guid        = release.Comments;

                    var dateUtc = DateTime.ParseExact((string)item["added"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                    release.PublishDate = DateTime.SpecifyKind(dateUtc, DateTimeKind.Utc).ToLocalTime();

                    release.Seeders = ParseUtil.CoerceInt((string)item["seeders"]);
                    release.Peers   = ParseUtil.CoerceInt((string)item["leechers"]) + release.Seeders;

                    release.Size = ParseUtil.CoerceLong((string)item["size"]);

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

            foreach (var title in query.ShowTitles ?? new string[] { "2015" })
            {
                var searchString     = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = baseUrl + string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim()));
                var results          = await client.GetStringAsync(episodeSearchUrl);

                try
                {
                    var jResults = JObject.Parse(results);
                    foreach (JObject result in (JArray)jResults["torrents"])
                    {
                        var release = new ReleaseInfo();

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

                        release.Title       = (string)result["torrent_title"];
                        release.Description = release.Title;
                        release.Seeders     = (int)result["seeds"];
                        release.Peers       = (int)result["leeches"] + release.Seeders;
                        release.Size        = (long)result["size"];

                        // "Apr  2, 2015", "Apr 12, 2015" (note the spacing)
                        var dateString = string.Join(" ", ((string)result["upload_date"]).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
                        release.PublishDate = DateTime.ParseExact(dateString, "MMM d, yyyy", CultureInfo.InvariantCulture);

                        release.Guid     = new Uri((string)result["page"]);
                        release.Comments = release.Guid;

                        release.InfoHash  = (string)result["torrent_hash"];
                        release.MagnetUri = new Uri((string)result["magnet_uri"]);
                        release.Link      = new Uri(string.Format("{0}{1}{2}", baseUrl, DownloadUrl, release.InfoHash));

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }

            return(releases.ToArray());
        }
Exemple #7
0
        private async Task ParseSeriesRelease(ICollection <ReleaseInfo> releases, TorznabQuery query,
                                              string commentsLink, string cat, DateTime publishDate)
        {
            var result = await RequestStringWithCookies(commentsLink);

            if (result.Status != HttpStatusCode.OK)
            {
                throw new ExceptionWithConfigData(result.Content, configData);
            }

            var searchResultParser = new HtmlParser();
            var doc = searchResultParser.ParseDocument(result.Content);

            var tables = doc.QuerySelectorAll("table.table");

            foreach (var table in tables)
            {
                var rows     = table.QuerySelectorAll("tr");
                var isHeader = true;
                foreach (var row in rows)
                {
                    if (isHeader)
                    {
                        isHeader = false;
                        continue;
                    }

                    var anchor            = row.QuerySelector("a");
                    var episodeTitle      = anchor.TextContent.Trim();
                    var onclick           = anchor.GetAttribute("onclick");
                    var downloadLink      = OnclickToDownloadLink(onclick);
                    var episodePublishStr = row.QuerySelectorAll("td")[3].TextContent.Trim();
                    var episodePublish    = TryToParseDate(episodePublishStr, publishDate);

                    // Convert the title to Scene format
                    episodeTitle = ParseDivxTotalSeriesTitle(episodeTitle, query);

                    // if the original query was in scene format, we filter the results to match episode
                    // query.Episode != null means scene title
                    if (query.Episode != null && !episodeTitle.Contains(query.GetEpisodeSearchString()))
                    {
                        continue;
                    }

                    GenerateRelease(releases, episodeTitle, commentsLink, downloadLink, cat, episodePublish,
                                    DivxTotalFizeSizes.Series);
                }
            }
        }
Exemple #8
0
        private async Task ParseSeriesRelease(ICollection <ReleaseInfo> releases, TorznabQuery query, string title,
                                              string detailsStr, string cat, DateTime publishDate)
        {
            var result = await RequestWithCookiesAsync(detailsStr);

            if (result.Status != HttpStatusCode.OK)
            {
                throw new ExceptionWithConfigData(result.ContentString, configData);
            }

            var searchResultParser = new HtmlParser();
            var doc = searchResultParser.ParseDocument(result.ContentString);

            var rows = doc.QuerySelectorAll("#main_table_center_center1 table table table tr");

            foreach (var row in rows)
            {
                var anchor = row.QuerySelector("a");
                if (anchor == null || anchor.GetAttribute("href") == "#abajo")
                {
                    continue;
                }

                var episodeTitle      = anchor.TextContent.Trim();
                var downloadLink      = SiteLink + anchor.GetAttribute("href").TrimStart('/');
                var episodePublishStr = row.QuerySelector("div").TextContent.Trim().Replace("Fecha: ", "");
                var episodePublish    = TryToParseDate(episodePublishStr, publishDate);

                // Convert the title to Scene format
                episodeTitle = ParseMejorTorrentSeriesTitle(title, episodeTitle, query);

                // if the original query was in scene format, we filter the results to match episode
                // query.Episode != null means scene title
                if (query.Episode != null && !episodeTitle.Contains(query.GetEpisodeSearchString()))
                {
                    continue;
                }

                // guess size
                var size = 524288000L; // 500 MB
                if (episodeTitle.ToLower().Contains("720p"))
                {
                    size = 1288490188L; // 1.2 GB
                }
                var release = GenerateRelease(episodeTitle, detailsStr, downloadLink, cat, episodePublish, size);
                releases.Add(release);
            }
        }
Exemple #9
0
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var results = new List <ReleaseInfo>();

            if (!(query.IsImdbQuery && query.IsTVSearch))
            {
                results = await PerformQueryAsync(query, null);
            }
            // if we search for a localized title nCore can't handle any extra S/E information
            // search without it and AND filter the results. See #1450
            if (query.IsTVSearch && (!results.Any() || query.IsImdbQuery))
            {
                results = await PerformQueryAsync(query, query.GetEpisodeSearchString());
            }
            return(results);
        }
Exemple #10
0
        private async Task ParseSeriesRelease(ICollection <ReleaseInfo> releases, TorznabQuery query, string title,
                                              string detailsStr, string cat, DateTime publishDate, string quality)
        {
            var result = await RequestWithCookiesAsync(detailsStr);

            if (result.Status != HttpStatusCode.OK)
            {
                throw new ExceptionWithConfigData(result.ContentString, configData);
            }

            var searchResultParser = new HtmlParser();
            var doc = searchResultParser.ParseDocument(result.ContentString);

            var rows = doc.QuerySelectorAll("tr.border");

            quality = CleanQuality(quality);
            ParseTags(title, quality);
            foreach (var row in rows)
            {
                var episodeTitle      = row.Children[1].TextContent.Replace("\n", String.Empty);
                var downloadLink      = row.Children.Last().Children[0].GetAttribute("href");
                var episodePublishStr = row.Children[2].TextContent.Replace("\n", String.Empty);
                var episodePublish    = TryToParseDate(episodePublishStr, publishDate);

                // Convert the title to Scene format
                episodeTitle = ParseMejorTorrentSeriesTitle(title, episodeTitle, quality, query);

                // if the original query was in scene format, we filter the results to match episode
                // query.Episode != null means scene title
                if (query.Episode != null && !episodeTitle.Contains(query.GetEpisodeSearchString()))
                {
                    continue;
                }

                // guess size
                var size = 536870912L; // 512 MB
                if (title.ToLower().Contains("720p"))
                {
                    size = 1073741824L; // 1 GB
                }
                var release = GenerateRelease(episodeTitle, detailsStr, downloadLink, cat, episodePublish, size);
                releases.Add(release);
            }
        }
Exemple #11
0
        private async Task <List <ReleaseInfo> > ParseSeriesReleaseAsync(TorznabQuery query, string detailsStr, string cat, DateTime publishDate)
        {
            var seriesReleases = new List <ReleaseInfo>();

            var htmlString = await LoadWebPageAsync(detailsStr);

            var htmlDocument = ParseHtmlIntoDocument(htmlString);

            var tables = htmlDocument.QuerySelectorAll("table.table");

            foreach (var table in tables)
            {
                var rows = table.QuerySelectorAll("tbody > tr");
                foreach (var row in rows)
                {
                    var anchor       = row.QuerySelector("a");
                    var episodeTitle = anchor.TextContent.Trim();

                    // Convert the title to Scene format
                    episodeTitle = ParseDivxTotalSeriesTitle(episodeTitle, query);

                    // if the original query was in scene format, we filter the results to match episode
                    // query.Episode != null means scene title
                    if (query.Episode != null && !episodeTitle.Contains(query.GetEpisodeSearchString()))
                    {
                        continue;
                    }

                    var downloadLink      = GetDownloadLink(row);
                    var episodePublishStr = row.QuerySelectorAll("td")[3].TextContent.Trim();
                    var episodePublish    = TryToParseDate(episodePublishStr, publishDate);

                    seriesReleases.Add(GenerateRelease(episodeTitle, detailsStr, downloadLink, cat, episodePublish, DivxTotalFizeSizes.Series));
                }
            }

            return(seriesReleases);
        }
Exemple #12
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            searchBlock Search = Definition.Search;

            // init template context
            var variables = getTemplateVariablesFromConfigData();

            variables[".Query.Type"]       = query.QueryType;
            variables[".Query.Q"]          = query.SearchTerm;
            variables[".Query.Series"]     = null;
            variables[".Query.Ep"]         = query.Episode;
            variables[".Query.Season"]     = query.Season;
            variables[".Query.Movie"]      = null;
            variables[".Query.Year"]       = null;
            variables[".Query.Limit"]      = query.Limit;
            variables[".Query.Offset"]     = query.Offset;
            variables[".Query.Extended"]   = query.Extended;
            variables[".Query.Categories"] = query.Categories;
            variables[".Query.APIKey"]     = query.ApiKey;
            variables[".Query.TVDBID"]     = null;
            variables[".Query.TVRageID"]   = query.RageID;
            variables[".Query.IMDBID"]     = query.ImdbID;
            variables[".Query.TVMazeID"]   = null;
            variables[".Query.TraktID"]    = null;

            variables[".Query.Episode"] = query.GetEpisodeSearchString();
            variables[".Categories"]    = MapTorznabCapsToTrackers(query);

            var KeywordTokens    = new List <string>();
            var KeywordTokenKeys = new List <string> {
                "Q", "Series", "Movie", "Year"
            };

            foreach (var key in KeywordTokenKeys)
            {
                var Value = (string)variables[".Query." + key];
                if (!string.IsNullOrWhiteSpace(Value))
                {
                    KeywordTokens.Add(Value);
                }
            }

            if (!string.IsNullOrWhiteSpace((string)variables[".Query.Episode"]))
            {
                KeywordTokens.Add((string)variables[".Query.Episode"]);
            }
            variables[".Query.Keywords"] = string.Join(" ", KeywordTokens);
            variables[".Keywords"]       = variables[".Query.Keywords"];

            // build search URL
            var searchUrl       = SiteLink + applyGoTemplateText(Search.Path, variables) + "?";
            var queryCollection = new NameValueCollection();

            if (Search.Inputs != null)
            {
                foreach (var Input in Search.Inputs)
                {
                    var value = applyGoTemplateText(Input.Value, variables);
                    if (Input.Key == "$raw")
                    {
                        searchUrl += value;
                    }
                    else
                    {
                        queryCollection.Add(Input.Key, value);
                    }
                }
            }
            searchUrl += "&" + queryCollection.GetQueryString();

            // send HTTP request
            var response = await RequestBytesWithCookies(searchUrl);

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

            try
            {
                var SearchResultParser   = new HtmlParser();
                var SearchResultDocument = SearchResultParser.Parse(results);

                var             RowsDom = SearchResultDocument.QuerySelectorAll(Search.Rows.Selector);
                List <IElement> Rows    = new List <IElement>();
                foreach (var RowDom in RowsDom)
                {
                    Rows.Add(RowDom);
                }

                // merge following rows for After selector
                var After = Definition.Search.Rows.After;
                if (After > 0)
                {
                    for (int i = 0; i < Rows.Count; i += 1)
                    {
                        var CurrentRow = Rows[i];
                        for (int j = 0; j < After; j += 1)
                        {
                            var          MergeRowIndex = i + j + 1;
                            var          MergeRow      = Rows[MergeRowIndex];
                            List <INode> MergeNodes    = new List <INode>();
                            foreach (var node in MergeRow.QuerySelectorAll("td"))
                            {
                                MergeNodes.Add(node);
                            }
                            CurrentRow.Append(MergeNodes.ToArray());
                        }
                        Rows.RemoveRange(i + 1, After);
                    }
                }

                foreach (var Row in Rows)
                {
                    try
                    {
                        var release = new ReleaseInfo();
                        release.MinimumRatio    = 1;
                        release.MinimumSeedTime = 48 * 60 * 60;

                        // Parse fields
                        foreach (var Field in Search.Fields)
                        {
                            string value = handleSelector(Field.Value, Row);
                            value = ParseUtil.NormalizeSpace(value);
                            try
                            {
                                switch (Field.Key)
                                {
                                case "download":
                                    if (value.StartsWith("magnet:"))
                                    {
                                        release.MagnetUri = new Uri(value);
                                        release.Link      = release.MagnetUri;
                                    }
                                    else
                                    {
                                        release.Link = resolvePath(value);
                                    }
                                    break;

                                case "details":
                                    var url = resolvePath(value);
                                    release.Guid = url;
                                    if (release.Comments == null)
                                    {
                                        release.Comments = url;
                                    }
                                    break;

                                case "comments":
                                    var CommentsUrl = resolvePath(value);
                                    release.Comments = CommentsUrl;
                                    if (release.Guid == null)
                                    {
                                        release.Guid = CommentsUrl;
                                    }
                                    break;

                                case "title":
                                    release.Title = value;
                                    break;

                                case "description":
                                    release.Description = value;
                                    break;

                                case "category":
                                    release.Category = MapTrackerCatToNewznab(value);
                                    break;

                                case "size":
                                    release.Size = ReleaseInfo.GetBytes(value);
                                    break;

                                case "leechers":
                                    if (release.Peers == null)
                                    {
                                        release.Peers = ParseUtil.CoerceInt(value);
                                    }
                                    else
                                    {
                                        release.Peers += ParseUtil.CoerceInt(value);
                                    }
                                    break;

                                case "seeders":
                                    release.Seeders = ParseUtil.CoerceInt(value);
                                    if (release.Peers == null)
                                    {
                                        release.Peers = release.Seeders;
                                    }
                                    else
                                    {
                                        release.Peers += release.Seeders;
                                    }
                                    break;

                                case "date":
                                    release.PublishDate = DateTimeUtil.FromUnknown(value);
                                    break;

                                case "files":
                                    release.Files = ParseUtil.CoerceLong(value);
                                    break;

                                case "grabs":
                                    release.Grabs = ParseUtil.CoerceLong(value);
                                    break;

                                case "downloadvolumefactor":
                                    release.DownloadVolumeFactor = ParseUtil.CoerceDouble(value);
                                    break;

                                case "uploadvolumefactor":
                                    release.UploadVolumeFactor = ParseUtil.CoerceDouble(value);
                                    break;

                                default:
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception(string.Format("Error while parsing field={0}, selector={1}, value={2}: {3}", Field.Key, Field.Value.Selector, value, ex.Message));
                            }
                        }

                        // if DateHeaders is set go through the previous rows and look for the header selector
                        var DateHeaders = Definition.Search.Rows.Dateheaders;
                        if (DateHeaders != null)
                        {
                            var    PrevRow = Row.PreviousElementSibling;
                            string value   = null;
                            while (PrevRow != null)
                            {
                                try
                                {
                                    value = handleSelector(DateHeaders, PrevRow);
                                    break;
                                }
                                catch (Exception ex)
                                {
                                    // do nothing
                                }
                                PrevRow = PrevRow.PreviousElementSibling;
                            }

                            if (value == null)
                            {
                                throw new Exception(string.Format("No date header row found for {0}", release.ToString()));
                            }

                            release.PublishDate = DateTimeUtil.FromUnknown(value);
                        }

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

            return(releases);
        }
Exemple #13
0
        private string BuildSearchUrl(TorznabQuery query)
        {
            var searchString        = query.GetQueryString();
            var episodeSearchString = query.GetEpisodeSearchString();
            var qc = new NameValueCollection
            {
                { "token", _token },
                { "format", "json_extended" },
                { "app_id", _appId },
                { "limit", "100" },
                { "ranked", "0" },
                { "sort", _sort }
            };

            if (query.IsTVSearch && !string.IsNullOrWhiteSpace(episodeSearchString) && query.ImdbID != null)
            {
                qc.Add("mode", "search");
                qc.Add("search_imdb", query.ImdbID);
                qc.Add("search_string", episodeSearchString);
            }
            else if (query.ImdbID != null)
            {
                qc.Add("mode", "search");
                qc.Add("search_imdb", query.ImdbID);
            }
            else if (query.RageID != null)
            {
                qc.Add("mode", "search");
                qc.Add("search_tvrage", query.RageID.ToString());
            }

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

            var querycats = MapTorznabCapsToTrackers(query);

            if (querycats.Count == 0)
            {
                // default to all, without specifying it some categories are missing (e.g. games), see #4146
                querycats = GetAllTrackerCategories();
            }
            var cats = string.Join(";", querycats);

            qc.Add("category", cats);

            return(ApiEndpoint + "?" + qc.GetQueryString());
        }
Exemple #14
0
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
                var results = await client.GetStringAsync(episodeSearchUrl);
                try
                {
                    CQ dom = results;
                    var rows = dom["#torrent_table > tbody > tr.torrent"];
                    foreach (var row in rows)
                    {
                        CQ qRow = row.Cq();
                        var release = new ReleaseInfo();

                        release.MinimumRatio = 1;
                        release.MinimumSeedTime = 172800;
                        release.Title = qRow.Find(".torrent_name_link").Text();
                        release.Description = release.Title;
                        release.Guid = new Uri(BaseUrl + "/" + qRow.Find(".torrent_name_link").Parent().Attr("href"));
                        release.Comments = release.Guid;
                        release.Link = new Uri(BaseUrl + "/" + qRow.Find(".torrent_handle_links > a").First().Attr("href"));

                        var dateStr = qRow.Find(".time").Text().Trim();
                        if (dateStr.ToLower().Contains("just now"))
                            release.PublishDate = DateTime.Now;
                        else
                        {
                            var dateParts = dateStr.Split(' ');
                            var dateValue = int.Parse(dateParts[0]);
                            TimeSpan ts = TimeSpan.Zero;
                            if (dateStr.Contains("sec"))
                                ts = TimeSpan.FromSeconds(dateValue);
                            else if (dateStr.Contains("min"))
                                ts = TimeSpan.FromMinutes(dateValue);
                            else if (dateStr.Contains("hour"))
                                ts = TimeSpan.FromHours(dateValue);
                            else if (dateStr.Contains("day"))
                                ts = TimeSpan.FromDays(dateValue);
                            else if (dateStr.Contains("week"))
                                ts = TimeSpan.FromDays(dateValue * 7);
                            else if (dateStr.Contains("month"))
                                ts = TimeSpan.FromDays(dateValue * 30);
                            else if (dateStr.Contains("year"))
                                ts = TimeSpan.FromDays(dateValue * 365);
                            release.PublishDate = DateTime.Now - ts;
                        }

                        var sizeStr = qRow.Find(".size")[0].ChildNodes[0].NodeValue.Trim();
                        var sizeParts = sizeStr.Split(' ');
                        release.Size = ReleaseInfo.GetBytes(sizeParts[1], float.Parse(sizeParts[0], NumberStyles.AllowThousands));
                        release.Seeders = int.Parse(qRow.Children().ElementAt(6).InnerText.Trim(), NumberStyles.AllowThousands);
                        release.Peers = int.Parse(qRow.Children().ElementAt(7).InnerText.Trim(), NumberStyles.AllowThousands) + release.Seeders;

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }
            return releases.ToArray();
        }
Exemple #15
0
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);
                var results = await client.GetStringAsync(episodeSearchUrl);
                try
                {
                    CQ dom = results;
                    dom["#needseed"].Remove();
                    var rows = dom["table[width='750'] > tbody"].Children();
                    foreach (var row in rows.Skip(1))
                    {

                        var release = new ReleaseInfo();

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

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

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

                        var sizeCol = qRow.Children().ElementAt(6);
                        var sizeVal = sizeCol.ChildNodes[0].NodeValue;
                        var sizeUnit = sizeCol.ChildNodes[2].NodeValue;
                        release.Size = ReleaseInfo.GetBytes(sizeUnit, ParseUtil.CoerceFloat(sizeVal));

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

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            // Return found releases
            return(releases);
        }
Exemple #17
0
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();

                var searchContent = GetSearchFormData(searchString);
                var response = await client.PostAsync(SearchUrl, searchContent);
                var results = await response.Content.ReadAsStringAsync();

                try
                {
                    CQ dom = results;
                    var rows = dom["tr.browse"];
                    foreach (var row in rows)
                    {
                        var release = new ReleaseInfo();
                        release.MinimumRatio = 1;
                        release.MinimumSeedTime = 172800;

                        var descCol = row.ChildElements.ElementAt(1);
                        var qDescCol = descCol.Cq();
                        var qLink = qDescCol.Find("a");
                        release.Title = qLink.Text();
                        release.Description = release.Title;
                        release.Comments = new Uri(BaseUrl + "/" + qLink.Attr("href"));
                        release.Guid = release.Comments;
                        var torrentId = qLink.Attr("href").Split('=')[1];
                        release.Link = new Uri(string.Format(DownloadUrl, torrentId));

                        var dateStr = descCol.ChildNodes.Last().NodeValue.Trim();
                        var euDate = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                        var localDate = TimeZoneInfo.ConvertTimeToUtc(euDate, TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time")).ToLocalTime();
                        release.PublishDate = localDate;

                        var sizeNodes = row.ChildElements.ElementAt(3).ChildNodes;
                        var sizeVal = sizeNodes.First().NodeValue;
                        var sizeUnit = sizeNodes.Last().NodeValue;
                        release.Size = ReleaseInfo.GetBytes(sizeUnit, ParseUtil.CoerceFloat(sizeVal));

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

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }
            return releases.ToArray();
        }
Exemple #18
0
        async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query, string baseUrl)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(searchAllUrl);

                XmlDocument xmlDoc = new XmlDocument();
                string xml = string.Empty;
                WebClient wc = getWebClient();

                try
                {
                    using (wc)
                    {
                        xml = wc.DownloadString(episodeSearchUrl);
                        xmlDoc.LoadXml(xml);
                    }

                    ReleaseInfo release;
                    string serie_title;

                    foreach (XmlNode node in xmlDoc.GetElementsByTagName("item"))
                    {
                        release = new ReleaseInfo();

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

                        serie_title = node.SelectSingleNode("title").InnerText;
                        release.Title = serie_title;

                        release.Comments = new Uri(node.SelectSingleNode("link").InnerText);
                        release.Category = node.SelectSingleNode("title").InnerText;
                        var test = node.SelectSingleNode("enclosure");
                        release.Guid = new Uri(test.Attributes["url"].Value);
                        release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture);

                        release.Description = node.SelectSingleNode("description").InnerText;
                        release.InfoHash = node.SelectSingleNode("description").InnerText;
                        release.Size = 0;
                        release.Seeders = 1;
                        release.Peers = 1;
                        release.MagnetUri = new Uri(node.SelectSingleNode("link").InnerText);
                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, xml, ex);
                    throw ex;
                }
            }

            return releases.ToArray();
        }
Exemple #19
0
        async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query, string baseUrl)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim()));

                XmlDocument xmlDoc = new XmlDocument();
                string xml = string.Empty;
                WebClient wc = getWebClient();

                try
                {
                    using (wc)
                    {
                        xml = wc.DownloadString(episodeSearchUrl);
                        xmlDoc.LoadXml(xml);
                    }

                    ReleaseInfo release;
                    TorrentzHelper td;
                    string serie_title;

                    foreach (XmlNode node in xmlDoc.GetElementsByTagName("item"))
                    {
                        release = new ReleaseInfo();

                        release.MinimumRatio = 1;
                        release.MinimumSeedTime = 172800;
                        serie_title = node.SelectSingleNode("title").InnerText;
                        release.Title = serie_title;

                        release.Comments = new Uri(node.SelectSingleNode("link").InnerText);
                        release.Category = node.SelectSingleNode("category").InnerText;
                        release.Guid = new Uri(node.SelectSingleNode("guid").InnerText);
                        release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture);

                        td = new TorrentzHelper(node.SelectSingleNode("description").InnerText);
                        release.Description = td.Description;
                        release.InfoHash = td.hash;
                        release.Size = td.Size;
                        release.Seeders = td.Seeders;
                        release.Peers = td.Peers + release.Seeders;
                        release.MagnetUri = TorrentzHelper.createMagnetLink(td.hash, serie_title);
                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, xml, ex);
                    throw ex;
                }
            }

            return releases.ToArray();
        }
Exemple #20
0
        async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query, string baseUrl)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();
            List<string> searchurls = new List<string>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                for (int page = 0; page < MAXPAGES; page++)
                    searchurls.Add(string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim()), page));
            }

            foreach (string SearchUrl in searchurls)
            {
                var results = await client.GetStringAsync(SearchUrl);
                try
                {
                    CQ dom = results;
                    ReleaseInfo release;

                    int rowCount = 0;
                    var rows = dom[".mainblockcontenttt > tbody > tr"];
                    foreach (var row in rows)
                    {
                        CQ qRow = row.Cq();
                        if (rowCount < 2 || qRow.Children().Count() != 12) //skip 2 rows because there's an empty row & a title/sort row
                        {
                            rowCount++;
                            continue;
                        }

                        release = new ReleaseInfo();
                        long? size;

                        release.Title = qRow.Find("td.mainblockcontent b a").Text();
                        release.Description = release.Title;

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

                        string fullSize = qRow.Find("td.mainblockcontent").Get(6).InnerText;
                        string[] sizeSplit = fullSize.Split(' ');
                        switch (sizeSplit[1].ToLower())
                        {
                            case "kb":
                                size = ReleaseInfo.BytesFromKB(ParseUtil.CoerceFloat(sizeSplit[0]));
                                break;
                            case "mb":
                                size = ReleaseInfo.BytesFromMB(ParseUtil.CoerceFloat(sizeSplit[0]));
                                break;
                            case "gb":
                                size = ReleaseInfo.BytesFromGB(ParseUtil.CoerceFloat(sizeSplit[0]));
                                break;
                            default:
                                size = null;
                                break;
                        }
                        release.Size = size;

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

                        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);
                       
                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }


            return releases.ToArray();
        }
Exemple #21
0
        public async Task <ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List <ReleaseInfo> releases = new List <ReleaseInfo>();


            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString     = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
                var results          = await client.GetStringAsync(episodeSearchUrl);

                try
                {
                    CQ dom = results;

                    CQ qRows = dom["#torrenttable > tbody > tr"];

                    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(".title > a").First();
                        release.Guid        = new Uri(BaseUrl + qLink.Attr("href"));
                        release.Comments    = release.Guid;
                        release.Title       = qLink.Text();
                        release.Description = release.Title;

                        release.Link = new Uri(BaseUrl + qRow.Find(".quickdownload > a").Attr("href"));

                        var dateString = qRow.Find(".name").First()[0].ChildNodes[4].NodeValue.Replace(" on", "").Trim();
                        //"2015-04-25 23:38:12"
                        //"yyyy-MMM-dd hh:mm:ss"
                        release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);

                        var sizeStringParts = qRow.Children().ElementAt(4).InnerText.Split(' ');
                        release.Size = ReleaseInfo.GetBytes(sizeStringParts[1], float.Parse(sizeStringParts[0]));

                        release.Seeders = int.Parse(qRow.Find(".seeders").Text());
                        release.Peers   = int.Parse(qRow.Find(".leechers").Text());

                        releases.Add(release);
                    }
                }

                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }


            return(releases.ToArray());
        }
Exemple #22
0
 // Avistaz has episodes without season. eg Running Man E323
 protected override string GetSearchTerm(TorznabQuery query) =>
 !string.IsNullOrWhiteSpace(query.Episode) && query.Season == 0 ?
 $"{query.SearchTerm} E{query.Episode}" :
 $"{query.SearchTerm} {query.GetEpisodeSearchString()}";
Exemple #23
0
        public async Task <ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List <ReleaseInfo> releases = new List <ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString     = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);

                string results;
                if (Program.IsWindows)
                {
                    var request = CreateHttpRequest(new Uri(episodeSearchUrl));
                    request.Method = HttpMethod.Get;
                    var response = await client.SendAsync(request);

                    results = await response.Content.ReadAsStringAsync();
                }
                else
                {
                    var response = await CurlHelper.GetAsync(episodeSearchUrl, cookieHeader);

                    results = Encoding.UTF8.GetString(response.Content);
                }
                try
                {
                    var json = JObject.Parse(results);
                    foreach (JObject r in json["response"]["results"])
                    {
                        DateTime pubDate = DateTime.MinValue;
                        double   dateNum;
                        if (double.TryParse((string)r["groupTime"], out dateNum))
                        {
                            pubDate = UnixTimestampToDateTime(dateNum);
                        }

                        var groupName = (string)r["groupName"];

                        if (r["torrents"] is JArray)
                        {
                            foreach (JObject t in r["torrents"])
                            {
                                var release = new ReleaseInfo();
                                release.PublishDate = pubDate;
                                release.Title       = groupName;
                                release.Description = groupName;
                                FillReleaseInfoFromJson(release, t);
                                releases.Add(release);
                            }
                        }
                        else
                        {
                            var release = new ReleaseInfo();
                            release.PublishDate = pubDate;
                            release.Title       = groupName;
                            release.Description = groupName;
                            FillReleaseInfoFromJson(release, r);
                            releases.Add(release);
                        }
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }

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

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

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

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

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

                // Getting results
                logger.Info("\nXthor - Querying API page " + nextPage);
                var results = await QueryTrackerAsync(request);

                // Torrents Result Count
                var torrentsCount = 0;

                try
                {
                    // Deserialize our Json Response
                    var xthorResponse = JsonConvert.DeserializeObject <XthorResponse>(results);

                    // Check Tracker's State
                    CheckApiState(xthorResponse.Error);

                    // If contains torrents
                    if (xthorResponse.Torrents != null)
                    {
                        // Store torrents rows count result
                        torrentsCount = xthorResponse.Torrents.Count();
                        logger.Info("\nXthor - Found " + torrentsCount + " torrents on current page.");

                        // Adding each torrent row to releases
                        // Exclude hidden torrents (category 106, example => search 'yoda' in the API) #10407
                        releases.AddRange(xthorResponse.Torrents
                                          .Where(torrent => torrent.Category != 106).Select(torrent =>
                        {
                            //issue #3847 replace multi keyword
                            if (!string.IsNullOrEmpty(MultiReplacement))
                            {
                                var regex    = new Regex("(?i)([\\.\\- ])MULTI([\\.\\- ])");
                                torrent.Name = regex.Replace(torrent.Name, "$1" + MultiReplacement + "$2");
                            }

                            // issue #8759 replace vostfr and subfrench with English
                            if (SubReplacement)
                            {
                                torrent.Name = torrent.Name.Replace("VOSTFR", "ENGLISH").Replace("SUBFRENCH", "ENGLISH");
                            }

                            var publishDate = DateTimeUtil.UnixTimestampToDateTime(torrent.Added);
                            //TODO replace with download link?
                            var guid    = new Uri(TorrentDetailsUrl.Replace("{id}", torrent.Id.ToString()));
                            var details = new Uri(TorrentDetailsUrl.Replace("{id}", torrent.Id.ToString()));
                            var link    = new Uri(torrent.Download_link);
                            var release = new ReleaseInfo
                            {
                                // Mapping data
                                Category             = MapTrackerCatToNewznab(torrent.Category.ToString()),
                                Title                = torrent.Name,
                                Seeders              = torrent.Seeders,
                                Peers                = torrent.Seeders + torrent.Leechers,
                                MinimumRatio         = 1,
                                MinimumSeedTime      = 345600,
                                PublishDate          = publishDate,
                                Size                 = torrent.Size,
                                Grabs                = torrent.Times_completed,
                                Files                = torrent.Numfiles,
                                UploadVolumeFactor   = 1,
                                DownloadVolumeFactor = (torrent.Freeleech == 1 ? 0 : 1),
                                Guid                 = guid,
                                Details              = details,
                                Link                 = link,
                                TMDb                 = torrent.Tmdb_id
                            };

                            return(release);
                        }));
                        nextPage++;
                    }
                    else
                    {
                        logger.Info("\nXthor - No results found on page  " + nextPage + ", stopping follow of next page.");
                        //  No results or no more results available
                        followingPages = false;
                        break;
                    }
                }
                catch (Exception ex)
                {
                    OnParseError("Unable to parse result \n" + ex.StackTrace, ex);
                }

                // Stop ?
                if (query.IsTmdbQuery && MaxPagesBypassForTMDB)
                {
                    if (nextPage > MaxPagesHardLimit)
                    {
                        logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due to page hard limit reached.");
                        break;
                    }
                    logger.Info("\nXthor - Continue to next page " + nextPage + " due to TMDB request and activated max page bypass for this type of query. Max page hard limit: 4.");
                    continue;
                }
                else
                {
                    if (torrentsCount < 32)
                    {
                        logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due max available results reached.");
                        break;
                    }
                    else if (nextPage > MaxPages)
                    {
                        logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due to page limit reached.");
                        break;
                    }
                    else if (query.IsTest)
                    {
                        logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due to index test query.");
                        break;
                    }
                }
            } while (followingPages);

            // Check if there is duplicate and return unique rows - Xthor API can be very buggy !
            var uniqReleases    = releases.GroupBy(x => x.Guid).Select(x => x.First()).ToList();
            var errorPercentage = 1 - ((double)uniqReleases.Count() / releases.Count());

            if (errorPercentage >= 0.25)
            {
                logger.Warn("\nXthor - High percentage error detected: " + string.Format("{0:0.0%}", errorPercentage) + "\nWe strongly recommend that you lower max page to 1, as there is no benefit to grab additionnals.\nTracker API sent us duplicated pages with same results, even if we deduplicate returned rows, please consider to lower as it's unnecessary and increase time used for query for the same result.");
            }
            // Return found releases
            return(uniqReleases);
        }
Exemple #25
0
        async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query, string baseUrl)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            List<string> searchUrls = new List<string>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var queryStr = HttpUtility.UrlEncode(searchString);
                var episodeSearchUrl = baseUrl + string.Format(SearchUrl, queryStr);
                var episodeSearchUrl2 = baseUrl + string.Format(SearchUrl2, queryStr);
                searchUrls.Add(episodeSearchUrl);
                searchUrls.Add(episodeSearchUrl2);
            }

            foreach (var episodeSearchUrl in searchUrls)
            {
                var message = new HttpRequestMessage
                {
                    Method = HttpMethod.Get,
                    RequestUri = new Uri(baseUrl + SwitchSingleViewUrl)
                };
                message.Headers.Referrer = new Uri(episodeSearchUrl);

                string results;

                if (Program.IsWindows)
                {
                    var response = await client.SendAsync(message);
                    results = await response.Content.ReadAsStringAsync();
                }
                else
                {
                    var response = await CurlHelper.GetAsync(baseUrl + SwitchSingleViewUrl, null, episodeSearchUrl);
                    results = Encoding.UTF8.GetString(response.Content);
                }
                try
                {
                    CQ dom = results;

                    var rows = dom["#searchResult > tbody > tr"];
                    foreach (var row in rows)
                    {
                        var release = new ReleaseInfo();

                        CQ qLink = row.ChildElements.ElementAt(1).Cq().Children("a").First();

                        release.MinimumRatio = 1;
                        release.MinimumSeedTime = 172800;
                        release.Title = qLink.Text().Trim();
                        release.Description = release.Title;
                        release.Comments = new Uri(baseUrl + "/" + qLink.Attr("href").TrimStart('/'));
                        release.Guid = release.Comments;

                        var timeString = row.ChildElements.ElementAt(2).Cq().Text();
                        if (timeString.Contains("mins ago"))
                            release.PublishDate = (DateTime.Now - TimeSpan.FromMinutes(int.Parse(timeString.Split(' ')[0])));
                        else if (timeString.Contains("Today"))
                            release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(2) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
                        else if (timeString.Contains("Y-day"))
                            release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(26) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
                        else if (timeString.Contains(':'))
                        {
                            var utc = DateTime.ParseExact(timeString, "MM-dd HH:mm", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
                            release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
                        }
                        else
                        {
                            var utc = DateTime.ParseExact(timeString, "MM-dd yyyy", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
                            release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
                        }

                        var downloadCol = row.ChildElements.ElementAt(3).Cq().Find("a");
                        release.MagnetUri = new Uri(downloadCol.Attr("href"));
                        release.InfoHash = release.MagnetUri.ToString().Split(':')[3].Split('&')[0];

                        var sizeString = row.ChildElements.ElementAt(4).Cq().Text().Split(' ');
                        var sizeVal = float.Parse(sizeString[0], CultureInfo.InvariantCulture);
                        var sizeUnit = sizeString[1];
                        release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal);

                        release.Seeders = int.Parse(row.ChildElements.ElementAt(5).Cq().Text());
                        release.Peers = int.Parse(row.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders;

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }
            return releases.ToArray();

        }
Exemple #26
0
        async Task <ReleaseInfo[]> PerformQuery(TorznabQuery query, string baseUrl)
        {
            List <ReleaseInfo> releases = new List <ReleaseInfo>();

            List <string> searchUrls = new List <string>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString      = title + " " + query.GetEpisodeSearchString();
                var queryStr          = HttpUtility.UrlEncode(searchString);
                var episodeSearchUrl  = baseUrl + string.Format(SearchUrl, queryStr);
                var episodeSearchUrl2 = baseUrl + string.Format(SearchUrl2, queryStr);
                searchUrls.Add(episodeSearchUrl);
                searchUrls.Add(episodeSearchUrl2);
            }

            foreach (var episodeSearchUrl in searchUrls)
            {
                var message = new HttpRequestMessage
                {
                    Method     = HttpMethod.Get,
                    RequestUri = new Uri(baseUrl + SwitchSingleViewUrl)
                };
                message.Headers.Referrer = new Uri(episodeSearchUrl);

                string results;

                if (Program.IsWindows)
                {
                    var response = await client.SendAsync(message);

                    results = await response.Content.ReadAsStringAsync();
                }
                else
                {
                    var response = await CurlHelper.GetAsync(baseUrl + SwitchSingleViewUrl, null, episodeSearchUrl);

                    results = Encoding.UTF8.GetString(response.Content);
                }
                try
                {
                    CQ dom = results;

                    var rows = dom["#searchResult > tbody > tr"];
                    foreach (var row in rows)
                    {
                        var release = new ReleaseInfo();

                        CQ qLink = row.ChildElements.ElementAt(1).Cq().Children("a").First();

                        release.MinimumRatio    = 1;
                        release.MinimumSeedTime = 172800;
                        release.Title           = qLink.Text().Trim();
                        release.Description     = release.Title;
                        release.Comments        = new Uri(baseUrl + "/" + qLink.Attr("href").TrimStart('/'));
                        release.Guid            = release.Comments;

                        var timeString = row.ChildElements.ElementAt(2).Cq().Text();
                        if (timeString.Contains("mins ago"))
                        {
                            release.PublishDate = (DateTime.Now - TimeSpan.FromMinutes(int.Parse(timeString.Split(' ')[0])));
                        }
                        else if (timeString.Contains("Today"))
                        {
                            release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(2) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
                        }
                        else if (timeString.Contains("Y-day"))
                        {
                            release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(26) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
                        }
                        else if (timeString.Contains(':'))
                        {
                            var utc = DateTime.ParseExact(timeString, "MM-dd HH:mm", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
                            release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
                        }
                        else
                        {
                            var utc = DateTime.ParseExact(timeString, "MM-dd yyyy", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
                            release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
                        }

                        var downloadCol = row.ChildElements.ElementAt(3).Cq().Find("a");
                        release.MagnetUri = new Uri(downloadCol.Attr("href"));
                        release.InfoHash  = release.MagnetUri.ToString().Split(':')[3].Split('&')[0];

                        var sizeString = row.ChildElements.ElementAt(4).Cq().Text().Split(' ');
                        var sizeVal    = float.Parse(sizeString[0], CultureInfo.InvariantCulture);
                        var sizeUnit   = sizeString[1];
                        release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal);

                        release.Seeders = int.Parse(row.ChildElements.ElementAt(5).Cq().Text());
                        release.Peers   = int.Parse(row.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders;

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }
            return(releases.ToArray());
        }
Exemple #27
0
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var searchSection = string.IsNullOrEmpty(query.Episode) ? "archive" : "browse";
                var searchCategory = string.IsNullOrEmpty(query.Episode) ? "26" : "27";

                var searchUrl = string.Format(SearchUrl, searchSection, searchCategory, searchString);

                string results;
                if (Program.IsWindows)
                {
                    results = await client.GetStringAsync(searchUrl);
                }
                else
                {
                    var response = await CurlHelper.GetAsync(searchUrl, cookieHeader);
                    results = Encoding.UTF8.GetString(response.Content);
                }

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

                        release.MinimumRatio = 1;
                        release.MinimumSeedTime = 129600;
                        release.Title = qRow.Find(".ttr_name > a").Text();
                        release.Description = release.Title;
                        release.Guid = new Uri(BaseUrl + "/" + qRow.Find(".ttr_name > a").Attr("href"));
                        release.Comments = release.Guid;
                        release.Link = new Uri(BaseUrl + "/" + qRow.Find(".td_dl > a").Attr("href"));

                        var sizeStr = qRow.Find(".ttr_size").Contents()[0].NodeValue;
                        var sizeParts = sizeStr.Split(' ');
                        release.Size = ReleaseInfo.GetBytes(sizeParts[1], float.Parse(sizeParts[0], NumberStyles.Float | NumberStyles.AllowThousands));

                        var timeStr = qRow.Find(".ttr_added").Text();
                        DateTime time;
                        if (DateTime.TryParseExact(timeStr, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out time))
                        {
                            release.PublishDate = time;
                        }

                        release.Seeders = int.Parse(qRow.Find(".ttr_seeders").Text(), NumberStyles.AllowThousands);
                        release.Peers = int.Parse(qRow.Find(".ttr_leechers").Text(), NumberStyles.AllowThousands) + release.Seeders;

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }

            return releases.ToArray();
        }
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();


            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
                var results = await client.GetStringAsync(episodeSearchUrl);
                try
                {
                    CQ dom = results;

                    CQ qRows = dom["#torrenttable > tbody > tr"];

                    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(".title > a").First();
                        release.Guid = new Uri(BaseUrl + qLink.Attr("href"));
                        release.Comments = release.Guid;
                        release.Title = qLink.Text();
                        release.Description = release.Title;

                        release.Link = new Uri(BaseUrl + qRow.Find(".quickdownload > a").Attr("href"));

                        var dateString = qRow.Find(".name").First()[0].ChildNodes[4].NodeValue.Replace(" on", "").Trim();
                        //"2015-04-25 23:38:12"
                        //"yyyy-MMM-dd hh:mm:ss"
                        release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);

                        var sizeStringParts = qRow.Children().ElementAt(4).InnerText.Split(' ');
                        release.Size = ReleaseInfo.GetBytes(sizeStringParts[1], ParseUtil.CoerceFloat(sizeStringParts[0]));

                        release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seeders").Text());
                        release.Peers = release.Seeders + ParseUtil.CoerceInt(qRow.Find(".leechers").Text());

                        releases.Add(release);
                    }
                }

                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }

            }


            return releases.ToArray();
        }
Exemple #29
0
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {

            List<ReleaseInfo> releases = new List<ReleaseInfo>();


            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {

                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);

                var request = CreateHttpRequest(new Uri(episodeSearchUrl));
                var response = await client.SendAsync(request);
                var results = await response.Content.ReadAsStringAsync();

                try
                {
                    CQ dom = results;

                    var rows = dom["table.torrents > tbody > tr"];
                    foreach (var row in rows.Skip(1))
                    {
                        var release = new ReleaseInfo();

                        var qRow = row.Cq();

                        var qTitleLink = qRow.Find("a.t_title").First();
                        release.Title = qTitleLink.Text().Trim();
                        release.Description = release.Title;
                        release.Guid = new Uri(BaseUrl + qTitleLink.Attr("href"));
                        release.Comments = release.Guid;

                        DateTime pubDate;
                        var descString = qRow.Find(".t_ctime").Text();
                        var dateString = descString.Split('|').Last().Trim();
                        dateString = dateString.Split(new string[] { " by " }, StringSplitOptions.None)[0];
                        var dateValue = ParseUtil.CoerceFloat(dateString.Split(' ')[0]);
                        var dateUnit = dateString.Split(' ')[1];
                        if (dateUnit.Contains("minute"))
                            pubDate = DateTime.Now - TimeSpan.FromMinutes(dateValue);
                        else if (dateUnit.Contains("hour"))
                            pubDate = DateTime.Now - TimeSpan.FromHours(dateValue);
                        else if (dateUnit.Contains("day"))
                            pubDate = DateTime.Now - TimeSpan.FromDays(dateValue);
                        else if (dateUnit.Contains("week"))
                            pubDate = DateTime.Now - TimeSpan.FromDays(7 * dateValue);
                        else if (dateUnit.Contains("month"))
                            pubDate = DateTime.Now - TimeSpan.FromDays(30 * dateValue);
                        else if (dateUnit.Contains("year"))
                            pubDate = DateTime.Now - TimeSpan.FromDays(365 * dateValue);
                        else
                            pubDate = DateTime.MinValue;
                        release.PublishDate = pubDate;

                        var qLink = row.ChildElements.ElementAt(3).Cq().Children("a");
                        release.Link = new Uri(BaseUrl + qLink.Attr("href"));

                        var sizeStr = row.ChildElements.ElementAt(5).Cq().Text().Trim();
                        var sizeVal = ParseUtil.CoerceFloat(sizeStr.Split(' ')[0]);
                        var sizeUnit = sizeStr.Split(' ')[1];
                        release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal);

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

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }

            }

            return releases.ToArray();

        }
Exemple #30
0
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {

                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);

                string results;
                if (Program.IsWindows)
                {
                    var request = CreateHttpRequest(new Uri(episodeSearchUrl));
                    request.Method = HttpMethod.Get;
                    var response = await client.SendAsync(request);
                    results = await response.Content.ReadAsStringAsync();
                }
                else
                {
                    var response = await CurlHelper.GetAsync(episodeSearchUrl, cookieHeader);
                    results = Encoding.UTF8.GetString(response.Content);
                }
                try
                {

                    var json = JObject.Parse(results);
                    foreach (JObject r in json["response"]["results"])
                    {
                        DateTime pubDate = DateTime.MinValue;
                        double dateNum;
                        if (double.TryParse((string)r["groupTime"], out dateNum))
                            pubDate = UnixTimestampToDateTime(dateNum);

                        var groupName = (string)r["groupName"];

                        if (r["torrents"] is JArray)
                        {
                            foreach (JObject t in r["torrents"])
                            {
                                var release = new ReleaseInfo();
                                release.PublishDate = pubDate;
                                release.Title = groupName;
                                release.Description = groupName;
                                FillReleaseInfoFromJson(release, t);
                                releases.Add(release);
                            }
                        }
                        else
                        {
                            var release = new ReleaseInfo();
                            release.PublishDate = pubDate;
                            release.Title = groupName;
                            release.Description = groupName;
                            FillReleaseInfoFromJson(release, r);
                            releases.Add(release);
                        }

                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }

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

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

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

            logger.Info("\nXthor - Search requested for \"" + searchTerm + "\"");

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

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

                // Getting results
                logger.Info("\nXthor - Querying API page " + nextPage);
                var results = await QueryTrackerAsync(request);

                // Torrents Result Count
                var torrentsCount = 0;

                try
                {
                    // Deserialize our Json Response
                    var xthorResponse = JsonConvert.DeserializeObject <XthorResponse>(results);

                    // Check Tracker's State
                    CheckApiState(xthorResponse.Error);

                    // If contains torrents
                    if (xthorResponse.Torrents != null)
                    {
                        // Store torrents rows count result
                        torrentsCount = xthorResponse.Torrents.Count();
                        logger.Info("\nXthor - Found " + torrentsCount + " torrents on current page.");

                        // Adding each torrent row to releases
                        // Exclude hidden torrents (category 106, example => search 'yoda' in the API) #10407
                        releases.AddRange(xthorResponse.Torrents
                                          .Where(torrent => torrent.Category != 106).Select(torrent =>
                        {
                            //issue #3847 replace multi keyword
                            if (!string.IsNullOrEmpty(ReplaceMulti))
                            {
                                var regex    = new Regex("(?i)([\\.\\- ])MULTI([\\.\\- ])");
                                torrent.Name = regex.Replace(torrent.Name, "$1" + ReplaceMulti + "$2");
                            }

                            // issue #8759 replace vostfr and subfrench with English
                            if (ConfigData.Vostfr.Value)
                            {
                                torrent.Name = torrent.Name.Replace("VOSTFR", "ENGLISH").Replace("SUBFRENCH", "ENGLISH");
                            }

                            var publishDate = DateTimeUtil.UnixTimestampToDateTime(torrent.Added);
                            //TODO replace with download link?
                            var guid    = new Uri(TorrentDetailsUrl.Replace("{id}", torrent.Id.ToString()));
                            var details = new Uri(TorrentDetailsUrl.Replace("{id}", torrent.Id.ToString()));
                            var link    = new Uri(torrent.Download_link);
                            var release = new ReleaseInfo
                            {
                                // Mapping data
                                Category             = MapTrackerCatToNewznab(torrent.Category.ToString()),
                                Title                = torrent.Name,
                                Seeders              = torrent.Seeders,
                                Peers                = torrent.Seeders + torrent.Leechers,
                                MinimumRatio         = 1,
                                MinimumSeedTime      = 345600,
                                PublishDate          = publishDate,
                                Size                 = torrent.Size,
                                Grabs                = torrent.Times_completed,
                                Files                = torrent.Numfiles,
                                UploadVolumeFactor   = 1,
                                DownloadVolumeFactor = (torrent.Freeleech == 1 ? 0 : 1),
                                Guid                 = guid,
                                Details              = details,
                                Link                 = link,
                                TMDb                 = torrent.Tmdb_id
                            };

                            return(release);
                        }));
                        nextPage++;
                    }
                    else
                    {
                        logger.Info("\nXthor - No results found on page  " + (nextPage - 1) + ", stopping follow of next page.");
                        //  No results or no more results available
                        followingPages = false;
                    }
                }
                catch (Exception ex)
                {
                    OnParseError("Unable to parse result \n" + ex.StackTrace, ex);
                }

                // Stop ?
                if (nextPage > MaxPageLoads | torrentsCount < 32 | string.IsNullOrWhiteSpace(searchTerm))
                {
                    logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due to page limit or max available results reached or indexer test.");
                    followingPages = false;
                }
            } while (followingPages);

            // Check if there is duplicate and return unique rows - Xthor API can be very buggy !
            var uniqReleases = releases.GroupBy(x => x.Guid).Select(x => x.First()).ToList();

            // Return found releases
            return(uniqReleases);
        }
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            searchBlock Search = Definition.Search;

            // init template context
            var variables = getTemplateVariablesFromConfigData();

            variables[".Query.Type"]       = query.QueryType;
            variables[".Query.Q"]          = query.SearchTerm;
            variables[".Query.Series"]     = null;
            variables[".Query.Ep"]         = query.Episode;
            variables[".Query.Season"]     = query.Season;
            variables[".Query.Movie"]      = null;
            variables[".Query.Year"]       = null;
            variables[".Query.Limit"]      = query.Limit;
            variables[".Query.Offset"]     = query.Offset;
            variables[".Query.Extended"]   = query.Extended;
            variables[".Query.Categories"] = query.Categories;
            variables[".Query.APIKey"]     = query.ApiKey;
            variables[".Query.TVDBID"]     = null;
            variables[".Query.TVRageID"]   = query.RageID;
            variables[".Query.IMDBID"]     = query.ImdbID;
            variables[".Query.TVMazeID"]   = null;
            variables[".Query.TraktID"]    = null;

            variables[".Query.Episode"] = query.GetEpisodeSearchString();
            variables[".Categories"]    = MapTorznabCapsToTrackers(query);

            var KeywordTokens    = new List <string>();
            var KeywordTokenKeys = new List <string> {
                "Q", "Series", "Movie", "Year"
            };

            foreach (var key in KeywordTokenKeys)
            {
                var Value = (string)variables[".Query." + key];
                if (!string.IsNullOrWhiteSpace(Value))
                {
                    KeywordTokens.Add(Value);
                }
            }

            if (!string.IsNullOrWhiteSpace((string)variables[".Query.Episode"]))
            {
                KeywordTokens.Add((string)variables[".Query.Episode"]);
            }
            variables[".Query.Keywords"] = string.Join(" ", KeywordTokens);
            variables[".Keywords"]       = variables[".Query.Keywords"];

            // build search URL
            var searchUrl       = SiteLink + applyGoTemplateText(Search.Path, variables) + "?";
            var queryCollection = new NameValueCollection();

            if (Search.Inputs != null)
            {
                foreach (var Input in Search.Inputs)
                {
                    var value = applyGoTemplateText(Input.Value, variables);
                    if (Input.Key == "$raw")
                    {
                        searchUrl += value;
                    }
                    else
                    {
                        queryCollection.Add(Input.Key, value);
                    }
                }
            }
            searchUrl += "&" + queryCollection.GetQueryString();

            // send HTTP request
            var response = await RequestBytesWithCookies(searchUrl);

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

            try
            {
                var SearchResultParser   = new HtmlParser();
                var SearchResultDocument = SearchResultParser.Parse(results);

                var Rows = SearchResultDocument.QuerySelectorAll(Search.Rows.Selector);
                foreach (var Row in Rows)
                {
                    try
                    {
                        var release = new ReleaseInfo();
                        release.MinimumRatio    = 1;
                        release.MinimumSeedTime = 48 * 60 * 60;

                        // Parse fields
                        foreach (var Field in Search.Fields)
                        {
                            string value = handleSelector(Field.Value, Row);
                            try
                            {
                                switch (Field.Key)
                                {
                                case "download":
                                    release.Link = resolvePath(value);
                                    break;

                                case "details":
                                    var url = resolvePath(value);
                                    release.Guid = url;
                                    if (release.Comments == null)
                                    {
                                        release.Comments = url;
                                    }
                                    break;

                                case "comments":
                                    release.Comments = resolvePath(value);
                                    break;

                                case "title":
                                    release.Title = value;
                                    break;

                                case "description":
                                    release.Description = value;
                                    break;

                                case "category":
                                    release.Category = MapTrackerCatToNewznab(value);
                                    break;

                                case "size":
                                    release.Size = ReleaseInfo.GetBytes(value);
                                    break;

                                case "leechers":
                                    if (release.Peers == null)
                                    {
                                        release.Peers = ParseUtil.CoerceInt(value);
                                    }
                                    else
                                    {
                                        release.Peers += ParseUtil.CoerceInt(value);
                                    }
                                    break;

                                case "seeders":
                                    release.Seeders = ParseUtil.CoerceInt(value);
                                    if (release.Peers == null)
                                    {
                                        release.Peers = release.Seeders;
                                    }
                                    else
                                    {
                                        release.Peers += release.Seeders;
                                    }

                                    break;

                                case "date":
                                    release.PublishDate = DateTimeUtil.FromUnknown(value);
                                    break;

                                default:
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception(string.Format("Error while parsing field={0}, selector={1}, value={2}: {3}", Field.Key, Field.Value.Selector, value, ex.Message));
                            }
                        }

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

            return(releases);
        }
Exemple #33
0
        public async Task <ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List <ReleaseInfo> releases = new List <ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString     = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
                var results          = await client.GetStringAsync(episodeSearchUrl);

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

                        release.MinimumRatio    = 1;
                        release.MinimumSeedTime = 172800;
                        release.Title           = qRow.Find(".torrent_name_link").Text();
                        release.Description     = release.Title;
                        release.Guid            = new Uri(BaseUrl + "/" + qRow.Find(".torrent_name_link").Parent().Attr("href"));
                        release.Comments        = release.Guid;
                        release.Link            = new Uri(BaseUrl + "/" + qRow.Find(".torrent_handle_links > a").First().Attr("href"));

                        var dateStr = qRow.Find(".time").Text().Trim();
                        if (dateStr.ToLower().Contains("just now"))
                        {
                            release.PublishDate = DateTime.Now;
                        }
                        else
                        {
                            var      dateParts = dateStr.Split(' ');
                            var      dateValue = int.Parse(dateParts[0]);
                            TimeSpan ts        = TimeSpan.Zero;
                            if (dateStr.Contains("sec"))
                            {
                                ts = TimeSpan.FromSeconds(dateValue);
                            }
                            else if (dateStr.Contains("min"))
                            {
                                ts = TimeSpan.FromMinutes(dateValue);
                            }
                            else if (dateStr.Contains("hour"))
                            {
                                ts = TimeSpan.FromHours(dateValue);
                            }
                            else if (dateStr.Contains("day"))
                            {
                                ts = TimeSpan.FromDays(dateValue);
                            }
                            else if (dateStr.Contains("week"))
                            {
                                ts = TimeSpan.FromDays(dateValue * 7);
                            }
                            else if (dateStr.Contains("month"))
                            {
                                ts = TimeSpan.FromDays(dateValue * 30);
                            }
                            else if (dateStr.Contains("year"))
                            {
                                ts = TimeSpan.FromDays(dateValue * 365);
                            }
                            release.PublishDate = DateTime.Now - ts;
                        }

                        var sizeStr   = qRow.Find(".size")[0].ChildNodes[0].NodeValue.Trim();
                        var sizeParts = sizeStr.Split(' ');
                        release.Size    = ReleaseInfo.GetBytes(sizeParts[1], float.Parse(sizeParts[0], NumberStyles.AllowThousands));
                        release.Seeders = int.Parse(qRow.Children().ElementAt(6).InnerText.Trim(), NumberStyles.AllowThousands);
                        release.Peers   = int.Parse(qRow.Children().ElementAt(7).InnerText.Trim(), NumberStyles.AllowThousands) + release.Seeders;

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }
            return(releases.ToArray());
        }
Exemple #34
0
 // hook to adjust the search term
 protected virtual string GetSearchTerm(TorznabQuery query) => $"{query.SearchTerm} {query.GetEpisodeSearchString()}";
Exemple #35
0
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query, string baseUrl)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { "2015" })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = baseUrl + string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim()));
                var results = await client.GetStringAsync(episodeSearchUrl);
                try
                {
                    var jResults = JObject.Parse(results);
                    foreach (JObject result in (JArray)jResults["torrents"])
                    {
                        var release = new ReleaseInfo();

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

                        release.Title = (string)result["torrent_title"];
                        release.Description = release.Title;
                        release.Seeders = (int)result["seeds"];
                        release.Peers = (int)result["leeches"] + release.Seeders;
                        release.Size = (long)result["size"];

                        // "Apr  2, 2015", "Apr 12, 2015" (note the spacing)
                        var dateString = string.Join(" ", ((string)result["upload_date"]).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
                        release.PublishDate = DateTime.ParseExact(dateString, "MMM d, yyyy", CultureInfo.InvariantCulture);

                        release.Guid = new Uri((string)result["page"]);
                        release.Comments = release.Guid;

                        release.InfoHash = (string)result["torrent_hash"];
                        release.MagnetUri = new Uri((string)result["magnet_uri"]);
                        release.Link = new Uri(string.Format("{0}{1}{2}", baseUrl, DownloadUrl, release.InfoHash));

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }

            return releases.ToArray();
        }
Exemple #36
0
        public async Task <ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List <ReleaseInfo> releases = new List <ReleaseInfo>();


            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString     = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);

                var request  = CreateHttpRequest(new Uri(episodeSearchUrl));
                var response = await client.SendAsync(request);

                var results = await response.Content.ReadAsStringAsync();

                try
                {
                    CQ dom = results;

                    var rows = dom["table.torrents > tbody > tr"];
                    foreach (var row in rows.Skip(1))
                    {
                        var release = new ReleaseInfo();

                        var qRow = row.Cq();

                        var qTitleLink = qRow.Find("a.t_title").First();
                        release.Title       = qTitleLink.Text().Trim();
                        release.Description = release.Title;
                        release.Guid        = new Uri(BaseUrl + qTitleLink.Attr("href"));
                        release.Comments    = release.Guid;

                        DateTime pubDate;
                        var      descString = qRow.Find(".t_ctime").Text();
                        var      dateString = descString.Split('|').Last().Trim();
                        dateString = dateString.Split(new string[] { " by " }, StringSplitOptions.None)[0];
                        var dateValue = float.Parse(dateString.Split(' ')[0]);
                        var dateUnit  = dateString.Split(' ')[1];
                        if (dateUnit.Contains("minute"))
                        {
                            pubDate = DateTime.Now - TimeSpan.FromMinutes(dateValue);
                        }
                        else if (dateUnit.Contains("hour"))
                        {
                            pubDate = DateTime.Now - TimeSpan.FromHours(dateValue);
                        }
                        else if (dateUnit.Contains("day"))
                        {
                            pubDate = DateTime.Now - TimeSpan.FromDays(dateValue);
                        }
                        else if (dateUnit.Contains("week"))
                        {
                            pubDate = DateTime.Now - TimeSpan.FromDays(7 * dateValue);
                        }
                        else if (dateUnit.Contains("month"))
                        {
                            pubDate = DateTime.Now - TimeSpan.FromDays(30 * dateValue);
                        }
                        else if (dateUnit.Contains("year"))
                        {
                            pubDate = DateTime.Now - TimeSpan.FromDays(365 * dateValue);
                        }
                        else
                        {
                            pubDate = DateTime.MinValue;
                        }
                        release.PublishDate = pubDate;

                        var qLink = row.ChildElements.ElementAt(3).Cq().Children("a");
                        release.Link = new Uri(BaseUrl + qLink.Attr("href"));

                        var sizeStr  = row.ChildElements.ElementAt(5).Cq().Text().Trim();
                        var sizeVal  = float.Parse(sizeStr.Split(' ')[0]);
                        var sizeUnit = sizeStr.Split(' ')[1];
                        release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal);

                        release.Seeders = int.Parse(qRow.Find(".t_seeders").Text().Trim(), NumberStyles.AllowThousands);
                        release.Peers   = int.Parse(qRow.Find(".t_leechers").Text().Trim(), NumberStyles.AllowThousands) + release.Seeders;

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }

            return(releases.ToArray());
        }
Exemple #37
0
        public async Task <ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List <ReleaseInfo> releases = new List <ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString   = title + " " + query.GetEpisodeSearchString();
                var searchSection  = string.IsNullOrEmpty(query.Episode) ? "archive" : "browse";
                var searchCategory = string.IsNullOrEmpty(query.Episode) ? "26" : "27";

                var searchUrl = string.Format(SearchUrl, searchSection, searchCategory, searchString);

                string results;
                if (Program.IsWindows)
                {
                    results = await client.GetStringAsync(searchUrl);
                }
                else
                {
                    var response = await CurlHelper.GetAsync(searchUrl, cookieHeader);

                    results = Encoding.UTF8.GetString(response.Content);
                }

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

                        release.MinimumRatio    = 1;
                        release.MinimumSeedTime = 129600;
                        release.Title           = qRow.Find(".ttr_name > a").Text();
                        release.Description     = release.Title;
                        release.Guid            = new Uri(BaseUrl + "/" + qRow.Find(".ttr_name > a").Attr("href"));
                        release.Comments        = release.Guid;
                        release.Link            = new Uri(BaseUrl + "/" + qRow.Find(".td_dl > a").Attr("href"));

                        var sizeStr   = qRow.Find(".ttr_size").Contents()[0].NodeValue;
                        var sizeParts = sizeStr.Split(' ');
                        release.Size = ReleaseInfo.GetBytes(sizeParts[1], float.Parse(sizeParts[0], NumberStyles.Float | NumberStyles.AllowThousands));

                        var      timeStr = qRow.Find(".ttr_added").Text();
                        DateTime time;
                        if (DateTime.TryParseExact(timeStr, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out time))
                        {
                            release.PublishDate = time;
                        }

                        release.Seeders = int.Parse(qRow.Find(".ttr_seeders").Text(), NumberStyles.AllowThousands);
                        release.Peers   = int.Parse(qRow.Find(".ttr_leechers").Text(), NumberStyles.AllowThousands) + release.Seeders;

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }

            return(releases.ToArray());
        }
Exemple #38
0
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
                var results = await client.GetStringAsync(episodeSearchUrl);
                try
                {
                    CQ dom = results;
                    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();
                        release.Description = release.Title;
                        release.Guid = new Uri(BaseUrl + "/" + qRow.Find(".torrentName").Attr("href"));
                        release.Comments = release.Guid;
                        release.Link = new Uri(BaseUrl + "/" + qRow.Find(".dlLinksInfo > a").Attr("href"));

                        var sizeStr = qRow.Find(".sizeInfo").Text().Trim();
                        var sizeParts = sizeStr.Split(' ');
                        release.Size = ReleaseInfo.GetBytes(sizeParts[1], ParseUtil.CoerceFloat(sizeParts[0]));

                        var dateStr = qRow.Find(".ulInfo").Text().Split('|').Last().Trim();
                        var dateParts = dateStr.Split(' ');
                        var dateValue = ParseUtil.CoerceInt(dateParts[0]);
                        TimeSpan ts = TimeSpan.Zero;
                        if (dateStr.Contains("sec"))
                            ts = TimeSpan.FromSeconds(dateValue);
                        else if (dateStr.Contains("min"))
                            ts = TimeSpan.FromMinutes(dateValue);
                        else if (dateStr.Contains("hour"))
                            ts = TimeSpan.FromHours(dateValue);
                        else if (dateStr.Contains("day"))
                            ts = TimeSpan.FromDays(dateValue);
                        else if (dateStr.Contains("week"))
                            ts = TimeSpan.FromDays(dateValue * 7);
                        else if (dateStr.Contains("month"))
                            ts = TimeSpan.FromDays(dateValue * 30);
                        else if (dateStr.Contains("year"))
                            ts = TimeSpan.FromDays(dateValue * 365);
                        release.PublishDate = DateTime.Now - ts;

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

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }
            return releases.ToArray();
        }
Exemple #39
0
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { "%20" })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));

                var message = new HttpRequestMessage();
                message.Method = HttpMethod.Get;
                message.RequestUri = new Uri(episodeSearchUrl);
                message.Headers.TryAddWithoutValidation("Authorization", await GetAuthToken());

                var response = await client.SendAsync(message);
                var results = await response.Content.ReadAsStringAsync();

                var jsonResult = JObject.Parse(results);
                try
                {
                    var items = (JArray)jsonResult["torrents"];
                    foreach (var item in items)
                    {
                        var release = new ReleaseInfo();

                        release.MinimumRatio = 1;
                        release.MinimumSeedTime = 172800;
                        var torrentId = (string)item["id"];
                        release.Link = new Uri(string.Format(DownloadUrl, torrentId));
                        release.Title = (string)item["name"];
                        release.Description = release.Title;
                        release.Comments = new Uri(string.Format(CommentsUrl, (string)item["rewritename"]));
                        release.Guid = release.Comments;

                        var dateUtc = DateTime.ParseExact((string)item["added"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                        release.PublishDate = DateTime.SpecifyKind(dateUtc, DateTimeKind.Utc).ToLocalTime();

                        release.Seeders = ParseUtil.CoerceInt((string)item["seeders"]);
                        release.Peers = ParseUtil.CoerceInt((string)item["leechers"]) + release.Seeders;

                        release.Size = ParseUtil.CoerceLong((string)item["size"]);

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }
            return releases.ToArray();
        }
Exemple #40
0
        /// <summary>
        /// Execute our search query
        /// </summary>
        /// <param name="query">Query</param>
        /// <returns>Releases</returns>
        protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases   = new List <ReleaseInfo>();
            var searchTerm = query.GetEpisodeSearchString() + " " + query.SanitizedSearchTerm; // use episode search string first, see issue #1202

            searchTerm = searchTerm.Trim();
            searchTerm = searchTerm.ToLower();

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

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

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

            // Build our query
            var request = BuildQuery(searchTerm, query, ApiEndpoint);

            // Getting results & Store content
            var results = await QueryExec(request);

            try
            {
                // Deserialize our Json Response
                var xthorResponse = JsonConvert.DeserializeObject <XthorResponse>(results);

                // Check Tracker's State
                CheckApiState(xthorResponse.error);

                // If contains torrents
                if (xthorResponse.torrents != null)
                {
                    // Adding each torrent row to releases
                    releases.AddRange(xthorResponse.torrents.Select(torrent =>
                    {
                        //issue #3847 replace multi keyword
                        if (!string.IsNullOrEmpty(ReplaceMulti))
                        {
                            var regex    = new Regex("(?i)([\\.\\- ])MULTI([\\.\\- ])");
                            torrent.name = regex.Replace(torrent.name, "$1" + ReplaceMulti + "$2");
                        }

                        var publishDate = DateTimeUtil.UnixTimestampToDateTime(torrent.added);
                        //TODO replace with download link?
                        var guid     = new Uri(TorrentDescriptionUrl.Replace("{id}", torrent.id.ToString()));
                        var comments = new Uri(TorrentCommentUrl.Replace("{id}", torrent.id.ToString()));
                        var link     = new Uri(torrent.download_link);
                        var release  = new ReleaseInfo
                        {
                            // Mapping data
                            Category             = MapTrackerCatToNewznab(torrent.category.ToString()),
                            Title                = torrent.name,
                            Seeders              = torrent.seeders,
                            Peers                = torrent.seeders + torrent.leechers,
                            MinimumRatio         = 1,
                            MinimumSeedTime      = 345600,
                            PublishDate          = publishDate,
                            Size                 = torrent.size,
                            Grabs                = torrent.times_completed,
                            Files                = torrent.numfiles,
                            UploadVolumeFactor   = 1,
                            DownloadVolumeFactor = (torrent.freeleech == 1 ? 0 : 1),
                            Guid                 = guid,
                            Comments             = comments,
                            Link                 = link,
                            TMDb                 = torrent.tmdb_id
                        };

                        //TODO make consistent with other trackers
                        if (DevMode)
                        {
                            Output(release.ToString());
                        }

                        return(release);
                    }));
                }
            }
            catch (Exception ex)
            {
                OnParseError("Unable to parse result \n" + ex.StackTrace, ex);
            }

            // Return found releases
            return(releases);
        }
Exemple #41
0
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
                var results = await client.GetStringAsync(episodeSearchUrl);

                try
                {
                    CQ dom = results;
                    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 qLink = row.ChildElements.ElementAt(2).FirstChild.Cq();
                        release.Link = new Uri(BaseUrl + "/" + 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.Description = release.Title;
                        release.Comments = new Uri(BaseUrl + "/" + qCommentLink.Attr("href"));
                        release.Guid = release.Comments;

                        var dateStr = descCol.ChildElements.Last().Cq().Text().Split('|').Last().ToLowerInvariant().Replace("ago.", "").Trim();
                        var dateParts = dateStr.Split(new char[] { ' ', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        var timeSpan = TimeSpan.Zero;
                        for (var i = 0; i < dateParts.Length / 2; i++)
                        {
                            var timeVal = ParseUtil.CoerceInt(dateParts[i * 2]);
                            var timeUnit = dateParts[i * 2 + 1];
                            if (timeUnit.Contains("year"))
                                timeSpan += TimeSpan.FromDays(365 * timeVal);
                            else if (timeUnit.Contains("month"))
                                timeSpan += TimeSpan.FromDays(30 * timeVal);
                            else if (timeUnit.Contains("day"))
                                timeSpan += TimeSpan.FromDays(timeVal);
                            else if (timeUnit.Contains("hour"))
                                timeSpan += TimeSpan.FromHours(timeVal);
                            else if (timeUnit.Contains("min"))
                                timeSpan += TimeSpan.FromMinutes(timeVal);
                        }
                        release.PublishDate = DateTime.SpecifyKind(DateTime.Now - timeSpan, DateTimeKind.Local);

                        var sizeEl = row.ChildElements.ElementAt(7);
                        var sizeVal = ParseUtil.CoerceFloat(sizeEl.ChildNodes.First().NodeValue);
                        var sizeUnit = sizeEl.ChildNodes.Last().NodeValue;

                        release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal);

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

                        releases.Add(release);

                    }
                }

                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }
            return releases.ToArray();
        }
        public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));

                var message = new HttpRequestMessage();
                message.Method = HttpMethod.Get;
                message.RequestUri = new Uri(episodeSearchUrl);

                var response = await client.SendAsync(message);
                var results = await response.Content.ReadAsStringAsync();
                try
                {

                    CQ dom = results;
                    var rows = dom[".results_index ul"];
                    foreach (var row in rows)
                    {
                        var release = new ReleaseInfo();
                        CQ qRow = row.Cq();
                        CQ qLink = qRow.Find("li.torrents_name > .torrents_name_link").First();
                        CQ qDlLink = qRow.Find("li.torrents_download  > a").First();

                        release.MinimumRatio = 1;
                        release.MinimumSeedTime = 172800;
                        release.Title = qLink.Text().Trim();
                        release.Description = release.Title;
                        release.Comments = new Uri(BaseUrl + "/" + qLink.Attr("href").TrimStart('/'));
                        release.Guid = release.Comments;
                        release.Link = new Uri(BaseUrl + "/" + qDlLink.Attr("href").TrimStart('/'));
                        release.PublishDate = DateTime.Now;
                        release.Seeders = ParseUtil.CoerceInt(qRow.Find("li.torrents_seeders").Text());
                        release.Peers = ParseUtil.CoerceInt(qRow.Find("li.torrents_leechers").Text()) + release.Seeders;
                        var sizeParts = qRow.Find("li.torrents_size").Text().Split(' ');
                        var sizeVal = ParseUtil.CoerceFloat(sizeParts[0]);
                        var sizeUnit = sizeParts[1];
                        release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal);

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }
            return releases.ToArray();
        }
        async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query, string baseUrl)
        {
            List<ReleaseInfo> releases = new List<ReleaseInfo>();

            List<string> searchUrls = new List<string>();

            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })
            {
                var searchString = title + " " + query.GetEpisodeSearchString();
                var queryStr = HttpUtility.UrlEncode(searchString);
                var episodeSearchUrl = baseUrl + string.Format(SearchUrl, queryStr);
                searchUrls.Add(episodeSearchUrl);
            }

            foreach (var episodeSearchUrl in searchUrls)
            {

                string results;

                if (Program.IsWindows)
                {
                    results = await client.GetStringAsync(episodeSearchUrl);
                }
                else
                {
                    var response = await CurlHelper.GetAsync(episodeSearchUrl, null, episodeSearchUrl);
                    results = Encoding.UTF8.GetString(response.Content);
                }

                try
                {
                    CQ dom = results;

                    var rows = dom["#searchResult > tbody > tr"];
                    foreach (var row in rows)
                    {
                        var release = new ReleaseInfo();

                        CQ qRow = row.Cq();
                        CQ qLink = qRow.Find(".detName > .detLink").First();

                        release.MinimumRatio = 1;
                        release.MinimumSeedTime = 172800;
                        release.Title = qLink.Text().Trim();
                        release.Description = release.Title;
                        release.Comments = new Uri(baseUrl + "/" + qLink.Attr("href").TrimStart('/'));
                        release.Guid = release.Comments;

                        var downloadCol = row.ChildElements.ElementAt(1).Cq().Children("a");
                        release.MagnetUri = new Uri(downloadCol.Attr("href"));
                        release.InfoHash = release.MagnetUri.ToString().Split(':')[3].Split('&')[0];

                        var descString = qRow.Find(".detDesc").Text().Trim();
                        var descParts = descString.Split(',');

                        var timeString = descParts[0].Split(' ')[1];

                        if (timeString.Contains("mins ago"))
                        {
                            release.PublishDate = (DateTime.Now - TimeSpan.FromMinutes(ParseUtil.CoerceInt(timeString.Split(' ')[0])));
                        }
                        else if (timeString.Contains("Today"))
                        {
                            release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(2) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
                        }
                        else if (timeString.Contains("Y-day"))
                        {
                            release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(26) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
                        }
                        else if (timeString.Contains(':'))
                        {
                            var utc = DateTime.ParseExact(timeString, "MM-dd HH:mm", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
                            release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
                        }
                        else
                        {
                            var utc = DateTime.ParseExact(timeString, "MM-dd yyyy", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
                            release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
                        }

                        var sizeParts = descParts[1].Split(new char[] { ' ', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        var sizeVal = ParseUtil.CoerceFloat(sizeParts[1]);
                        var sizeUnit = sizeParts[2];
                        release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal);

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

                        releases.Add(release);
                    }
                }
                catch (Exception ex)
                {
                    OnResultParsingError(this, results, ex);
                    throw ex;
                }
            }
            return releases.ToArray();

        }