parent
d348232e0d
commit
58ddbcd77e
@ -0,0 +1,26 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using NzbDrone.Common.Composition;
|
||||
|
||||
namespace NzbDrone.Host
|
||||
{
|
||||
public class ControllerActivator : IControllerActivator
|
||||
{
|
||||
private readonly IContainer _container;
|
||||
|
||||
public ControllerActivator(IContainer container)
|
||||
{
|
||||
_container = container;
|
||||
}
|
||||
|
||||
public object Create(ControllerContext context)
|
||||
{
|
||||
return _container.Resolve(context.ActionDescriptor.ControllerTypeInfo.AsType());
|
||||
}
|
||||
|
||||
public void Release(ControllerContext context, object controller)
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
namespace NzbDrone.Host.Middleware
|
||||
{
|
||||
public interface IAspNetCoreMiddleware
|
||||
{
|
||||
int Order { get; }
|
||||
void Attach(IApplicationBuilder appBuilder);
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Nancy.Bootstrapper;
|
||||
using Nancy.Owin;
|
||||
|
||||
namespace NzbDrone.Host.Middleware
|
||||
{
|
||||
public class NancyMiddleware : IAspNetCoreMiddleware
|
||||
{
|
||||
private readonly INancyBootstrapper _nancyBootstrapper;
|
||||
|
||||
public int Order => 2;
|
||||
|
||||
public NancyMiddleware(INancyBootstrapper nancyBootstrapper)
|
||||
{
|
||||
_nancyBootstrapper = nancyBootstrapper;
|
||||
}
|
||||
|
||||
public void Attach(IApplicationBuilder appBuilder)
|
||||
{
|
||||
var options = new NancyOptions
|
||||
{
|
||||
Bootstrapper = _nancyBootstrapper,
|
||||
PerformPassThrough = context => context.Request.Path.StartsWith("/signalr")
|
||||
};
|
||||
|
||||
appBuilder.UseOwin(x => x.UseNancy(options));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Composition;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.SignalR;
|
||||
|
||||
namespace NzbDrone.Host.Middleware
|
||||
{
|
||||
public class SignalRMiddleware : IAspNetCoreMiddleware
|
||||
{
|
||||
private readonly IContainer _container;
|
||||
private readonly Logger _logger;
|
||||
private static string API_KEY;
|
||||
private static string URL_BASE;
|
||||
public int Order => 1;
|
||||
|
||||
public SignalRMiddleware(IContainer container,
|
||||
IConfigFileProvider configFileProvider,
|
||||
Logger logger)
|
||||
{
|
||||
_container = container;
|
||||
_logger = logger;
|
||||
API_KEY = configFileProvider.ApiKey;
|
||||
URL_BASE = configFileProvider.UrlBase;
|
||||
}
|
||||
|
||||
public void Attach(IApplicationBuilder appBuilder)
|
||||
{
|
||||
appBuilder.UseWebSockets();
|
||||
|
||||
appBuilder.Use(async (context, next) =>
|
||||
{
|
||||
if (context.Request.Path.StartsWithSegments("/signalr") &&
|
||||
!context.Request.Path.Value.EndsWith("/negotiate") &&
|
||||
(!context.Request.Query.ContainsKey("access_token") ||
|
||||
context.Request.Query["access_token"] != API_KEY))
|
||||
{
|
||||
context.Response.StatusCode = 401;
|
||||
await context.Response.WriteAsync("Unauthorized");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await next();
|
||||
}
|
||||
catch (OperationCanceledException e)
|
||||
{
|
||||
// Demote the exception to trace logging so users don't worry (as much).
|
||||
_logger.Trace(e);
|
||||
}
|
||||
});
|
||||
|
||||
appBuilder.UseEndpoints(x =>
|
||||
{
|
||||
x.MapHub<MessageHub>(URL_BASE + "/signalr/messages");
|
||||
});
|
||||
|
||||
// This is a side effect of haing multiple IoC containers, TinyIoC and whatever
|
||||
// Kestrel/SignalR is using. Ideally we'd have one IoC container, but that's non-trivial with TinyIoC
|
||||
// TODO: Use a single IoC container if supported for TinyIoC or if we switch to another system (ie Autofac).
|
||||
var hubContext = appBuilder.ApplicationServices.GetService<IHubContext<MessageHub>>();
|
||||
_container.Register(hubContext);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Nancy;
|
||||
using NzbDrone.Core.Books;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.Extensions;
|
||||
|
||||
namespace Readarr.Api.V1.Author
|
||||
{
|
||||
public class AuthorImportModule : ReadarrRestModule<AuthorResource>
|
||||
{
|
||||
private readonly IAddAuthorService _addAuthorService;
|
||||
|
||||
public AuthorImportModule(IAddAuthorService addAuthorService)
|
||||
: base("/author/import")
|
||||
{
|
||||
_addAuthorService = addAuthorService;
|
||||
Post("/", x => Import());
|
||||
}
|
||||
|
||||
private object Import()
|
||||
{
|
||||
var resource = Request.Body.FromJson<List<AuthorResource>>();
|
||||
var newAuthors = resource.ToModel();
|
||||
|
||||
return _addAuthorService.AddAuthors(newAuthors).ToResource();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Nancy;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.Author
|
||||
{
|
||||
public class AuthorLookupModule : ReadarrRestModule<AuthorResource>
|
||||
[V1ApiController("author/lookup")]
|
||||
public class AuthorLookupController : Controller
|
||||
{
|
||||
private readonly ISearchForNewAuthor _searchProxy;
|
||||
|
||||
public AuthorLookupModule(ISearchForNewAuthor searchProxy)
|
||||
: base("/author/lookup")
|
||||
public AuthorLookupController(ISearchForNewAuthor searchProxy)
|
||||
{
|
||||
_searchProxy = searchProxy;
|
||||
Get("/", x => Search());
|
||||
}
|
||||
|
||||
private object Search()
|
||||
[HttpGet]
|
||||
public object Search([FromQuery] string term)
|
||||
{
|
||||
var searchResults = _searchProxy.SearchForNewAuthor((string)Request.Query.term);
|
||||
var searchResults = _searchProxy.SearchForNewAuthor(term);
|
||||
return MapToResource(searchResults).ToList();
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Blacklisting;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Http.REST.Attributes;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.Extensions;
|
||||
|
||||
namespace Readarr.Api.V1.Blacklist
|
||||
{
|
||||
[V1ApiController]
|
||||
public class BlacklistController : Controller
|
||||
{
|
||||
private readonly IBlacklistService _blacklistService;
|
||||
|
||||
public BlacklistController(IBlacklistService blacklistService)
|
||||
{
|
||||
_blacklistService = blacklistService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public PagingResource<BlacklistResource> GetBlacklist()
|
||||
{
|
||||
var pagingResource = Request.ReadPagingResourceFromRequest<BlacklistResource>();
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<BlacklistResource, NzbDrone.Core.Blacklisting.Blacklist>("date", SortDirection.Descending);
|
||||
|
||||
return pagingSpec.ApplyToPage(_blacklistService.Paged, BlacklistResourceMapper.MapToResource);
|
||||
}
|
||||
|
||||
[RestDeleteById]
|
||||
public void DeleteBlacklist(int id)
|
||||
{
|
||||
_blacklistService.Delete(id);
|
||||
}
|
||||
|
||||
[HttpDelete("bulk")]
|
||||
public object Remove([FromBody] BlacklistBulkResource resource)
|
||||
{
|
||||
_blacklistService.Delete(resource.Ids);
|
||||
|
||||
return new object();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
using NzbDrone.Core.Blacklisting;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.Extensions;
|
||||
|
||||
namespace Readarr.Api.V1.Blacklist
|
||||
{
|
||||
public class BlacklistModule : ReadarrRestModule<BlacklistResource>
|
||||
{
|
||||
private readonly IBlacklistService _blacklistService;
|
||||
|
||||
public BlacklistModule(IBlacklistService blacklistService)
|
||||
{
|
||||
_blacklistService = blacklistService;
|
||||
GetResourcePaged = GetBlacklist;
|
||||
DeleteResource = DeleteBlacklist;
|
||||
|
||||
Delete("/bulk", x => Remove());
|
||||
}
|
||||
|
||||
private PagingResource<BlacklistResource> GetBlacklist(PagingResource<BlacklistResource> pagingResource)
|
||||
{
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<BlacklistResource, NzbDrone.Core.Blacklisting.Blacklist>("date", SortDirection.Descending);
|
||||
|
||||
return ApplyToPage(_blacklistService.Paged, pagingSpec, BlacklistResourceMapper.MapToResource);
|
||||
}
|
||||
|
||||
private void DeleteBlacklist(int id)
|
||||
{
|
||||
_blacklistService.Delete(id);
|
||||
}
|
||||
|
||||
private object Remove()
|
||||
{
|
||||
var resource = Request.Body.FromJson<BlacklistBulkResource>();
|
||||
|
||||
_blacklistService.Delete(resource.Ids);
|
||||
|
||||
return new object();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Nancy;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.Books
|
||||
{
|
||||
public class BookLookupModule : ReadarrRestModule<BookResource>
|
||||
[V1ApiController("book/lookup")]
|
||||
public class BookLookupController : Controller
|
||||
{
|
||||
private readonly ISearchForNewBook _searchProxy;
|
||||
|
||||
public BookLookupModule(ISearchForNewBook searchProxy)
|
||||
: base("/book/lookup")
|
||||
public BookLookupController(ISearchForNewBook searchProxy)
|
||||
{
|
||||
_searchProxy = searchProxy;
|
||||
Get("/", x => Search());
|
||||
}
|
||||
|
||||
private object Search()
|
||||
[HttpGet]
|
||||
public object Search(string term)
|
||||
{
|
||||
var searchResults = _searchProxy.SearchForNewBook((string)Request.Query.term, null);
|
||||
var searchResults = _searchProxy.SearchForNewBook(term, null);
|
||||
return MapToResource(searchResults).ToList();
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.Books
|
||||
{
|
||||
[V1ApiController("rename")]
|
||||
public class RenameBookController : Controller
|
||||
{
|
||||
private readonly IRenameBookFileService _renameBookFileService;
|
||||
|
||||
public RenameBookController(IRenameBookFileService renameBookFileService)
|
||||
{
|
||||
_renameBookFileService = renameBookFileService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public List<RenameBookResource> GetBookFiles(int authorId, int? bookId)
|
||||
{
|
||||
if (bookId.HasValue)
|
||||
{
|
||||
return _renameBookFileService.GetRenamePreviews(authorId, bookId.Value).ToResource();
|
||||
}
|
||||
|
||||
return _renameBookFileService.GetRenamePreviews(authorId).ToResource();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Books
|
||||
{
|
||||
public class RenameBookModule : ReadarrRestModule<RenameBookResource>
|
||||
{
|
||||
private readonly IRenameBookFileService _renameBookFileService;
|
||||
|
||||
public RenameBookModule(IRenameBookFileService renameBookFileService)
|
||||
: base("rename")
|
||||
{
|
||||
_renameBookFileService = renameBookFileService;
|
||||
|
||||
GetResourceAll = GetBookFiles;
|
||||
}
|
||||
|
||||
private List<RenameBookResource> GetBookFiles()
|
||||
{
|
||||
int authorId;
|
||||
|
||||
if (Request.Query.AuthorId.HasValue)
|
||||
{
|
||||
authorId = (int)Request.Query.AuthorId;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new BadRequestException("authorId is missing");
|
||||
}
|
||||
|
||||
if (Request.Query.bookId.HasValue)
|
||||
{
|
||||
var bookId = (int)Request.Query.bookId;
|
||||
return _renameBookFileService.GetRenamePreviews(authorId, bookId).ToResource();
|
||||
}
|
||||
|
||||
return _renameBookFileService.GetRenamePreviews(authorId).ToResource();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,34 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Books
|
||||
{
|
||||
public class RetagBookModule : ReadarrRestModule<RetagBookResource>
|
||||
[V1ApiController("retag")]
|
||||
public class RetagBookController : Controller
|
||||
{
|
||||
private readonly IAudioTagService _audioTagService;
|
||||
|
||||
public RetagBookModule(IAudioTagService audioTagService)
|
||||
: base("retag")
|
||||
public RetagBookController(IAudioTagService audioTagService)
|
||||
{
|
||||
_audioTagService = audioTagService;
|
||||
|
||||
GetResourceAll = GetBooks;
|
||||
}
|
||||
|
||||
private List<RetagBookResource> GetBooks()
|
||||
[HttpGet]
|
||||
public List<RetagBookResource> GetBooks(int? authorId, int? bookId)
|
||||
{
|
||||
if (Request.Query.bookId.HasValue)
|
||||
if (bookId.HasValue)
|
||||
{
|
||||
var bookId = (int)Request.Query.bookId;
|
||||
return _audioTagService.GetRetagPreviewsByBook(bookId).Where(x => x.Changes.Any()).ToResource();
|
||||
return _audioTagService.GetRetagPreviewsByBook(bookId.Value).Where(x => x.Changes.Any()).ToResource();
|
||||
}
|
||||
else if (Request.Query.AuthorId.HasValue)
|
||||
else if (authorId.HasValue)
|
||||
{
|
||||
var authorId = (int)Request.Query.AuthorId;
|
||||
return _audioTagService.GetRetagPreviewsByAuthor(authorId).Where(x => x.Changes.Any()).ToResource();
|
||||
return _audioTagService.GetRetagPreviewsByAuthor(authorId.Value).Where(x => x.Changes.Any()).ToResource();
|
||||
}
|
||||
else
|
||||
{
|
@ -1,53 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.AuthorStats;
|
||||
using NzbDrone.Core.Books;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.SignalR;
|
||||
using Readarr.Api.V1.Books;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.Extensions;
|
||||
|
||||
namespace Readarr.Api.V1.Calendar
|
||||
{
|
||||
public class CalendarModule : BookModuleWithSignalR
|
||||
[V1ApiController]
|
||||
public class CalendarController : BookControllerWithSignalR
|
||||
{
|
||||
public CalendarModule(IBookService bookService,
|
||||
public CalendarController(IBookService bookService,
|
||||
ISeriesBookLinkService seriesBookLinkService,
|
||||
IAuthorStatisticsService authorStatisticsService,
|
||||
IMapCoversToLocal coverMapper,
|
||||
IUpgradableSpecification upgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster)
|
||||
: base(bookService, seriesBookLinkService, authorStatisticsService, coverMapper, upgradableSpecification, signalRBroadcaster, "calendar")
|
||||
: base(bookService, seriesBookLinkService, authorStatisticsService, coverMapper, upgradableSpecification, signalRBroadcaster)
|
||||
{
|
||||
GetResourceAll = GetCalendar;
|
||||
}
|
||||
|
||||
private List<BookResource> GetCalendar()
|
||||
[HttpGet]
|
||||
public List<BookResource> GetCalendar(DateTime? start, DateTime? end, bool unmonitored = false, bool includeAuthor = false)
|
||||
{
|
||||
var start = DateTime.Today;
|
||||
var end = DateTime.Today.AddDays(2);
|
||||
var includeUnmonitored = Request.GetBooleanQueryParameter("unmonitored");
|
||||
var includeAuthor = Request.GetBooleanQueryParameter("includeAuthor");
|
||||
|
||||
//TODO: Add Book Image support to BookModuleWithSignalR
|
||||
//TODO: Add Book Image support to BookControllerWithSignalR
|
||||
var includeBookImages = Request.GetBooleanQueryParameter("includeBookImages");
|
||||
|
||||
var queryStart = Request.Query.Start;
|
||||
var queryEnd = Request.Query.End;
|
||||
|
||||
if (queryStart.HasValue)
|
||||
{
|
||||
start = DateTime.Parse(queryStart.Value);
|
||||
}
|
||||
|
||||
if (queryEnd.HasValue)
|
||||
{
|
||||
end = DateTime.Parse(queryEnd.Value);
|
||||
}
|
||||
var startUse = start ?? DateTime.Today;
|
||||
var endUse = end ?? DateTime.Today.AddDays(2);
|
||||
|
||||
var resources = MapToResource(_bookService.BooksBetweenDates(start, end, includeUnmonitored), includeAuthor);
|
||||
var resources = MapToResource(_bookService.BooksBetweenDates(startUse, endUse, unmonitored), includeAuthor);
|
||||
|
||||
return resources.OrderBy(e => e.ReleaseDate).ToList();
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Http.REST.Attributes;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Config
|
||||
{
|
||||
public abstract class ConfigController<TResource> : RestController<TResource>
|
||||
where TResource : RestResource, new()
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
|
||||
protected ConfigController(IConfigService configService)
|
||||
{
|
||||
_configService = configService;
|
||||
}
|
||||
|
||||
public override TResource GetResourceById(int id)
|
||||
{
|
||||
return GetConfig();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public TResource GetConfig()
|
||||
{
|
||||
var resource = ToResource(_configService);
|
||||
resource.Id = 1;
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
[RestPutById]
|
||||
public ActionResult<TResource> SaveConfig(TResource resource)
|
||||
{
|
||||
var dictionary = resource.GetType()
|
||||
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||
.ToDictionary(prop => prop.Name, prop => prop.GetValue(resource, null));
|
||||
|
||||
_configService.SaveConfigDictionary(dictionary);
|
||||
|
||||
return Accepted(resource.Id);
|
||||
}
|
||||
|
||||
protected abstract TResource ToResource(IConfigService model);
|
||||
}
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
using NzbDrone.Core.Configuration;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.Config
|
||||
{
|
||||
public class DownloadClientConfigModule : ReadarrConfigModule<DownloadClientConfigResource>
|
||||
[V1ApiController("config/downloadclient")]
|
||||
public class DownloadClientConfigController : ConfigController<DownloadClientConfigResource>
|
||||
{
|
||||
public DownloadClientConfigModule(IConfigService configService)
|
||||
public DownloadClientConfigController(IConfigService configService)
|
||||
: base(configService)
|
||||
{
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.Validation;
|
||||
|
||||
namespace Readarr.Api.V1.Config
|
||||
{
|
||||
public class IndexerConfigModule : ReadarrConfigModule<IndexerConfigResource>
|
||||
[V1ApiController("config/indexer")]
|
||||
public class IndexerConfigController : ConfigController<IndexerConfigResource>
|
||||
{
|
||||
public IndexerConfigModule(IConfigService configService)
|
||||
public IndexerConfigController(IConfigService configService)
|
||||
: base(configService)
|
||||
{
|
||||
SharedValidator.RuleFor(c => c.MinimumAge)
|
@ -1,53 +0,0 @@
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Config
|
||||
{
|
||||
public abstract class ReadarrConfigModule<TResource> : ReadarrRestModule<TResource>
|
||||
where TResource : RestResource, new()
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
|
||||
protected ReadarrConfigModule(IConfigService configService)
|
||||
: this(new TResource().ResourceName.Replace("config", ""), configService)
|
||||
{
|
||||
}
|
||||
|
||||
protected ReadarrConfigModule(string resource, IConfigService configService)
|
||||
: base("config/" + resource.Trim('/'))
|
||||
{
|
||||
_configService = configService;
|
||||
|
||||
GetResourceSingle = GetConfig;
|
||||
GetResourceById = GetConfig;
|
||||
UpdateResource = SaveConfig;
|
||||
}
|
||||
|
||||
private TResource GetConfig()
|
||||
{
|
||||
var resource = ToResource(_configService);
|
||||
resource.Id = 1;
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
protected abstract TResource ToResource(IConfigService model);
|
||||
|
||||
private TResource GetConfig(int id)
|
||||
{
|
||||
return GetConfig();
|
||||
}
|
||||
|
||||
private void SaveConfig(TResource resource)
|
||||
{
|
||||
var dictionary = resource.GetType()
|
||||
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||
.ToDictionary(prop => prop.Name, prop => prop.GetValue(resource, null));
|
||||
|
||||
_configService.SaveConfigDictionary(dictionary);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.CustomFilters;
|
||||
using NzbDrone.Http.REST.Attributes;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.CustomFilters
|
||||
{
|
||||
[V1ApiController]
|
||||
public class CustomFilterController : RestController<CustomFilterResource>
|
||||
{
|
||||
private readonly ICustomFilterService _customFilterService;
|
||||
|
||||
public CustomFilterController(ICustomFilterService customFilterService)
|
||||
{
|
||||
_customFilterService = customFilterService;
|
||||
}
|
||||
|
||||
public override CustomFilterResource GetResourceById(int id)
|
||||
{
|
||||
return _customFilterService.Get(id).ToResource();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public List<CustomFilterResource> GetCustomFilters()
|
||||
{
|
||||
return _customFilterService.All().ToResource();
|
||||
}
|
||||
|
||||
[RestPostById]
|
||||
public ActionResult<CustomFilterResource> AddCustomFilter(CustomFilterResource resource)
|
||||
{
|
||||
var customFilter = _customFilterService.Add(resource.ToModel());
|
||||
|
||||
return Created(customFilter.Id);
|
||||
}
|
||||
|
||||
[RestPutById]
|
||||
public ActionResult<CustomFilterResource> UpdateCustomFilter(CustomFilterResource resource)
|
||||
{
|
||||
_customFilterService.Update(resource.ToModel());
|
||||
return Accepted(resource.Id);
|
||||
}
|
||||
|
||||
[RestDeleteById]
|
||||
public void DeleteCustomResource(int id)
|
||||
{
|
||||
_customFilterService.Delete(id);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.CustomFilters;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.CustomFilters
|
||||
{
|
||||
public class CustomFilterModule : ReadarrRestModule<CustomFilterResource>
|
||||
{
|
||||
private readonly ICustomFilterService _customFilterService;
|
||||
|
||||
public CustomFilterModule(ICustomFilterService customFilterService)
|
||||
{
|
||||
_customFilterService = customFilterService;
|
||||
|
||||
GetResourceById = GetCustomFilter;
|
||||
GetResourceAll = GetCustomFilters;
|
||||
CreateResource = AddCustomFilter;
|
||||
UpdateResource = UpdateCustomFilter;
|
||||
DeleteResource = DeleteCustomResource;
|
||||
}
|
||||
|
||||
private CustomFilterResource GetCustomFilter(int id)
|
||||
{
|
||||
return _customFilterService.Get(id).ToResource();
|
||||
}
|
||||
|
||||
private List<CustomFilterResource> GetCustomFilters()
|
||||
{
|
||||
return _customFilterService.All().ToResource();
|
||||
}
|
||||
|
||||
private int AddCustomFilter(CustomFilterResource resource)
|
||||
{
|
||||
var customFilter = _customFilterService.Add(resource.ToModel());
|
||||
|
||||
return customFilter.Id;
|
||||
}
|
||||
|
||||
private void UpdateCustomFilter(CustomFilterResource resource)
|
||||
{
|
||||
_customFilterService.Update(resource.ToModel());
|
||||
}
|
||||
|
||||
private void DeleteCustomResource(int id)
|
||||
{
|
||||
_customFilterService.Delete(id);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
using NzbDrone.Core.ImportLists;
|
||||
using NzbDrone.Core.Validation;
|
||||
using NzbDrone.Core.Validation.Paths;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.ImportLists
|
||||
{
|
||||
public class ImportListModule : ProviderModuleBase<ImportListResource, IImportList, ImportListDefinition>
|
||||
[V1ApiController]
|
||||
public class ImportListController : ProviderControllerBase<ImportListResource, IImportList, ImportListDefinition>
|
||||
{
|
||||
public static readonly ImportListResourceMapper ResourceMapper = new ImportListResourceMapper();
|
||||
|
||||
public ImportListModule(ImportListFactory importListFactory,
|
||||
public ImportListController(ImportListFactory importListFactory,
|
||||
QualityProfileExistsValidator qualityProfileExistsValidator,
|
||||
MetadataProfileExistsValidator metadataProfileExistsValidator)
|
||||
: base(importListFactory, "importlist", ResourceMapper)
|
@ -1,54 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.ImportLists.Exclusions;
|
||||
using NzbDrone.Core.Validation;
|
||||
using NzbDrone.Http.REST.Attributes;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.ImportLists
|
||||
{
|
||||
public class ImportListExclusionModule : ReadarrRestModule<ImportListExclusionResource>
|
||||
[V1ApiController]
|
||||
public class ImportListExclusionController : RestController<ImportListExclusionResource>
|
||||
{
|
||||
private readonly IImportListExclusionService _importListExclusionService;
|
||||
|
||||
public ImportListExclusionModule(IImportListExclusionService importListExclusionService,
|
||||
public ImportListExclusionController(IImportListExclusionService importListExclusionService,
|
||||
ImportListExclusionExistsValidator importListExclusionExistsValidator,
|
||||
GuidValidator guidValidator)
|
||||
{
|
||||
_importListExclusionService = importListExclusionService;
|
||||
|
||||
GetResourceById = GetImportListExclusion;
|
||||
GetResourceAll = GetImportListExclusions;
|
||||
CreateResource = AddImportListExclusion;
|
||||
UpdateResource = UpdateImportListExclusion;
|
||||
DeleteResource = DeleteImportListExclusionResource;
|
||||
|
||||
SharedValidator.RuleFor(c => c.ForeignId).NotEmpty().SetValidator(guidValidator).SetValidator(importListExclusionExistsValidator);
|
||||
SharedValidator.RuleFor(c => c.AuthorName).NotEmpty();
|
||||
}
|
||||
|
||||
private ImportListExclusionResource GetImportListExclusion(int id)
|
||||
public override ImportListExclusionResource GetResourceById(int id)
|
||||
{
|
||||
return _importListExclusionService.Get(id).ToResource();
|
||||
}
|
||||
|
||||
private List<ImportListExclusionResource> GetImportListExclusions()
|
||||
[HttpGet]
|
||||
public List<ImportListExclusionResource> GetImportListExclusions()
|
||||
{
|
||||
return _importListExclusionService.All().ToResource();
|
||||
}
|
||||
|
||||
private int AddImportListExclusion(ImportListExclusionResource resource)
|
||||
[RestPostById]
|
||||
public ActionResult<ImportListExclusionResource> AddImportListExclusion(ImportListExclusionResource resource)
|
||||
{
|
||||
var customFilter = _importListExclusionService.Add(resource.ToModel());
|
||||
|
||||
return customFilter.Id;
|
||||
return Created(customFilter.Id);
|
||||
}
|
||||
|
||||
private void UpdateImportListExclusion(ImportListExclusionResource resource)
|
||||
[RestPutById]
|
||||
public ActionResult<ImportListExclusionResource> UpdateImportListExclusion(ImportListExclusionResource resource)
|
||||
{
|
||||
_importListExclusionService.Update(resource.ToModel());
|
||||
return Accepted(resource.Id);
|
||||
}
|
||||
|
||||
private void DeleteImportListExclusionResource(int id)
|
||||
[RestDeleteById]
|
||||
public void DeleteImportListExclusionResource(int id)
|
||||
{
|
||||
_importListExclusionService.Delete(id);
|
||||
}
|
@ -1,51 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Profiles.Metadata;
|
||||
using NzbDrone.Http.REST.Attributes;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Profiles.Metadata
|
||||
{
|
||||
public class MetadataProfileModule : ReadarrRestModule<MetadataProfileResource>
|
||||
[V1ApiController]
|
||||
public class MetadataProfileController : RestController<MetadataProfileResource>
|
||||
{
|
||||
private readonly IMetadataProfileService _profileService;
|
||||
|
||||
public MetadataProfileModule(IMetadataProfileService profileService)
|
||||
public MetadataProfileController(IMetadataProfileService profileService)
|
||||
{
|
||||
_profileService = profileService;
|
||||
SharedValidator.RuleFor(c => c.Name).NotEqual("None").WithMessage("'None' is a reserved profile name").NotEmpty();
|
||||
|
||||
GetResourceAll = GetAll;
|
||||
GetResourceById = GetById;
|
||||
UpdateResource = Update;
|
||||
CreateResource = Create;
|
||||
DeleteResource = DeleteProfile;
|
||||
}
|
||||
|
||||
private int Create(MetadataProfileResource resource)
|
||||
[RestPostById]
|
||||
public ActionResult<MetadataProfileResource> Create(MetadataProfileResource resource)
|
||||
{
|
||||
var model = resource.ToModel();
|
||||
model = _profileService.Add(model);
|
||||
return model.Id;
|
||||
return Created(model.Id);
|
||||
}
|
||||
|
||||
private void DeleteProfile(int id)
|
||||
[RestDeleteById]
|
||||
public void DeleteProfile(int id)
|
||||
{
|
||||
_profileService.Delete(id);
|
||||
}
|
||||
|
||||
private void Update(MetadataProfileResource resource)
|
||||
[RestPutById]
|
||||
public ActionResult<MetadataProfileResource> Update(MetadataProfileResource resource)
|
||||
{
|
||||
var model = resource.ToModel();
|
||||
|
||||
_profileService.Update(model);
|
||||
|
||||
return Accepted(model.Id);
|
||||
}
|
||||
|
||||
private MetadataProfileResource GetById(int id)
|
||||
public override MetadataProfileResource GetResourceById(int id)
|
||||
{
|
||||
return _profileService.Get(id).ToResource();
|
||||
}
|
||||
|
||||
private List<MetadataProfileResource> GetAll()
|
||||
[HttpGet]
|
||||
public List<MetadataProfileResource> GetAll()
|
||||
{
|
||||
var profiles = _profileService.All().ToResource();
|
||||
|
@ -1,17 +1,14 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Profiles.Metadata;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.Profiles.Metadata
|
||||
{
|
||||
public class MetadataProfileSchemaModule : ReadarrRestModule<MetadataProfileResource>
|
||||
[V1ApiController("metadataprofile/schema")]
|
||||
public class MetadataProfileSchemaController : Controller
|
||||
{
|
||||
public MetadataProfileSchemaModule()
|
||||
: base("/metadataprofile/schema")
|
||||
{
|
||||
GetResourceSingle = GetAll;
|
||||
}
|
||||
|
||||
private MetadataProfileResource GetAll()
|
||||
[HttpGet]
|
||||
public MetadataProfileResource GetAll()
|
||||
{
|
||||
var profile = new MetadataProfile
|
||||
{
|
@ -1,53 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Profiles.Qualities;
|
||||
using NzbDrone.Http.REST.Attributes;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Profiles.Quality
|
||||
{
|
||||
public class ProfileModule : ReadarrRestModule<QualityProfileResource>
|
||||
[V1ApiController]
|
||||
public class QualityProfileController : RestController<QualityProfileResource>
|
||||
{
|
||||
private readonly IProfileService _profileService;
|
||||
|
||||
public ProfileModule(IProfileService profileService)
|
||||
public QualityProfileController(IProfileService profileService)
|
||||
{
|
||||
_profileService = profileService;
|
||||
SharedValidator.RuleFor(c => c.Name).NotEmpty();
|
||||
SharedValidator.RuleFor(c => c.Cutoff).ValidCutoff();
|
||||
SharedValidator.RuleFor(c => c.Items).ValidItems();
|
||||
|
||||
GetResourceAll = GetAll;
|
||||
GetResourceById = GetById;
|
||||
UpdateResource = Update;
|
||||
CreateResource = Create;
|
||||
DeleteResource = DeleteProfile;
|
||||
}
|
||||
|
||||
private int Create(QualityProfileResource resource)
|
||||
[RestPostById]
|
||||
public ActionResult<QualityProfileResource> Create(QualityProfileResource resource)
|
||||
{
|
||||
var model = resource.ToModel();
|
||||
model = _profileService.Add(model);
|
||||
return model.Id;
|
||||
return Created(model.Id);
|
||||
}
|
||||
|
||||
private void DeleteProfile(int id)
|
||||
[RestDeleteById]
|
||||
public void DeleteProfile(int id)
|
||||
{
|
||||
_profileService.Delete(id);
|
||||
}
|
||||
|
||||
private void Update(QualityProfileResource resource)
|
||||
[RestPutById]
|
||||
public ActionResult<QualityProfileResource> Update(QualityProfileResource resource)
|
||||
{
|
||||
var model = resource.ToModel();
|
||||
|
||||
_profileService.Update(model);
|
||||
|
||||
return Accepted(model.Id);
|
||||
}
|
||||
|
||||
private QualityProfileResource GetById(int id)
|
||||
public override QualityProfileResource GetResourceById(int id)
|
||||
{
|
||||
return _profileService.Get(id).ToResource();
|
||||
}
|
||||
|
||||
private List<QualityProfileResource> GetAll()
|
||||
[HttpGet]
|
||||
public List<QualityProfileResource> GetAll()
|
||||
{
|
||||
return _profileService.All().ToResource();
|
||||
}
|
@ -1,20 +1,21 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Profiles.Qualities;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.Profiles.Quality
|
||||
{
|
||||
public class QualityProfileSchemaModule : ReadarrRestModule<QualityProfileResource>
|
||||
[V1ApiController("qualityprofile/schema")]
|
||||
public class QualityProfileSchemaController : Controller
|
||||
{
|
||||
private readonly IProfileService _profileService;
|
||||
|
||||
public QualityProfileSchemaModule(IProfileService profileService)
|
||||
: base("/qualityprofile/schema")
|
||||
public QualityProfileSchemaController(IProfileService profileService)
|
||||
{
|
||||
_profileService = profileService;
|
||||
GetResourceSingle = GetSchema;
|
||||
}
|
||||
|
||||
private QualityProfileResource GetSchema()
|
||||
[HttpGet]
|
||||
public QualityProfileResource GetSchema()
|
||||
{
|
||||
QualityProfile qualityProfile = _profileService.GetDefaultProfile(string.Empty);
|
||||
|
@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Http.REST.Attributes;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Qualities
|
||||
{
|
||||
[V1ApiController]
|
||||
public class QualityDefinitionController : RestController<QualityDefinitionResource>
|
||||
{
|
||||
private readonly IQualityDefinitionService _qualityDefinitionService;
|
||||
|
||||
public QualityDefinitionController(IQualityDefinitionService qualityDefinitionService)
|
||||
{
|
||||
_qualityDefinitionService = qualityDefinitionService;
|
||||
}
|
||||
|
||||
[RestPutById]
|
||||
public ActionResult<QualityDefinitionResource> Update(QualityDefinitionResource resource)
|
||||
{
|
||||
var model = resource.ToModel();
|
||||
_qualityDefinitionService.Update(model);
|
||||
return Accepted(model.Id);
|
||||
}
|
||||
|
||||
public override QualityDefinitionResource GetResourceById(int id)
|
||||
{
|
||||
return _qualityDefinitionService.GetById(id).ToResource();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public List<QualityDefinitionResource> GetAll()
|
||||
{
|
||||
return _qualityDefinitionService.All().ToResource();
|
||||
}
|
||||
|
||||
[HttpPut("update")]
|
||||
public object UpdateMany([FromBody] List<QualityDefinitionResource> resource)
|
||||
{
|
||||
//Read from request
|
||||
var qualityDefinitions = resource
|
||||
.ToModel()
|
||||
.ToList();
|
||||
|
||||
_qualityDefinitionService.UpdateMany(qualityDefinitions);
|
||||
|
||||
return Accepted(_qualityDefinitionService.All()
|
||||
.ToResource());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Pending;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Queue
|
||||
{
|
||||
[V1ApiController("queue")]
|
||||
public class QueueActionController : Controller
|
||||
{
|
||||
private readonly IPendingReleaseService _pendingReleaseService;
|
||||
private readonly IDownloadService _downloadService;
|
||||
|
||||
public QueueActionController(IPendingReleaseService pendingReleaseService,
|
||||
IDownloadService downloadService)
|
||||
{
|
||||
_pendingReleaseService = pendingReleaseService;
|
||||
_downloadService = downloadService;
|
||||
}
|
||||
|
||||
[HttpPost("grab/{id:int}")]
|
||||
public object Grab(int id)
|
||||
{
|
||||
var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id);
|
||||
|
||||
if (pendingRelease == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
_downloadService.DownloadReport(pendingRelease.RemoteBook);
|
||||
|
||||
return new object();
|
||||
}
|
||||
|
||||
[HttpPost("grab/bulk")]
|
||||
public object Grab([FromBody] QueueBulkResource resource)
|
||||
{
|
||||
foreach (var id in resource.Ids)
|
||||
{
|
||||
var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id);
|
||||
|
||||
if (pendingRelease == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
_downloadService.DownloadReport(pendingRelease.RemoteBook);
|
||||
}
|
||||
|
||||
return new object();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Nancy;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Pending;
|
||||
using NzbDrone.Core.Download.TrackedDownloads;
|
||||
using NzbDrone.Core.Queue;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.Extensions;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Queue
|
||||
{
|
||||
public class QueueActionModule : ReadarrRestModule<QueueResource>
|
||||
{
|
||||
private readonly IQueueService _queueService;
|
||||
private readonly ITrackedDownloadService _trackedDownloadService;
|
||||
private readonly IFailedDownloadService _failedDownloadService;
|
||||
private readonly IIgnoredDownloadService _ignoredDownloadService;
|
||||
private readonly IProvideDownloadClient _downloadClientProvider;
|
||||
private readonly IPendingReleaseService _pendingReleaseService;
|
||||
private readonly IDownloadService _downloadService;
|
||||
|
||||
public QueueActionModule(IQueueService queueService,
|
||||
ITrackedDownloadService trackedDownloadService,
|
||||
IFailedDownloadService failedDownloadService,
|
||||
IIgnoredDownloadService ignoredDownloadService,
|
||||
IProvideDownloadClient downloadClientProvider,
|
||||
IPendingReleaseService pendingReleaseService,
|
||||
IDownloadService downloadService)
|
||||
{
|
||||
_queueService = queueService;
|
||||
_trackedDownloadService = trackedDownloadService;
|
||||
_failedDownloadService = failedDownloadService;
|
||||
_ignoredDownloadService = ignoredDownloadService;
|
||||
_downloadClientProvider = downloadClientProvider;
|
||||
_pendingReleaseService = pendingReleaseService;
|
||||
_downloadService = downloadService;
|
||||
|
||||
Post(@"/grab/(?<id>[\d]{1,10})", x => Grab((int)x.Id));
|
||||
Post("/grab/bulk", x => Grab());
|
||||
|
||||
Delete(@"/(?<id>[\d]{1,10})", x => Remove((int)x.Id));
|
||||
Delete("/bulk", x => Remove());
|
||||
}
|
||||
|
||||
private object Grab(int id)
|
||||
{
|
||||
var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id);
|
||||
|
||||
if (pendingRelease == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
_downloadService.DownloadReport(pendingRelease.RemoteBook);
|
||||
|
||||
return new object();
|
||||
}
|
||||
|
||||
private object Grab()
|
||||
{
|
||||
var resource = Request.Body.FromJson<QueueBulkResource>();
|
||||
|
||||
foreach (var id in resource.Ids)
|
||||
{
|
||||
var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id);
|
||||
|
||||
if (pendingRelease == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
_downloadService.DownloadReport(pendingRelease.RemoteBook);
|
||||
}
|
||||
|
||||
return new object();
|
||||
}
|
||||
|
||||
private object Remove(int id)
|
||||
{
|
||||
var removeFromClient = Request.GetBooleanQueryParameter("removeFromClient", true);
|
||||
var blacklist = Request.GetBooleanQueryParameter("blacklist");
|
||||
var skipReDownload = Request.GetBooleanQueryParameter("skipredownload");
|
||||
|
||||
var trackedDownload = Remove(id, removeFromClient, blacklist, skipReDownload);
|
||||
|
||||
if (trackedDownload != null)
|
||||
{
|
||||
_trackedDownloadService.StopTracking(trackedDownload.DownloadItem.DownloadId);
|
||||
}
|
||||
|
||||
return new object();
|
||||
}
|
||||
|
||||
private object Remove()
|
||||
{
|
||||
var removeFromClient = Request.GetBooleanQueryParameter("removeFromClient", true);
|
||||
var blacklist = Request.GetBooleanQueryParameter("blacklist");
|
||||
var skipReDownload = Request.GetBooleanQueryParameter("skipredownload");
|
||||
|
||||
var resource = Request.Body.FromJson<QueueBulkResource>();
|
||||
var trackedDownloadIds = new List<string>();
|
||||
|
||||
foreach (var id in resource.Ids)
|
||||
{
|
||||
var trackedDownload = Remove(id, removeFromClient, blacklist, skipReDownload);
|
||||
|
||||
if (trackedDownload != null)
|
||||
{
|
||||
trackedDownloadIds.Add(trackedDownload.DownloadItem.DownloadId);
|
||||
}
|
||||
}
|
||||
|
||||
_trackedDownloadService.StopTracking(trackedDownloadIds);
|
||||
|
||||
return new object();
|
||||
}
|
||||
|
||||
private TrackedDownload Remove(int id, bool removeFromClient, bool blacklist, bool skipReDownload)
|
||||
{
|
||||
var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id);
|
||||
|
||||
if (pendingRelease != null)
|
||||
{
|
||||
_pendingReleaseService.RemovePendingQueueItems(pendingRelease.Id);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var trackedDownload = GetTrackedDownload(id);
|
||||
|
||||
if (trackedDownload == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
if (removeFromClient)
|
||||
{
|
||||
var downloadClient = _downloadClientProvider.Get(trackedDownload.DownloadClient);
|
||||
|
||||
if (downloadClient == null)
|
||||
{
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true);
|
||||
}
|
||||
|
||||
if (blacklist)
|
||||
{
|
||||
_failedDownloadService.MarkAsFailed(trackedDownload.DownloadItem.DownloadId, skipReDownload);
|
||||
}
|
||||
|
||||
if (!removeFromClient && !blacklist)
|
||||
{
|
||||
if (!_ignoredDownloadService.IgnoreDownload(trackedDownload))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return trackedDownload;
|
||||
}
|
||||
|
||||
private TrackedDownload GetTrackedDownload(int queueId)
|
||||
{
|
||||
var queueItem = _queueService.Find(queueId);
|
||||
|
||||
if (queueItem == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var trackedDownload = _trackedDownloadService.Find(queueItem.DownloadId);
|
||||
|
||||
if (trackedDownload == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return trackedDownload;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,65 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.Download.Pending;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Queue;
|
||||
using NzbDrone.SignalR;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.Extensions;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Queue
|
||||
{
|
||||
public class QueueDetailsModule : ReadarrRestModuleWithSignalR<QueueResource, NzbDrone.Core.Queue.Queue>,
|
||||
[V1ApiController("queue/details")]
|
||||
public class QueueDetailsController : RestControllerWithSignalR<QueueResource, NzbDrone.Core.Queue.Queue>,
|
||||
IHandle<QueueUpdatedEvent>, IHandle<PendingReleasesUpdatedEvent>
|
||||
{
|
||||
private readonly IQueueService _queueService;
|
||||
private readonly IPendingReleaseService _pendingReleaseService;
|
||||
|
||||
public QueueDetailsModule(IBroadcastSignalRMessage broadcastSignalRMessage, IQueueService queueService, IPendingReleaseService pendingReleaseService)
|
||||
: base(broadcastSignalRMessage, "queue/details")
|
||||
public QueueDetailsController(IBroadcastSignalRMessage broadcastSignalRMessage, IQueueService queueService, IPendingReleaseService pendingReleaseService)
|
||||
: base(broadcastSignalRMessage)
|
||||
{
|
||||
_queueService = queueService;
|
||||
_pendingReleaseService = pendingReleaseService;
|
||||
GetResourceAll = GetQueue;
|
||||
}
|
||||
|
||||
private List<QueueResource> GetQueue()
|
||||
public override QueueResource GetResourceById(int id)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public List<QueueResource> GetQueue(int? authorId, [FromQuery]List<int> bookIds, bool includeAuthor = false, bool includeBook = true)
|
||||
{
|
||||
var includeAuthor = Request.GetBooleanQueryParameter("includeAuthor");
|
||||
var includeBook = Request.GetBooleanQueryParameter("includeBook", true);
|
||||
var queue = _queueService.GetQueue();
|
||||
var pending = _pendingReleaseService.GetPendingQueue();
|
||||
var fullQueue = queue.Concat(pending);
|
||||
|
||||
var authorIdQuery = Request.Query.AuthorId;
|
||||
var bookIdsQuery = Request.Query.BookIds;
|
||||
|
||||
if (authorIdQuery.HasValue)
|
||||
if (authorId.HasValue)
|
||||
{
|
||||
return fullQueue.Where(q => q.Author?.Id == (int)authorIdQuery).ToResource(includeAuthor, includeBook);
|
||||
return fullQueue.Where(q => q.Author?.Id == authorId.Value).ToResource(includeAuthor, includeBook);
|
||||
}
|
||||
|
||||
if (bookIdsQuery.HasValue)
|
||||
if (bookIds.Any())
|
||||
{
|
||||
string bookIdsValue = bookIdsQuery.Value.ToString();
|
||||
|
||||
var bookIds = bookIdsValue.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(e => Convert.ToInt32(e))
|
||||
.ToList();
|
||||
|
||||
return fullQueue.Where(q => q.Book != null && bookIds.Contains(q.Book.Id)).ToResource(includeAuthor, includeBook);
|
||||
}
|
||||
|
||||
return fullQueue.ToResource(includeAuthor, includeBook);
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public void Handle(QueueUpdatedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Sync);
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public void Handle(PendingReleasesUpdatedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Sync);
|
@ -1,12 +0,0 @@
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1
|
||||
{
|
||||
public abstract class ReadarrV1FeedModule : ReadarrModule
|
||||
{
|
||||
protected ReadarrV1FeedModule(string resource)
|
||||
: base("/feed/v1/" + resource.Trim('/'))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1
|
||||
{
|
||||
public abstract class ReadarrV1Module : ReadarrModule
|
||||
{
|
||||
protected ReadarrV1Module(string resource)
|
||||
: base("/api/v1/" + resource.Trim('/'))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Books;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.Series
|
||||
{
|
||||
[V1ApiController]
|
||||
public class SeriesController : Controller
|
||||
{
|
||||
protected readonly ISeriesService _seriesService;
|
||||
|
||||
public SeriesController(ISeriesService seriesService)
|
||||
{
|
||||
_seriesService = seriesService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public List<SeriesResource> GetSeries(int authorId)
|
||||
{
|
||||
return _seriesService.GetByAuthorId(authorId).ToResource();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Nancy;
|
||||
using NzbDrone.Core.Books;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Series
|
||||
{
|
||||
public class SeriesModule : ReadarrRestModule<SeriesResource>
|
||||
{
|
||||
protected readonly ISeriesService _seriesService;
|
||||
|
||||
public SeriesModule(ISeriesService seriesService)
|
||||
{
|
||||
_seriesService = seriesService;
|
||||
|
||||
GetResourceAll = GetSeries;
|
||||
}
|
||||
|
||||
private List<SeriesResource> GetSeries()
|
||||
{
|
||||
var authorIdQuery = Request.Query.AuthorId;
|
||||
|
||||
if (!authorIdQuery.HasValue)
|
||||
{
|
||||
throw new BadRequestException("authorId must be provided");
|
||||
}
|
||||
|
||||
int authorId = Convert.ToInt32(authorIdQuery.Value);
|
||||
|
||||
return _seriesService.GetByAuthorId(authorId).ToResource();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,54 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Tags;
|
||||
using NzbDrone.Http.REST.Attributes;
|
||||
using NzbDrone.SignalR;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Tags
|
||||
{
|
||||
public class TagModule : ReadarrRestModuleWithSignalR<TagResource, Tag>, IHandle<TagsUpdatedEvent>
|
||||
[V1ApiController]
|
||||
public class TagController : RestControllerWithSignalR<TagResource, Tag>, IHandle<TagsUpdatedEvent>
|
||||
{
|
||||
private readonly ITagService _tagService;
|
||||
|
||||
public TagModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
public TagController(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
ITagService tagService)
|
||||
: base(signalRBroadcaster)
|
||||
{
|
||||
_tagService = tagService;
|
||||
|
||||
GetResourceById = GetTag;
|
||||
GetResourceAll = GetAll;
|
||||
CreateResource = Create;
|
||||
UpdateResource = Update;
|
||||
DeleteResource = DeleteTag;
|
||||
}
|
||||
|
||||
private TagResource GetTag(int id)
|
||||
public override TagResource GetResourceById(int id)
|
||||
{
|
||||
return _tagService.GetTag(id).ToResource();
|
||||
}
|
||||
|
||||
private List<TagResource> GetAll()
|
||||
[HttpGet]
|
||||
public List<TagResource> GetAll()
|
||||
{
|
||||
return _tagService.All().ToResource();
|
||||
}
|
||||
|
||||
private int Create(TagResource resource)
|
||||
[RestPostById]
|
||||
public ActionResult<TagResource> Create(TagResource resource)
|
||||
{
|
||||
return _tagService.Add(resource.ToModel()).Id;
|
||||
return Created(_tagService.Add(resource.ToModel()).Id);
|
||||
}
|
||||
|
||||
private void Update(TagResource resource)
|
||||
[RestPutById]
|
||||
public ActionResult<TagResource> Update(TagResource resource)
|
||||
{
|
||||
_tagService.Update(resource.ToModel());
|
||||
return Accepted(resource.Id);
|
||||
}
|
||||
|
||||
private void DeleteTag(int id)
|
||||
[RestDeleteById]
|
||||
public void DeleteTag(int id)
|
||||
{
|
||||
_tagService.Delete(id);
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public void Handle(TagsUpdatedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Sync);
|
@ -1,28 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Tags;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.Tags
|
||||
{
|
||||
public class TagDetailsModule : ReadarrRestModule<TagDetailsResource>
|
||||
[V1ApiController("tag/detail")]
|
||||
public class TagDetailsController : RestController<TagDetailsResource>
|
||||
{
|
||||
private readonly ITagService _tagService;
|
||||
|
||||
public TagDetailsModule(ITagService tagService)
|
||||
: base("/tag/detail")
|
||||
public TagDetailsController(ITagService tagService)
|
||||
{
|
||||
_tagService = tagService;
|
||||
|
||||
GetResourceById = GetTagDetails;
|
||||
GetResourceAll = GetAll;
|
||||
}
|
||||
|
||||
private TagDetailsResource GetTagDetails(int id)
|
||||
public override TagDetailsResource GetResourceById(int id)
|
||||
{
|
||||
return _tagService.Details(id).ToResource();
|
||||
}
|
||||
|
||||
private List<TagDetailsResource> GetAll()
|
||||
[HttpGet]
|
||||
public List<TagDetailsResource> GetAll()
|
||||
{
|
||||
var tags = _tagService.Details().ToResource();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue