Esempio n. 1
0
        private TorrentRssIndexerParserSettings GetEzrssParserSettings(IndexerResponse response, TorrentRssIndexerSettings indexerSettings)
        {
            if (!IsEZTVFeed(response))
            {
                return(null);
            }

            _logger.Trace("Feed has Ezrss schema");

            var parser   = new EzrssTorrentRssParser();
            var releases = ParseResponse(parser, response);

            try
            {
                ValidateReleases(releases, indexerSettings);
                ValidateReleaseSize(releases, indexerSettings);

                _logger.Debug("Feed was parseable by Ezrss Parser");
                return(new TorrentRssIndexerParserSettings
                {
                    UseEZTVFormat = true
                });
            }
            catch (Exception ex)
            {
                _logger.Trace(ex, "Feed wasn't parsable by Ezrss Parser");
                return(null);
            }
        }
Esempio n. 2
0
        private IList <TorrentInfo> ParseRelease(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <TorrentInfo>();
            var parser       = new HtmlParser();
            var dom          = parser.ParseDocument(indexerResponse.Content);

            foreach (var t in dom.QuerySelectorAll("#tabs .torrent_c > div"))
            {
                var release = new TorrentInfo
                {
                    Title   = GetTitle(dom, t),
                    InfoUrl = indexerResponse.Request.Url.ToString(),
                    DownloadVolumeFactor = 0,
                    UploadVolumeFactor   = 1,

                    Guid        = indexerResponse.Request.Url.ToString() + t.Id,
                    Seeders     = GetReleaseSeeders(t),
                    Peers       = GetReleaseSeeders(t) + GetReleaseLeechers(t),
                    Grabs       = GetReleaseGrabs(t),
                    Categories  = ParseCategories(indexerResponse.Request.Url.Path),
                    PublishDate = GetDateFromShowPage(dom),
                    DownloadUrl = GetReleaseLink(t),
                    Size        = GetReleaseSize(t),
                    Resolution  = GetQuality(t)
                };
                torrentInfos.Add(release);
            }

            return(torrentInfos);
        }
        private TorrentRssIndexerParserSettings GetEzrssParserSettings(IndexerResponse response, TorrentRssIndexerSettings indexerSettings)
        {
            if (!IsEZTVFeed(response))
            {
                return null;
            }

            _logger.Trace("Feed has Ezrss schema");

            var parser = new EzrssTorrentRssParser();
            var releases = ParseResponse(parser, response);

            try
            {
                ValidateReleases(releases, indexerSettings);
                ValidateReleaseSize(releases, indexerSettings);

                _logger.Debug("Feed was parseable by Ezrss Parser");
                return new TorrentRssIndexerParserSettings
                {
                    UseEZTVFormat = true
                };
            }
            catch (Exception ex)
            {
                _logger.TraceException("Feed wasn't parsable by Ezrss Parser", ex);
                return null;
            }
        }
Esempio n. 4
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var results = new List <ReleaseInfo>();

            switch (indexerResponse.HttpResponse.StatusCode)
            {
            case HttpStatusCode.Unauthorized:
                throw new ApiKeyException("API Key invalid or not authorized");

            case HttpStatusCode.NotFound:
                throw new IndexerException(indexerResponse, "Indexer API call returned NotFound, the Indexer API may have changed.");

            case HttpStatusCode.ServiceUnavailable:
                throw new RequestLimitReachedException("Cannot do more than 150 API requests per hour.");

            default:
                if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
                {
                    throw new IndexerException(indexerResponse, "Indexer API call returned an unexpected StatusCode [{0}]", indexerResponse.HttpResponse.StatusCode);
                }
                break;
            }

            var jsonResponse = new HttpResponse <JsonRpcResponse <BroadcastheNetTorrents> >(indexerResponse.HttpResponse).Resource;

            if (jsonResponse.Error != null || jsonResponse.Result == null)
            {
                throw new IndexerException(indexerResponse, "Indexer API call returned an error [{0}]", jsonResponse.Error);
            }

            if (jsonResponse.Result.Results == 0)
            {
                return(results);
            }

            foreach (var torrent in jsonResponse.Result.Torrents.Values)
            {
                var torrentInfo = new TorrentInfo();

                torrentInfo.Guid        = String.Format("BTN-{0}", torrent.TorrentID);
                torrentInfo.Title       = torrent.ReleaseName;
                torrentInfo.Size        = torrent.Size;
                torrentInfo.DownloadUrl = torrent.DownloadURL;
                torrentInfo.InfoUrl     = String.Format("https://broadcasthe.net/torrents.php?id={0}&torrentid={1}", torrent.GroupID, torrent.TorrentID);
                //torrentInfo.CommentUrl =
                if (torrent.TvrageID.HasValue)
                {
                    torrentInfo.TvRageId = torrent.TvrageID.Value;
                }
                torrentInfo.PublishDate = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).ToUniversalTime().AddSeconds(torrent.Time);
                //torrentInfo.MagnetUrl =
                torrentInfo.InfoHash = torrent.InfoHash;
                torrentInfo.Seeders  = torrent.Seeders;
                torrentInfo.Peers    = torrent.Leechers + torrent.Seeders;

                results.Add(torrentInfo);
            }

            return(results);
        }
Esempio n. 5
0
        protected override bool PreProcess(IndexerResponse indexerResponse)
        {
            var xdoc = LoadXmlDocument(indexerResponse);
            var error = xdoc.Descendants("error").FirstOrDefault();

            if (error == null) return true;

            var code = Convert.ToInt32(error.Attribute("code").Value);
            var errorMessage = error.Attribute("description").Value;

            if (code >= 100 && code <= 199)
            {
                _logger.Warn("Invalid API Key: {0}", errorMessage);
                throw new ApiKeyException("Invalid API key");
            }

            if (!indexerResponse.Request.Url.ToString().Contains("apikey=") && (errorMessage == "Missing parameter" || errorMessage.Contains("apikey")))
            {
                throw new ApiKeyException("Indexer requires an API key");
            }

            if (errorMessage == "Request limit reached")
            {
                throw new RequestLimitReachedException("API limit reached");
            }

            throw new NewznabException(indexerResponse, errorMessage);
        }
Esempio n. 6
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse response)
        {
            var torrentInfos = new List <ReleaseInfo>();

            var jsonResponse = new HttpResponse <DeemixSearchResponse>(response.HttpResponse);

            foreach (var result in jsonResponse.Resource.Data)
            {
                // MP3 128
                torrentInfos.Add(ToReleaseInfo(result, 1));

                // MP3 320
                if (User.CanStreamHq)
                {
                    torrentInfos.Add(ToReleaseInfo(result, 3));
                }

                // FLAC
                if (User.CanStreamHq)
                {
                    torrentInfos.Add(ToReleaseInfo(result, 9));
                }
            }

            // order by date
            return
                (torrentInfos
                 .OrderByDescending(o => o.Size)
                 .ToArray());
        }
