diff --git a/Kyoo.Common/Controllers/ILibraryManager.cs b/Kyoo.Common/Controllers/ILibraryManager.cs index c28daa61..aac86eff 100644 --- a/Kyoo.Common/Controllers/ILibraryManager.cs +++ b/Kyoo.Common/Controllers/ILibraryManager.cs @@ -128,6 +128,26 @@ namespace Kyoo.Controllers Expression> sort, Pagination limit = default ) => GetPeopleFromShow(showSlug, where, new Sort(sort), limit); + + Task> GetGenresFromShow(int showID, + Expression> where = null, + Sort sort = default, + Pagination limit = default); + Task> GetGenresFromShow(int showID, + [Optional] Expression> where, + Expression> sort, + Pagination limit = default + ) => GetGenresFromShow(showID, where, new Sort(sort), limit); + + Task> GetGenresFromShow(string showSlug, + Expression> where = null, + Sort sort = default, + Pagination limit = default); + Task> GetGenresFromShow(string showSlug, + [Optional] Expression> where, + Expression> sort, + Pagination limit = default + ) => GetGenresFromShow(showSlug, where, new Sort(sort), limit); // Helpers diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Common/Controllers/IRepository.cs index d72908d2..1034c947 100644 --- a/Kyoo.Common/Controllers/IRepository.cs +++ b/Kyoo.Common/Controllers/IRepository.cs @@ -195,7 +195,29 @@ namespace Kyoo.Controllers } public interface ILibraryRepository : IRepository {} public interface ICollectionRepository : IRepository {} - public interface IGenreRepository : IRepository {} + + public interface IGenreRepository : IRepository + { + Task> GetFromShow(int showID, + Expression> where = null, + Sort sort = default, + Pagination limit = default); + Task> GetFromShow(int showID, + [Optional] Expression> where, + Expression> sort, + Pagination limit = default + ) => GetFromShow(showID, where, new Sort(sort), limit); + + Task> GetFromShow(string showSlug, + Expression> where = null, + Sort sort = default, + Pagination limit = default); + Task> GetFromShow(string showSlug, + [Optional] Expression> where, + Expression> sort, + Pagination limit = default + ) => GetFromShow(showSlug, where, new Sort(sort), limit); + } public interface IStudioRepository : IRepository {} public interface IPeopleRepository : IRepository diff --git a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs index b46028ee..c0968952 100644 --- a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs +++ b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs @@ -271,6 +271,22 @@ namespace Kyoo.Controllers return PeopleRepository.GetFromShow(showSlug, where, sort, limit); } + public Task> GetGenresFromShow(int showID, + Expression> where = null, + Sort sort = default, + Pagination limit = default) + { + return GenreRepository.GetFromShow(showID, where, sort, limit); + } + + public Task> GetGenresFromShow(string showSlug, + Expression> where = null, + Sort sort = default, + Pagination limit = default) + { + return GenreRepository.GetFromShow(showSlug, where, sort, limit); + } + public Task AddShowLink(int showID, int? libraryID, int? collectionID) { return ShowRepository.AddShowLink(showID, libraryID, collectionID); diff --git a/Kyoo/Controllers/Repositories/GenreRepository.cs b/Kyoo/Controllers/Repositories/GenreRepository.cs index dc891283..982fad76 100644 --- a/Kyoo/Controllers/Repositories/GenreRepository.cs +++ b/Kyoo/Controllers/Repositories/GenreRepository.cs @@ -6,18 +6,21 @@ using System.Threading.Tasks; using Kyoo.Models; using Kyoo.Models.Exceptions; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; namespace Kyoo.Controllers { public class GenreRepository : LocalRepository, IGenreRepository { private readonly DatabaseContext _database; + private readonly Lazy _shows; protected override Expression> DefaultSort => x => x.Slug; - public GenreRepository(DatabaseContext database) : base(database) + public GenreRepository(DatabaseContext database, IServiceProvider services) : base(database) { _database = database; + _shows = new Lazy(services.GetRequiredService); } @@ -68,5 +71,35 @@ namespace Kyoo.Controllers _database.Entry(link).State = EntityState.Deleted; await _database.SaveChangesAsync(); } + + public async Task> GetFromShow(int showID, + Expression> where = null, + Sort sort = default, + Pagination limit = default) + { + ICollection genres = await ApplyFilters(_database.GenreLinks.Where(x => x.ShowID == showID) + .Select(x => x.Genre), + where, + sort, + limit); + if (!genres.Any() && await _shows.Value.Get(showID) == null) + throw new ItemNotFound(); + return genres; + } + + public async Task> GetFromShow(string showSlug, + Expression> where = null, + Sort sort = default, + Pagination limit = default) + { + ICollection genres = await ApplyFilters(_database.GenreLinks.Where(x => x.Show.Slug == showSlug) + .Select(x => x.Genre), + where, + sort, + limit); + if (!genres.Any() && await _shows.Value.Get(showSlug) == null) + throw new ItemNotFound(); + return genres; + } } } \ No newline at end of file diff --git a/Kyoo/Views/API/ShowsApi.cs b/Kyoo/Views/API/ShowsApi.cs index f04973df..29c76071 100644 --- a/Kyoo/Views/API/ShowsApi.cs +++ b/Kyoo/Views/API/ShowsApi.cs @@ -220,5 +220,71 @@ namespace Kyoo.Api return BadRequest(new {Error = ex.Message}); } } + + [HttpGet("{showID:int}/genre")] + [HttpGet("{showID:int}/genres")] + [Authorize(Policy = "Read")] + public async Task>> GetGenres(int showID, + [FromQuery] string sortBy, + [FromQuery] int afterID, + [FromQuery] Dictionary where, + [FromQuery] int limit = 30) + { + where.Remove("showID"); + where.Remove("sortBy"); + where.Remove("limit"); + where.Remove("afterID"); + + try + { + ICollection ressources = await _libraryManager.GetGenresFromShow(showID, + ApiHelper.ParseWhere(where), + new Sort(sortBy), + new Pagination(limit, afterID)); + + return Page(ressources, limit); + } + catch (ItemNotFound) + { + return NotFound(); + } + catch (ArgumentException ex) + { + return BadRequest(new {Error = ex.Message}); + } + } + + [HttpGet("{slug}/genre")] + [HttpGet("{slug}/genres")] + [Authorize(Policy = "Read")] + public async Task>> GetGenre(string slug, + [FromQuery] string sortBy, + [FromQuery] int afterID, + [FromQuery] Dictionary where, + [FromQuery] int limit = 30) + { + where.Remove("slug"); + where.Remove("sortBy"); + where.Remove("limit"); + where.Remove("afterID"); + + try + { + ICollection ressources = await _libraryManager.GetGenresFromShow(slug, + ApiHelper.ParseWhere(where), + new Sort(sortBy), + new Pagination(limit, afterID)); + + return Page(ressources, limit); + } + catch (ItemNotFound) + { + return NotFound(); + } + catch (ArgumentException ex) + { + return BadRequest(new {Error = ex.Message}); + } + } } }