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); } }
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; } }
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); }
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); }
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()); }
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); } }
/// <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; } }
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); }
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()); }
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); }
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); }
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; }
protected override bool PreProcess(IndexerResponse indexerResponse) { var xdoc = LoadXmlDocument(indexerResponse); CheckError(xdoc, indexerResponse); return(true); }
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()); }
protected override bool PreProcess(IndexerResponse indexerResponse) { if (indexerResponse.HttpResponse.StatusCode == System.Net.HttpStatusCode.NotFound) { return(false); } return(base.PreProcess(indexerResponse)); }
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()); }
protected override bool PreProcess(IndexerResponse indexerResponse) { if (indexerResponse.HttpResponse.StatusCode == System.Net.HttpStatusCode.NotFound) { return false; } return base.PreProcess(indexerResponse); }
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; }
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); }
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()); }
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); }
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()); }
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); }
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()); }
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); } }
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()); }
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()); }
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(); }
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()); }
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()); }
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()); }
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); }
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()); }
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; }
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); }
public NewznabException(IndexerResponse response, string message) : base(response, message) { }
public IndexerException(IndexerResponse response, string message) : base(message) { }
public IndexerException(IndexerResponse response, string message, params object[] args) : base(message, args) { }
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); } }