Esempio n. 7
0
        protected override bool PreProcess(IndexerResponse indexerResponse)
        {
            var xdoc  = LoadXmlDocument(indexerResponse);
            var error = xdoc.Descendants("error").FirstOrDefault();

            if (error == null)
            {
                return(true);
            }

            var code         = Convert.ToInt32(error.Attribute("code").Value);
            var errorMessage = error.Attribute("description").Value;

            if (code >= 100 && code <= 199)
            {
                throw new ApiKeyException("Invalid Pass key");
            }

            if (!indexerResponse.Request.Url.FullUri.Contains("passkey=") && errorMessage == "Missing parameter")
            {
                throw new ApiKeyException("Indexer requires an Pass key");
            }

            if (errorMessage == "Request limit reached")
            {
                throw new RequestLimitReachedException("API limit reached");
            }

            throw new IndexerException(indexerResponse, errorMessage);
        }
        private Boolean IsEZTVFeed(IndexerResponse response)
        {
            using (var xmlTextReader = XmlReader.Create(new StringReader(response.Content), new XmlReaderSettings {
                DtdProcessing = DtdProcessing.Parse, ValidationType = ValidationType.None, IgnoreComments = true, XmlResolver = null
            }))
            {
                var document = XDocument.Load(xmlTextReader);

                // Check Namespace
                if (document.Root == null)
                {
                    throw new InvalidDataException("Could not parse IndexerResponse into XML.");
                }

                var ns = document.Root.GetNamespaceOfPrefix("torrent");
                if (ns == "http://xmlns.ezrss.it/0.1/")
                {
                    _logger.Trace("Identified feed as EZTV compatible by EZTV Namespace");
                    return(true);
                }

                // Check DTD in DocType
                if (document.DocumentType != null && document.DocumentType.SystemId == "http://xmlns.ezrss.it/0.1/dtd/")
                {
                    _logger.Trace("Identified feed as EZTV compatible by EZTV DTD");
                    return(true);
                }

                return(false);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Detect settings for Parser, based on URL
        /// </summary>
        /// <param name="settings">Indexer Settings to use for Parser</param>
        /// <returns>Parsed Settings or <c>null</c></returns>
        public TorrentRssIndexerParserSettings Detect(TorrentRssIndexerSettings indexerSettings)
        {
            _logger.Debug("Evaluating TorrentRss feed '{0}'", indexerSettings.BaseUrl);

            try
            {
                var requestGenerator = new TorrentRssIndexerRequestGenerator {
                    Settings = indexerSettings
                };
                var request = requestGenerator.GetRecentRequests().GetAllTiers().First().First();

                HttpResponse httpResponse = null;
                try
                {
                    httpResponse = _httpClient.Execute(request.HttpRequest);
                }
                catch (Exception ex)
                {
                    _logger.Warn(ex, string.Format("Unable to connect to indexer {0}: {1}", request.Url, ex.Message));
                    return(null);
                }

                var indexerResponse = new IndexerResponse(request, httpResponse);
                return(GetParserSettings(indexerResponse, indexerSettings));
            }
            catch (Exception ex)
            {
                ex.WithData("FeedUrl", indexerSettings.BaseUrl);
                throw;
            }
        }
Esempio n. 10
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var results = new List <ReleaseInfo>();

            switch (indexerResponse.HttpResponse.StatusCode)
            {
            default:
                if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
                {
                    throw new IndexerException(indexerResponse, "Indexer API call returned an unexpected StatusCode [{0}]", indexerResponse.HttpResponse.StatusCode);
                }
                break;
            }

            var jsonResponse = new HttpResponse <TorrentPotatoResponse>(indexerResponse.HttpResponse);

            foreach (var torrent in jsonResponse.Resource.results)
            {
                var torrentInfo = new TorrentInfo();

                torrentInfo.Guid        = GetGuid(torrent);
                torrentInfo.Title       = torrent.release_name;
                torrentInfo.Size        = (long)torrent.size * 1000 * 1000;
                torrentInfo.DownloadUrl = torrent.download_url;
                torrentInfo.InfoUrl     = torrent.details_url;
                torrentInfo.PublishDate = torrent.publish_date.ToUniversalTime();
                torrentInfo.Seeders     = torrent.seeders;
                torrentInfo.Peers       = torrent.leechers + torrent.seeders;
                torrentInfo.Freeleech   = torrent.freeleech;

                results.Add(torrentInfo);
            }

            return(results);
        }
Esempio n. 11
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <ReleaseInfo>();

            if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
            {
                throw new IndexerException(indexerResponse,
                                           "Unexpected response status {0} code from API request",
                                           indexerResponse.HttpResponse.StatusCode);
            }

            var queryResults = JsonConvert.DeserializeObject <List <FileListTorrent> >(indexerResponse.Content);

            foreach (var result in queryResults)
            {
                var id = result.Id;

                //if (result.FreeLeech)
                torrentInfos.Add(new TorrentInfo()
                {
                    Guid        = $"FileList-{id}",
                    Title       = result.Name,
                    Size        = result.Size,
                    DownloadUrl = GetDownloadUrl(id),
                    InfoUrl     = GetInfoUrl(id),
                    Seeders     = result.Seeders,
                    Peers       = result.Leechers + result.Seeders,
                    PublishDate = result.UploadDate.ToUniversalTime()
                });
            }

            return(torrentInfos.ToArray());
        }
Esempio n. 12
0
        protected override bool PreProcess(IndexerResponse indexerResponse)
        {
            var xdoc  = XDocument.Parse(indexerResponse.Content);
            var error = xdoc.Descendants("error").FirstOrDefault();

            if (error == null)
            {
                return(true);
            }

            var code         = Convert.ToInt32(error.Attribute("code").Value);
            var errorMessage = error.Attribute("description").Value;

            if (code >= 100 && code <= 199)
            {
                throw new ApiKeyException("Invalid API key");
            }

            if (!indexerResponse.Request.Url.ToString().Contains("apikey=") && errorMessage == "Missing parameter")
            {
                throw new ApiKeyException("Indexer requires an API key");
            }

            if (errorMessage == "Request limit reached")
            {
                throw new RequestLimitReachedException("API limit reached");
            }

            throw new TorznabException("Torznab error detected: {0}", errorMessage);
        }
Esempio n. 13
0
        public static void CheckError(XDocument xdoc, IndexerResponse indexerResponse)
        {
            var error = xdoc.Descendants("error").FirstOrDefault();

            if (error == null)
            {
                return;
            }

            var code         = Convert.ToInt32(error.Attribute("code").Value);
            var errorMessage = error.Attribute("description").Value;

            if (code >= 100 && code <= 199)
            {
                throw new ApiKeyException(errorMessage);
            }

            if (!indexerResponse.Request.Url.FullUri.Contains("apikey=") && (errorMessage == "Missing parameter" || errorMessage.Contains("apikey")))
            {
                throw new ApiKeyException("Indexer requires an API key");
            }

            if (errorMessage == "Request limit reached")
            {
                throw new RequestLimitReachedException("API limit reached");
            }

            throw new NewznabException(indexerResponse, errorMessage);
        }
