diff --git a/Kyoo.Common/Controllers/ILibraryManager.cs b/Kyoo.Common/Controllers/ILibraryManager.cs index 232c1cdb..33d65c42 100644 --- a/Kyoo.Common/Controllers/ILibraryManager.cs +++ b/Kyoo.Common/Controllers/ILibraryManager.cs @@ -10,6 +10,18 @@ namespace Kyoo.Controllers { public interface ILibraryManager : IDisposable, IAsyncDisposable { + // Repositories + ILibraryRepository LibraryRepository { get; } + ICollectionRepository CollectionRepository { get; } + IShowRepository ShowRepository { get; } + ISeasonRepository SeasonRepository { get; } + IEpisodeRepository EpisodeRepository { get; } + ITrackRepository TrackRepository { get; } + IPeopleRepository PeopleRepository { get; } + IStudioRepository StudioRepository { get; } + IGenreRepository GenreRepository { get; } + IProviderRepository ProviderRepository { get; } + // Get by slug Task GetLibrary(string slug); Task GetCollection(string slug); @@ -24,8 +36,24 @@ namespace Kyoo.Controllers Task GetPeople(string slug); // Get by relations - Task> GetSeasons(int showID); - Task> GetSeasons(string showSlug); + Task> GetSeasons(int showID, + Expression> where = null, + Sort sort = default, + Pagination limit = default); + Task> GetSeasons(int showID, + [Optional] Expression> where, + Expression> sort, + Pagination limit = default + ) => GetSeasons(showID, where, new Sort(sort), limit); + Task> GetSeasons(string showSlug, + Expression> where = null, + Sort sort = default, + Pagination limit = default); + Task> GetSeasons(string showSlug, + [Optional] Expression> where, + Expression> sort, + Pagination limit = default + ) => GetSeasons(showSlug, where, new Sort(sort), limit); Task> GetEpisodes(int showID, int seasonNumber); Task> GetEpisodes(string showSlug, int seasonNumber); diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Common/Controllers/IRepository.cs index 54bcb678..2c971a13 100644 --- a/Kyoo.Common/Controllers/IRepository.cs +++ b/Kyoo.Common/Controllers/IRepository.cs @@ -109,8 +109,26 @@ namespace Kyoo.Controllers Task Get(string showSlug, int seasonNumber); Task Delete(string showSlug, int seasonNumber); - Task> GetSeasons(int showID); - Task> GetSeasons(string showSlug); + Task> GetSeasons(int showID, + Expression> where = null, + Sort sort = default, + Pagination limit = default); + Task> GetSeasons(int showID, + [Optional] Expression> where, + Expression> sort, + Pagination limit = default + ) => GetSeasons(showID, where, new Sort(sort), limit); + + Task> GetSeasons(string showSlug, + Expression> where = null, + Sort sort = default, + Pagination limit = default); + Task> GetSeasons(string showSlug, + [Optional] Expression> where, + Expression> sort, + Pagination limit = default + ) => GetSeasons(showSlug, where, new Sort(sort), limit); + } public interface IEpisodeRepository : IRepository diff --git a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs index cd3f080d..6956100c 100644 --- a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs +++ b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs @@ -8,223 +8,229 @@ namespace Kyoo.Controllers { public class LibraryManager : ILibraryManager { - private readonly ILibraryRepository _libraries; - private readonly ICollectionRepository _collections; - private readonly IShowRepository _shows; - private readonly ISeasonRepository _seasons; - private readonly IEpisodeRepository _episodes; - private readonly ITrackRepository _tracks; - private readonly IGenreRepository _genres; - private readonly IStudioRepository _studios; - private readonly IPeopleRepository _people; - private readonly IProviderRepository _providers; + public ILibraryRepository LibraryRepository { get; } + public ICollectionRepository CollectionRepository { get; } + public IShowRepository ShowRepository { get; } + public ISeasonRepository SeasonRepository { get; } + public IEpisodeRepository EpisodeRepository { get; } + public ITrackRepository TrackRepository { get; } + public IGenreRepository GenreRepository { get; } + public IStudioRepository StudioRepository { get; } + public IPeopleRepository PeopleRepository { get; } + public IProviderRepository ProviderRepository { get; } - public LibraryManager(ILibraryRepository libraries, - ICollectionRepository collections, - IShowRepository shows, - ISeasonRepository seasons, - IEpisodeRepository episodes, - ITrackRepository tracks, - IGenreRepository genres, - IStudioRepository studios, - IProviderRepository providers, - IPeopleRepository people) + public LibraryManager(ILibraryRepository libraryRepository, + ICollectionRepository collectionRepository, + IShowRepository showRepository, + ISeasonRepository seasonRepository, + IEpisodeRepository episodeRepository, + ITrackRepository trackRepository, + IGenreRepository genreRepository, + IStudioRepository studioRepository, + IProviderRepository providerRepository, + IPeopleRepository peopleRepository) { - _libraries = libraries; - _collections = collections; - _shows = shows; - _seasons = seasons; - _episodes = episodes; - _tracks = tracks; - _genres = genres; - _studios = studios; - _providers = providers; - _people = people; + LibraryRepository = libraryRepository; + CollectionRepository = collectionRepository; + ShowRepository = showRepository; + SeasonRepository = seasonRepository; + EpisodeRepository = episodeRepository; + TrackRepository = trackRepository; + GenreRepository = genreRepository; + StudioRepository = studioRepository; + ProviderRepository = providerRepository; + PeopleRepository = peopleRepository; } public void Dispose() { - _libraries.Dispose(); - _collections.Dispose(); - _shows.Dispose(); - _seasons.Dispose(); - _episodes.Dispose(); - _tracks.Dispose(); - _genres.Dispose(); - _studios.Dispose(); - _people.Dispose(); - _providers.Dispose(); + LibraryRepository.Dispose(); + CollectionRepository.Dispose(); + ShowRepository.Dispose(); + SeasonRepository.Dispose(); + EpisodeRepository.Dispose(); + TrackRepository.Dispose(); + GenreRepository.Dispose(); + StudioRepository.Dispose(); + PeopleRepository.Dispose(); + ProviderRepository.Dispose(); } public async ValueTask DisposeAsync() { await Task.WhenAll( - _libraries.DisposeAsync().AsTask(), - _collections.DisposeAsync().AsTask(), - _shows.DisposeAsync().AsTask(), - _seasons.DisposeAsync().AsTask(), - _episodes.DisposeAsync().AsTask(), - _tracks.DisposeAsync().AsTask(), - _genres.DisposeAsync().AsTask(), - _studios.DisposeAsync().AsTask(), - _people.DisposeAsync().AsTask(), - _providers.DisposeAsync().AsTask() + LibraryRepository.DisposeAsync().AsTask(), + CollectionRepository.DisposeAsync().AsTask(), + ShowRepository.DisposeAsync().AsTask(), + SeasonRepository.DisposeAsync().AsTask(), + EpisodeRepository.DisposeAsync().AsTask(), + TrackRepository.DisposeAsync().AsTask(), + GenreRepository.DisposeAsync().AsTask(), + StudioRepository.DisposeAsync().AsTask(), + PeopleRepository.DisposeAsync().AsTask(), + ProviderRepository.DisposeAsync().AsTask() ); } public Task GetLibrary(string slug) { - return _libraries.Get(slug); + return LibraryRepository.Get(slug); } public Task GetCollection(string slug) { - return _collections.Get(slug); + return CollectionRepository.Get(slug); } public Task GetShow(string slug) { - return _shows.Get(slug); + return ShowRepository.Get(slug); } public Task GetSeason(string showSlug, int seasonNumber) { - return _seasons.Get(showSlug, seasonNumber); + return SeasonRepository.Get(showSlug, seasonNumber); } public Task GetEpisode(string showSlug, int seasonNumber, int episodeNumber) { - return _episodes.Get(showSlug, seasonNumber, episodeNumber); + return EpisodeRepository.Get(showSlug, seasonNumber, episodeNumber); } public Task GetMovieEpisode(string movieSlug) { - return _episodes.Get(movieSlug); + return EpisodeRepository.Get(movieSlug); } public Task GetTrack(int id) { - return _tracks.Get(id); + return TrackRepository.Get(id); } public Task GetTrack(int episodeID, string language, bool isForced) { - return _tracks.Get(episodeID, language, isForced); + return TrackRepository.Get(episodeID, language, isForced); } public Task GetGenre(string slug) { - return _genres.Get(slug); + return GenreRepository.Get(slug); } public Task GetStudio(string slug) { - return _studios.Get(slug); + return StudioRepository.Get(slug); } public Task GetPeople(string slug) { - return _people.Get(slug); + return PeopleRepository.Get(slug); } public Task> GetLibraries(Expression> where = null, Sort sort = default, Pagination page = default) { - return _libraries.GetAll(where, sort, page); + return LibraryRepository.GetAll(where, sort, page); } public Task> GetCollections(Expression> where = null, Sort sort = default, Pagination page = default) { - return _collections.GetAll(where, sort, page); + return CollectionRepository.GetAll(where, sort, page); } public Task> GetShows(Expression> where = null, Sort sort = default, Pagination limit = default) { - return _shows.GetAll(where, sort, limit); + return ShowRepository.GetAll(where, sort, limit); } public Task> GetSeasons(Expression> where = null, Sort sort = default, Pagination page = default) { - return _seasons.GetAll(where, sort, page); + return SeasonRepository.GetAll(where, sort, page); } public Task> GetEpisodes(Expression> where = null, Sort sort = default, Pagination page = default) { - return _episodes.GetAll(where, sort, page); + return EpisodeRepository.GetAll(where, sort, page); } public Task> GetTracks(Expression> where = null, Sort sort = default, Pagination page = default) { - return _tracks.GetAll(where, sort, page); + return TrackRepository.GetAll(where, sort, page); } public Task> GetStudios(Expression> where = null, Sort sort = default, Pagination page = default) { - return _studios.GetAll(where, sort, page); + return StudioRepository.GetAll(where, sort, page); } public Task> GetPeople(Expression> where = null, Sort sort = default, Pagination page = default) { - return _people.GetAll(where, sort, page); + return PeopleRepository.GetAll(where, sort, page); } public Task> GetGenres(Expression> where = null, Sort sort = default, Pagination page = default) { - return _genres.GetAll(where, sort, page); + return GenreRepository.GetAll(where, sort, page); } public Task> GetProviders(Expression> where = null, Sort sort = default, Pagination page = default) { - return _providers.GetAll(where, sort, page); + return ProviderRepository.GetAll(where, sort, page); } - public Task> GetSeasons(int showID) + public Task> GetSeasons(int showID, + Expression> where = null, + Sort sort = default, + Pagination limit = default) { - return _seasons.GetSeasons(showID); + return SeasonRepository.GetSeasons(showID, where, sort, limit); } - public Task> GetSeasons(string showSlug) + public Task> GetSeasons(string showSlug, + Expression> where = null, + Sort sort = default, + Pagination limit = default) { - return _seasons.GetSeasons(showSlug); + return SeasonRepository.GetSeasons(showSlug, where, sort, limit); } public Task> GetEpisodes(int showID, int seasonNumber) { - return _episodes.GetEpisodes(showID, seasonNumber); + return EpisodeRepository.GetEpisodes(showID, seasonNumber); } public Task> GetEpisodes(string showSlug, int seasonNumber) { - return _episodes.GetEpisodes(showSlug, seasonNumber); + return EpisodeRepository.GetEpisodes(showSlug, seasonNumber); } public Task> GetEpisodes(int seasonID) { - return _episodes.GetEpisodes(seasonID); + return EpisodeRepository.GetEpisodes(seasonID); } public Task AddShowLink(int showID, int? libraryID, int? collectionID) { - return _shows.AddShowLink(showID, libraryID, collectionID); + return ShowRepository.AddShowLink(showID, libraryID, collectionID); } public Task AddShowLink(Show show, Library library, Collection collection) @@ -236,267 +242,267 @@ namespace Kyoo.Controllers public Task> SearchLibraries(string searchQuery) { - return _libraries.Search(searchQuery); + return LibraryRepository.Search(searchQuery); } public Task> SearchCollections(string searchQuery) { - return _collections.Search(searchQuery); + return CollectionRepository.Search(searchQuery); } public Task> SearchShows(string searchQuery) { - return _shows.Search(searchQuery); + return ShowRepository.Search(searchQuery); } public Task> SearchSeasons(string searchQuery) { - return _seasons.Search(searchQuery); + return SeasonRepository.Search(searchQuery); } public Task> SearchEpisodes(string searchQuery) { - return _episodes.Search(searchQuery); + return EpisodeRepository.Search(searchQuery); } public Task> SearchGenres(string searchQuery) { - return _genres.Search(searchQuery); + return GenreRepository.Search(searchQuery); } public Task> SearchStudios(string searchQuery) { - return _studios.Search(searchQuery); + return StudioRepository.Search(searchQuery); } public Task> SearchPeople(string searchQuery) { - return _people.Search(searchQuery); + return PeopleRepository.Search(searchQuery); } public Task RegisterLibrary(Library library) { - return _libraries.Create(library); + return LibraryRepository.Create(library); } public Task RegisterCollection(Collection collection) { - return _collections.Create(collection); + return CollectionRepository.Create(collection); } public Task RegisterShow(Show show) { - return _shows.Create(show); + return ShowRepository.Create(show); } public Task RegisterSeason(Season season) { - return _seasons.Create(season); + return SeasonRepository.Create(season); } public Task RegisterEpisode(Episode episode) { - return _episodes.Create(episode); + return EpisodeRepository.Create(episode); } public Task RegisterTrack(Track track) { - return _tracks.Create(track); + return TrackRepository.Create(track); } public Task RegisterGenre(Genre genre) { - return _genres.Create(genre); + return GenreRepository.Create(genre); } public Task RegisterStudio(Studio studio) { - return _studios.Create(studio); + return StudioRepository.Create(studio); } public Task RegisterPeople(People people) { - return _people.Create(people); + return PeopleRepository.Create(people); } public Task EditLibrary(Library library, bool resetOld) { - return _libraries.Edit(library, resetOld); + return LibraryRepository.Edit(library, resetOld); } public Task EditCollection(Collection collection, bool resetOld) { - return _collections.Edit(collection, resetOld); + return CollectionRepository.Edit(collection, resetOld); } public Task EditShow(Show show, bool resetOld) { - return _shows.Edit(show, resetOld); + return ShowRepository.Edit(show, resetOld); } public Task EditSeason(Season season, bool resetOld) { - return _seasons.Edit(season, resetOld); + return SeasonRepository.Edit(season, resetOld); } public Task EditEpisode(Episode episode, bool resetOld) { - return _episodes.Edit(episode, resetOld); + return EpisodeRepository.Edit(episode, resetOld); } public Task EditTrack(Track track, bool resetOld) { - return _tracks.Edit(track, resetOld); + return TrackRepository.Edit(track, resetOld); } public Task EditGenre(Genre genre, bool resetOld) { - return _genres.Edit(genre, resetOld); + return GenreRepository.Edit(genre, resetOld); } public Task EditStudio(Studio studio, bool resetOld) { - return _studios.Edit(studio, resetOld); + return StudioRepository.Edit(studio, resetOld); } public Task EditPeople(People people, bool resetOld) { - return _people.Edit(people, resetOld); + return PeopleRepository.Edit(people, resetOld); } public Task DelteLibrary(Library library) { - return _libraries.Delete(library); + return LibraryRepository.Delete(library); } public Task DeleteCollection(Collection collection) { - return _collections.Delete(collection); + return CollectionRepository.Delete(collection); } public Task DeleteShow(Show show) { - return _shows.Delete(show); + return ShowRepository.Delete(show); } public Task DeleteSeason(Season season) { - return _seasons.Delete(season); + return SeasonRepository.Delete(season); } public Task DeleteEpisode(Episode episode) { - return _episodes.Delete(episode); + return EpisodeRepository.Delete(episode); } public Task DeleteTrack(Track track) { - return _tracks.Delete(track); + return TrackRepository.Delete(track); } public Task DeleteGenre(Genre genre) { - return _genres.Delete(genre); + return GenreRepository.Delete(genre); } public Task DeleteStudio(Studio studio) { - return _studios.Delete(studio); + return StudioRepository.Delete(studio); } public Task DeletePeople(People people) { - return _people.Delete(people); + return PeopleRepository.Delete(people); } public Task DelteLibrary(string library) { - return _libraries.Delete(library); + return LibraryRepository.Delete(library); } public Task DeleteCollection(string collection) { - return _collections.Delete(collection); + return CollectionRepository.Delete(collection); } public Task DeleteShow(string show) { - return _shows.Delete(show); + return ShowRepository.Delete(show); } public Task DeleteSeason(string season) { - return _seasons.Delete(season); + return SeasonRepository.Delete(season); } public Task DeleteEpisode(string episode) { - return _episodes.Delete(episode); + return EpisodeRepository.Delete(episode); } public Task DeleteTrack(string track) { - return _tracks.Delete(track); + return TrackRepository.Delete(track); } public Task DeleteGenre(string genre) { - return _genres.Delete(genre); + return GenreRepository.Delete(genre); } public Task DeleteStudio(string studio) { - return _studios.Delete(studio); + return StudioRepository.Delete(studio); } public Task DeletePeople(string people) { - return _people.Delete(people); + return PeopleRepository.Delete(people); } public Task DelteLibrary(int library) { - return _libraries.Delete(library); + return LibraryRepository.Delete(library); } public Task DeleteCollection(int collection) { - return _collections.Delete(collection); + return CollectionRepository.Delete(collection); } public Task DeleteShow(int show) { - return _shows.Delete(show); + return ShowRepository.Delete(show); } public Task DeleteSeason(int season) { - return _seasons.Delete(season); + return SeasonRepository.Delete(season); } public Task DeleteEpisode(int episode) { - return _episodes.Delete(episode); + return EpisodeRepository.Delete(episode); } public Task DeleteTrack(int track) { - return _tracks.Delete(track); + return TrackRepository.Delete(track); } public Task DeleteGenre(int genre) { - return _genres.Delete(genre); + return GenreRepository.Delete(genre); } public Task DeleteStudio(int studio) { - return _studios.Delete(studio); + return StudioRepository.Delete(studio); } public Task DeletePeople(int people) { - return _people.Delete(people); + return PeopleRepository.Delete(people); } } } diff --git a/Kyoo.Common/Models/Collection.cs b/Kyoo.Common/Models/Ressources/Collection.cs similarity index 100% rename from Kyoo.Common/Models/Collection.cs rename to Kyoo.Common/Models/Ressources/Collection.cs diff --git a/Kyoo.Common/Models/Episode.cs b/Kyoo.Common/Models/Ressources/Episode.cs similarity index 100% rename from Kyoo.Common/Models/Episode.cs rename to Kyoo.Common/Models/Ressources/Episode.cs diff --git a/Kyoo.Common/Models/Genre.cs b/Kyoo.Common/Models/Ressources/Genre.cs similarity index 100% rename from Kyoo.Common/Models/Genre.cs rename to Kyoo.Common/Models/Ressources/Genre.cs diff --git a/Kyoo.Common/Models/IRessource.cs b/Kyoo.Common/Models/Ressources/IRessource.cs similarity index 100% rename from Kyoo.Common/Models/IRessource.cs rename to Kyoo.Common/Models/Ressources/IRessource.cs diff --git a/Kyoo.Common/Models/Library.cs b/Kyoo.Common/Models/Ressources/Library.cs similarity index 100% rename from Kyoo.Common/Models/Library.cs rename to Kyoo.Common/Models/Ressources/Library.cs diff --git a/Kyoo.Common/Models/People.cs b/Kyoo.Common/Models/Ressources/People.cs similarity index 100% rename from Kyoo.Common/Models/People.cs rename to Kyoo.Common/Models/Ressources/People.cs diff --git a/Kyoo.Common/Models/ProviderID.cs b/Kyoo.Common/Models/Ressources/ProviderID.cs similarity index 100% rename from Kyoo.Common/Models/ProviderID.cs rename to Kyoo.Common/Models/Ressources/ProviderID.cs diff --git a/Kyoo.Common/Models/Season.cs b/Kyoo.Common/Models/Ressources/Season.cs similarity index 100% rename from Kyoo.Common/Models/Season.cs rename to Kyoo.Common/Models/Ressources/Season.cs diff --git a/Kyoo.Common/Models/Show.cs b/Kyoo.Common/Models/Ressources/Show.cs similarity index 100% rename from Kyoo.Common/Models/Show.cs rename to Kyoo.Common/Models/Ressources/Show.cs diff --git a/Kyoo.Common/Models/Studio.cs b/Kyoo.Common/Models/Ressources/Studio.cs similarity index 100% rename from Kyoo.Common/Models/Studio.cs rename to Kyoo.Common/Models/Ressources/Studio.cs diff --git a/Kyoo.Common/Models/Track.cs b/Kyoo.Common/Models/Ressources/Track.cs similarity index 100% rename from Kyoo.Common/Models/Track.cs rename to Kyoo.Common/Models/Ressources/Track.cs diff --git a/Kyoo.CommonAPI/CrudApi.cs b/Kyoo.CommonAPI/CrudApi.cs index 981b5d39..9ab38dce 100644 --- a/Kyoo.CommonAPI/CrudApi.cs +++ b/Kyoo.CommonAPI/CrudApi.cs @@ -1,12 +1,15 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; +using System.Runtime.InteropServices; using System.Threading.Tasks; using Kyoo.Controllers; using Kyoo.Models; using Kyoo.Models.Exceptions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Configuration; namespace Kyoo.CommonApi @@ -50,15 +53,13 @@ namespace Kyoo.CommonApi [HttpGet] [Authorize(Policy = "Read")] public async Task>> GetAll([FromQuery] string sortBy, - [FromQuery] int limit, [FromQuery] int afterID, - [FromQuery] Dictionary where) + [FromQuery] Dictionary where, + [FromQuery] int limit = 20) { where.Remove("sortBy"); where.Remove("limit"); where.Remove("afterID"); - if (limit == 0) - limit = 20; try { @@ -66,10 +67,7 @@ namespace Kyoo.CommonApi new Sort(sortBy), new Pagination(limit, afterID)); - return new Page(ressources, - _baseURL + Request.Path, - Request.Query.ToDictionary(x => x.Key, x => x.Value.ToString(), StringComparer.InvariantCultureIgnoreCase), - limit); + return Page(ressources, limit); } catch (ArgumentException ex) { @@ -77,6 +75,15 @@ namespace Kyoo.CommonApi } } + protected Page Page(ICollection ressources, int limit) + where TResult : IRessource + { + return new Page(ressources, + _baseURL + Request.Path, + Request.Query.ToDictionary(x => x.Key, x => x.Value.ToString(), StringComparer.InvariantCultureIgnoreCase), + limit); + } + [HttpPost] [Authorize(Policy = "Write")] public async Task> Create([FromBody] T ressource) @@ -91,6 +98,20 @@ namespace Kyoo.CommonApi return Conflict(existing); } } + + [HttpPut] + [Authorize(Policy = "Write")] + public async Task> Edit([FromQuery] bool resetOld, [FromBody] T ressource) + { + if (ressource.ID <= 0) + { + T old = await _repository.Get(ressource.Slug); + if (old == null) + return NotFound(); + ressource.ID = old.ID; + } + return await _repository.Edit(ressource, resetOld); + } [HttpPut("{id}")] [Authorize(Policy = "Write")] diff --git a/Kyoo.CommonAPI/Kyoo.CommonAPI.csproj b/Kyoo.CommonAPI/Kyoo.CommonAPI.csproj index 8e7ca25d..7bd6a5d4 100644 --- a/Kyoo.CommonAPI/Kyoo.CommonAPI.csproj +++ b/Kyoo.CommonAPI/Kyoo.CommonAPI.csproj @@ -6,6 +6,7 @@ Kyoo.CommonApi Kyoo.CommonApi AnonymusRaccoon + Library diff --git a/Kyoo.CommonAPI/LocalRepository.cs b/Kyoo.CommonAPI/LocalRepository.cs index 9356d6c3..555538ab 100644 --- a/Kyoo.CommonAPI/LocalRepository.cs +++ b/Kyoo.CommonAPI/LocalRepository.cs @@ -45,12 +45,18 @@ namespace Kyoo.Controllers public abstract Task> Search(string query); - public virtual async Task> GetAll(Expression> where = null, + public Task> GetAll(Expression> where = null, + Sort sort = default, + Pagination limit = default) + { + return ApplyFilters(_database.Set(), where, sort, limit); + } + + protected async Task> ApplyFilters(IQueryable query, + Expression> where = null, Sort sort = default, Pagination limit = default) { - IQueryable query = _database.Set(); - if (where != null) query = query.Where(where); diff --git a/Kyoo/Controllers/Repositories/SeasonRepository.cs b/Kyoo/Controllers/Repositories/SeasonRepository.cs index 8ecb92ad..2d9fc938 100644 --- a/Kyoo/Controllers/Repositories/SeasonRepository.cs +++ b/Kyoo/Controllers/Repositories/SeasonRepository.cs @@ -102,14 +102,26 @@ namespace Kyoo.Controllers } } - public async Task> GetSeasons(int showID) + public Task> GetSeasons(int showID, + Expression> where = null, + Sort sort = default, + Pagination limit = default) { - return await _database.Seasons.Where(x => x.ShowID == showID).ToListAsync(); + return ApplyFilters(_database.Seasons.Where(x => x.ShowID == showID), + where, + sort, + limit); } - public async Task> GetSeasons(string showSlug) + public Task> GetSeasons(string showSlug, + Expression> where = null, + Sort sort = default, + Pagination limit = default) { - return await _database.Seasons.Where(x => x.Show.Slug == showSlug).ToListAsync(); + return ApplyFilters(_database.Seasons.Where(x => x.Show.Slug == showSlug), + where, + sort, + limit); } public async Task Delete(string showSlug, int seasonNumber) diff --git a/Kyoo/Startup.cs b/Kyoo/Startup.cs index 06a578dd..4c3984b9 100644 --- a/Kyoo/Startup.cs +++ b/Kyoo/Startup.cs @@ -1,7 +1,7 @@ using System; using System.Reflection; using IdentityServer4.Services; -using Kyoo.API; +using Kyoo.Api; using Kyoo.Controllers; using Kyoo.Models; using Microsoft.AspNetCore.Authentication.JwtBearer; diff --git a/Kyoo/Views/API/AccountAPI.cs b/Kyoo/Views/API/AccountAPI.cs index aa30b5d6..80eea5f0 100644 --- a/Kyoo/Views/API/AccountAPI.cs +++ b/Kyoo/Views/API/AccountAPI.cs @@ -16,7 +16,7 @@ using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.Configuration; using SignInResult = Microsoft.AspNetCore.Identity.SignInResult; -namespace Kyoo.API +namespace Kyoo.Api { public class RegisterRequest { diff --git a/Kyoo/Views/API/CollectionAPI.cs b/Kyoo/Views/API/CollectionAPI.cs index 535fcc84..c4223e20 100644 --- a/Kyoo/Views/API/CollectionAPI.cs +++ b/Kyoo/Views/API/CollectionAPI.cs @@ -1,33 +1,20 @@ using Kyoo.Controllers; using Kyoo.Models; using Microsoft.AspNetCore.Mvc; -using System.Collections.Generic; using System.Threading.Tasks; +using Kyoo.CommonApi; using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Configuration; -namespace Kyoo.API +namespace Kyoo.Api { - [Route("api/[controller]")] + [Route("api/collection")] + [Route("api/collections")] [ApiController] - public class CollectionController : ControllerBase + public class CollectionApi : CrudApi { - private readonly ILibraryManager _libraryManager; - - public CollectionController(ILibraryManager libraryManager) - { - _libraryManager = libraryManager; - } - - [HttpGet("{collectionSlug}")] - [Authorize(Policy="Read")] - public async Task> GetShows(string collectionSlug) - { - Collection collection = await _libraryManager.GetCollection(collectionSlug); - - if (collection == null) - return NotFound(); - - return collection; - } + public CollectionApi(ICollectionRepository repository, IConfiguration configuration) + : base(repository, configuration) + { } } } \ No newline at end of file diff --git a/Kyoo/Views/API/EpisodesAPI.cs b/Kyoo/Views/API/EpisodesAPI.cs index fad605b1..abf0650d 100644 --- a/Kyoo/Views/API/EpisodesAPI.cs +++ b/Kyoo/Views/API/EpisodesAPI.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Kyoo.Controllers; using Microsoft.AspNetCore.Authorization; -namespace Kyoo.API +namespace Kyoo.Api { [Route("api/[controller]")] [ApiController] diff --git a/Kyoo/Views/API/GenresAPI.cs b/Kyoo/Views/API/GenresAPI.cs index 98d27e7f..118c4fcc 100644 --- a/Kyoo/Views/API/GenresAPI.cs +++ b/Kyoo/Views/API/GenresAPI.cs @@ -5,7 +5,7 @@ using Kyoo.Controllers; using Kyoo.Models; using Microsoft.AspNetCore.Mvc; -namespace Kyoo.API +namespace Kyoo.Api { [Route("api/genres")] [Route("api/genre")] diff --git a/Kyoo/Views/API/LibrariesAPI.cs b/Kyoo/Views/API/LibrariesAPI.cs index 4fe33cad..eeeee468 100644 --- a/Kyoo/Views/API/LibrariesAPI.cs +++ b/Kyoo/Views/API/LibrariesAPI.cs @@ -6,7 +6,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; -namespace Kyoo.API +namespace Kyoo.Api { [Route("api/libraries")] [Route("api/library")] diff --git a/Kyoo/Views/API/PeopleAPI.cs b/Kyoo/Views/API/PeopleAPI.cs index 59918418..ad27d8b9 100644 --- a/Kyoo/Views/API/PeopleAPI.cs +++ b/Kyoo/Views/API/PeopleAPI.cs @@ -5,7 +5,7 @@ using Kyoo.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace Kyoo.API +namespace Kyoo.Api { [Route("api/[controller]")] [ApiController] diff --git a/Kyoo/Views/API/ProviderAPI.cs b/Kyoo/Views/API/ProviderAPI.cs index 019e304c..d1390e2c 100644 --- a/Kyoo/Views/API/ProviderAPI.cs +++ b/Kyoo/Views/API/ProviderAPI.cs @@ -3,7 +3,7 @@ using Kyoo.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace Kyoo.API +namespace Kyoo.Api { [Route("api/provider")] [Route("api/providers")] diff --git a/Kyoo/Views/API/SearchAPI.cs b/Kyoo/Views/API/SearchAPI.cs index 3f1489fe..4efcf93a 100644 --- a/Kyoo/Views/API/SearchAPI.cs +++ b/Kyoo/Views/API/SearchAPI.cs @@ -4,7 +4,7 @@ using Kyoo.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace Kyoo.API +namespace Kyoo.Api { [Route("api/[controller]")] [ApiController] diff --git a/Kyoo/Views/API/ShowsAPI.cs b/Kyoo/Views/API/ShowsAPI.cs deleted file mode 100644 index abea4b1e..00000000 --- a/Kyoo/Views/API/ShowsAPI.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using Kyoo.Models; -using Microsoft.AspNetCore.Mvc; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models.Exceptions; -using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.Configuration; - -namespace Kyoo.API -{ - [Route("api/shows")] - [Route("api/show")] - [ApiController] - public class ShowsAPI : ControllerBase - { - - } -} diff --git a/Kyoo/Views/API/ShowsApi.cs b/Kyoo/Views/API/ShowsApi.cs new file mode 100644 index 00000000..4e62fb3b --- /dev/null +++ b/Kyoo/Views/API/ShowsApi.cs @@ -0,0 +1,85 @@ +using System; +using Kyoo.Models; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.Threading.Tasks; +using Kyoo.CommonApi; +using Kyoo.Controllers; +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Configuration; + +namespace Kyoo.Api +{ + [Route("api/show")] + [Route("api/shows")] + [ApiController] + public class ShowsApi : CrudApi + { + private readonly ILibraryManager _libraryManager; + + public ShowsApi(ILibraryManager libraryManager, + IConfiguration configuration) + : base(libraryManager.ShowRepository, configuration) + { + _libraryManager = libraryManager; + } + + [HttpGet("{showID}/season")] + [HttpGet("{showID}/seasons")] + [Authorize(Policy = "Read")] + public async Task>> GetSeasons(int showID, + [FromQuery] string sortBy, + [FromQuery] int limit, + [FromQuery] int afterID, + [FromQuery] Dictionary where) + { + where.Remove("showID"); + where.Remove("sortBy"); + where.Remove("limit"); + where.Remove("afterID"); + + try + { + ICollection ressources = await _libraryManager.GetSeasons(showID, + ApiHelper.ParseWhere(where), + new Sort(sortBy), + new Pagination(limit, afterID)); + + return Page(ressources, limit); + } + catch (ArgumentException ex) + { + return BadRequest(new {Error = ex.Message}); + } + } + + [HttpGet("{slug}/season")] + [HttpGet("{slug}/seasons")] + [Authorize(Policy = "Read")] + public async Task>> GetSeasons(string slug, + [FromQuery] string sortBy, + [FromQuery] int limit, + [FromQuery] int afterID, + [FromQuery] Dictionary where) + { + where.Remove("slug"); + where.Remove("sortBy"); + where.Remove("limit"); + where.Remove("afterID"); + + try + { + ICollection ressources = await _libraryManager.GetSeasons(slug, + ApiHelper.ParseWhere(where), + new Sort(sortBy), + new Pagination(limit, afterID)); + + return Page(ressources, limit); + } + catch (ArgumentException ex) + { + return BadRequest(new {Error = ex.Message}); + } + } + } +} diff --git a/Kyoo/Views/API/StudioAPI.cs b/Kyoo/Views/API/StudioAPI.cs index 59228155..88efca86 100644 --- a/Kyoo/Views/API/StudioAPI.cs +++ b/Kyoo/Views/API/StudioAPI.cs @@ -5,7 +5,7 @@ using Kyoo.Controllers; using Kyoo.Models; using Microsoft.AspNetCore.Mvc; -namespace Kyoo.API +namespace Kyoo.Api { [Route("api/studios")] [Route("api/studio")] diff --git a/Kyoo/Views/API/SubtitleAPI.cs b/Kyoo/Views/API/SubtitleAPI.cs index 2861b40f..3ffd72c3 100644 --- a/Kyoo/Views/API/SubtitleAPI.cs +++ b/Kyoo/Views/API/SubtitleAPI.cs @@ -8,7 +8,7 @@ using Kyoo.Controllers; using Kyoo.Models.Watch; using Microsoft.AspNetCore.Authorization; -namespace Kyoo.API +namespace Kyoo.Api { [Route("[controller]")] [ApiController] diff --git a/Kyoo/Views/API/TaskAPI.cs b/Kyoo/Views/API/TaskAPI.cs index 4becbcd7..24ab8845 100644 --- a/Kyoo/Views/API/TaskAPI.cs +++ b/Kyoo/Views/API/TaskAPI.cs @@ -2,7 +2,7 @@ using Kyoo.Controllers; using Microsoft.AspNetCore.Authorization; -namespace Kyoo.API +namespace Kyoo.Api { [Route("api/[controller]")] [ApiController] diff --git a/Kyoo/Views/API/ThumbnailAPI.cs b/Kyoo/Views/API/ThumbnailAPI.cs index 3955cc6b..455c680d 100644 --- a/Kyoo/Views/API/ThumbnailAPI.cs +++ b/Kyoo/Views/API/ThumbnailAPI.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; using Kyoo.Controllers; using Microsoft.AspNetCore.Authorization; -namespace Kyoo.API +namespace Kyoo.Api { public class ThumbnailController : ControllerBase { diff --git a/Kyoo/Views/API/VideoAPI.cs b/Kyoo/Views/API/VideoAPI.cs index 0570a03c..2c12cea7 100644 --- a/Kyoo/Views/API/VideoAPI.cs +++ b/Kyoo/Views/API/VideoAPI.cs @@ -6,7 +6,7 @@ using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; -namespace Kyoo.API +namespace Kyoo.Api { [Route("[controller]")] [ApiController] diff --git a/Kyoo/Views/API/WatchAPI.cs b/Kyoo/Views/API/WatchAPI.cs index 7e44997d..07039073 100644 --- a/Kyoo/Views/API/WatchAPI.cs +++ b/Kyoo/Views/API/WatchAPI.cs @@ -4,7 +4,7 @@ using Kyoo.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace Kyoo.API +namespace Kyoo.Api { [Route("api/[controller]")] [ApiController]