public async Task <HttpResponseMessage> Call(string indexerID) { var indexer = indexerService.GetIndexer(indexerID); var torznabQuery = TorznabQuery.FromHttpQuery(HttpUtility.ParseQueryString(Request.RequestUri.Query)); if (string.Equals(torznabQuery.QueryType, "caps", StringComparison.InvariantCultureIgnoreCase)) { return(new HttpResponseMessage() { Content = new StringContent(indexer.TorznabCaps.ToXml(), Encoding.UTF8, "application/xml") }); } torznabQuery.ExpandCatsToSubCats(); var allowBadApiDueToDebug = false; #if DEBUG allowBadApiDueToDebug = Debugger.IsAttached; #endif if (!allowBadApiDueToDebug && !string.Equals(torznabQuery.ApiKey, serverService.Config.APIKey, StringComparison.InvariantCultureIgnoreCase)) { logger.Warn(string.Format("A request from {0} was made with an incorrect API key.", Request.GetOwinContext().Request.RemoteIpAddress)); return(Request.CreateResponse(HttpStatusCode.Forbidden, "Incorrect API key")); } if (!indexer.IsConfigured) { logger.Warn(string.Format("Rejected a request to {0} which is unconfigured.", indexer.DisplayName)); return(Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer is not configured.")); } if (torznabQuery.ImdbID != null) { if (torznabQuery.QueryType != "movie") { logger.Warn(string.Format("A non movie request with an imdbid was made from {0}.", Request.GetOwinContext().Request.RemoteIpAddress)); return(GetErrorXML(201, "Incorrect parameter: only movie-search supports the imdbid parameter")); } if (!string.IsNullOrEmpty(torznabQuery.SearchTerm)) { logger.Warn(string.Format("A movie-search request from {0} was made contining q and imdbid.", Request.GetOwinContext().Request.RemoteIpAddress)); return(GetErrorXML(201, "Incorrect parameter: please specify either imdbid or q")); } torznabQuery.ImdbID = ParseUtil.GetFullImdbID(torznabQuery.ImdbID); // normalize ImdbID if (torznabQuery.ImdbID == null) { logger.Warn(string.Format("A movie-search request from {0} was made with an invalid imdbid.", Request.GetOwinContext().Request.RemoteIpAddress)); return(GetErrorXML(201, "Incorrect parameter: invalid imdbid format")); } if (!indexer.TorznabCaps.SupportsImdbSearch) { logger.Warn(string.Format("A movie-search request with imdbid from {0} was made but the indexer {1} doesn't support it.", Request.GetOwinContext().Request.RemoteIpAddress, indexer.DisplayName)); return(GetErrorXML(203, "Function Not Available: imdbid is not supported by this indexer")); } } var releases = await indexer.PerformQuery(torznabQuery); releases = indexer.CleanLinks(releases); // Some trackers do not keep their clocks up to date and can be ~20 minutes out! foreach (var release in releases.Where(r => r.PublishDate > DateTime.Now)) { release.PublishDate = DateTime.Now; } // Some trackers do not support multiple category filtering so filter the releases that match manually. var filteredReleases = releases = indexer.FilterResults(torznabQuery, releases); int?newItemCount = null; // Cache non query results if (string.IsNullOrEmpty(torznabQuery.SanitizedSearchTerm)) { newItemCount = cacheService.GetNewItemCount(indexer, filteredReleases); cacheService.CacheRssResults(indexer, releases); } // Log info var logBuilder = new StringBuilder(); if (newItemCount != null) { logBuilder.AppendFormat(string.Format("Found {0} ({1} new) releases from {2}", releases.Count(), newItemCount, indexer.DisplayName)); } else { logBuilder.AppendFormat(string.Format("Found {0} releases from {1}", releases.Count(), indexer.DisplayName)); } if (!string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm)) { logBuilder.AppendFormat(" for: {0}", torznabQuery.GetQueryString()); } logger.Info(logBuilder.ToString()); var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath()); var resultPage = new ResultPage(new ChannelInfo { Title = indexer.DisplayName, Description = indexer.DisplayDescription, Link = new Uri(indexer.SiteLink), ImageUrl = new Uri(serverUrl + "logos/" + indexer.ID + ".png"), ImageTitle = indexer.DisplayName, ImageLink = new Uri(indexer.SiteLink), ImageDescription = indexer.DisplayName }); foreach (var result in releases) { var clone = Mapper.Map <ReleaseInfo>(result); clone.Link = serverService.ConvertToProxyLink(clone.Link, serverUrl, indexerID, "dl", result.Title + ".torrent"); resultPage.Releases.Add(clone); } var xml = resultPage.ToXml(new Uri(serverUrl)); // Force the return as XML return(new HttpResponseMessage() { Content = new StringContent(xml, Encoding.UTF8, "application/rss+xml") }); }