Esempio n. 14
0
        public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var results = new List<ReleaseInfo>();

            switch (indexerResponse.HttpResponse.StatusCode)
            {
                case HttpStatusCode.Unauthorized:
                    throw new ApiKeyException("API Key invalid or not authorized");
                case HttpStatusCode.NotFound:
                    throw new IndexerException(indexerResponse, "Indexer API call returned NotFound, the Indexer API may have changed.");
                case HttpStatusCode.ServiceUnavailable:
                    throw new RequestLimitReachedException("Cannot do more than 150 API requests per hour.");
                default:
                    if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
                    {
                        throw new IndexerException(indexerResponse, "Indexer API call returned an unexpected StatusCode [{0}]", indexerResponse.HttpResponse.StatusCode);
                    }
                    break;
            }

            var jsonResponse = new HttpResponse<JsonRpcResponse<BroadcastheNetTorrents>>(indexerResponse.HttpResponse).Resource;

            if (jsonResponse.Error != null || jsonResponse.Result == null)
            {
                throw new IndexerException(indexerResponse, "Indexer API call returned an error [{0}]", jsonResponse.Error);
            }

            if (jsonResponse.Result.Results == 0)
            {
                return results;
            }

            var protocol = indexerResponse.HttpRequest.Url.Scheme + ":";

            foreach (var torrent in jsonResponse.Result.Torrents.Values)
            {
                var torrentInfo = new TorrentInfo();

                torrentInfo.Guid = string.Format("BTN-{0}", torrent.TorrentID);
                torrentInfo.Title = torrent.ReleaseName;
                torrentInfo.Size = torrent.Size;
                torrentInfo.DownloadUrl = RegexProtocol.Replace(torrent.DownloadURL, protocol);
                torrentInfo.InfoUrl = string.Format("{0}//broadcasthe.net/torrents.php?id={1}&torrentid={2}", protocol, torrent.GroupID, torrent.TorrentID);
                //torrentInfo.CommentUrl =
                if (torrent.TvrageID.HasValue)
                {
                    torrentInfo.TvRageId = torrent.TvrageID.Value;
                }
                torrentInfo.PublishDate = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).ToUniversalTime().AddSeconds(torrent.Time);
                //torrentInfo.MagnetUrl =
                torrentInfo.InfoHash = torrent.InfoHash;
                torrentInfo.Seeders = torrent.Seeders;
                torrentInfo.Peers = torrent.Leechers + torrent.Seeders;

                results.Add(torrentInfo);
            }

            return results;
        }
Esempio n. 15
0
        protected override bool PreProcess(IndexerResponse indexerResponse)
        {
            var xdoc = LoadXmlDocument(indexerResponse);

            CheckError(xdoc, indexerResponse);

            return(true);
        }
Esempio n. 16
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos        = new List <TorrentInfo>();
            var indexerHttpResponse = indexerResponse.HttpResponse;

            if (indexerHttpResponse.StatusCode != HttpStatusCode.OK)
            {
                throw new IndexerException(indexerResponse, $"Unexpected response status {indexerHttpResponse.StatusCode} code from API request");
            }

            if (!indexerHttpResponse.Headers.ContentType.Contains(HttpAccept.Json.Value))
            {
                throw new IndexerException(indexerResponse, $"Unexpected response header {indexerHttpResponse.Headers.ContentType} from API request, expected {HttpAccept.Json.Value}");
            }

            if (indexerResponse.Content.ContainsIgnoreCase("Invalid API Key"))
            {
                throw new IndexerAuthException("API Key invalid or not authorized");
            }

            var jsonResponse = new HttpResponse <BeyondHDResponse>(indexerHttpResponse);

            foreach (var row in jsonResponse.Resource.Results)
            {
                var details = row.InfoUrl;
                var link    = row.DownloadLink;

                // BHD can return crazy values for tmdb
                var tmdbId = row.TmdbId.IsNullOrWhiteSpace() ? 0 : ParseUtil.TryCoerceInt(row.TmdbId.Split("/")[1], out var tmdbResult) ? tmdbResult : 0;
                var imdbId = ParseUtil.GetImdbID(row.ImdbId).GetValueOrDefault();

                var release = new TorrentInfo
                {
                    Title                = row.Name,
                    DownloadUrl          = link,
                    InfoHash             = row.InfoHash,
                    InfoUrl              = details,
                    Guid                 = details,
                    Categories           = _categories.MapTrackerCatDescToNewznab(row.Category),
                    PublishDate          = DateTime.Parse(row.CreatedAt, CultureInfo.InvariantCulture),
                    Size                 = row.Size,
                    Grabs                = row.Grabs,
                    Seeders              = row.Seeders,
                    ImdbId               = imdbId,
                    TmdbId               = tmdbId,
                    Peers                = row.Leechers + row.Seeders,
                    DownloadVolumeFactor = row.Freeleech || row.Limited ? 0 : row.Promo75 ? 0.25 : row.Promo50 ? 0.5 : row.Promo25 ? 0.75 : 1,
                    UploadVolumeFactor   = 1,
                    MinimumRatio         = 1,
                    MinimumSeedTime      = 172800, // 120 hours
                };

                torrentInfos.Add(release);
            }

            // order by date
            return(torrentInfos.OrderByDescending(o => o.PublishDate).ToArray());
        }
Esempio n. 17
0
        protected override bool PreProcess(IndexerResponse indexerResponse)
        {
            if (indexerResponse.HttpResponse.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                return(false);
            }

            return(base.PreProcess(indexerResponse));
        }
Esempio n. 18
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <ReleaseInfo>();

            var parser = new HtmlParser();
            var dom    = parser.ParseDocument(indexerResponse.Content);
            var rows   = dom.QuerySelectorAll("table > tbody > tr.browse");

            foreach (var row in rows)
            {
                var qLink = row.Children[1].QuerySelector("a");
                var title = qLink.GetAttribute("title");
                if (qLink.QuerySelectorAll("span").Length == 1 && title.StartsWith("NEW! |"))
                {
                    title = title.Substring(6).Trim();
                }

                // TODO: Asses if we should be throwing this out
                //if (!query.MatchQueryStringAND(title))
                //{
                //    continue; // we have to skip bad titles due to tags + any word search
                //}
                var details     = _settings.BaseUrl + qLink.GetAttribute("href");
                var link        = _settings.BaseUrl + row.Children[2].QuerySelector("a").GetAttribute("href");
                var dateStr     = Regex.Replace(row.Children[5].InnerHtml, @"\<br[\s]{0,1}[\/]{0,1}\>", " ");
                var publishDate = DateTimeUtil.FromTimeAgo(dateStr);
                var files       = ParseUtil.CoerceInt(row.Children[3].TextContent);
                var size        = ParseUtil.GetBytes(row.Children[7].TextContent);
                var grabs       = ParseUtil.CoerceInt(row.Children[8].TextContent);
                var seeders     = ParseUtil.CoerceInt(row.Children[9].TextContent);
                var leechers    = ParseUtil.CoerceInt(row.Children[10].TextContent);
                var cat         = row.FirstElementChild.FirstElementChild.GetAttribute("href").Replace("browse.php?", string.Empty);

                var release = new TorrentInfo
                {
                    Title                = title,
                    InfoUrl              = details,
                    Guid                 = details,
                    DownloadUrl          = link,
                    PublishDate          = publishDate,
                    Size                 = size,
                    Categories           = _categories.MapTrackerCatToNewznab(cat),
                    Files                = files,
                    Grabs                = grabs,
                    Seeders              = seeders,
                    Peers                = leechers + seeders,
                    MinimumRatio         = 0.75,
                    MinimumSeedTime      = 216000, // 60 hours
                    DownloadVolumeFactor = 0,      // ratioless
                    UploadVolumeFactor   = 1
                };

                torrentInfos.Add(release);
            }

            return(torrentInfos.ToArray());
        }
