// 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 Microsoft.EntityFrameworkCore; namespace Kyoo.Core.Controllers { /// /// A local repository to handle library items. /// public class LibraryItemRepository : LocalRepository, ILibraryItemRepository { /// /// The database handle /// private readonly DatabaseContext _database; /// /// A lazy loaded library repository to validate queries (check if a library does exist) /// private readonly Lazy _libraries; /// protected override Expression> DefaultSort => x => x.Title; /// /// Create a new . /// /// The database instance /// A lazy loaded library repository public LibraryItemRepository(DatabaseContext database, Lazy libraries) : base(database) { _database = database; _libraries = libraries; } /// public override Task GetOrDefault(int id) { return _database.LibraryItems.FirstOrDefaultAsync(x => x.ID == id); } /// public override Task GetOrDefault(string slug) { return _database.LibraryItems.SingleOrDefaultAsync(x => x.Slug == slug); } /// public override Task> GetAll(Expression> where = null, Sort sort = default, Pagination limit = default) { return ApplyFilters(_database.LibraryItems, where, sort, limit); } /// public override Task GetCount(Expression> where = null) { IQueryable query = _database.LibraryItems; if (where != null) query = query.Where(where); return query.CountAsync(); } /// public override async Task> Search(string query) { return await _database.LibraryItems .Where(_database.Like(x => x.Title, $"%{query}%")) .OrderBy(DefaultSort) .Take(20) .ToListAsync(); } /// public override Task Create(LibraryItem obj) => throw new InvalidOperationException(); /// public override Task CreateIfNotExists(LibraryItem obj) => throw new InvalidOperationException(); /// public override Task Edit(LibraryItem obj, bool resetOld) => throw new InvalidOperationException(); /// public override Task Delete(int id) => throw new InvalidOperationException(); /// public override Task Delete(string slug) => throw new InvalidOperationException(); /// public override Task Delete(LibraryItem obj) => throw new InvalidOperationException(); /// /// Get a basic queryable for a library with the right mapping from shows and collections. /// Shows contained in a collection are excluded. /// /// Only items that are part of a library that match this predicate will be returned. /// A queryable containing items that are part of a library matching the selector. private IQueryable _LibraryRelatedQuery(Expression> selector) => _database.Libraries .Where(selector) .SelectMany(x => x.Shows) .Where(x => !x.Collections.Any()) .Select(LibraryItem.FromShow) .Concat(_database.Libraries .Where(selector) .SelectMany(x => x.Collections) .Select(LibraryItem.FromCollection)); /// public async Task> GetFromLibrary(int id, Expression> where = null, Sort sort = default, Pagination limit = default) { ICollection items = await ApplyFilters(_LibraryRelatedQuery(x => x.ID == id), where, sort, limit); if (!items.Any() && await _libraries.Value.GetOrDefault(id) == null) throw new ItemNotFoundException(); return items; } /// public async Task> GetFromLibrary(string slug, Expression> where = null, Sort sort = default, Pagination limit = default) { ICollection items = await ApplyFilters(_LibraryRelatedQuery(x => x.Slug == slug), where, sort, limit); if (!items.Any() && await _libraries.Value.GetOrDefault(slug) == null) throw new ItemNotFoundException(); return items; } } }