diff --git a/Kyoo.Common/Controllers/ILibraryManager.cs b/Kyoo.Common/Controllers/ILibraryManager.cs index e6972d04..374f012a 100644 --- a/Kyoo.Common/Controllers/ILibraryManager.cs +++ b/Kyoo.Common/Controllers/ILibraryManager.cs @@ -117,25 +117,25 @@ namespace Kyoo.Controllers ) => GetPeopleFromShow(showSlug, where, new Sort(sort), limit); // Show Role relations - Task> GetRolesFromPeople(int showID, - Expression> where = null, - Sort sort = default, + Task> GetRolesFromPeople(int showID, + Expression> where = null, + Sort sort = default, Pagination limit = default); - Task> GetRolesFromPeople(int showID, - [Optional] Expression> where, - Expression> sort, + Task> GetRolesFromPeople(int showID, + [Optional] Expression> where, + Expression> sort, Pagination limit = default - ) => GetRolesFromPeople(showID, where, new Sort(sort), limit); + ) => GetRolesFromPeople(showID, where, new Sort(sort), limit); - Task> GetRolesFromPeople(string showSlug, - Expression> where = null, - Sort sort = default, + Task> GetRolesFromPeople(string showSlug, + Expression> where = null, + Sort sort = default, Pagination limit = default); - Task> GetRolesFromPeople(string showSlug, - [Optional] Expression> where, - Expression> sort, + Task> GetRolesFromPeople(string showSlug, + [Optional] Expression> where, + Expression> sort, Pagination limit = default - ) => GetRolesFromPeople(showSlug, where, new Sort(sort), limit); + ) => GetRolesFromPeople(showSlug, where, new Sort(sort), limit); // Helpers Task AddShowLink(int showID, int? libraryID, int? collectionID); diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Common/Controllers/IRepository.cs index 21f3318a..6ed573dc 100644 --- a/Kyoo.Common/Controllers/IRepository.cs +++ b/Kyoo.Common/Controllers/IRepository.cs @@ -186,25 +186,25 @@ namespace Kyoo.Controllers Pagination limit = default ) => GetFromShow(showSlug, where, new Sort(sort), limit); - Task> GetFromPeople(int showID, - Expression> where = null, - Sort sort = default, + Task> GetFromPeople(int showID, + Expression> where = null, + Sort sort = default, Pagination limit = default); - Task> GetFromPeople(int showID, - [Optional] Expression> where, - Expression> sort, + Task> GetFromPeople(int showID, + [Optional] Expression> where, + Expression> sort, Pagination limit = default - ) => GetFromPeople(showID, where, new Sort(sort), limit); + ) => GetFromPeople(showID, where, new Sort(sort), limit); - Task> GetFromPeople(string showSlug, - Expression> where = null, - Sort sort = default, + Task> GetFromPeople(string showSlug, + Expression> where = null, + Sort sort = default, Pagination limit = default); - Task> GetFromPeople(string showSlug, - [Optional] Expression> where, - Expression> sort, + Task> GetFromPeople(string showSlug, + [Optional] Expression> where, + Expression> sort, Pagination limit = default - ) => GetFromPeople(showSlug, where, new Sort(sort), limit); + ) => GetFromPeople(showSlug, where, new Sort(sort), limit); } public interface IProviderRepository : IRepository diff --git a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs index 306e9bd7..18159706 100644 --- a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs +++ b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs @@ -266,61 +266,58 @@ namespace Kyoo.Controllers return (obj, member) switch { (Library l, nameof(Library.Providers)) => ProviderRepository - .GetAll(x => x.Libraries.Any(y => y.ID == obj.ID || y.Slug == obj.Slug)) + .GetAll(x => x.Libraries.Any(y => y.ID == obj.ID)) .Then(x => l.Providers = x), (Library l, nameof(Library.Shows)) => ShowRepository - .GetAll(x => x.Libraries.Any(y => y.ID == obj.ID || y.Slug == obj.Slug)) + .GetAll(x => x.Libraries.Any(y => y.ID == obj.ID)) .Then(x => l.Shows = x), (Library l, nameof(Library.Collections)) => CollectionRepository - .GetAll(x => x.Libraries.Any(y => y.ID == obj.ID || y.Slug == obj.Slug)) + .GetAll(x => x.Libraries.Any(y => y.ID == obj.ID)) .Then(x => l.Collections = x), (Collection c, nameof(Library.Shows)) => ShowRepository - .GetAll(x => x.Collections.Any(y => y.ID == obj.ID || y.Slug == obj.Slug)) + .GetAll(x => x.Collections.Any(y => y.ID == obj.ID)) .Then(x => c.Shows = x), (Collection c, nameof(Collection.Libraries)) => LibraryRepository - .GetAll(x => x.Collections.Any(y => y.ID == obj.ID || y.Slug == obj.Slug)) + .GetAll(x => x.Collections.Any(y => y.ID == obj.ID)) .Then(x => c.Libraries = x), (Show s, nameof(Show.ExternalIDs)) => ProviderRepository .GetMetadataID(x => x.ShowID == obj.ID) .Then(x => s.ExternalIDs = x), (Show s, nameof(Show.Genres)) => GenreRepository - .GetAll(x => x.Shows.Any(y => y.ID == obj.ID || y.Slug == obj.Slug)) + .GetAll(x => x.Shows.Any(y => y.ID == obj.ID)) .Then(x => s.Genres = x), - (Show s, nameof(Show.People)) => ( - PeopleRepository.GetFromShow((dynamic)(obj.ID > 0 ? obj.ID : obj.Slug)) - as Task>) + (Show s, nameof(Show.People)) => PeopleRepository + .GetFromShow(obj.ID) .Then(x => s.People = x), (Show s, nameof(Show.Seasons)) => SeasonRepository - .GetAll(x => x.Show.ID == obj.ID || x.Show.Slug == obj.Slug) + .GetAll(x => x.Show.ID == obj.ID) .Then(x => s.Seasons = x), (Show s, nameof(Show.Episodes)) => EpisodeRepository - .GetAll(x => x.Show.ID == obj.ID || x.Show.Slug == obj.Slug) + .GetAll(x => x.Show.ID == obj.ID) .Then(x => s.Episodes = x), (Show s, nameof(Show.Libraries)) => LibraryRepository - .GetAll(x => x.Shows.Any(y => y.ID == obj.ID || y.Slug == obj.Slug)) + .GetAll(x => x.Shows.Any(y => y.ID == obj.ID)) .Then(x => s.Libraries = x), (Show s, nameof(Show.Collections)) => CollectionRepository - .GetAll(x => x.Shows.Any(y => y.ID == obj.ID || y.Slug == obj.Slug)) + .GetAll(x => x.Shows.Any(y => y.ID == obj.ID)) .Then(x => s.Collections = x), // TODO Studio loading does not work. (Show s, nameof(Show.Studio)) => StudioRepository - .Get(x => x.Shows.Any(y => y.ID == obj.ID || y.Slug == obj.Slug)) + .Get(x => x.Shows.Any(y => y.ID == obj.ID)) .Then(x => s.Studio = x), (Season s, nameof(Season.ExternalIDs)) => ProviderRepository .GetMetadataID(x => x.SeasonID == obj.ID) .Then(x => s.ExternalIDs = x), (Season s, nameof(Season.Episodes)) => EpisodeRepository - .GetAll(x => x.Season.ID == obj.ID || x.Season.Slug == obj.Slug) + .GetAll(x => x.Season.ID == obj.ID) .Then(x => s.Episodes = x), (Season s, nameof(Season.Show)) => ShowRepository - .Get(x => x.Seasons - .Any(y => y.ID == obj.ID || y.ShowID == s.ShowID && y.SeasonNumber == s.SeasonNumber)) + .Get(x => x.Seasons.Any(y => y.ID == obj.ID)) .Then(x => s.Show = x), - // TODO maybe add slug support for episodes (Episode e, nameof(Episode.ExternalIDs)) => ProviderRepository .GetMetadataID(x => x.EpisodeID == obj.ID) .Then(x => e.ExternalIDs = x), @@ -339,19 +336,19 @@ namespace Kyoo.Controllers .Then(x => t.Episode = x), (Genre g, nameof(Genre.Shows)) => ShowRepository - .GetAll(x => x.Genres.Any(y => y.ID == obj.ID || y.Slug == obj.Slug)) + .GetAll(x => x.Genres.Any(y => y.ID == obj.ID)) .Then(x => g.Shows = x), (Studio s, nameof(Studio.Shows)) => ShowRepository - .GetAll(x => x.Studio.ID == obj.ID || x.Studio.Slug == obj.Slug) + .GetAll(x => x.Studio.ID == obj.ID) .Then(x => s.Shows = x), (People p, nameof(People.ExternalIDs)) => ProviderRepository .GetMetadataID(x => x.PeopleID == obj.ID) .Then(x => p.ExternalIDs = x), - (People p, nameof(People.Roles)) => ( - PeopleRepository.GetFromPeople((dynamic)(obj.ID > 0 ? obj.ID : obj.Slug)) - as Task>).Then(x => p.Roles = x), + (People p, nameof(People.Roles)) => PeopleRepository + .GetFromPeople(obj.ID) + .Then(x => p.Roles = x), _ => throw new ArgumentException($"Couldn't find a way to load {member} of {obj.Slug}.") }; @@ -459,17 +456,17 @@ namespace Kyoo.Controllers return PeopleRepository.GetFromShow(showSlug, where, sort, limit); } - public Task> GetRolesFromPeople(int id, - Expression> where = null, - Sort sort = default, + public Task> GetRolesFromPeople(int id, + Expression> where = null, + Sort sort = default, Pagination limit = default) { return PeopleRepository.GetFromPeople(id, where, sort, limit); } - public Task> GetRolesFromPeople(string slug, - Expression> where = null, - Sort sort = default, + public Task> GetRolesFromPeople(string slug, + Expression> where = null, + Sort sort = default, Pagination limit = default) { return PeopleRepository.GetFromPeople(slug, where, sort, limit); diff --git a/Kyoo.Common/Models/PeopleRole.cs b/Kyoo.Common/Models/PeopleRole.cs index fbde0d5e..533f0fca 100644 --- a/Kyoo.Common/Models/PeopleRole.cs +++ b/Kyoo.Common/Models/PeopleRole.cs @@ -9,37 +9,11 @@ namespace Kyoo.Models public class PeopleRole : IResource { [SerializeIgnore] public int ID { get; set; } + [SerializeIgnore] public string Slug => ForPeople ? Show.Slug : People.Slug; + [SerializeIgnore] public bool ForPeople; [SerializeIgnore] public int PeopleID { get; set; } + // TODO implement a SerializeInline for People or Show depending on the context. [SerializeIgnore] public virtual People People { get; set; } - - [ExpressionRewrite(nameof(People) + "." + nameof(Models.People.Slug))] - public string Slug - { - get => People.Slug; - set => People.Slug = value; - } - - [ExpressionRewrite(nameof(People) + "."+ nameof(Models.People.Name))] - public string Name - { - get => People.Name; - set => People.Name = value; - } - - [ExpressionRewrite(nameof(People) + "."+ nameof(Models.People.Poster))] - public string Poster - { - get => People.Poster; - set => People.Poster = value; - } - - [ExpressionRewrite(nameof(People) + "."+ nameof(Models.People.ExternalIDs))] - public ICollection ExternalIDs - { - get => People.ExternalIDs; - set => People.ExternalIDs = value; - } - [SerializeIgnore] public int ShowID { get; set; } [SerializeIgnore] public virtual Show Show { get; set; } public string Role { get; set; } @@ -67,67 +41,4 @@ namespace Kyoo.Models Type = type; } } - - public class ShowRole : IResource - { - public int ID { get; set; } - public string Role { get; set; } - public string Type { get; set; } - - public string Slug { get; set; } - public string Title { get; set; } - public ICollection Aliases { get; set; } - [SerializeIgnore] public string Path { get; set; } - public string Overview { get; set; } - public Status? Status { get; set; } - public string TrailerUrl { get; set; } - public int? StartYear { get; set; } - public int? EndYear { get; set; } - public string Poster { get; set; } - public string Logo { get; set; } - public string Backdrop { get; set; } - public bool IsMovie { get; set; } - - public ShowRole() {} - - public ShowRole(PeopleRole x) - { - ID = x.ID; - Role = x.Role; - Type = x.Type; - Slug = x.Show.Slug; - Title = x.Show.Title; - Aliases = x.Show.Aliases?.ToArray(); - Path = x.Show.Path; - Overview = x.Show.Overview; - Status = x.Show.Status; - TrailerUrl = x.Show.TrailerUrl; - StartYear = x.Show.StartYear; - EndYear = x.Show.EndYear; - Poster = x.Show.Poster; - Logo = x.Show.Logo; - Backdrop = x.Show.Backdrop; - IsMovie = x.Show.IsMovie; - } - - public static Expression> FromPeopleRole => x => new ShowRole - { - ID = x.ID, - Role = x.Role, - Type = x.Type, - Slug = x.Show.Slug, - Title = x.Show.Title, - Aliases = x.Show.Aliases != null ? x.Show.Aliases.ToArray() : null, - Path = x.Show.Path, - Overview = x.Show.Overview, - Status = x.Show.Status, - TrailerUrl = x.Show.TrailerUrl, - StartYear = x.Show.StartYear, - EndYear = x.Show.EndYear, - Poster = x.Show.Poster, - Logo = x.Show.Logo, - Backdrop = x.Show.Backdrop, - IsMovie = x.Show.IsMovie - }; - } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/PeopleRepository.cs b/Kyoo/Controllers/Repositories/PeopleRepository.cs index a0f7c0bb..f537e59b 100644 --- a/Kyoo/Controllers/Repositories/PeopleRepository.cs +++ b/Kyoo/Controllers/Repositories/PeopleRepository.cs @@ -126,37 +126,39 @@ namespace Kyoo.Controllers return people; } - public async Task> GetFromPeople(int peopleID, - Expression> where = null, - Sort sort = default, + public async Task> GetFromPeople(int peopleID, + Expression> where = null, + Sort sort = default, Pagination limit = default) { - ICollection roles = await ApplyFilters(_database.PeopleRoles.Where(x => x.PeopleID == peopleID) - .Select(ShowRole.FromPeopleRole), - async id => new ShowRole(await _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id)), - x => x.Title, + ICollection roles = await ApplyFilters(_database.PeopleRoles.Where(x => x.PeopleID == peopleID), + id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id), + x => x.Show.Title, where, sort, limit); if (!roles.Any() && await Get(peopleID) == null) throw new ItemNotFound(); + foreach (PeopleRole role in roles) + role.ForPeople = true; return roles; } - public async Task> GetFromPeople(string slug, - Expression> where = null, - Sort sort = default, + public async Task> GetFromPeople(string slug, + Expression> where = null, + Sort sort = default, Pagination limit = default) { - ICollection roles = await ApplyFilters(_database.PeopleRoles.Where(x => x.People.Slug == slug) - .Select(ShowRole.FromPeopleRole), - async id => new ShowRole(await _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id)), - x => x.Title, + ICollection roles = await ApplyFilters(_database.PeopleRoles.Where(x => x.People.Slug == slug), + id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id), + x => x.Show.Title, where, sort, limit); if (!roles.Any() && await Get(slug) == null) throw new ItemNotFound(); + foreach (PeopleRole role in roles) + role.ForPeople = true; return roles; } } diff --git a/Kyoo/Models/DatabaseContext.cs b/Kyoo/Models/DatabaseContext.cs index e7470268..4ab750f3 100644 --- a/Kyoo/Models/DatabaseContext.cs +++ b/Kyoo/Models/DatabaseContext.cs @@ -98,10 +98,7 @@ namespace Kyoo .Ignore(x => x.Collections); modelBuilder.Entity() - .Ignore(x => x.Slug) - .Ignore(x => x.Name) - .Ignore(x => x.Poster) - .Ignore(x => x.ExternalIDs); + .Ignore(x => x.Slug); modelBuilder.Entity() .Ignore(x => x.Shows); diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20210228210101_Initial.Designer.cs b/Kyoo/Models/DatabaseMigrations/Internal/20210228224046_Initial.Designer.cs similarity index 99% rename from Kyoo/Models/DatabaseMigrations/Internal/20210228210101_Initial.Designer.cs rename to Kyoo/Models/DatabaseMigrations/Internal/20210228224046_Initial.Designer.cs index ccd23f6a..d08a2a98 100644 --- a/Kyoo/Models/DatabaseMigrations/Internal/20210228210101_Initial.Designer.cs +++ b/Kyoo/Models/DatabaseMigrations/Internal/20210228224046_Initial.Designer.cs @@ -10,7 +10,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace Kyoo.Models.DatabaseMigrations.Internal { [DbContext(typeof(DatabaseContext))] - [Migration("20210228210101_Initial")] + [Migration("20210228224046_Initial")] partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20210228210101_Initial.cs b/Kyoo/Models/DatabaseMigrations/Internal/20210228224046_Initial.cs similarity index 100% rename from Kyoo/Models/DatabaseMigrations/Internal/20210228210101_Initial.cs rename to Kyoo/Models/DatabaseMigrations/Internal/20210228224046_Initial.cs diff --git a/Kyoo/Views/API/PeopleApi.cs b/Kyoo/Views/API/PeopleApi.cs index a264363c..88088757 100644 --- a/Kyoo/Views/API/PeopleApi.cs +++ b/Kyoo/Views/API/PeopleApi.cs @@ -29,7 +29,7 @@ namespace Kyoo.Api [HttpGet("{id:int}/role")] [HttpGet("{id:int}/roles")] [Authorize(Policy = "Read")] - public async Task>> GetRoles(int id, + public async Task>> GetRoles(int id, [FromQuery] string sortBy, [FromQuery] int afterID, [FromQuery] Dictionary where, @@ -37,9 +37,9 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetRolesFromPeople(id, - ApiHelper.ParseWhere(where), - new Sort(sortBy), + ICollection resources = await _libraryManager.GetRolesFromPeople(id, + ApiHelper.ParseWhere(where), + new Sort(sortBy), new Pagination(limit, afterID)); return Page(resources, limit); @@ -57,7 +57,7 @@ namespace Kyoo.Api [HttpGet("{slug}/role")] [HttpGet("{slug}/roles")] [Authorize(Policy = "Read")] - public async Task>> GetRoles(string slug, + public async Task>> GetRoles(string slug, [FromQuery] string sortBy, [FromQuery] int afterID, [FromQuery] Dictionary where, @@ -65,9 +65,9 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetRolesFromPeople(slug, - ApiHelper.ParseWhere(where), - new Sort(sortBy), + ICollection resources = await _libraryManager.GetRolesFromPeople(slug, + ApiHelper.ParseWhere(where), + new Sort(sortBy), new Pagination(limit, afterID)); return Page(resources, limit);