Esempio n. 19
0
        protected override bool PreProcess(IndexerResponse indexerResponse)
        {
            if (indexerResponse.HttpResponse.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                return false;
            }

            return base.PreProcess(indexerResponse);
        }
Esempio n. 20
0
        public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var results = new List<ReleaseInfo>();

            switch (indexerResponse.HttpResponse.StatusCode)
            {
                default:
                    if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
                    {
                        throw new IndexerException(indexerResponse, "Indexer API call returned an unexpected StatusCode [{0}]", indexerResponse.HttpResponse.StatusCode);
                    }
                    break;
            }

            var jsonResponse = new HttpResponse<RarbgResponse>(indexerResponse.HttpResponse);

            if (jsonResponse.Resource.error_code.HasValue)
            {
                if (jsonResponse.Resource.error_code == 20 || jsonResponse.Resource.error_code == 8)
                {
                    // No results found
                    return results;
                }

                throw new IndexerException(indexerResponse, "Indexer API call returned error {0}: {1}", jsonResponse.Resource.error_code, jsonResponse.Resource.error);
            }

            if (jsonResponse.Resource.torrent_results == null)
            {
                return results;
            }

            foreach (var torrent in jsonResponse.Resource.torrent_results)
            {
                var torrentInfo = new TorrentInfo();

                torrentInfo.Guid = GetGuid(torrent);
                torrentInfo.Title = torrent.title;
                torrentInfo.Size = torrent.size;
                torrentInfo.DownloadUrl = torrent.download;
                torrentInfo.InfoUrl = torrent.info_page;
                torrentInfo.PublishDate = torrent.pubdate;
                torrentInfo.Seeders = torrent.seeders;
                torrentInfo.Peers = torrent.leechers + torrent.seeders;

                if (torrent.episode_info != null && torrent.episode_info.tvrage != null)
                {
                    torrentInfo.TvRageId = torrent.episode_info.tvrage.Value;
                }

                results.Add(torrentInfo);
            }

            return results;
        }
Esempio n. 21
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var results = new List <ReleaseInfo>();

            switch (indexerResponse.HttpResponse.StatusCode)
            {
            default:
                if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
                {
                    throw new IndexerException(indexerResponse, "Indexer API call returned an unexpected StatusCode [{0}]", indexerResponse.HttpResponse.StatusCode);
                }
                break;
            }

            var jsonResponse = new HttpResponse <RarbgResponse>(indexerResponse.HttpResponse);

            if (jsonResponse.Resource.error_code.HasValue)
            {
                if (jsonResponse.Resource.error_code == 20 || jsonResponse.Resource.error_code == 8)
                {
                    // No results found
                    return(results);
                }

                throw new IndexerException(indexerResponse, "Indexer API call returned error {0}: {1}", jsonResponse.Resource.error_code, jsonResponse.Resource.error);
            }

            if (jsonResponse.Resource.torrent_results == null)
            {
                return(results);
            }

            foreach (var torrent in jsonResponse.Resource.torrent_results)
            {
                var torrentInfo = new TorrentInfo();

                torrentInfo.Guid        = GetGuid(torrent);
                torrentInfo.Title       = torrent.title;
                torrentInfo.Size        = torrent.size;
                torrentInfo.DownloadUrl = torrent.download;
                torrentInfo.InfoUrl     = torrent.info_page;
                torrentInfo.PublishDate = torrent.pubdate;
                torrentInfo.Seeders     = torrent.seeders;
                torrentInfo.Peers       = torrent.leechers + torrent.seeders;

                if (torrent.episode_info != null && torrent.episode_info.tvrage != null)
                {
                    torrentInfo.TvRageId = torrent.episode_info.tvrage.Value;
                }

                results.Add(torrentInfo);
            }

            return(results);
        }
Esempio n. 22
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <TorrentInfo>();

            var rows = JsonConvert.DeserializeObject <dynamic>(indexerResponse.Content).torrentList;

            foreach (var row in rows ?? Enumerable.Empty <dynamic>())
            {
                var title = row.name.ToString();

                var torrentId   = row.fid.ToString();
                var details     = new Uri(_settings.BaseUrl + "torrent/" + torrentId);
                var link        = new Uri(_settings.BaseUrl + "download/" + torrentId + "/" + row.filename);
                var publishDate = DateTime.ParseExact(row.addedTimestamp.ToString(), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
                var seeders     = (int)row.seeders;
                var leechers    = (int)row.leechers;
                var grabs       = (int)row.completed;
                var size        = (long)row.size;
                var cats        = _categories.MapTrackerCatToNewznab(((int)row.categoryID).ToString());
                var imdb        = (string)row.imdbID;
                var imdbId      = 0;
                if (imdb.Length > 2)
                {
                    imdbId = int.Parse(imdb.Substring(2));
                }

                // freeleech #6579 #6624 #7367
                string dlMultiplier   = row.download_multiplier.ToString();
                var    dlVolumeFactor = dlMultiplier.IsNullOrWhiteSpace() ? 1 : ParseUtil.CoerceInt(dlMultiplier);

                var release = new TorrentInfo
                {
                    Title                = title,
                    InfoUrl              = details.AbsoluteUri,
                    Guid                 = details.AbsoluteUri,
                    DownloadUrl          = link.AbsoluteUri,
                    PublishDate          = publishDate,
                    Categories           = cats,
                    Size                 = size,
                    Grabs                = grabs,
                    Seeders              = seeders,
                    Peers                = seeders + leechers,
                    ImdbId               = imdbId,
                    UploadVolumeFactor   = 1,
                    DownloadVolumeFactor = dlVolumeFactor,
                    MinimumRatio         = 1,
                    MinimumSeedTime      = 864000 // 10 days for registered users, less for upgraded users
                };

                torrentInfos.Add(release);
            }

            return(torrentInfos.ToArray());
        }
Esempio n. 23
0
        protected override bool PreProcess(IndexerResponse indexerResponse)
        {
            var xdoc = LoadXmlDocument(indexerResponse);
            var notice = xdoc.Descendants("notice").FirstOrDefault();

            if (notice == null) return true;

            if (!notice.Value.ContainsIgnoreCase("api")) return true;

            throw new ApiKeyException(notice.Value);
        }
