diff --git a/Kyoo.Common/Controllers/ILibraryManager.cs b/Kyoo.Common/Controllers/ILibraryManager.cs index 69302e21..6da3a7b7 100644 --- a/Kyoo.Common/Controllers/ILibraryManager.cs +++ b/Kyoo.Common/Controllers/ILibraryManager.cs @@ -33,7 +33,6 @@ namespace Kyoo.Controllers // Helpers - Task GetShowByPath(string path); Task AddShowLink(int showID, int? libraryID, int? collectionID); Task AddShowLink([NotNull] Show show, Library library, Collection collection); @@ -122,26 +121,26 @@ namespace Kyoo.Controllers Task> SearchPeople(string searchQuery); //Register values - Task RegisterLibrary(Library library); - Task RegisterCollection(Collection collection); - Task RegisterShow(Show show); - Task RegisterSeason(Season season); - Task RegisterEpisode(Episode episode); - Task RegisterTrack(Track track); - Task RegisterGenre(Genre genre); - Task RegisterStudio(Studio studio); - Task RegisterPeople(People people); + Task RegisterLibrary(Library library); + Task RegisterCollection(Collection collection); + Task RegisterShow(Show show); + Task RegisterSeason(Season season); + Task RegisterEpisode(Episode episode); + Task RegisterTrack(Track track); + Task RegisterGenre(Genre genre); + Task RegisterStudio(Studio studio); + Task RegisterPeople(People people); // Edit values - Task EditLibrary(Library library, bool resetOld); - Task EditCollection(Collection collection, bool resetOld); - Task EditShow(Show show, bool resetOld); - Task EditSeason(Season season, bool resetOld); - Task EditEpisode(Episode episode, bool resetOld); - Task EditTrack(Track track, bool resetOld); - Task EditGenre(Genre genre, bool resetOld); - Task EditStudio(Studio studio, bool resetOld); - Task EditPeople(People people, bool resetOld); + Task EditLibrary(Library library, bool resetOld); + Task EditCollection(Collection collection, bool resetOld); + Task EditShow(Show show, bool resetOld); + Task EditSeason(Season season, bool resetOld); + Task EditEpisode(Episode episode, bool resetOld); + Task EditTrack(Track track, bool resetOld); + Task EditGenre(Genre genre, bool resetOld); + Task EditStudio(Studio studio, bool resetOld); + Task EditPeople(People people, bool resetOld); // Delete values @@ -154,5 +153,27 @@ namespace Kyoo.Controllers Task DeleteGenre(Genre genre); Task DeleteStudio(Studio studio); Task DeletePeople(People people); + + //Delete by slug + Task DelteLibrary(string slug); + Task DeleteCollection(string slug); + Task DeleteShow(string slug); + Task DeleteSeason(string slug); + Task DeleteEpisode(string slug); + Task DeleteTrack(string slug); + Task DeleteGenre(string slug); + Task DeleteStudio(string slug); + Task DeletePeople(string slug); + + //Delete by id + Task DelteLibrary(int id); + Task DeleteCollection(int id); + Task DeleteShow(int id); + Task DeleteSeason(int id); + Task DeleteEpisode(int id); + Task DeleteTrack(int id); + Task DeleteGenre(int id); + Task DeleteStudio(int id); + Task DeletePeople(int id); } } diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Common/Controllers/IRepository.cs index 34daa52a..69a09df3 100644 --- a/Kyoo.Common/Controllers/IRepository.cs +++ b/Kyoo.Common/Controllers/IRepository.cs @@ -81,9 +81,9 @@ namespace Kyoo.Controllers Pagination page = default ) => GetAll(where, new Sort(sort), page); - Task Create([NotNull] T obj); - Task CreateIfNotExists([NotNull] T obj); - Task Edit([NotNull] T edited, bool resetOld); + Task Create([NotNull] T obj); + Task CreateIfNotExists([NotNull] T obj); + Task Edit([NotNull] T edited, bool resetOld); Task Delete(int id); Task Delete(string slug); @@ -99,7 +99,6 @@ namespace Kyoo.Controllers public interface IShowRepository : IRepository { - Task GetByPath(string path); Task AddShowLink(int showID, int? libraryID, int? collectionID); } diff --git a/Kyoo/Controllers/LibraryManager.cs b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs similarity index 77% rename from Kyoo/Controllers/LibraryManager.cs rename to Kyoo.Common/Controllers/Implementations/LibraryManager.cs index cf65dc8d..2ffbcaca 100644 --- a/Kyoo/Controllers/LibraryManager.cs +++ b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs @@ -221,12 +221,7 @@ namespace Kyoo.Controllers { return _episodes.GetEpisodes(seasonID); } - - public Task GetShowByPath(string path) - { - return _shows.GetByPath(path); - } - + public Task AddShowLink(int showID, int? libraryID, int? collectionID) { return _shows.AddShowLink(showID, libraryID, collectionID); @@ -279,92 +274,92 @@ namespace Kyoo.Controllers return _people.Search(searchQuery); } - public Task RegisterLibrary(Library library) + public Task RegisterLibrary(Library library) { return _libraries.Create(library); } - public Task RegisterCollection(Collection collection) + public Task RegisterCollection(Collection collection) { return _collections.Create(collection); } - public Task RegisterShow(Show show) + public Task RegisterShow(Show show) { return _shows.Create(show); } - public Task RegisterSeason(Season season) + public Task RegisterSeason(Season season) { return _seasons.Create(season); } - public Task RegisterEpisode(Episode episode) + public Task RegisterEpisode(Episode episode) { return _episodes.Create(episode); } - public Task RegisterTrack(Track track) + public Task RegisterTrack(Track track) { return _tracks.Create(track); } - public Task RegisterGenre(Genre genre) + public Task RegisterGenre(Genre genre) { return _genres.Create(genre); } - public Task RegisterStudio(Studio studio) + public Task RegisterStudio(Studio studio) { return _studios.Create(studio); } - public Task RegisterPeople(People people) + public Task RegisterPeople(People people) { return _people.Create(people); } - public Task EditLibrary(Library library, bool resetOld) + public Task EditLibrary(Library library, bool resetOld) { return _libraries.Edit(library, resetOld); } - public Task EditCollection(Collection collection, bool resetOld) + public Task EditCollection(Collection collection, bool resetOld) { return _collections.Edit(collection, resetOld); } - public Task EditShow(Show show, bool resetOld) + public Task EditShow(Show show, bool resetOld) { return _shows.Edit(show, resetOld); } - public Task EditSeason(Season season, bool resetOld) + public Task EditSeason(Season season, bool resetOld) { return _seasons.Edit(season, resetOld); } - public Task EditEpisode(Episode episode, bool resetOld) + public Task EditEpisode(Episode episode, bool resetOld) { return _episodes.Edit(episode, resetOld); } - public Task EditTrack(Track track, bool resetOld) + public Task EditTrack(Track track, bool resetOld) { return _tracks.Edit(track, resetOld); } - public Task EditGenre(Genre genre, bool resetOld) + public Task EditGenre(Genre genre, bool resetOld) { return _genres.Edit(genre, resetOld); } - public Task EditStudio(Studio studio, bool resetOld) + public Task EditStudio(Studio studio, bool resetOld) { return _studios.Edit(studio, resetOld); } - public Task EditPeople(People people, bool resetOld) + public Task EditPeople(People people, bool resetOld) { return _people.Edit(people, resetOld); } @@ -413,5 +408,95 @@ namespace Kyoo.Controllers { return _people.Delete(people); } + + public Task DelteLibrary(string library) + { + return _libraries.Delete(library); + } + + public Task DeleteCollection(string collection) + { + return _collections.Delete(collection); + } + + public Task DeleteShow(string show) + { + return _shows.Delete(show); + } + + public Task DeleteSeason(string season) + { + return _seasons.Delete(season); + } + + public Task DeleteEpisode(string episode) + { + return _episodes.Delete(episode); + } + + public Task DeleteTrack(string track) + { + return _tracks.Delete(track); + } + + public Task DeleteGenre(string genre) + { + return _genres.Delete(genre); + } + + public Task DeleteStudio(string studio) + { + return _studios.Delete(studio); + } + + public Task DeletePeople(string people) + { + return _people.Delete(people); + } + + public Task DelteLibrary(int library) + { + return _libraries.Delete(library); + } + + public Task DeleteCollection(int collection) + { + return _collections.Delete(collection); + } + + public Task DeleteShow(int show) + { + return _shows.Delete(show); + } + + public Task DeleteSeason(int season) + { + return _seasons.Delete(season); + } + + public Task DeleteEpisode(int episode) + { + return _episodes.Delete(episode); + } + + public Task DeleteTrack(int track) + { + return _tracks.Delete(track); + } + + public Task DeleteGenre(int genre) + { + return _genres.Delete(genre); + } + + public Task DeleteStudio(int studio) + { + return _studios.Delete(studio); + } + + public Task DeletePeople(int people) + { + return _people.Delete(people); + } } } diff --git a/Kyoo/Controllers/Repositories/CollectionRepository.cs b/Kyoo/Controllers/Repositories/CollectionRepository.cs index e9253b07..955abc2d 100644 --- a/Kyoo/Controllers/Repositories/CollectionRepository.cs +++ b/Kyoo/Controllers/Repositories/CollectionRepository.cs @@ -72,7 +72,7 @@ namespace Kyoo.Controllers return await query.ToListAsync(); } - public async Task Create(Collection obj) + public async Task Create(Collection obj) { if (obj == null) throw new ArgumentNullException(nameof(obj)); @@ -91,17 +91,17 @@ namespace Kyoo.Controllers throw; } - return obj.ID; + return obj; } - public async Task CreateIfNotExists(Collection obj) + public async Task CreateIfNotExists(Collection obj) { if (obj == null) throw new ArgumentNullException(nameof(obj)); Collection old = await Get(obj.Slug); if (old != null) - return old.ID; + return old; try { return await Create(obj); @@ -111,11 +111,11 @@ namespace Kyoo.Controllers old = await Get(obj.Slug); if (old == null) throw new SystemException("Unknown database state."); - return old.ID; + return old; } } - public async Task Edit(Collection edited, bool resetOld) + public async Task Edit(Collection edited, bool resetOld) { if (edited == null) throw new ArgumentNullException(nameof(edited)); @@ -130,6 +130,7 @@ namespace Kyoo.Controllers Utility.Merge(old, edited); await _database.SaveChangesAsync(); + return old; } public async Task Delete(int id) diff --git a/Kyoo/Startup.cs b/Kyoo/Startup.cs index 4c3984b9..06a578dd 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 80eea5f0..aa30b5d6 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 bd4658fa..535fcc84 100644 --- a/Kyoo/Views/API/CollectionAPI.cs +++ b/Kyoo/Views/API/CollectionAPI.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; -namespace Kyoo.Api +namespace Kyoo.API { [Route("api/[controller]")] [ApiController] diff --git a/Kyoo/Views/API/EpisodesAPI.cs b/Kyoo/Views/API/EpisodesAPI.cs index abf0650d..fad605b1 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/LibrariesAPI.cs b/Kyoo/Views/API/LibrariesAPI.cs index eeeee468..4fe33cad 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 ad27d8b9..59918418 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/SearchAPI.cs b/Kyoo/Views/API/SearchAPI.cs index 4efcf93a..3f1489fe 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 index 58f9d504..76d2754d 100644 --- a/Kyoo/Views/API/ShowsAPI.cs +++ b/Kyoo/Views/API/ShowsAPI.cs @@ -5,34 +5,31 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Kyoo.Controllers; +using Kyoo.Models.Exceptions; using Microsoft.AspNetCore.Authorization; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; -namespace Kyoo.Api +namespace Kyoo.API { [Route("api/shows")] [Route("api/show")] [ApiController] public class ShowsAPI : ControllerBase { - private readonly ILibraryManager _libraryManager; + private readonly IShowRepository _shows; private readonly IProviderManager _providerManager; - private readonly DatabaseContext _database; private readonly IThumbnailsManager _thumbnailsManager; private readonly ITaskManager _taskManager; private readonly string _baseURL; - public ShowsAPI(ILibraryManager libraryManager, + public ShowsAPI(IShowRepository shows, IProviderManager providerManager, - DatabaseContext database, IThumbnailsManager thumbnailsManager, ITaskManager taskManager, IConfiguration configuration) { - _libraryManager = libraryManager; + _shows = shows; _providerManager = providerManager; - _database = database; _thumbnailsManager = thumbnailsManager; _taskManager = taskManager; _baseURL = configuration.GetValue("public_url").TrimEnd('/'); @@ -51,23 +48,34 @@ namespace Kyoo.Api if (limit == 0) limit = 20; - ICollection shows; try { - shows = await _libraryManager.GetShows(Utility.ParseWhere(where), + ICollection shows = await _shows.GetAll(Utility.ParseWhere(where), new Sort(sortBy), new Pagination(limit, afterID)); + + return new Page(shows, + x => $"{x.ID}", + _baseURL + Request.Path, + Request.Query.ToDictionary(x => x.Key, x => x.Value.ToString(), StringComparer.InvariantCultureIgnoreCase), + limit); } catch (ArgumentException ex) { return BadRequest(new { Error = ex.Message }); } - - return new Page(shows, - x => $"{x.ID}", - _baseURL + Request.Path, - Request.Query.ToDictionary(x => x.Key, x => x.Value.ToString(), StringComparer.InvariantCultureIgnoreCase), - limit); + } + + [HttpGet("{id}")] + [Authorize(Policy="Read")] + [JsonDetailed] + public async Task> GetShow(int id) + { + Show show = await _shows.Get(id); + if (show == null) + return NotFound(); + + return show; } [HttpGet("{slug}")] @@ -75,28 +83,67 @@ namespace Kyoo.Api [JsonDetailed] public async Task> GetShow(string slug) { - Show show = await _libraryManager.GetShow(slug); - + Show show = await _shows.Get(slug); if (show == null) return NotFound(); return show; } - - [HttpPost("edit/{slug}")] - [Authorize(Policy="Write")] - public async Task EditShow(string slug, [FromBody] Show show) - { - if (!ModelState.IsValid) - return BadRequest(show); - Show old = _database.Shows.AsNoTracking().FirstOrDefault(x => x.Slug == slug); + [HttpPost] + [Authorize(Policy="Write")] + public async Task> CreateShow([FromBody] Show show) + { + try + { + return await _shows.Create(show); + } + catch (DuplicatedItemException) + { + Show existing = await _shows.Get(show.Slug); + return Conflict(existing); + } + } + + [HttpPut("{slug}")] + [Authorize(Policy="Write")] + public async Task> EditShow(string slug, [FromQuery] bool resetOld, [FromBody] Show show) + { + Show old = await _shows.Get(slug); if (old == null) return NotFound(); show.ID = old.ID; - show.Slug = slug; show.Path = old.Path; - await _libraryManager.EditShow(show, false); + return await _shows.Edit(show, resetOld); + } + + [HttpDelete("{slug}")] + // [Authorize(Policy="Write")] + public async Task DeleteShow(string slug) + { + try + { + await _shows.Delete(slug); + } + catch (ItemNotFound) + { + return NotFound(); + } + return Ok(); + } + + [HttpDelete("{id}")] + // [Authorize(Policy="Write")] + public async Task DeleteShow(int id) + { + try + { + await _shows.Delete(id); + } + catch (ItemNotFound) + { + return NotFound(); + } return Ok(); } diff --git a/Kyoo/Views/API/SubtitleAPI.cs b/Kyoo/Views/API/SubtitleAPI.cs index 00d4d998..2861b40f 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] @@ -33,7 +33,7 @@ namespace Kyoo.Api string identifier, string extension) { - string languageTag = identifier.Length == 3 ? identifier.Substring(0, 3) : null; + string languageTag = identifier.Length >= 3 ? identifier.Substring(0, 3) : null; bool forced = identifier.Length > 4 && identifier.Substring(4) == "forced"; Track subtitle = null; diff --git a/Kyoo/Views/API/TaskAPI.cs b/Kyoo/Views/API/TaskAPI.cs index 24ab8845..4becbcd7 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 455c680d..3955cc6b 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 2c12cea7..0570a03c 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 07039073..7e44997d 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]