New: (Indexers) Per indexer api and download limits

This commit is contained in:
Qstick
2021-07-05 17:30:13 -04:00
parent 0fe2cf5c2d
commit 4116c10caa
52 changed files with 298 additions and 80 deletions

View File

@@ -3,11 +3,13 @@ using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Core.Download;
using NzbDrone.Core.History;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.IndexerSearch;
using NzbDrone.Core.Parser;
@@ -24,16 +26,19 @@ namespace NzbDrone.Api.V1.Indexers
{
private IIndexerFactory _indexerFactory { get; set; }
private ISearchForNzb _nzbSearchService { get; set; }
private IIndexerLimitService _indexerLimitService { get; set; }
private IDownloadMappingService _downloadMappingService { get; set; }
private IDownloadService _downloadService { get; set; }
public NewznabController(IndexerFactory indexerFactory,
ISearchForNzb nzbSearchService,
IIndexerLimitService indexerLimitService,
IDownloadMappingService downloadMappingService,
IDownloadService downloadService)
{
_indexerFactory = indexerFactory;
_nzbSearchService = nzbSearchService;
_indexerLimitService = indexerLimitService;
_downloadMappingService = downloadMappingService;
_downloadService = downloadService;
}
@@ -49,7 +54,7 @@ namespace NzbDrone.Api.V1.Indexers
if (requestType.IsNullOrWhiteSpace())
{
throw new BadRequestException("Missing Function Parameter");
return Content(CreateErrorXML(200, "Missing parameter (t)"), "application/rss+xml");
}
request.imdbid = request.imdbid?.TrimStart('t') ?? null;
@@ -58,7 +63,7 @@ namespace NzbDrone.Api.V1.Indexers
{
if (!int.TryParse(request.imdbid, out var imdb) || imdb == 0)
{
throw new BadRequestException("Invalid Value for ImdbId");
return Content(CreateErrorXML(201, "Incorrect parameter (imdbid)"), "application/rss+xml");
}
}
@@ -95,40 +100,46 @@ namespace NzbDrone.Api.V1.Indexers
}
}
var indexer = _indexerFactory.Get(id);
var indexerDef = _indexerFactory.Get(id);
if (indexer == null)
if (indexerDef == null)
{
throw new NotFoundException("Indexer Not Found");
}
var indexerInstance = _indexerFactory.GetInstance(indexer);
var indexer = _indexerFactory.GetInstance(indexerDef);
//TODO Optimize this so it's not called here and in NzbSearchService (for manual search)
if (_indexerLimitService.AtQueryLimit(indexerDef))
{
return Content(CreateErrorXML(500, $"Request limit reached ({((IIndexerSettings)indexer.Definition.Settings).BaseSettings.QueryLimit})"), "application/rss+xml");
}
switch (requestType)
{
case "caps":
var caps = indexerInstance.GetCapabilities();
var caps = indexer.GetCapabilities();
return Content(caps.ToXml(), "application/rss+xml");
case "search":
case "tvsearch":
case "music":
case "book":
case "movie":
var results = await _nzbSearchService.Search(request, new List<int> { indexer.Id }, false);
var results = await _nzbSearchService.Search(request, new List<int> { indexerDef.Id }, false);
foreach (var result in results.Releases)
{
result.DownloadUrl = result.DownloadUrl != null ? _downloadMappingService.ConvertToProxyLink(new Uri(result.DownloadUrl), request.server, indexer.Id, result.Title).ToString() : null;
result.DownloadUrl = result.DownloadUrl != null ? _downloadMappingService.ConvertToProxyLink(new Uri(result.DownloadUrl), request.server, indexerDef.Id, result.Title).ToString() : null;
if (result.DownloadProtocol == DownloadProtocol.Torrent)
{
((TorrentInfo)result).MagnetUrl = ((TorrentInfo)result).MagnetUrl != null ? _downloadMappingService.ConvertToProxyLink(new Uri(((TorrentInfo)result).MagnetUrl), request.server, indexer.Id, result.Title).ToString() : null;
((TorrentInfo)result).MagnetUrl = ((TorrentInfo)result).MagnetUrl != null ? _downloadMappingService.ConvertToProxyLink(new Uri(((TorrentInfo)result).MagnetUrl), request.server, indexerDef.Id, result.Title).ToString() : null;
}
}
return Content(results.ToXml(indexerInstance.Protocol), "application/rss+xml");
return Content(results.ToXml(indexer.Protocol), "application/rss+xml");
default:
throw new BadRequestException("Function Not Available");
return Content(CreateErrorXML(202, $"No such function ({requestType})"), "application/rss+xml");
}
}
@@ -139,6 +150,11 @@ namespace NzbDrone.Api.V1.Indexers
var indexerDef = _indexerFactory.Get(id);
var indexer = _indexerFactory.GetInstance(indexerDef);
if (_indexerLimitService.AtDownloadLimit(indexerDef))
{
throw new BadRequestException("Grab limit reached");
}
if (link.IsNullOrWhiteSpace() || file.IsNullOrWhiteSpace())
{
throw new BadRequestException("Invalid Prowlarr link");
@@ -146,7 +162,7 @@ namespace NzbDrone.Api.V1.Indexers
file = WebUtility.UrlDecode(file);
if (indexer == null)
if (indexerDef == null)
{
throw new NotFoundException("Indexer Not Found");
}
@@ -186,5 +202,16 @@ namespace NzbDrone.Api.V1.Indexers
return File(downloadBytes, contentType, filename);
}
public static string CreateErrorXML(int code, string description)
{
var xdoc = new XDocument(
new XDeclaration("1.0", "UTF-8", null),
new XElement("error",
new XAttribute("code", code.ToString()),
new XAttribute("description", description)));
return xdoc.Declaration + Environment.NewLine + xdoc;
}
}
}