Esempio n. 24
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <TorrentInfo>();

            if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
            {
                throw new IndexerException(indexerResponse, $"Unexpected response status {indexerResponse.HttpResponse.StatusCode} code from API request");
            }

            if (!indexerResponse.HttpResponse.Headers.ContentType.Contains(HttpAccept.Json.Value))
            {
                throw new IndexerException(indexerResponse, $"Unexpected response header {indexerResponse.HttpResponse.Headers.ContentType} from API request, expected {HttpAccept.Json.Value}");
            }

            var jsonResponse = new HttpResponse <InternetArchiveResponse>(indexerResponse.HttpResponse);

            foreach (var searchResult in jsonResponse.Resource.SearchResults)
            {
                var title = searchResult.Title ?? searchResult.Identifier;

                var downloadUrl = string.Format("{0}/download/{1}/{1}_archive.torrent", _settings.BaseUrl.TrimEnd('/'), searchResult.Identifier);
                var detailsUrl  = string.Format("{0}/details/{1}", _settings.BaseUrl.TrimEnd('/'), searchResult.Identifier);

                var category = _categories.MapTrackerCatToNewznab(searchResult.MediaType ?? "other");

                var release = new TorrentInfo
                {
                    Categories           = category,
                    CommentUrl           = detailsUrl,
                    DownloadUrl          = downloadUrl,
                    DownloadVolumeFactor = 0,
                    Guid               = detailsUrl,
                    Grabs              = searchResult.Downloads,
                    InfoHash           = searchResult.InfoHash,
                    InfoUrl            = detailsUrl,
                    Peers              = 2,
                    PublishDate        = searchResult.PublicDate,
                    Seeders            = 1,
                    Size               = searchResult.Size,
                    Title              = title,
                    UploadVolumeFactor = 1
                };

                if (!_settings.TorrentFileOnly && searchResult.InfoHash != null)
                {
                    release.MagnetUrl = MagnetLinkBuilder.BuildPublicMagnetLink(searchResult.InfoHash, title);
                }

                torrentInfos.Add(release);
            }

            return(torrentInfos.ToArray());
        }
Esempio n. 25
0
        public override IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var releases = base.ParseResponse(indexerResponse);

            foreach (TorrentInfo release in releases)
            {
                release.MinimumRatio    = 0.6;
                release.MinimumSeedTime = 259200;
            }

            return(releases);
        }
Esempio n. 26
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <ReleaseInfo>();

            if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
            {
                throw new IndexerException(indexerResponse,
                                           "Unexpected response status {0} code from API request",
                                           indexerResponse.HttpResponse.StatusCode);
            }

            var queryResults = JsonConvert.DeserializeObject <List <FileListTorrent> >(indexerResponse.Content);

            foreach (var result in queryResults)
            {
                var id = result.Id;

                var flags = new List <IndexerFlag>();

                var imdbId = 0;
                if (result.ImdbId != null && result.ImdbId.Length > 2)
                {
                    imdbId = int.Parse(result.ImdbId.Substring(2));
                }

                var downloadVolumeFactor = result.FreeLeech == true ? 0 : 1;
                var uploadVolumeFactor   = result.DoubleUp == true ? 2 : 1;

                torrentInfos.Add(new TorrentInfo()
                {
                    Guid                 = string.Format("FileList-{0}", id),
                    Title                = result.Name,
                    Size                 = result.Size,
                    Categories           = _categories.MapTrackerCatDescToNewznab(result.Category),
                    DownloadUrl          = GetDownloadUrl(id),
                    InfoUrl              = GetInfoUrl(id),
                    Seeders              = result.Seeders,
                    Peers                = result.Leechers + result.Seeders,
                    PublishDate          = result.UploadDate,
                    ImdbId               = imdbId,
                    IndexerFlags         = flags,
                    Files                = (int)result.Files,
                    Grabs                = (int)result.TimesCompleted,
                    DownloadVolumeFactor = downloadVolumeFactor,
                    UploadVolumeFactor   = uploadVolumeFactor,
                    MinimumRatio         = 1,
                    MinimumSeedTime      = 172800, //48 hours
                });
            }

            return(torrentInfos.ToArray());
        }
Esempio n. 27
0
 private TorrentInfo[] ParseResponse(IParseIndexerResponse parser, IndexerResponse response)
 {
     try
     {
         var releases = parser.ParseResponse(response).Cast <TorrentInfo>().ToArray();
         return(releases);
     }
     catch (Exception ex)
     {
         _logger.Debug(ex, "Unable to parse indexer feed: " + ex.Message);
         throw new UnsupportedFeedException("Unable to parse indexer: " + ex.Message);
     }
 }
Esempio n. 28
0
        public virtual IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <TorrentInfo>();

            if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
            {
                throw new IndexerException(indexerResponse, $"Unexpected response status {indexerResponse.HttpResponse.StatusCode} code from API request");
            }

            if (!indexerResponse.HttpResponse.Headers.ContentType.Contains(HttpAccept.Json.Value))
            {
                throw new IndexerException(indexerResponse, $"Unexpected response header {indexerResponse.HttpResponse.Headers.ContentType} from API request, expected {HttpAccept.Json.Value}");
            }

            var jsonResponse = new HttpResponse <Unit3dResponse>(indexerResponse.HttpResponse);

            foreach (var row in jsonResponse.Resource.Data)
            {
                var details = row.Attributes.DetailsLink;
                var link    = row.Attributes.DownloadLink;

                var release = new TorrentInfo
                {
                    Title                = row.Attributes.Name,
                    DownloadUrl          = link,
                    InfoHash             = row.Id,
                    InfoUrl              = details,
                    Guid                 = details,
                    Categories           = _categories.MapTrackerCatDescToNewznab(row.Attributes.Category),
                    PublishDate          = DateTime.Parse(row.Attributes.CreatedAt, CultureInfo.InvariantCulture),
                    Size                 = row.Attributes.Size,
                    Files                = row.Attributes.Files,
                    Grabs                = row.Attributes.Grabs,
                    Seeders              = row.Attributes.Seeders,
                    ImdbId               = ParseUtil.GetImdbID(row.Attributes.ImdbId).GetValueOrDefault(),
                    TmdbId               = row.Attributes.TmdbId.IsNullOrWhiteSpace() ? 0 : ParseUtil.CoerceInt(row.Attributes.TmdbId),
                    TvdbId               = row.Attributes.TvdbId.IsNullOrWhiteSpace() ? 0 : ParseUtil.CoerceInt(row.Attributes.TvdbId),
                    Peers                = row.Attributes.Leechers + row.Attributes.Seeders,
                    DownloadVolumeFactor = row.Attributes.Freeleech ? 0 : 1,
                    UploadVolumeFactor   = row.Attributes.DoubleUpload ? 2 : 1,
                    MinimumRatio         = 1,
                    MinimumSeedTime      = 172800, // 48 hours
                };

                torrentInfos.Add(release);
            }

            // order by date
            return(torrentInfos.OrderByDescending(o => o.PublishDate).ToArray());
        }
Esempio n. 29
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <ReleaseInfo>();

            if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
            {
                throw new IndexerException(indexerResponse,
                                           "Unexpected response status {0} code from API request",
                                           indexerResponse.HttpResponse.StatusCode);
            }

            var jsonResponse = JsonConvert.DeserializeObject <HDBitsResponse>(indexerResponse.Content);

            if (jsonResponse.Status != StatusCode.Success)
            {
                throw new IndexerException(indexerResponse,
                                           "HDBits API request returned status code {0}: {1}",
                                           jsonResponse.Status,
                                           jsonResponse.Message ?? string.Empty);
            }

            var responseData = jsonResponse.Data as JArray;

            if (responseData == null)
            {
                throw new IndexerException(indexerResponse,
                                           "Indexer API call response missing result data");
            }

            var queryResults = responseData.ToObject <TorrentQueryResponse[]>();

            foreach (var result in queryResults)
            {
                var id = result.Id;
                torrentInfos.Add(new TorrentInfo()
                {
                    Guid        = string.Format("HDBits-{0}", id),
                    Title       = result.Name,
                    Size        = result.Size,
                    InfoHash    = result.Hash,
                    DownloadUrl = GetDownloadUrl(id),
                    InfoUrl     = GetInfoUrl(id),
                    Seeders     = result.Seeders,
                    Peers       = result.Leechers + result.Seeders,
                    PublishDate = result.Added.ToUniversalTime()
                });
            }

            return(torrentInfos.ToArray());
        }
