public async Task <IHttpActionResult> Torznab([FromUri] Common.Models.DTO.TorznabRequest request) { if (string.Equals(CurrentQuery.QueryType, "caps", StringComparison.InvariantCultureIgnoreCase)) { return(ResponseMessage(new HttpResponseMessage() { Content = new StringContent(CurrentIndexer.TorznabCaps.ToXml(), Encoding.UTF8, "application/xml") })); } // indexers - returns a list of all included indexers (meta indexers only) if (string.Equals(CurrentQuery.QueryType, "indexers", StringComparison.InvariantCultureIgnoreCase)) { if (!(CurrentIndexer is BaseMetaIndexer)) // shouldn't be needed because CanHandleQuery should return false { logger.Warn($"A search request with t=indexers from {Request.GetOwinContext().Request.RemoteIpAddress} was made but the indexer {CurrentIndexer.DisplayName} isn't a meta indexer."); return(GetErrorXML(203, "Function Not Available: this isn't a meta indexer")); } var CurrentBaseMetaIndexer = (BaseMetaIndexer)CurrentIndexer; var indexers = CurrentBaseMetaIndexer.Indexers; if (string.Equals(request.configured, "true", StringComparison.InvariantCultureIgnoreCase)) { indexers = indexers.Where(i => i.IsConfigured); } else if (string.Equals(request.configured, "false", StringComparison.InvariantCultureIgnoreCase)) { indexers = indexers.Where(i => !i.IsConfigured); } var xdoc = new XDocument( new XDeclaration("1.0", "UTF-8", null), new XElement("indexers", from i in indexers select new XElement("indexer", new XAttribute("id", i.ID), new XAttribute("configured", i.IsConfigured), new XElement("title", i.DisplayName), new XElement("description", i.DisplayDescription), new XElement("link", i.SiteLink), new XElement("language", i.Language), new XElement("type", i.Type), i.TorznabCaps.GetXDocument().FirstNode ) ) ); return(ResponseMessage(new HttpResponseMessage() { Content = new StringContent(xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString(), Encoding.UTF8, "application/xml") })); } if (CurrentQuery.ImdbID != null) { if (!string.IsNullOrEmpty(CurrentQuery.SearchTerm)) { logger.Warn($"A search request from {Request.GetOwinContext().Request.RemoteIpAddress} was made containing q and imdbid."); return(GetErrorXML(201, "Incorrect parameter: please specify either imdbid or q")); } CurrentQuery.ImdbID = ParseUtil.GetFullImdbID(CurrentQuery.ImdbID); // normalize ImdbID if (CurrentQuery.ImdbID == null) { logger.Warn($"A search request from {Request.GetOwinContext().Request.RemoteIpAddress} was made with an invalid imdbid."); return(GetErrorXML(201, "Incorrect parameter: invalid imdbid format")); } if (!CurrentIndexer.TorznabCaps.SupportsImdbSearch) { logger.Warn($"A search request with imdbid from {Request.GetOwinContext().Request.RemoteIpAddress} was made but the indexer {CurrentIndexer.DisplayName} doesn't support it."); return(GetErrorXML(203, "Function Not Available: imdbid is not supported by this indexer")); } } try { var result = await CurrentIndexer.ResultsForQuery(CurrentQuery); // Some trackers do not support multiple category filtering so filter the releases that match manually. int?newItemCount = null; // Cache non query results if (string.IsNullOrEmpty(CurrentQuery.SanitizedSearchTerm)) { newItemCount = cacheService.GetNewItemCount(CurrentIndexer, result.Releases); cacheService.CacheRssResults(CurrentIndexer, result.Releases); } // Log info var logBuilder = new StringBuilder(); if (newItemCount != null) { logBuilder.AppendFormat("Found {0} ({1} new) releases from {2}", result.Releases.Count(), newItemCount, CurrentIndexer.DisplayName); } else { logBuilder.AppendFormat("Found {0} releases from {1}", result.Releases.Count(), CurrentIndexer.DisplayName); } if (!string.IsNullOrWhiteSpace(CurrentQuery.SanitizedSearchTerm)) { logBuilder.AppendFormat(" for: {0}", CurrentQuery.GetQueryString()); } logger.Info(logBuilder.ToString()); var serverUrl = serverService.GetServerUrl(Request); var resultPage = new ResultPage(new ChannelInfo { Title = CurrentIndexer.DisplayName, Description = CurrentIndexer.DisplayDescription, Link = new Uri(CurrentIndexer.SiteLink), ImageUrl = new Uri(serverUrl + "logos/" + CurrentIndexer.ID + ".png"), ImageTitle = CurrentIndexer.DisplayName, ImageLink = new Uri(CurrentIndexer.SiteLink), ImageDescription = CurrentIndexer.DisplayName }); var proxiedReleases = result.Releases.Select(r => AutoMapper.Mapper.Map <ReleaseInfo>(r)).Select(r => { r.Link = serverService.ConvertToProxyLink(r.Link, serverUrl, r.Origin.ID, "dl", r.Title); return(r); }); resultPage.Releases = proxiedReleases.ToList(); var xml = resultPage.ToXml(new Uri(serverUrl)); // Force the return as XML return(ResponseMessage(new HttpResponseMessage() { Content = new StringContent(xml, Encoding.UTF8, "application/rss+xml") })); } catch (Exception e) { Engine.Logger.Error(e); return(GetErrorXML(900, e.Message)); } }
public async Task <IHttpActionResult> Torznab([FromUri] Common.Models.DTO.TorznabRequest request) { if (string.Equals(CurrentQuery.QueryType, "caps", StringComparison.InvariantCultureIgnoreCase)) { return(ResponseMessage(new HttpResponseMessage() { Content = new StringContent(CurrentIndexer.TorznabCaps.ToXml(), Encoding.UTF8, "application/xml") })); } if (CurrentQuery.ImdbID != null) { if (CurrentQuery.QueryType != "movie") { logger.Warn($"A non movie request with an imdbid was made from {Request.GetOwinContext().Request.RemoteIpAddress}."); return(GetErrorXML(201, "Incorrect parameter: only movie-search supports the imdbid parameter")); } if (!string.IsNullOrEmpty(CurrentQuery.SearchTerm)) { logger.Warn($"A movie-search request from {Request.GetOwinContext().Request.RemoteIpAddress} was made contining q and imdbid."); return(GetErrorXML(201, "Incorrect parameter: please specify either imdbid or q")); } CurrentQuery.ImdbID = ParseUtil.GetFullImdbID(CurrentQuery.ImdbID); // normalize ImdbID if (CurrentQuery.ImdbID == null) { logger.Warn($"A movie-search request from {Request.GetOwinContext().Request.RemoteIpAddress} was made with an invalid imdbid."); return(GetErrorXML(201, "Incorrect parameter: invalid imdbid format")); } if (!CurrentIndexer.TorznabCaps.SupportsImdbSearch) { logger.Warn($"A movie-search request with imdbid from {Request.GetOwinContext().Request.RemoteIpAddress} was made but the indexer {CurrentIndexer.DisplayName} doesn't support it."); return(GetErrorXML(203, "Function Not Available: imdbid is not supported by this indexer")); } } var result = await CurrentIndexer.ResultsForQuery(CurrentQuery); // Some trackers do not support multiple category filtering so filter the releases that match manually. int?newItemCount = null; // Cache non query results if (string.IsNullOrEmpty(CurrentQuery.SanitizedSearchTerm)) { newItemCount = cacheService.GetNewItemCount(CurrentIndexer, result.Releases); cacheService.CacheRssResults(CurrentIndexer, result.Releases); } // Log info var logBuilder = new StringBuilder(); if (newItemCount != null) { logBuilder.AppendFormat("Found {0} ({1} new) releases from {2}", result.Releases.Count(), newItemCount, CurrentIndexer.DisplayName); } else { logBuilder.AppendFormat("Found {0} releases from {1}", result.Releases.Count(), CurrentIndexer.DisplayName); } if (!string.IsNullOrWhiteSpace(CurrentQuery.SanitizedSearchTerm)) { logBuilder.AppendFormat(" for: {0}", CurrentQuery.GetQueryString()); } logger.Info(logBuilder.ToString()); var serverUrl = serverService.GetServerUrl(Request); var resultPage = new ResultPage(new ChannelInfo { Title = CurrentIndexer.DisplayName, Description = CurrentIndexer.DisplayDescription, Link = new Uri(CurrentIndexer.SiteLink), ImageUrl = new Uri(serverUrl + "logos/" + CurrentIndexer.ID + ".png"), ImageTitle = CurrentIndexer.DisplayName, ImageLink = new Uri(CurrentIndexer.SiteLink), ImageDescription = CurrentIndexer.DisplayName }); var proxiedReleases = result.Releases.Select(r => AutoMapper.Mapper.Map <ReleaseInfo>(r)).Select(r => { r.Link = serverService.ConvertToProxyLink(r.Link, serverUrl, r.Origin.ID, "dl", r.Title); return(r); }); resultPage.Releases = proxiedReleases.ToList(); var xml = resultPage.ToXml(new Uri(serverUrl)); // Force the return as XML return(ResponseMessage(new HttpResponseMessage() { Content = new StringContent(xml, Encoding.UTF8, "application/rss+xml") })); }