// 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; 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; namespace Kyoo.Core.Controllers { /// /// A local repository to handle people. /// public class PeopleRepository : LocalRepository, IPeopleRepository { /// /// The database handle /// private readonly DatabaseContext _database; /// /// A provider repository to handle externalID creation and deletion /// private readonly IProviderRepository _providers; /// /// A lazy loaded show repository to validate requests from shows. /// private readonly Lazy _shows; /// protected override Expression> DefaultSort => x => x.Name; /// /// Create a new /// /// The database handle /// A provider repository /// A lazy loaded show repository public PeopleRepository(DatabaseContext database, IProviderRepository providers, Lazy shows) : base(database) { _database = database; _providers = providers; _shows = shows; } /// public override async Task> Search(string query) { return await _database.People .Where(_database.Like(x => x.Name, $"%{query}%")) .OrderBy(DefaultSort) .Take(20) .ToListAsync(); } /// public override async Task Create(People obj) { await base.Create(obj); _database.Entry(obj).State = EntityState.Added; await _database.SaveChangesAsync($"Trying to insert a duplicated people (slug {obj.Slug} already exists)."); return obj; } /// protected override async Task Validate(People resource) { await base.Validate(resource); if (resource.ExternalIDs != null) { foreach (MetadataID id in resource.ExternalIDs) { id.Provider = _database.LocalEntity(id.Provider.Slug) ?? await _providers.CreateIfNotExists(id.Provider); id.ProviderID = id.Provider.ID; } _database.MetadataIds().AttachRange(resource.ExternalIDs); } if (resource.Roles != null) { foreach (PeopleRole role in resource.Roles) { role.Show = _database.LocalEntity(role.Show.Slug) ?? await _shows.Value.CreateIfNotExists(role.Show); role.ShowID = role.Show.ID; _database.Entry(role).State = EntityState.Added; } } } /// protected override async Task EditRelations(People resource, People changed, bool resetOld) { await Validate(changed); if (changed.Roles != null || resetOld) { await Database.Entry(resource).Collection(x => x.Roles).LoadAsync(); resource.Roles = changed.Roles; } if (changed.ExternalIDs != null || resetOld) { await Database.Entry(resource).Collection(x => x.ExternalIDs).LoadAsync(); resource.ExternalIDs = changed.ExternalIDs; } } /// public override async Task Delete(People obj) { if (obj == null) throw new ArgumentNullException(nameof(obj)); _database.Entry(obj).State = EntityState.Deleted; obj.ExternalIDs.ForEach(x => _database.Entry(x).State = EntityState.Deleted); obj.Roles.ForEach(x => _database.Entry(x).State = EntityState.Deleted); await _database.SaveChangesAsync(); } /// public async Task> GetFromShow(int showID, Expression> where = null, Sort sort = default, Pagination limit = default) { ICollection people = await ApplyFilters(_database.PeopleRoles .Where(x => x.ShowID == showID) .Include(x => x.People), id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id), x => x.People.Name, 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; } /// public async Task> GetFromShow(string showSlug, Expression> where = null, Sort sort = default, Pagination limit = default) { ICollection people = await ApplyFilters(_database.PeopleRoles .Where(x => x.Show.Slug == showSlug) .Include(x => x.People) .Include(x => x.Show), id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id), x => x.People.Name, 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; } /// public async Task> GetFromPeople(int id, Expression> where = null, Sort sort = default, Pagination limit = default) { ICollection roles = await ApplyFilters(_database.PeopleRoles .Where(x => x.PeopleID == id) .Include(x => x.Show), y => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == y), x => x.Show.Title, where, sort, limit); if (!roles.Any() && await GetOrDefault(id) == null) throw new ItemNotFoundException(); return roles; } /// 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) .Include(x => x.Show), id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id), x => x.Show.Title, where, sort, limit); if (!roles.Any() && await GetOrDefault(slug) == null) throw new ItemNotFoundException(); return roles; } } }