Esempio n. 30
0
        public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List<ReleaseInfo>();

            if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
            {
                throw new IndexerException(indexerResponse,
                    "Unexpected response status {0} code from API request",
                    indexerResponse.HttpResponse.StatusCode);
            }

            var jsonResponse = JsonConvert.DeserializeObject<HDBitsResponse>(indexerResponse.Content);

            if (jsonResponse.Status != StatusCode.Success)
            {
                throw new IndexerException(indexerResponse,
                    "HDBits API request returned status code {0}: {1}",
                    jsonResponse.Status,
                    jsonResponse.Message ?? string.Empty);
            }

            var responseData = jsonResponse.Data as JArray;
            if (responseData == null)
            {
                throw new IndexerException(indexerResponse,
                    "Indexer API call response missing result data");
            }

            var queryResults = responseData.ToObject<TorrentQueryResponse[]>();

            foreach (var result in queryResults)
            {
                var id = result.Id;
                torrentInfos.Add(new TorrentInfo()
                {
                    Guid = string.Format("HDBits-{0}", id),
                    Title = result.Name,
                    Size = result.Size,
                    InfoHash = result.Hash,
                    DownloadUrl = GetDownloadUrl(id),
                    InfoUrl = GetInfoUrl(id),
                    Seeders = result.Seeders,
                    Peers = result.Leechers + result.Seeders,
                    PublishDate = result.Added.ToUniversalTime()
                });
            }

            return torrentInfos.ToArray();
        }
Esempio n. 31
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <ReleaseInfo>();

            var parser = new HtmlParser();
            var dom    = parser.ParseDocument(indexerResponse.Content);
            var rows   = dom.QuerySelectorAll("div.boxContent > table > tbody > tr");

            foreach (var row in rows)
            {
                var cells = row.QuerySelectorAll("td");

                var title    = row.QuerySelector("td[class='lft'] > div > a").TextContent.Trim();
                var link     = new Uri(_settings.BaseUrl + row.QuerySelector("img[title='Download']").ParentElement.GetAttribute("href").TrimStart('/'));
                var details  = new Uri(_settings.BaseUrl + row.QuerySelector("td[class='lft'] > div > a").GetAttribute("href").TrimStart('/'));
                var size     = ParseUtil.GetBytes(cells[5].TextContent);
                var grabs    = ParseUtil.CoerceInt(cells[6].TextContent);
                var seeders  = ParseUtil.CoerceInt(cells[7].TextContent);
                var leechers = ParseUtil.CoerceInt(cells[8].TextContent);

                var pubDateStr  = row.QuerySelector("span[class^='elapsedDate']").GetAttribute("title").Replace(" at", "");
                var publishDate = DateTime.ParseExact(pubDateStr, "dddd, MMMM d, yyyy h:mmtt", CultureInfo.InvariantCulture);

                var cat = row.QuerySelector("a").GetAttribute("href").Split('/').Last();
                var downloadVolumeFactor = row.QuerySelector("span:contains(\"[Freeleech]\")") != null ? 0 : 1;

                var release = new TorrentInfo
                {
                    Title                = title,
                    DownloadUrl          = link.AbsoluteUri,
                    Guid                 = link.AbsoluteUri,
                    InfoUrl              = details.AbsoluteUri,
                    PublishDate          = publishDate,
                    Categories           = _categories.MapTrackerCatToNewznab(cat),
                    Size                 = size,
                    Grabs                = grabs,
                    Seeders              = seeders,
                    Peers                = seeders + leechers,
                    MinimumRatio         = 1,
                    MinimumSeedTime      = 259200, // 72 hours
                    DownloadVolumeFactor = downloadVolumeFactor,
                    UploadVolumeFactor   = 1
                };

                torrentInfos.Add(release);
            }

            return(torrentInfos.ToArray());
        }
Esempio n. 32
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <ReleaseInfo>();

            var detailsUrl  = _settings.BaseUrl + "details.php?";
            var downloadUrl = _settings.BaseUrl + "download.php?";

            if (indexerResponse.Content?.Contains("User not found or passkey not set") == true)
            {
                throw new IndexerAuthException("The passkey is invalid. Check the indexer configuration.");
            }

            var jsonContent = JArray.Parse(indexerResponse.Content);

            foreach (var item in jsonContent)
            {
                var title = item.Value <string>("name");

                var id             = item.Value <long>("id");
                var details        = new Uri(detailsUrl + "id=" + id).AbsoluteUri;
                var link           = new Uri(downloadUrl + "id=" + id + "&passkey=" + _settings.Passkey).AbsoluteUri;
                var publishDate    = DateTime.ParseExact(item.Value <string>("added"), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                var dlVolumeFactor = item.Value <int>("is_freeleech") == 1 ? 0 : 1;

                var release = new TorrentInfo
                {
                    Title                = title,
                    DownloadUrl          = link,
                    InfoUrl              = details,
                    Guid                 = details,
                    Categories           = _categories.MapTrackerCatToNewznab(item.Value <string>("category")),
                    PublishDate          = publishDate,
                    Size                 = item.Value <long>("size"),
                    Grabs                = item.Value <int>("times_completed"),
                    Files                = item.Value <int>("numfiles"),
                    Seeders              = item.Value <int>("seeders"),
                    Peers                = item.Value <int>("leechers") + item.Value <int>("seeders"),
                    ImdbId               = ParseUtil.GetImdbID(item.Value <string>("imdbid")) ?? 0,
                    MinimumRatio         = 1,
                    MinimumSeedTime      = 0,
                    DownloadVolumeFactor = dlVolumeFactor,
                    UploadVolumeFactor   = 1
                };

                torrentInfos.Add(release);
            }

            return(torrentInfos.ToArray());
        }
