mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-03 13:44:33 -04:00
Starting the library crud api & fixing the regex
This commit is contained in:
parent
193004a3ee
commit
6d29298073
@ -191,6 +191,46 @@ namespace Kyoo.Controllers
|
|||||||
Expression<Func<Collection, object>> sort,
|
Expression<Func<Collection, object>> sort,
|
||||||
Pagination limit = default
|
Pagination limit = default
|
||||||
) => GetCollectionsFromShow(showSlug, where, new Sort<Collection>(sort), limit);
|
) => GetCollectionsFromShow(showSlug, where, new Sort<Collection>(sort), limit);
|
||||||
|
|
||||||
|
Task<ICollection<Show>> GetShowsFromLibrary(int id,
|
||||||
|
Expression<Func<Show, bool>> where = null,
|
||||||
|
Sort<Show> sort = default,
|
||||||
|
Pagination limit = default);
|
||||||
|
Task<ICollection<Show>> GetShowsFromLibrary(int id,
|
||||||
|
[Optional] Expression<Func<Show, bool>> where,
|
||||||
|
Expression<Func<Show, object>> sort,
|
||||||
|
Pagination limit = default
|
||||||
|
) => GetShowsFromLibrary(id, where, new Sort<Show>(sort), limit);
|
||||||
|
|
||||||
|
Task<ICollection<Show>> GetShowsFromLibrary(string slug,
|
||||||
|
Expression<Func<Show, bool>> where = null,
|
||||||
|
Sort<Show> sort = default,
|
||||||
|
Pagination limit = default);
|
||||||
|
Task<ICollection<Show>> GetShowsFromLibrary(string slug,
|
||||||
|
[Optional] Expression<Func<Show, bool>> where,
|
||||||
|
Expression<Func<Show, object>> sort,
|
||||||
|
Pagination limit = default
|
||||||
|
) => GetShowsFromLibrary(slug, where, new Sort<Show>(sort), limit);
|
||||||
|
|
||||||
|
Task<ICollection<Collection>> GetCollectionsFromLibrary(int id,
|
||||||
|
Expression<Func<Collection, bool>> where = null,
|
||||||
|
Sort<Collection> sort = default,
|
||||||
|
Pagination limit = default);
|
||||||
|
Task<ICollection<Collection>> GetCollectionsFromLibrary(int id,
|
||||||
|
[Optional] Expression<Func<Collection, bool>> where,
|
||||||
|
Expression<Func<Collection, object>> sort,
|
||||||
|
Pagination limit = default
|
||||||
|
) => GetCollectionsFromLibrary(id, where, new Sort<Collection>(sort), limit);
|
||||||
|
|
||||||
|
Task<ICollection<Collection>> GetCollectionsFromLibrary(string showSlug,
|
||||||
|
Expression<Func<Collection, bool>> where = null,
|
||||||
|
Sort<Collection> sort = default,
|
||||||
|
Pagination limit = default);
|
||||||
|
Task<ICollection<Collection>> GetCollectionsFromLibrary(string showSlug,
|
||||||
|
[Optional] Expression<Func<Collection, bool>> where,
|
||||||
|
Expression<Func<Collection, object>> sort,
|
||||||
|
Pagination limit = default
|
||||||
|
) => GetCollectionsFromLibrary(showSlug, where, new Sort<Collection>(sort), limit);
|
||||||
|
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
@ -102,6 +102,46 @@ namespace Kyoo.Controllers
|
|||||||
public interface IShowRepository : IRepository<Show>
|
public interface IShowRepository : IRepository<Show>
|
||||||
{
|
{
|
||||||
Task AddShowLink(int showID, int? libraryID, int? collectionID);
|
Task AddShowLink(int showID, int? libraryID, int? collectionID);
|
||||||
|
|
||||||
|
Task<ICollection<Show>> GetFromLibrary(int id,
|
||||||
|
Expression<Func<Show, bool>> where = null,
|
||||||
|
Sort<Show> sort = default,
|
||||||
|
Pagination limit = default);
|
||||||
|
Task<ICollection<Show>> GetFromLibrary(int id,
|
||||||
|
[Optional] Expression<Func<Show, bool>> where,
|
||||||
|
Expression<Func<Show, object>> sort,
|
||||||
|
Pagination limit = default
|
||||||
|
) => GetFromLibrary(id, where, new Sort<Show>(sort), limit);
|
||||||
|
|
||||||
|
Task<ICollection<Show>> GetFromLibrary(string slug,
|
||||||
|
Expression<Func<Show, bool>> where = null,
|
||||||
|
Sort<Show> sort = default,
|
||||||
|
Pagination limit = default);
|
||||||
|
Task<ICollection<Show>> GetFromLibrary(string slug,
|
||||||
|
[Optional] Expression<Func<Show, bool>> where,
|
||||||
|
Expression<Func<Show, object>> sort,
|
||||||
|
Pagination limit = default
|
||||||
|
) => GetFromLibrary(slug, where, new Sort<Show>(sort), limit);
|
||||||
|
|
||||||
|
// Task<ICollection<Show>> GetFromCollection(int id,
|
||||||
|
// Expression<Func<Show, bool>> where = null,
|
||||||
|
// Sort<Show> sort = default,
|
||||||
|
// Pagination limit = default);
|
||||||
|
// Task<ICollection<Show>> GetFromCollection(int id,
|
||||||
|
// [Optional] Expression<Func<Show, bool>> where,
|
||||||
|
// Expression<Func<Show, object>> sort,
|
||||||
|
// Pagination limit = default
|
||||||
|
// ) => GetFromCollection(id, where, new Sort<Show>(sort), limit);
|
||||||
|
//
|
||||||
|
// Task<ICollection<Show>> GetFromCollection(string slug,
|
||||||
|
// Expression<Func<Show, bool>> where = null,
|
||||||
|
// Sort<Show> sort = default,
|
||||||
|
// Pagination limit = default);
|
||||||
|
// Task<ICollection<Show>> GetFromCollection(string slug,
|
||||||
|
// [Optional] Expression<Func<Show, bool>> where,
|
||||||
|
// Expression<Func<Show, object>> sort,
|
||||||
|
// Pagination limit = default
|
||||||
|
// ) => GetFromCollection(slug, where, new Sort<Show>(sort), limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ISeasonRepository : IRepository<Season>
|
public interface ISeasonRepository : IRepository<Season>
|
||||||
@ -238,6 +278,26 @@ namespace Kyoo.Controllers
|
|||||||
Expression<Func<Collection, object>> sort,
|
Expression<Func<Collection, object>> sort,
|
||||||
Pagination limit = default
|
Pagination limit = default
|
||||||
) => GetFromShow(showSlug, where, new Sort<Collection>(sort), limit);
|
) => GetFromShow(showSlug, where, new Sort<Collection>(sort), limit);
|
||||||
|
|
||||||
|
Task<ICollection<Collection>> GetFromLibrary(int id,
|
||||||
|
Expression<Func<Collection, bool>> where = null,
|
||||||
|
Sort<Collection> sort = default,
|
||||||
|
Pagination limit = default);
|
||||||
|
Task<ICollection<Collection>> GetFromLibrary(int id,
|
||||||
|
[Optional] Expression<Func<Collection, bool>> where,
|
||||||
|
Expression<Func<Collection, object>> sort,
|
||||||
|
Pagination limit = default
|
||||||
|
) => GetFromLibrary(id, where, new Sort<Collection>(sort), limit);
|
||||||
|
|
||||||
|
Task<ICollection<Collection>> GetFromLibrary(string slug,
|
||||||
|
Expression<Func<Collection, bool>> where = null,
|
||||||
|
Sort<Collection> sort = default,
|
||||||
|
Pagination limit = default);
|
||||||
|
Task<ICollection<Collection>> GetFromLibrary(string slug,
|
||||||
|
[Optional] Expression<Func<Collection, bool>> where,
|
||||||
|
Expression<Func<Collection, object>> sort,
|
||||||
|
Pagination limit = default
|
||||||
|
) => GetFromLibrary(slug, where, new Sort<Collection>(sort), limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IGenreRepository : IRepository<Genre>
|
public interface IGenreRepository : IRepository<Genre>
|
||||||
|
@ -329,6 +329,38 @@ namespace Kyoo.Controllers
|
|||||||
return CollectionRepository.GetFromShow(showSlug, where, sort, limit);
|
return CollectionRepository.GetFromShow(showSlug, where, sort, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Show>> GetShowsFromLibrary(int id,
|
||||||
|
Expression<Func<Show, bool>> where = null,
|
||||||
|
Sort<Show> sort = default,
|
||||||
|
Pagination limit = default)
|
||||||
|
{
|
||||||
|
return ShowRepository.GetFromLibrary(id, where, sort, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Show>> GetShowsFromLibrary(string slug,
|
||||||
|
Expression<Func<Show, bool>> where = null,
|
||||||
|
Sort<Show> sort = default,
|
||||||
|
Pagination limit = default)
|
||||||
|
{
|
||||||
|
return ShowRepository.GetFromLibrary(slug, where, sort, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Collection>> GetCollectionsFromLibrary(int id,
|
||||||
|
Expression<Func<Collection, bool>> where = null,
|
||||||
|
Sort<Collection> sort = default,
|
||||||
|
Pagination limit = default)
|
||||||
|
{
|
||||||
|
return CollectionRepository.GetFromLibrary(id, where, sort, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Collection>> GetCollectionsFromLibrary(string slug,
|
||||||
|
Expression<Func<Collection, bool>> where = null,
|
||||||
|
Sort<Collection> sort = default,
|
||||||
|
Pagination limit = default)
|
||||||
|
{
|
||||||
|
return CollectionRepository.GetFromLibrary(slug, where, sort, limit);
|
||||||
|
}
|
||||||
|
|
||||||
public Task AddShowLink(int showID, int? libraryID, int? collectionID)
|
public Task AddShowLink(int showID, int? libraryID, int? collectionID)
|
||||||
{
|
{
|
||||||
return ShowRepository.AddShowLink(showID, libraryID, collectionID);
|
return ShowRepository.AddShowLink(showID, libraryID, collectionID);
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Kyoo.Models.Exceptions;
|
using Kyoo.Models.Exceptions;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
namespace Kyoo.CommonApi
|
namespace Kyoo.CommonApi
|
||||||
@ -29,7 +26,7 @@ namespace Kyoo.CommonApi
|
|||||||
[HttpGet("{id:int}")]
|
[HttpGet("{id:int}")]
|
||||||
[Authorize(Policy = "Read")]
|
[Authorize(Policy = "Read")]
|
||||||
[JsonDetailed]
|
[JsonDetailed]
|
||||||
public async Task<ActionResult<T>> Get(int id)
|
public virtual async Task<ActionResult<T>> Get(int id)
|
||||||
{
|
{
|
||||||
T ressource = await _repository.Get(id);
|
T ressource = await _repository.Get(id);
|
||||||
if (ressource == null)
|
if (ressource == null)
|
||||||
@ -41,7 +38,7 @@ namespace Kyoo.CommonApi
|
|||||||
[HttpGet("{slug}")]
|
[HttpGet("{slug}")]
|
||||||
[Authorize(Policy = "Read")]
|
[Authorize(Policy = "Read")]
|
||||||
[JsonDetailed]
|
[JsonDetailed]
|
||||||
public async Task<ActionResult<T>> Get(string slug)
|
public virtual async Task<ActionResult<T>> Get(string slug)
|
||||||
{
|
{
|
||||||
T ressource = await _repository.Get(slug);
|
T ressource = await _repository.Get(slug);
|
||||||
if (ressource == null)
|
if (ressource == null)
|
||||||
@ -52,7 +49,7 @@ namespace Kyoo.CommonApi
|
|||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Authorize(Policy = "Read")]
|
[Authorize(Policy = "Read")]
|
||||||
public async Task<ActionResult<Page<T>>> GetAll([FromQuery] string sortBy,
|
public virtual async Task<ActionResult<Page<T>>> GetAll([FromQuery] string sortBy,
|
||||||
[FromQuery] int afterID,
|
[FromQuery] int afterID,
|
||||||
[FromQuery] Dictionary<string, string> where,
|
[FromQuery] Dictionary<string, string> where,
|
||||||
[FromQuery] int limit = 20)
|
[FromQuery] int limit = 20)
|
||||||
@ -86,12 +83,16 @@ namespace Kyoo.CommonApi
|
|||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Authorize(Policy = "Write")]
|
[Authorize(Policy = "Write")]
|
||||||
public async Task<ActionResult<T>> Create([FromBody] T ressource)
|
public virtual async Task<ActionResult<T>> Create([FromBody] T ressource)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return await _repository.Create(ressource);
|
return await _repository.Create(ressource);
|
||||||
}
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new {Error = ex.Message});
|
||||||
|
}
|
||||||
catch (DuplicatedItemException)
|
catch (DuplicatedItemException)
|
||||||
{
|
{
|
||||||
T existing = await _repository.Get(ressource.Slug);
|
T existing = await _repository.Get(ressource.Slug);
|
||||||
@ -101,21 +102,22 @@ namespace Kyoo.CommonApi
|
|||||||
|
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
[Authorize(Policy = "Write")]
|
[Authorize(Policy = "Write")]
|
||||||
public async Task<ActionResult<T>> Edit([FromQuery] bool resetOld, [FromBody] T ressource)
|
public virtual async Task<ActionResult<T>> Edit([FromQuery] bool resetOld, [FromBody] T ressource)
|
||||||
{
|
{
|
||||||
if (ressource.ID <= 0)
|
if (ressource.ID > 0)
|
||||||
{
|
return await _repository.Edit(ressource, resetOld);
|
||||||
T old = await _repository.Get(ressource.Slug);
|
|
||||||
if (old == null)
|
T old = await _repository.Get(ressource.Slug);
|
||||||
return NotFound();
|
if (old == null)
|
||||||
ressource.ID = old.ID;
|
return NotFound();
|
||||||
}
|
|
||||||
|
ressource.ID = old.ID;
|
||||||
return await _repository.Edit(ressource, resetOld);
|
return await _repository.Edit(ressource, resetOld);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("{id:int}")]
|
[HttpPut("{id:int}")]
|
||||||
[Authorize(Policy = "Write")]
|
[Authorize(Policy = "Write")]
|
||||||
public async Task<ActionResult<T>> Edit(int id, [FromQuery] bool resetOld, [FromBody] T ressource)
|
public virtual async Task<ActionResult<T>> Edit(int id, [FromQuery] bool resetOld, [FromBody] T ressource)
|
||||||
{
|
{
|
||||||
ressource.ID = id;
|
ressource.ID = id;
|
||||||
try
|
try
|
||||||
@ -130,7 +132,7 @@ namespace Kyoo.CommonApi
|
|||||||
|
|
||||||
[HttpPut("{slug}")]
|
[HttpPut("{slug}")]
|
||||||
[Authorize(Policy = "Write")]
|
[Authorize(Policy = "Write")]
|
||||||
public async Task<ActionResult<T>> Edit(string slug, [FromQuery] bool resetOld, [FromBody] T ressource)
|
public virtual async Task<ActionResult<T>> Edit(string slug, [FromQuery] bool resetOld, [FromBody] T ressource)
|
||||||
{
|
{
|
||||||
T old = await _repository.Get(slug);
|
T old = await _repository.Get(slug);
|
||||||
if (old == null)
|
if (old == null)
|
||||||
@ -141,7 +143,7 @@ namespace Kyoo.CommonApi
|
|||||||
|
|
||||||
[HttpDelete("{id:int}")]
|
[HttpDelete("{id:int}")]
|
||||||
[Authorize(Policy = "Write")]
|
[Authorize(Policy = "Write")]
|
||||||
public async Task<IActionResult> Delete(int id)
|
public virtual async Task<IActionResult> Delete(int id)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -157,7 +159,7 @@ namespace Kyoo.CommonApi
|
|||||||
|
|
||||||
[HttpDelete("{slug}")]
|
[HttpDelete("{slug}")]
|
||||||
[Authorize(Policy = "Write")]
|
[Authorize(Policy = "Write")]
|
||||||
public async Task<IActionResult> Delete(string slug)
|
public virtual async Task<IActionResult> Delete(string slug)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -14,12 +14,14 @@ namespace Kyoo.Controllers
|
|||||||
{
|
{
|
||||||
private readonly DatabaseContext _database;
|
private readonly DatabaseContext _database;
|
||||||
private readonly Lazy<IShowRepository> _shows;
|
private readonly Lazy<IShowRepository> _shows;
|
||||||
|
private readonly Lazy<ILibraryRepository> _libraries;
|
||||||
protected override Expression<Func<Collection, object>> DefaultSort => x => x.Name;
|
protected override Expression<Func<Collection, object>> DefaultSort => x => x.Name;
|
||||||
|
|
||||||
public CollectionRepository(DatabaseContext database, IServiceProvider services) : base(database)
|
public CollectionRepository(DatabaseContext database, IServiceProvider services) : base(database)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
_shows = new Lazy<IShowRepository>(services.GetRequiredService<IShowRepository>);
|
_shows = new Lazy<IShowRepository>(services.GetRequiredService<IShowRepository>);
|
||||||
|
_libraries = new Lazy<ILibraryRepository>(services.GetRequiredService<ILibraryRepository>);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
@ -27,6 +29,8 @@ namespace Kyoo.Controllers
|
|||||||
base.Dispose();
|
base.Dispose();
|
||||||
if (_shows.IsValueCreated)
|
if (_shows.IsValueCreated)
|
||||||
_shows.Value.Dispose();
|
_shows.Value.Dispose();
|
||||||
|
if (_libraries.IsValueCreated)
|
||||||
|
_libraries.Value.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async ValueTask DisposeAsync()
|
public override async ValueTask DisposeAsync()
|
||||||
@ -34,6 +38,8 @@ namespace Kyoo.Controllers
|
|||||||
await _database.DisposeAsync();
|
await _database.DisposeAsync();
|
||||||
if (_shows.IsValueCreated)
|
if (_shows.IsValueCreated)
|
||||||
await _shows.Value.DisposeAsync();
|
await _shows.Value.DisposeAsync();
|
||||||
|
if (_libraries.IsValueCreated)
|
||||||
|
await _libraries.Value.DisposeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<ICollection<Collection>> Search(string query)
|
public override async Task<ICollection<Collection>> Search(string query)
|
||||||
@ -117,5 +123,39 @@ namespace Kyoo.Controllers
|
|||||||
throw new ItemNotFound();
|
throw new ItemNotFound();
|
||||||
return collections;
|
return collections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Collection>> GetFromLibrary(int id,
|
||||||
|
Expression<Func<Collection, bool>> where = null,
|
||||||
|
Sort<Collection> sort = default,
|
||||||
|
Pagination limit = default)
|
||||||
|
{
|
||||||
|
ICollection<Collection> collections = await ApplyFilters(_database.LibraryLinks
|
||||||
|
.Where(x => x.LibraryID == id && x.CollectionID != null)
|
||||||
|
.Select(x => x.Collection),
|
||||||
|
where,
|
||||||
|
sort,
|
||||||
|
limit);
|
||||||
|
if (!collections.Any() && await _libraries.Value.Get(id) == null)
|
||||||
|
throw new ItemNotFound();
|
||||||
|
return collections;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Collection>> GetFromLibrary(string slug,
|
||||||
|
Expression<Func<Collection, bool>> where = null,
|
||||||
|
Sort<Collection> sort = default,
|
||||||
|
Pagination limit = default)
|
||||||
|
{
|
||||||
|
ICollection<Collection> collections = await ApplyFilters(_database.LibraryLinks
|
||||||
|
.Where(x => x.Library.Slug == slug && x.CollectionID != null)
|
||||||
|
.Select(x => x.Collection),
|
||||||
|
where,
|
||||||
|
sort,
|
||||||
|
limit);
|
||||||
|
if (!collections.Any() && await _libraries.Value.Get(slug) == null)
|
||||||
|
throw new ItemNotFound();
|
||||||
|
return collections;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -78,6 +78,13 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
protected override async Task Validate(Library obj)
|
protected override async Task Validate(Library obj)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(obj.Slug))
|
||||||
|
throw new ArgumentException("The library's slug must be set and not empty");
|
||||||
|
if (string.IsNullOrEmpty(obj.Name))
|
||||||
|
throw new ArgumentException("The library's name must be set and not empty");
|
||||||
|
if (obj.Paths == null || !obj.Paths.Any())
|
||||||
|
throw new ArgumentException("The library should have a least one path.");
|
||||||
|
|
||||||
if (obj.ProviderLinks != null)
|
if (obj.ProviderLinks != null)
|
||||||
foreach (ProviderLink link in obj.ProviderLinks)
|
foreach (ProviderLink link in obj.ProviderLinks)
|
||||||
link.Provider = await _providers.CreateIfNotExists(link.Provider);
|
link.Provider = await _providers.CreateIfNotExists(link.Provider);
|
||||||
|
@ -19,6 +19,8 @@ namespace Kyoo.Controllers
|
|||||||
private readonly IProviderRepository _providers;
|
private readonly IProviderRepository _providers;
|
||||||
private readonly Lazy<ISeasonRepository> _seasons;
|
private readonly Lazy<ISeasonRepository> _seasons;
|
||||||
private readonly Lazy<IEpisodeRepository> _episodes;
|
private readonly Lazy<IEpisodeRepository> _episodes;
|
||||||
|
private readonly Lazy<ILibraryRepository> _libraries;
|
||||||
|
private readonly Lazy<ICollectionRepository> _collections;
|
||||||
protected override Expression<Func<Show, object>> DefaultSort => x => x.Title;
|
protected override Expression<Func<Show, object>> DefaultSort => x => x.Title;
|
||||||
|
|
||||||
public ShowRepository(DatabaseContext database,
|
public ShowRepository(DatabaseContext database,
|
||||||
@ -36,6 +38,8 @@ namespace Kyoo.Controllers
|
|||||||
_providers = providers;
|
_providers = providers;
|
||||||
_seasons = new Lazy<ISeasonRepository>(services.GetRequiredService<ISeasonRepository>);
|
_seasons = new Lazy<ISeasonRepository>(services.GetRequiredService<ISeasonRepository>);
|
||||||
_episodes = new Lazy<IEpisodeRepository>(services.GetRequiredService<IEpisodeRepository>);
|
_episodes = new Lazy<IEpisodeRepository>(services.GetRequiredService<IEpisodeRepository>);
|
||||||
|
_libraries = new Lazy<ILibraryRepository>(services.GetRequiredService<ILibraryRepository>);
|
||||||
|
_collections = new Lazy<ICollectionRepository>(services.GetRequiredService<ICollectionRepository>);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
@ -49,6 +53,10 @@ namespace Kyoo.Controllers
|
|||||||
_seasons.Value.Dispose();
|
_seasons.Value.Dispose();
|
||||||
if (_episodes.IsValueCreated)
|
if (_episodes.IsValueCreated)
|
||||||
_episodes.Value.Dispose();
|
_episodes.Value.Dispose();
|
||||||
|
if (_libraries.IsValueCreated)
|
||||||
|
_libraries.Value.Dispose();
|
||||||
|
if (_collections.IsValueCreated)
|
||||||
|
_collections.Value.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async ValueTask DisposeAsync()
|
public override async ValueTask DisposeAsync()
|
||||||
@ -62,6 +70,10 @@ namespace Kyoo.Controllers
|
|||||||
await _seasons.Value.DisposeAsync();
|
await _seasons.Value.DisposeAsync();
|
||||||
if (_episodes.IsValueCreated)
|
if (_episodes.IsValueCreated)
|
||||||
await _episodes.Value.DisposeAsync();
|
await _episodes.Value.DisposeAsync();
|
||||||
|
if (_libraries.IsValueCreated)
|
||||||
|
await _libraries.Value.DisposeAsync();
|
||||||
|
if (_collections.IsValueCreated)
|
||||||
|
await _collections.Value.DisposeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<ICollection<Show>> Search(string query)
|
public override async Task<ICollection<Show>> Search(string query)
|
||||||
@ -181,5 +193,37 @@ namespace Kyoo.Controllers
|
|||||||
if (obj.Episodes != null)
|
if (obj.Episodes != null)
|
||||||
await _episodes.Value.DeleteRange(obj.Episodes);
|
await _episodes.Value.DeleteRange(obj.Episodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Show>> GetFromLibrary(int id,
|
||||||
|
Expression<Func<Show, bool>> where = null,
|
||||||
|
Sort<Show> sort = default,
|
||||||
|
Pagination limit = default)
|
||||||
|
{
|
||||||
|
ICollection<Show> shows = await ApplyFilters(_database.LibraryLinks
|
||||||
|
.Where(x => x.LibraryID == id && x.ShowID != null)
|
||||||
|
.Select(x => x.Show),
|
||||||
|
where,
|
||||||
|
sort,
|
||||||
|
limit);
|
||||||
|
if (!shows.Any() && await _libraries.Value.Get(id) == null)
|
||||||
|
throw new ItemNotFound();
|
||||||
|
return shows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Show>> GetFromLibrary(string slug,
|
||||||
|
Expression<Func<Show, bool>> where = null,
|
||||||
|
Sort<Show> sort = default,
|
||||||
|
Pagination limit = default)
|
||||||
|
{
|
||||||
|
ICollection<Show> shows = await ApplyFilters(_database.LibraryLinks
|
||||||
|
.Where(x => x.Library.Slug == slug && x.ShowID != null)
|
||||||
|
.Select(x => x.Show),
|
||||||
|
where,
|
||||||
|
sort,
|
||||||
|
limit);
|
||||||
|
if (!shows.Any() && await _libraries.Value.Get(slug) == null)
|
||||||
|
throw new ItemNotFound();
|
||||||
|
return shows;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,63 +0,0 @@
|
|||||||
using Kyoo.Controllers;
|
|
||||||
using Kyoo.Models;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
|
|
||||||
namespace Kyoo.Api
|
|
||||||
{
|
|
||||||
[Route("api/libraries")]
|
|
||||||
[Route("api/library")]
|
|
||||||
[ApiController]
|
|
||||||
public class LibrariesAPI : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly ILibraryManager _libraryManager;
|
|
||||||
private readonly ITaskManager _taskManager;
|
|
||||||
|
|
||||||
public LibrariesAPI(ILibraryManager libraryManager, ITaskManager taskManager)
|
|
||||||
{
|
|
||||||
_libraryManager = libraryManager;
|
|
||||||
_taskManager = taskManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public async Task<IEnumerable<Library>> GetLibraries()
|
|
||||||
{
|
|
||||||
return await _libraryManager.GetLibraries();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Route("/api/library/create")]
|
|
||||||
[HttpPost]
|
|
||||||
[Authorize(Policy="Admin")]
|
|
||||||
public async Task<IActionResult> CreateLibrary([FromBody] Library library)
|
|
||||||
{
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(library);
|
|
||||||
if (string.IsNullOrEmpty(library.Slug))
|
|
||||||
return BadRequest(new {error = "The library's slug must be set and not empty"});
|
|
||||||
if (string.IsNullOrEmpty(library.Name))
|
|
||||||
return BadRequest(new {error = "The library's name must be set and not empty"});
|
|
||||||
if (library.Paths == null || !library.Paths.Any())
|
|
||||||
return BadRequest(new {error = "The library should have a least one path."});
|
|
||||||
if (await _libraryManager.GetLibrary(library.Slug) != null)
|
|
||||||
return BadRequest(new {error = "Duplicated library slug"});
|
|
||||||
await _libraryManager.RegisterLibrary(library);
|
|
||||||
_taskManager.StartTask("scan", library.Slug);
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("{librarySlug}")]
|
|
||||||
[Authorize(Policy="Read")]
|
|
||||||
public async Task<ActionResult<IEnumerable<Show>>> GetShows(string librarySlug)
|
|
||||||
{
|
|
||||||
Library library = await _libraryManager.GetLibrary(librarySlug);
|
|
||||||
|
|
||||||
if (library == null)
|
|
||||||
return NotFound();
|
|
||||||
|
|
||||||
return library.Shows.Concat(library.Collections.Select(x => x.AsShow())).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
236
Kyoo/Views/API/LibrariesApi.cs
Normal file
236
Kyoo/Views/API/LibrariesApi.cs
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Kyoo.Controllers;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.CommonApi;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
|
namespace Kyoo.Api
|
||||||
|
{
|
||||||
|
[Route("api/library")]
|
||||||
|
[Route("api/libraries")]
|
||||||
|
[ApiController]
|
||||||
|
public class LibrariesAPI : CrudApi<Library>
|
||||||
|
{
|
||||||
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
private readonly ITaskManager _taskManager;
|
||||||
|
|
||||||
|
public LibrariesAPI(ILibraryManager libraryManager, ITaskManager taskManager, IConfiguration configuration)
|
||||||
|
: base(libraryManager.LibraryRepository, configuration)
|
||||||
|
{
|
||||||
|
_libraryManager = libraryManager;
|
||||||
|
_taskManager = taskManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(Policy = "Admin")]
|
||||||
|
public override async Task<ActionResult<Library>> Create(Library ressource)
|
||||||
|
{
|
||||||
|
ActionResult<Library> result = await base.Create(ressource);
|
||||||
|
if (result.Value != null)
|
||||||
|
_taskManager.StartTask("scan", result.Value.Slug);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id:int}/show")]
|
||||||
|
[HttpGet("{id:int}/shows")]
|
||||||
|
[Authorize(Policy = "Read")]
|
||||||
|
public async Task<ActionResult<Page<Show>>> GetShows(int id,
|
||||||
|
[FromQuery] string sortBy,
|
||||||
|
[FromQuery] int afterID,
|
||||||
|
[FromQuery] Dictionary<string, string> where,
|
||||||
|
[FromQuery] int limit = 50)
|
||||||
|
{
|
||||||
|
where.Remove("id");
|
||||||
|
where.Remove("sortBy");
|
||||||
|
where.Remove("limit");
|
||||||
|
where.Remove("afterID");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ICollection<Show> ressources = await _libraryManager.GetShowsFromLibrary(id,
|
||||||
|
ApiHelper.ParseWhere<Show>(where),
|
||||||
|
new Sort<Show>(sortBy),
|
||||||
|
new Pagination(limit, afterID));
|
||||||
|
|
||||||
|
return Page(ressources, limit);
|
||||||
|
}
|
||||||
|
catch (ItemNotFound)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new {Error = ex.Message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{slug}/show")]
|
||||||
|
[HttpGet("{slug}/shows")]
|
||||||
|
[Authorize(Policy = "Read")]
|
||||||
|
public async Task<ActionResult<Page<Show>>> GetShows(string slug,
|
||||||
|
[FromQuery] string sortBy,
|
||||||
|
[FromQuery] int afterID,
|
||||||
|
[FromQuery] Dictionary<string, string> where,
|
||||||
|
[FromQuery] int limit = 20)
|
||||||
|
{
|
||||||
|
where.Remove("slug");
|
||||||
|
where.Remove("sortBy");
|
||||||
|
where.Remove("limit");
|
||||||
|
where.Remove("afterID");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ICollection<Show> ressources = await _libraryManager.GetShowsFromLibrary(slug,
|
||||||
|
ApiHelper.ParseWhere<Show>(where),
|
||||||
|
new Sort<Show>(sortBy),
|
||||||
|
new Pagination(limit, afterID));
|
||||||
|
|
||||||
|
return Page(ressources, limit);
|
||||||
|
}
|
||||||
|
catch (ItemNotFound)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new {Error = ex.Message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id:int}/collection")]
|
||||||
|
[HttpGet("{id:int}/collections")]
|
||||||
|
[Authorize(Policy = "Read")]
|
||||||
|
public async Task<ActionResult<Page<Collection>>> GetCollections(int id,
|
||||||
|
[FromQuery] string sortBy,
|
||||||
|
[FromQuery] int afterID,
|
||||||
|
[FromQuery] Dictionary<string, string> where,
|
||||||
|
[FromQuery] int limit = 50)
|
||||||
|
{
|
||||||
|
where.Remove("id");
|
||||||
|
where.Remove("sortBy");
|
||||||
|
where.Remove("limit");
|
||||||
|
where.Remove("afterID");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ICollection<Collection> ressources = await _libraryManager.GetCollectionsFromLibrary(id,
|
||||||
|
ApiHelper.ParseWhere<Collection>(where),
|
||||||
|
new Sort<Collection>(sortBy),
|
||||||
|
new Pagination(limit, afterID));
|
||||||
|
|
||||||
|
return Page(ressources, limit);
|
||||||
|
}
|
||||||
|
catch (ItemNotFound)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new {Error = ex.Message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{slug}/collection")]
|
||||||
|
[HttpGet("{slug}/collections")]
|
||||||
|
[Authorize(Policy = "Read")]
|
||||||
|
public async Task<ActionResult<Page<Collection>>> GetCollections(string slug,
|
||||||
|
[FromQuery] string sortBy,
|
||||||
|
[FromQuery] int afterID,
|
||||||
|
[FromQuery] Dictionary<string, string> where,
|
||||||
|
[FromQuery] int limit = 20)
|
||||||
|
{
|
||||||
|
where.Remove("slug");
|
||||||
|
where.Remove("sortBy");
|
||||||
|
where.Remove("limit");
|
||||||
|
where.Remove("afterID");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ICollection<Collection> ressources = await _libraryManager.GetCollectionsFromLibrary(slug,
|
||||||
|
ApiHelper.ParseWhere<Collection>(where),
|
||||||
|
new Sort<Collection>(sortBy),
|
||||||
|
new Pagination(limit, afterID));
|
||||||
|
|
||||||
|
return Page(ressources, limit);
|
||||||
|
}
|
||||||
|
catch (ItemNotFound)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new {Error = ex.Message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// [HttpGet("{id:int}/item")]
|
||||||
|
// [HttpGet("{id:int}/items")]
|
||||||
|
// [Authorize(Policy = "Read")]
|
||||||
|
// public async Task<ActionResult<Page<Collection>>> GetItems(int id,
|
||||||
|
// [FromQuery] string sortBy,
|
||||||
|
// [FromQuery] int afterID,
|
||||||
|
// [FromQuery] Dictionary<string, string> where,
|
||||||
|
// [FromQuery] int limit = 50)
|
||||||
|
// {
|
||||||
|
// where.Remove("id");
|
||||||
|
// where.Remove("sortBy");
|
||||||
|
// where.Remove("limit");
|
||||||
|
// where.Remove("afterID");
|
||||||
|
//
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// ICollection<Collection> ressources = await _libraryManager.GetItemsFromLibrary(id,
|
||||||
|
// ApiHelper.ParseWhere<Collection>(where),
|
||||||
|
// new Sort<Collection>(sortBy),
|
||||||
|
// new Pagination(limit, afterID));
|
||||||
|
//
|
||||||
|
// return Page(ressources, limit);
|
||||||
|
// }
|
||||||
|
// catch (ItemNotFound)
|
||||||
|
// {
|
||||||
|
// return NotFound();
|
||||||
|
// }
|
||||||
|
// catch (ArgumentException ex)
|
||||||
|
// {
|
||||||
|
// return BadRequest(new {Error = ex.Message});
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// [HttpGet("{slug}/collection")]
|
||||||
|
// [HttpGet("{slug}/collections")]
|
||||||
|
// [Authorize(Policy = "Read")]
|
||||||
|
// public async Task<ActionResult<Page<Collection>>> GetCollections(string slug,
|
||||||
|
// [FromQuery] string sortBy,
|
||||||
|
// [FromQuery] int afterID,
|
||||||
|
// [FromQuery] Dictionary<string, string> where,
|
||||||
|
// [FromQuery] int limit = 20)
|
||||||
|
// {
|
||||||
|
// where.Remove("slug");
|
||||||
|
// where.Remove("sortBy");
|
||||||
|
// where.Remove("limit");
|
||||||
|
// where.Remove("afterID");
|
||||||
|
//
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// ICollection<Collection> ressources = await _libraryManager.GetCollectionsFromLibrary(slug,
|
||||||
|
// ApiHelper.ParseWhere<Collection>(where),
|
||||||
|
// new Sort<Collection>(sortBy),
|
||||||
|
// new Pagination(limit, afterID));
|
||||||
|
//
|
||||||
|
// return Page(ressources, limit);
|
||||||
|
// }
|
||||||
|
// catch (ItemNotFound)
|
||||||
|
// {
|
||||||
|
// return NotFound();
|
||||||
|
// }
|
||||||
|
// catch (ArgumentException ex)
|
||||||
|
// {
|
||||||
|
// return BadRequest(new {Error = ex.Message});
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,7 @@ namespace Kyoo.Api
|
|||||||
{
|
{
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
public ShowsApi(ILibraryManager libraryManager,
|
public ShowsApi(ILibraryManager libraryManager, IConfiguration configuration)
|
||||||
IConfiguration configuration)
|
|
||||||
: base(libraryManager.ShowRepository, configuration)
|
: base(libraryManager.ShowRepository, configuration)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
@ -33,5 +33,5 @@
|
|||||||
"plugins": "plugins/",
|
"plugins": "plugins/",
|
||||||
"defaultPermissions": "read,play,write,admin",
|
"defaultPermissions": "read,play,write,admin",
|
||||||
"newUserPermissions": "read,play,write,admin",
|
"newUserPermissions": "read,play,write,admin",
|
||||||
"regex": "(?:\\/(?<Collection>.*?))?\\/(?<Show>.*)(?: \\(\\d+\\))?\\/\\k<Show>(?: \\(\\d+\\))?(?:(?: S(?<Season>\\d+)E(?<Episode>\\d+))| (?<Absolute>\\d+))?.*$"
|
"regex": "(?:\\/(?<Collection>.*?))?\\/(?<Show>.*?)(?: \\(\\d+\\))?\\/\\k<Show>(?: \\(\\d+\\))?(?:(?: S(?<Season>\\d+)E(?<Episode>\\d+))| (?<Absolute>\\d+))?.*$"
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user