diff --git a/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs b/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs index 1bbe147f..3b1a1b7f 100644 --- a/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs +++ b/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs @@ -318,6 +318,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No library exist with the given ID. /// A list of items that match every filters Task> GetItemsFromLibrary(int id, Expression> where = null, @@ -331,6 +332,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No library exist with the given ID. /// A list of items that match every filters Task> GetItemsFromLibrary(int id, [Optional] Expression> where, @@ -345,6 +347,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No library exist with the given slug. /// A list of items that match every filters Task> GetItemsFromLibrary(string slug, Expression> where = null, @@ -358,6 +361,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No library exist with the given slug. /// A list of items that match every filters Task> GetItemsFromLibrary(string slug, [Optional] Expression> where, @@ -372,6 +376,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No exist with the given ID. /// A list of items that match every filters Task> GetPeopleFromShow(int showID, Expression> where = null, @@ -385,6 +390,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No exist with the given ID. /// A list of items that match every filters Task> GetPeopleFromShow(int showID, [Optional] Expression> where, @@ -399,6 +405,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No exist with the given slug. /// A list of items that match every filters Task> GetPeopleFromShow(string showSlug, Expression> where = null, @@ -412,6 +419,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No exist with the given slug. /// A list of items that match every filters Task> GetPeopleFromShow(string showSlug, [Optional] Expression> where, @@ -426,6 +434,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No exist with the given ID. /// A list of items that match every filters Task> GetRolesFromPeople(int id, Expression> where = null, @@ -439,6 +448,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No exist with the given ID. /// A list of items that match every filters Task> GetRolesFromPeople(int id, [Optional] Expression> where, @@ -453,6 +463,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No exist with the given slug. /// A list of items that match every filters Task> GetRolesFromPeople(string slug, Expression> where = null, @@ -466,6 +477,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No exist with the given slug. /// A list of items that match every filters Task> GetRolesFromPeople(string slug, [Optional] Expression> where, diff --git a/src/Kyoo.Abstractions/Controllers/IRepository.cs b/src/Kyoo.Abstractions/Controllers/IRepository.cs index 4deae6e8..1d996e97 100644 --- a/src/Kyoo.Abstractions/Controllers/IRepository.cs +++ b/src/Kyoo.Abstractions/Controllers/IRepository.cs @@ -345,6 +345,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No library exist with the given ID. /// A list of items that match every filters public Task> GetFromLibrary(int id, Expression> where = null, @@ -358,6 +359,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No library exist with the given ID. /// A list of items that match every filters public Task> GetFromLibrary(int id, [Optional] Expression> where, @@ -372,6 +374,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No library exist with the given slug. /// A list of items that match every filters public Task> GetFromLibrary(string slug, Expression> where = null, @@ -385,6 +388,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No library exist with the given slug. /// A list of items that match every filters public Task> GetFromLibrary(string slug, [Optional] Expression> where, @@ -420,6 +424,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No exist with the given ID. /// A list of items that match every filters Task> GetFromShow(int showID, Expression> where = null, @@ -433,6 +438,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No exist with the given ID. /// A list of items that match every filters Task> GetFromShow(int showID, [Optional] Expression> where, @@ -447,6 +453,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No exist with the given slug. /// A list of items that match every filters Task> GetFromShow(string showSlug, Expression> where = null, @@ -460,6 +467,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No exist with the given slug. /// A list of items that match every filters Task> GetFromShow(string showSlug, [Optional] Expression> where, @@ -474,6 +482,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No exist with the given ID. /// A list of items that match every filters Task> GetFromPeople(int id, Expression> where = null, @@ -487,6 +496,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No exist with the given ID. /// A list of items that match every filters Task> GetFromPeople(int id, [Optional] Expression> where, @@ -501,6 +511,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// Sort information (sort order and sort by) /// How many items to return and where to start + /// No exist with the given slug. /// A list of items that match every filters Task> GetFromPeople(string slug, Expression> where = null, @@ -514,6 +525,7 @@ namespace Kyoo.Abstractions.Controllers /// A filter function /// A sort by method /// How many items to return and where to start + /// No exist with the given slug. /// A list of items that match every filters Task> GetFromPeople(string slug, [Optional] Expression> where, diff --git a/src/Kyoo.Core/Controllers/Repositories/PeopleRepository.cs b/src/Kyoo.Core/Controllers/Repositories/PeopleRepository.cs index d599d6ee..09809426 100644 --- a/src/Kyoo.Core/Controllers/Repositories/PeopleRepository.cs +++ b/src/Kyoo.Core/Controllers/Repositories/PeopleRepository.cs @@ -23,6 +23,7 @@ using System.Linq.Expressions; using System.Threading.Tasks; using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; using Kyoo.Database; using Kyoo.Utils; using Microsoft.EntityFrameworkCore; @@ -159,6 +160,8 @@ namespace Kyoo.Core.Controllers where, sort, limit); + if (!people.Any() && await _shows.Value.GetOrDefault(showID) == null) + throw new ItemNotFoundException(); foreach (PeopleRole role in people) role.ForPeople = true; return people; @@ -179,6 +182,8 @@ namespace Kyoo.Core.Controllers where, sort, limit); + if (!people.Any() && await _shows.Value.GetOrDefault(showSlug) == null) + throw new ItemNotFoundException(); foreach (PeopleRole role in people) role.ForPeople = true; return people; @@ -190,7 +195,7 @@ namespace Kyoo.Core.Controllers Sort sort = default, Pagination limit = default) { - return await ApplyFilters(_database.PeopleRoles + ICollection roles = await ApplyFilters(_database.PeopleRoles .Where(x => x.PeopleID == id) .Include(x => x.Show), y => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == y), @@ -198,6 +203,9 @@ namespace Kyoo.Core.Controllers where, sort, limit); + if (!roles.Any() && await GetOrDefault(id) == null) + throw new ItemNotFoundException(); + return roles; } /// @@ -206,7 +214,7 @@ namespace Kyoo.Core.Controllers Sort sort = default, Pagination limit = default) { - return await ApplyFilters(_database.PeopleRoles + ICollection roles = await ApplyFilters(_database.PeopleRoles .Where(x => x.People.Slug == slug) .Include(x => x.Show), id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id), @@ -214,6 +222,9 @@ namespace Kyoo.Core.Controllers where, sort, limit); + if (!roles.Any() && await GetOrDefault(slug) == null) + throw new ItemNotFoundException(); + return roles; } } } diff --git a/src/Kyoo.Core/Views/Metadata/StaffApi.cs b/src/Kyoo.Core/Views/Metadata/StaffApi.cs new file mode 100644 index 00000000..fc20365a --- /dev/null +++ b/src/Kyoo.Core/Views/Metadata/StaffApi.cs @@ -0,0 +1,116 @@ +// Kyoo - A portable and vast media library solution. +// Copyright (c) Kyoo. +// +// See AUTHORS.md and LICENSE file in the project root for full license information. +// +// Kyoo is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// Kyoo is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Kyoo. If not, see . + +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Threading.Tasks; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; +using Kyoo.Abstractions.Models.Utils; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using static Kyoo.Abstractions.Models.Utils.Constants; + +namespace Kyoo.Core.Api +{ + /// + /// Information about one or multiple staff member. + /// + [Route("api/staff")] + [Route("api/people", Order = AlternativeRoute)] + [ApiController] + [ResourceView] + [PartialPermission(nameof(StaffApi))] + [ApiDefinition("Staff", Group = MetadataGroup)] + public class StaffApi : CrudThumbsApi + { + /// + /// The library manager used to modify or retrieve information in the data store. + /// + private readonly ILibraryManager _libraryManager; + + /// + /// Create a new . + /// + /// + /// The library manager used to modify or retrieve information about the data store. + /// + /// The file manager used to send images and fonts. + /// The thumbnail manager used to retrieve images paths. + public StaffApi(ILibraryManager libraryManager, + IFileSystem files, + IThumbnailsManager thumbs) + : base(libraryManager.PeopleRepository, files, thumbs) + { + _libraryManager = libraryManager; + } + + /// + /// Get roles + /// + /// + /// List the roles in witch this person has played, written or worked in a way. + /// + /// The ID or slug of the person. + /// A key to sort roles by. + /// An optional list of filters. + /// The number of roles to return. + /// An optional role's ID to start the query from this specific item. + /// A page of roles. + /// The filters or the sort parameters are invalid. + /// No person with the given ID or slug could be found. + [HttpGet("{identifier:id}/roles")] + [HttpGet("{identifier:id}/role", Order = AlternativeRoute)] + [PartialPermission(Kind.Read)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task>> GetRoles(Identifier identifier, + [FromQuery] string sortBy, + [FromQuery] Dictionary where, + [FromQuery] int limit = 20, + [FromQuery] int? afterID = null) + { + try + { + Expression> whereQuery = ApiHelper.ParseWhere(where); + Sort sort = new(sortBy); + Pagination pagination = new(limit, afterID); + + ICollection resources = await identifier.Match( + id => _libraryManager.GetRolesFromPeople(id, whereQuery, sort, pagination), + slug => _libraryManager.GetRolesFromPeople(slug, whereQuery, sort, pagination) + ); + + return Page(resources, limit); + } + catch (ItemNotFoundException) + { + return NotFound(); + } + catch (ArgumentException ex) + { + return BadRequest(new RequestError(ex.Message)); + } + } + } +} diff --git a/src/Kyoo.Core/Views/PeopleApi.cs b/src/Kyoo.Core/Views/PeopleApi.cs deleted file mode 100644 index 2246d2ad..00000000 --- a/src/Kyoo.Core/Views/PeopleApi.cs +++ /dev/null @@ -1,123 +0,0 @@ -// Kyoo - A portable and vast media library solution. -// Copyright (c) Kyoo. -// -// See AUTHORS.md and LICENSE file in the project root for full license information. -// -// Kyoo is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// any later version. -// -// Kyoo is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Kyoo. If not, see . - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Kyoo.Abstractions.Controllers; -using Kyoo.Abstractions.Models; -using Kyoo.Abstractions.Models.Exceptions; -using Kyoo.Abstractions.Models.Permissions; -using Microsoft.AspNetCore.Mvc; - -namespace Kyoo.Core.Api -{ - [Route("api/people")] - [ApiController] - [PartialPermission(nameof(PeopleApi))] - public class PeopleApi : CrudApi - { - private readonly ILibraryManager _libraryManager; - private readonly IFileSystem _files; - private readonly IThumbnailsManager _thumbs; - - public PeopleApi(ILibraryManager libraryManager, - IFileSystem files, - IThumbnailsManager thumbs) - : base(libraryManager.PeopleRepository) - { - _libraryManager = libraryManager; - _files = files; - _thumbs = thumbs; - } - - [HttpGet("{id:int}/role")] - [HttpGet("{id:int}/roles")] - [PartialPermission(Kind.Read)] - public async Task>> GetRoles(int id, - [FromQuery] string sortBy, - [FromQuery] int afterID, - [FromQuery] Dictionary where, - [FromQuery] int limit = 20) - { - try - { - ICollection resources = await _libraryManager.GetRolesFromPeople(id, - ApiHelper.ParseWhere(where), - new Sort(sortBy), - new Pagination(limit, afterID)); - - return Page(resources, limit); - } - catch (ItemNotFoundException) - { - return NotFound(); - } - catch (ArgumentException ex) - { - return BadRequest(new { Error = ex.Message }); - } - } - - [HttpGet("{slug}/role")] - [HttpGet("{slug}/roles")] - [PartialPermission(Kind.Read)] - public async Task>> GetRoles(string slug, - [FromQuery] string sortBy, - [FromQuery] int afterID, - [FromQuery] Dictionary where, - [FromQuery] int limit = 20) - { - try - { - ICollection resources = await _libraryManager.GetRolesFromPeople(slug, - ApiHelper.ParseWhere(where), - new Sort(sortBy), - new Pagination(limit, afterID)); - - return Page(resources, limit); - } - catch (ItemNotFoundException) - { - return NotFound(); - } - catch (ArgumentException ex) - { - return BadRequest(new { Error = ex.Message }); - } - } - - [HttpGet("{id:int}/poster")] - public async Task GetPeopleIcon(int id) - { - People people = await _libraryManager.GetOrDefault(id); - if (people == null) - return NotFound(); - return _files.FileResult(await _thumbs.GetImagePath(people, Images.Poster)); - } - - [HttpGet("{slug}/poster")] - public async Task GetPeopleIcon(string slug) - { - People people = await _libraryManager.GetOrDefault(slug); - if (people == null) - return NotFound(); - return _files.FileResult(await _thumbs.GetImagePath(people, Images.Poster)); - } - } -} diff --git a/src/Kyoo.Core/Views/Resources/LibraryApi.cs b/src/Kyoo.Core/Views/Resources/LibraryApi.cs index 045b7b70..d440fae3 100644 --- a/src/Kyoo.Core/Views/Resources/LibraryApi.cs +++ b/src/Kyoo.Core/Views/Resources/LibraryApi.cs @@ -24,6 +24,7 @@ using System.Threading.Tasks; using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models; using Kyoo.Abstractions.Models.Attributes; +using Kyoo.Abstractions.Models.Exceptions; using Kyoo.Abstractions.Models.Permissions; using Kyoo.Abstractions.Models.Utils; using Microsoft.AspNetCore.Http; @@ -188,10 +189,12 @@ namespace Kyoo.Core.Api slug => _libraryManager.GetItemsFromLibrary(slug, whereQuery, sort, pagination) ); - if (!resources.Any() && await _libraryManager.GetOrDefault(identifier.IsSame()) == null) - return NotFound(); return Page(resources, limit); } + catch (ItemNotFoundException) + { + return NotFound(); + } catch (ArgumentException ex) { return BadRequest(new RequestError(ex.Message)); diff --git a/src/Kyoo.Core/Views/Resources/ShowApi.cs b/src/Kyoo.Core/Views/Resources/ShowApi.cs index ec179df0..37f3ccd1 100644 --- a/src/Kyoo.Core/Views/Resources/ShowApi.cs +++ b/src/Kyoo.Core/Views/Resources/ShowApi.cs @@ -25,6 +25,7 @@ using System.Threading.Tasks; using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models; using Kyoo.Abstractions.Models.Attributes; +using Kyoo.Abstractions.Models.Exceptions; using Kyoo.Abstractions.Models.Permissions; using Kyoo.Abstractions.Models.Utils; using Kyoo.Core.Models.Options; @@ -174,7 +175,7 @@ namespace Kyoo.Core.Api } /// - /// Get people that made this show + /// Get staff /// /// /// List staff members that made this show. @@ -187,8 +188,8 @@ namespace Kyoo.Core.Api /// A page of people. /// The filters or the sort parameters are invalid. /// No show with the given ID or slug could be found. - [HttpGet("{identifier:id}/people")] - [HttpGet("{identifier:id}/staff", Order = AlternativeRoute)] + [HttpGet("{identifier:id}/staff")] + [HttpGet("{identifier:id}/people", Order = AlternativeRoute)] [PartialPermission(Kind.Read)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))] @@ -209,11 +210,12 @@ namespace Kyoo.Core.Api id => _libraryManager.GetPeopleFromShow(id, whereQuery, sort, pagination), slug => _libraryManager.GetPeopleFromShow(slug, whereQuery, sort, pagination) ); - - if (!resources.Any() && await _libraryManager.GetOrDefault(identifier.IsSame()) == null) - return NotFound(); return Page(resources, limit); } + catch (ItemNotFoundException) + { + return NotFound(); + } catch (ArgumentException ex) { return BadRequest(new RequestError(ex.Message));