Esempio n. 33
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var releaseInfos = new List <ReleaseInfo>();

            var parser = new HtmlParser();
            var doc    = parser.ParseDocument(indexerResponse.Content);
            var rows   = doc.QuerySelectorAll("table.xMenuT > tbody > tr").Skip(1);

            foreach (var row in rows)
            {
                var titleElement = row.QuerySelector("td > span.s");

                if (titleElement == null)
                {
                    continue;
                }

                var parsedTitle = ParseTitleRegex.Match(titleElement.TextContent);

                if (!parsedTitle.Success || parsedTitle.Groups["title"].Value.IsNullOrWhiteSpace())
                {
                    continue;
                }

                var guid        = row.QuerySelector("input[type=checkbox]").GetAttribute("name");
                var publishDate = DateTimeUtil.FromUnknown(row.QuerySelector("td:nth-child(6)").TextContent);
                var sizeElement = row.QuerySelector("td > span.d");
                var size        = ParseSizeRegex.Match(sizeElement.TextContent);
                var infoUrl     = string.Format("{0}{1}", _settings.BaseUrl.TrimEnd('/'), row.QuerySelector("a").GetAttribute("href"));
                var downloadUrl = string.Format("{0}/?action=nzb&{1}=1", _settings.BaseUrl.TrimEnd('/'), guid);

                var release = new ReleaseInfo
                {
                    Guid        = guid,
                    Title       = parsedTitle.Groups["title"].Value,
                    Size        = ParseUtil.GetBytes(string.Format("{0} {1}", size.Groups["size"].Value, size.Groups["unit"].Value)),
                    PublishDate = publishDate,
                    Categories  = new List <IndexerCategory> {
                        NewznabStandardCategory.Other
                    },
                    InfoUrl     = infoUrl,
                    DownloadUrl = downloadUrl
                };

                releaseInfos.Add(release);
            }

            return(releaseInfos.ToArray());
        }
Esempio n. 34
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var results = new List <ReleaseInfo>();

            switch (indexerResponse.HttpResponse.StatusCode)
            {
            case HttpStatusCode.Unauthorized:
                throw new ApiKeyException("API Key invalid or not authorized");

            case HttpStatusCode.NotFound:
                throw new IndexerException(indexerResponse, "Indexer API call returned NotFound, the Indexer API may have changed.");

            case HttpStatusCode.ServiceUnavailable:
                throw new RequestLimitReachedException("Indexer API is temporarily unavailable, try again later");

            default:
                if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
                {
                    throw new IndexerException(indexerResponse, "Indexer API call returned an unexpected StatusCode [{0}]", indexerResponse.HttpResponse.StatusCode);
                }
                break;
            }

            var content  = indexerResponse.HttpResponse.Content;
            var parsed   = Json.Deserialize <TitansOfTvApiResult>(content);
            var protocol = indexerResponse.HttpRequest.Url.Scheme + ":";

            foreach (var parsedItem in parsed.results)
            {
                var release = new TorrentInfo();
                release.Guid        = string.Format("ToTV-{0}", parsedItem.id);
                release.DownloadUrl = RegexProtocol.Replace(parsedItem.download, protocol);
                release.InfoUrl     = RegexProtocol.Replace(parsedItem.episodeUrl, protocol);
                if (parsedItem.commentUrl.IsNotNullOrWhiteSpace())
                {
                    release.CommentUrl = RegexProtocol.Replace(parsedItem.commentUrl, protocol);
                }
                release.DownloadProtocol = DownloadProtocol.Torrent;
                release.Title            = parsedItem.release_name;
                release.Size             = parsedItem.size;
                release.Seeders          = parsedItem.seeders;
                release.Peers            = parsedItem.leechers + release.Seeders;
                release.PublishDate      = parsedItem.created_at;
                results.Add(release);
            }

            return(results);
        }
Esempio n. 35
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <ReleaseInfo>();

            var jsonStart   = indexerResponse.Content;
            var jsonContent = JArray.Parse(jsonStart);

            foreach (var torrent in jsonContent)
            {
                if (torrent == null)
                {
                    continue;
                }

                var title    = torrent.Value <string>("name");
                var size     = torrent.Value <long>("size_bytes");
                var seeders  = torrent.Value <int>("seeders");
                var leechers = torrent.Value <int>("leechers");
                var grabs    = ParseUtil.CoerceInt(torrent.Value <string>("completed") ?? "0");
                var infoHash = torrent.Value <JToken>("infohash").ToString();

                // convert unix timestamp to human readable date
                var publishDate = new DateTime(1970, 1, 1, 0, 0, 0, 0);
                publishDate = publishDate.AddSeconds(torrent.Value <long>("created_unix"));

                var release = new TorrentInfo
                {
                    Title      = title,
                    InfoUrl    = _settings.BaseUrl, // there is no details link
                    Guid       = $"magnet:?xt=urn:btih:{infoHash}",
                    InfoHash   = infoHash,          // magnet link is auto generated from infohash
                    Categories = new List <IndexerCategory> {
                        NewznabStandardCategory.Other
                    },
                    PublishDate          = publishDate,
                    Size                 = size,
                    Grabs                = grabs,
                    Seeders              = seeders,
                    Peers                = leechers + seeders,
                    DownloadVolumeFactor = 0,
                    UploadVolumeFactor   = 1
                };

                torrentInfos.Add(release);
            }

            return(torrentInfos.ToArray());
        }
Esempio n. 36
0
        public IList <ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var torrentInfos = new List <ReleaseInfo>();

            var xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(indexerResponse.Content);
            foreach (XmlNode node in xmlDoc.GetElementsByTagName("item"))
            {
                var title = node.SelectSingleNode(".//*[local-name()='raw_title']").InnerText;

                // TODO: Make sure we don't return all sorts of trash
                //if (!query.MatchQueryStringAND(title))
                //{
                //    continue;
                //}
                var category = title.Contains("720p") || title.Contains("1080p") ?
                               NewznabStandardCategory.TVHD :
                               NewznabStandardCategory.TVSD;

                var magnetUri   = node.SelectSingleNode("link")?.InnerText;
                var publishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture);
                var infoHash    = node.SelectSingleNode(".//*[local-name()='info_hash']").InnerText;
                var details     = BrowseUrl + node.SelectSingleNode(".//*[local-name()='show_id']").InnerText;

                var release = new TorrentInfo
                {
                    Title      = title,
                    InfoUrl    = details,
                    Categories = new List <IndexerCategory> {
                        category
                    },
                    Guid                 = magnetUri,
                    PublishDate          = publishDate,
                    InfoHash             = infoHash,
                    MagnetUrl            = magnetUri,
                    Size                 = 512,
                    Seeders              = 1,
                    Peers                = 2,
                    DownloadVolumeFactor = 0,
                    UploadVolumeFactor   = 1
                };

                torrentInfos.Add(release);
            }

            return(torrentInfos.ToArray());
        }
        private TorrentRssIndexerParserSettings GetParserSettings(IndexerResponse response, TorrentRssIndexerSettings indexerSettings)
        {
            var settings = GetEzrssParserSettings(response, indexerSettings);
            if (settings != null)
            {
                return settings;
            }

            settings = GetGenericTorrentRssParserSettings(response, indexerSettings);
            if (settings != null)
            {
                return settings;
            }

            return null;
        }
