diff --git a/src/Jackett.Common/Indexers/BaseIndexer.cs b/src/Jackett.Common/Indexers/BaseIndexer.cs index 67d53c920..1e2c49dc8 100644 --- a/src/Jackett.Common/Indexers/BaseIndexer.cs +++ b/src/Jackett.Common/Indexers/BaseIndexer.cs @@ -193,7 +193,7 @@ namespace Jackett.Common.Indexers return filteredResults; } - public bool CanHandleQuery(TorznabQuery query) + public virtual bool CanHandleQuery(TorznabQuery query) { if (query == null) return false; diff --git a/src/Jackett.Common/Indexers/Meta/BaseMetaIndexer.cs b/src/Jackett.Common/Indexers/Meta/BaseMetaIndexer.cs index 544fc0835..fd3c7ebe3 100644 --- a/src/Jackett.Common/Indexers/Meta/BaseMetaIndexer.cs +++ b/src/Jackett.Common/Indexers/Meta/BaseMetaIndexer.cs @@ -22,6 +22,15 @@ namespace Jackett.Common.Indexers.Meta this.resultFilterProvider = resultFilterProvider; } + public override bool CanHandleQuery(TorznabQuery query) + { + if (query == null) + return false; + if (query.QueryType == "indexers") + return true; + return base.CanHandleQuery(query); + } + public override Task ApplyConfiguration(JToken configJson) { return Task.FromResult(IndexerConfigurationStatus.Completed); diff --git a/src/Jackett.Common/Models/TorznabCapabilities.cs b/src/Jackett.Common/Models/TorznabCapabilities.cs index 49e12d1e8..7970422d9 100644 --- a/src/Jackett.Common/Models/TorznabCapabilities.cs +++ b/src/Jackett.Common/Models/TorznabCapabilities.cs @@ -93,7 +93,7 @@ namespace Jackett.Common.Models return supportsCategory; } - public string ToXml() + public XDocument GetXDocument() { var xdoc = new XDocument( new XDeclaration("1.0", "UTF-8", null), @@ -144,6 +144,12 @@ namespace Jackett.Common.Models ) ) ); + return xdoc; + } + + public string ToXml() + { + var xdoc = GetXDocument(); return xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString(); } diff --git a/src/Jackett/Controllers/ResultsController.cs b/src/Jackett/Controllers/ResultsController.cs index a73efa054..3bcadb49a 100644 --- a/src/Jackett/Controllers/ResultsController.cs +++ b/src/Jackett/Controllers/ResultsController.cs @@ -12,6 +12,7 @@ using System.Web.Http.Filters; using System.Xml.Linq; using Jackett.Common; using Jackett.Common.Indexers; +using Jackett.Common.Indexers.Meta; using Jackett.Common.Models; using Jackett.Common.Models.DTO; using Jackett.Common.Services.Interfaces; @@ -248,6 +249,39 @@ namespace Jackett.Controllers }); } + // 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 xdoc = new XDocument( + new XDeclaration("1.0", "UTF-8", null), + new XElement("indexers", + from i in CurrentBaseMetaIndexer.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))