Esempio n. 38
0
        public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
        {
            var results = new List<ReleaseInfo>();

            switch (indexerResponse.HttpResponse.StatusCode)
            {
                case HttpStatusCode.Unauthorized:
                    throw new ApiKeyException("API Key invalid or not authorized");
                case HttpStatusCode.NotFound:
                    throw new IndexerException(indexerResponse, "Indexer API call returned NotFound, the Indexer API may have changed.");
                case HttpStatusCode.ServiceUnavailable:
                    throw new RequestLimitReachedException("Indexer API is temporarily unavailable, try again later");
                default:
                    if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
                    {
                        throw new IndexerException(indexerResponse, "Indexer API call returned an unexpected StatusCode [{0}]", indexerResponse.HttpResponse.StatusCode);
                    }
                    break;
            }

            var content = indexerResponse.HttpResponse.Content;
            var parsed = Json.Deserialize<TitansOfTvApiResult>(content);
            var protocol = indexerResponse.HttpRequest.Url.Scheme + ":";

            foreach (var parsedItem in parsed.results)
            {
                var release = new TorrentInfo();
                release.Guid = string.Format("ToTV-{0}", parsedItem.id);
                release.DownloadUrl = RegexProtocol.Replace(parsedItem.download, protocol);
                release.InfoUrl = RegexProtocol.Replace(parsedItem.episodeUrl, protocol);
                if (parsedItem.commentUrl.IsNotNullOrWhiteSpace())
                {
                    release.CommentUrl = RegexProtocol.Replace(parsedItem.commentUrl, protocol);
                }
                release.DownloadProtocol = DownloadProtocol.Torrent;
                release.Title = parsedItem.release_name;
                release.Size = parsedItem.size;
                release.Seeders = parsedItem.seeders;
                release.Peers = parsedItem.leechers + release.Seeders;
                release.PublishDate = parsedItem.created_at;
                results.Add(release);
            }

            return results;
        }
        /// <summary>
        /// Detect settings for Parser, based on URL
        /// </summary>
        /// <param name="settings">Indexer Settings to use for Parser</param>
        /// <returns>Parsed Settings or <c>null</c></returns>
        public TorrentRssIndexerParserSettings Detect(TorrentRssIndexerSettings indexerSettings)
        {
            _logger.Debug("Evaluating TorrentRss feed '{0}'", indexerSettings.BaseUrl);

            var requestGenerator = new TorrentRssIndexerRequestGenerator { Settings = indexerSettings };
            var request = requestGenerator.GetRecentRequests().GetAllTiers().First().First();

            HttpResponse httpResponse = null;
            try
            {
                httpResponse = _httpClient.Execute(request.HttpRequest);
            }
            catch (Exception ex)
            {
                _logger.Warn(ex, string.Format("Unable to connect to indexer {0}: {1}", request.Url, ex.Message));
                return null;
            }

            var indexerResponse = new IndexerResponse(request, httpResponse);
            return GetParserSettings(indexerResponse, indexerSettings);
        }
Esempio n. 40
0
 public NewznabException(IndexerResponse response, string message)
     : base(response, message)
 {
 }
Esempio n. 41
0
 public IndexerException(IndexerResponse response, string message)
     : base(message)
 {
 }
Esempio n. 42
0
 public IndexerException(IndexerResponse response, string message, params object[] args)
     : base(message, args)
 {
 }
Esempio n. 43
0
 public NewznabException(IndexerResponse response, string message, params object[] args)
     : base(response, message, args)
 {
 }
        private TorrentRssIndexerParserSettings GetGenericTorrentRssParserSettings(IndexerResponse response, TorrentRssIndexerSettings indexerSettings)
        {
            var parser = new TorrentRssParser
            {
                UseEnclosureUrl = true,
                UseEnclosureLength = true,
                ParseSeedersInDescription = true
            };

            var item = parser.GetItems(response).FirstOrDefault();
            if (item == null)
            {
                throw new UnsupportedFeedException("Empty feed, cannot check if feed is parsable.");
            }

            var settings = new TorrentRssIndexerParserSettings()
            {
                UseEnclosureUrl = true,
                UseEnclosureLength = true,
                ParseSeedersInDescription = true
            };

            if (item.Element("enclosure") == null)
            {
                parser.UseEnclosureUrl = settings.UseEnclosureUrl = false;
            }

            var releases = ParseResponse(parser, response);
            ValidateReleases(releases, indexerSettings);

            if (!releases.Any(v => v.Seeders.HasValue))
            {
                _logger.Trace("Feed doesn't have Seeders in Description, disabling option.");
                parser.ParseSeedersInDescription = settings.ParseSeedersInDescription = false;
            }

            if (!releases.Any(r => r.Size < ValidSizeThreshold))
            {
                _logger.Trace("Feed has valid size in enclosure.");
                return settings;
            }

            parser.UseEnclosureLength = settings.UseEnclosureLength = false;

            foreach (var sizeElementName in new[] { "size", "Size" })
            {
                parser.SizeElementName = settings.SizeElementName = sizeElementName;

                releases = ParseResponse(parser, response);
                ValidateReleases(releases, indexerSettings);

                if (!releases.Any(r => r.Size < ValidSizeThreshold))
                {
                    _logger.Trace("Feed has valid size in Size element.");
                    return settings;
                }
            }

            parser.SizeElementName = settings.SizeElementName = null;
            parser.ParseSizeInDescription = settings.ParseSizeInDescription = true;

            releases = ParseResponse(parser, response);
            ValidateReleases(releases, indexerSettings);

            if (releases.Count(r => r.Size >= ValidSizeThreshold) > releases.Count() / 2)
            {
                if (releases.Any(r => r.Size < ValidSizeThreshold))
                {
                    _logger.Debug("Feed {0} contains very small releases.", response.Request.Url);
                }
                _logger.Trace("Feed has valid size in description.");
                return settings;
            }

            parser.ParseSizeInDescription = settings.ParseSizeInDescription = false;

            _logger.Debug("Feed doesn't have release size.");

            releases = ParseResponse(parser, response);
            ValidateReleases(releases, indexerSettings);
            ValidateReleaseSize(releases, indexerSettings);

            return settings;
        }
        private bool IsEZTVFeed(IndexerResponse response)
        {
            using (var xmlTextReader = XmlReader.Create(new StringReader(response.Content), new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse, ValidationType = ValidationType.None, IgnoreComments = true, XmlResolver = null }))
            {
                var document = XDocument.Load(xmlTextReader);

                // Check Namespace
                if (document.Root == null)
                {
                    throw new InvalidDataException("Could not parse IndexerResponse into XML.");
                }

                var ns = document.Root.GetNamespaceOfPrefix("torrent");
                if (ns == "http://xmlns.ezrss.it/0.1/")
                {
                    _logger.Trace("Identified feed as EZTV compatible by EZTV Namespace");
                    return true;
                }

                // Check DTD in DocType
                if (document.DocumentType != null && document.DocumentType.SystemId == "http://xmlns.ezrss.it/0.1/dtd/")
                {
                    _logger.Trace("Identified feed as EZTV compatible by EZTV DTD");
                    return true;
                }

                // Check namespaces
                if (document.Descendants().Any(v => v.GetDefaultNamespace().NamespaceName == "http://xmlns.ezrss.it/0.1/"))
                {
                    _logger.Trace("Identified feed as EZTV compatible by EZTV Namespace");
                    return true;
                }

                return false;
            }
        }
        private TorrentInfo[] ParseResponse(IParseIndexerResponse parser, IndexerResponse response)
        {
            try
            {
                var releases = parser.ParseResponse(response).Cast<TorrentInfo>().ToArray();
                return releases;

            }
            catch (Exception ex)
            {
                _logger.Debug(ex, "Unable to parse indexer feed: " + ex.Message);
                throw new UnsupportedFeedException("Unable to parse indexer: " + ex.Message);
            }
        }