From 7dbb84780ce4569f3ac348f4d46bc0f980d49b09 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 18 Apr 2021 02:17:15 +0200 Subject: [PATCH] Reworking the LibraryManager's interface --- Kyoo.Common/Controllers/ILibraryManager.cs | 560 +++++++---- Kyoo.Common/Controllers/IMetadataProvider.cs | 2 +- Kyoo.Common/Controllers/IRepository.cs | 19 +- Kyoo.Common/Controllers/IThumbnailsManager.cs | 4 +- .../Implementations/LibraryManager.cs | 935 +++++++----------- Kyoo.Common/Models/MetadataID.cs | 4 +- Kyoo.Common/Models/Resources/Library.cs | 6 +- .../Resources/{ProviderID.cs => Provider.cs} | 10 +- Kyoo.Common/Models/WatchItem.cs | 12 +- Kyoo.CommonAPI/LocalRepository.cs | 4 +- Kyoo.WebApp | 2 +- .../Repositories/ProviderRepository.cs | 10 +- Kyoo/Controllers/ThumbnailsManager.cs | 4 +- Kyoo/Models/DatabaseContext.cs | 12 +- ....cs => 20210417232515_Initial.Designer.cs} | 16 +- ...5_Initial.cs => 20210417232515_Initial.cs} | 14 +- .../Internal/DatabaseContextModelSnapshot.cs | 14 +- Kyoo/Startup.cs | 14 + Kyoo/Tasks/Crawler.cs | 46 +- Kyoo/Tasks/ExtractMetadata.cs | 14 +- Kyoo/Views/CollectionApi.cs | 16 +- Kyoo/Views/EpisodeApi.cs | 37 +- Kyoo/Views/GenreApi.cs | 8 +- Kyoo/Views/LibraryApi.cs | 20 +- Kyoo/Views/PeopleApi.cs | 4 +- Kyoo/Views/ProviderApi.cs | 6 +- Kyoo/Views/SearchApi.cs | 50 +- Kyoo/Views/SeasonApi.cs | 26 +- Kyoo/Views/ShowApi.cs | 58 +- Kyoo/Views/StudioApi.cs | 8 +- Kyoo/Views/TrackApi.cs | 4 +- Kyoo/Views/VideoApi.cs | 120 +-- Kyoo/Views/WatchApi.cs | 16 +- 33 files changed, 1008 insertions(+), 1067 deletions(-) rename Kyoo.Common/Models/Resources/{ProviderID.cs => Provider.cs} (79%) rename Kyoo/Models/DatabaseMigrations/Internal/{20210325184215_Initial.Designer.cs => 20210417232515_Initial.Designer.cs} (98%) rename Kyoo/Models/DatabaseMigrations/Internal/{20210325184215_Initial.cs => 20210417232515_Initial.cs} (98%) diff --git a/Kyoo.Common/Controllers/ILibraryManager.cs b/Kyoo.Common/Controllers/ILibraryManager.cs index ae1d0ccb..fb597293 100644 --- a/Kyoo.Common/Controllers/ILibraryManager.cs +++ b/Kyoo.Common/Controllers/ILibraryManager.cs @@ -5,284 +5,454 @@ using System.Runtime.InteropServices; using System.Threading.Tasks; using JetBrains.Annotations; using Kyoo.Models; +using Kyoo.Models.Exceptions; namespace Kyoo.Controllers { + /// + /// An interface to interract with the database. Every repository is mapped through here. + /// public interface ILibraryManager : IDisposable, IAsyncDisposable { - // Repositories + /// + /// Get the repository corresponding to the T item. + /// + /// The type you want + /// If the item is not found + /// The repository corresponding + IRepository GetRepository() where T : class, IResource; + + /// + /// The repository that handle libraries. + /// ILibraryRepository LibraryRepository { get; } + + /// + /// The repository that handle libraries's items (a wrapper arround shows & collections). + /// ILibraryItemRepository LibraryItemRepository { get; } + + /// + /// The repository that handle collections. + /// ICollectionRepository CollectionRepository { get; } + + /// + /// The repository that handle shows. + /// IShowRepository ShowRepository { get; } + + /// + /// The repository that handle seasons. + /// ISeasonRepository SeasonRepository { get; } + + /// + /// The repository that handle episodes. + /// IEpisodeRepository EpisodeRepository { get; } + + /// + /// The repository that handle tracks. + /// ITrackRepository TrackRepository { get; } + + /// + /// The repository that handle people. + /// IPeopleRepository PeopleRepository { get; } + + /// + /// The repository that handle studios. + /// IStudioRepository StudioRepository { get; } + + /// + /// The repository that handle genres. + /// IGenreRepository GenreRepository { get; } + + /// + /// The repository that handle providers. + /// IProviderRepository ProviderRepository { get; } - // Get by id - Task GetLibrary(int id); - Task GetCollection(int id); - Task GetShow(int id); - Task GetSeason(int id); - Task GetSeason(int showID, int seasonNumber); - Task GetEpisode(int id); - Task GetEpisode(int showID, int seasonNumber, int episodeNumber); - Task GetGenre(int id); - Task GetTrack(int id); - Task GetStudio(int id); - Task GetPeople(int id); - Task GetProvider(int id); + /// + /// Get the resource by it's ID + /// + /// The id of the resource + /// The type of the resource + /// If the item is not found + /// The resource found + Task Get(int id) where T : class, IResource; - // Get by slug - Task GetLibrary(string slug); - Task GetCollection(string slug); - Task GetShow(string slug); - Task GetSeason(string slug); - Task GetSeason(string showSlug, int seasonNumber); - Task GetEpisode(string slug); - Task GetEpisode(string showSlug, int seasonNumber, int episodeNumber); - Task GetMovieEpisode(string movieSlug); - Task GetTrack(string slug, StreamType type = StreamType.Unknown); - Task GetGenre(string slug); - Task GetStudio(string slug); - Task GetPeople(string slug); - Task GetProvider(string slug); + /// + /// Get the resource by it's slug + /// + /// The slug of the resource + /// The type of the resource + /// If the item is not found + /// The resource found + Task Get(string slug) where T : class, IResource; - // Get by predicate - Task GetLibrary(Expression> where); - Task GetCollection(Expression> where); - Task GetShow(Expression> where); - Task GetSeason(Expression> where); - Task GetEpisode(Expression> where); - Task GetTrack(Expression> where); - Task GetGenre(Expression> where); - Task GetStudio(Expression> where); - Task GetPerson(Expression> where); + /// + /// Get the resource by a filter function. + /// + /// The filter function. + /// The type of the resource + /// If the item is not found + /// The first resource found that match the where function + Task Get(Expression> where) where T : class, IResource; + /// + /// Get a season from it's showID and it's seasonNumber + /// + /// The id of the show + /// The season's number + /// If the item is not found + /// The season found + Task Get(int showID, int seasonNumber); + + /// + /// Get a season from it's show slug and it's seasonNumber + /// + /// The slug of the show + /// The season's number + /// If the item is not found + /// The season found + Task Get(string showSlug, int seasonNumber); + + /// + /// Get a episode from it's showID, it's seasonNumber and it's episode number. + /// + /// The id of the show + /// The season's number + /// The episode's number + /// If the item is not found + /// The episode found + Task Get(int showID, int seasonNumber, int episodeNumber); + + /// + /// Get a episode from it's show slug, it's seasonNumber and it's episode number. + /// + /// The slug of the show + /// The season's number + /// The episode's number + /// If the item is not found + /// The episode found + Task Get(string showSlug, int seasonNumber, int episodeNumber); + + /// + /// Get a tracck from it's slug and it's type. + /// + /// The slug of the track + /// The type (Video, Audio or Subtitle) + /// If the item is not found + /// The tracl found + Task GetTrack(string slug, StreamType type = StreamType.Unknown); + + + /// + /// Load a related resource + /// + /// The source object. + /// A getter function for the member to load + /// The type of the source object + /// The related resource's type + /// The param Task Load([NotNull] T obj, Expression> member) where T : class, IResource where T2 : class, IResource, new(); + /// + /// Load a collection of related resource + /// + /// The source object. + /// A getter function for the member to load + /// The type of the source object + /// The related resource's type + /// The param Task Load([NotNull] T obj, Expression>> member) where T : class, IResource where T2 : class, new(); + /// + /// Load a related resource by it's name + /// + /// The source object. + /// The name of the resource to load (case sensitive) + /// The type of the source object + /// The param Task Load([NotNull] T obj, string memberName) where T : class, IResource; + /// + /// Load a related resource without specifing it's type. + /// + /// The source object. + /// The name of the resource to load (case sensitive) Task Load([NotNull] IResource obj, string memberName); - - // Library Items relations + + /// + /// Get items (A wrapper arround shows or collections) from a library. + /// + /// The ID of the library + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters Task> GetItemsFromLibrary(int id, Expression> where = null, Sort sort = default, Pagination limit = default); + + /// + /// Get items (A wrapper arround shows or collections) from a library. + /// + /// The ID of the library + /// A filter function + /// A sort by method + /// How many items to return and where to start + /// A list of items that match every filters Task> GetItemsFromLibrary(int id, [Optional] Expression> where, Expression> sort, Pagination limit = default ) => GetItemsFromLibrary(id, where, new Sort(sort), limit); - Task> GetItemsFromLibrary(string librarySlug, + /// + /// Get items (A wrapper arround shows or collections) from a library. + /// + /// The slug of the library + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters + Task> GetItemsFromLibrary(string slug, Expression> where = null, Sort sort = default, Pagination limit = default); - Task> GetItemsFromLibrary(string librarySlug, + + /// + /// Get items (A wrapper arround shows or collections) from a library. + /// + /// The slug of the library + /// A filter function + /// A sort by method + /// How many items to return and where to start + /// A list of items that match every filters + Task> GetItemsFromLibrary(string slug, [Optional] Expression> where, Expression> sort, Pagination limit = default - ) => GetItemsFromLibrary(librarySlug, where, new Sort(sort), limit); + ) => GetItemsFromLibrary(slug, where, new Sort(sort), limit); - // People Role relations + + /// + /// Get people's roles from a show. + /// + /// The ID of the show + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters Task> GetPeopleFromShow(int showID, Expression> where = null, Sort sort = default, Pagination limit = default); + + /// + /// Get people's roles from a show. + /// + /// The ID of the show + /// A filter function + /// A sort by method + /// How many items to return and where to start + /// A list of items that match every filters Task> GetPeopleFromShow(int showID, [Optional] Expression> where, Expression> sort, Pagination limit = default ) => GetPeopleFromShow(showID, where, new Sort(sort), limit); + /// + /// Get people's roles from a show. + /// + /// The slug of the show + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters Task> GetPeopleFromShow(string showSlug, Expression> where = null, Sort sort = default, Pagination limit = default); + + /// + /// Get people's roles from a show. + /// + /// The slug of the show + /// A filter function + /// A sort by method + /// How many items to return and where to start + /// A list of items that match every filters Task> GetPeopleFromShow(string showSlug, [Optional] Expression> where, Expression> sort, Pagination limit = default ) => GetPeopleFromShow(showSlug, where, new Sort(sort), limit); - // Show Role relations - Task> GetRolesFromPeople(int showID, - Expression> where = null, - Sort sort = default, - Pagination limit = default); - Task> GetRolesFromPeople(int showID, - [Optional] Expression> where, - Expression> sort, - Pagination limit = default - ) => GetRolesFromPeople(showID, where, new Sort(sort), limit); - Task> GetRolesFromPeople(string showSlug, + /// + /// Get people's roles from a person. + /// + /// The id of the person + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters + Task> GetRolesFromPeople(int id, Expression> where = null, Sort sort = default, Pagination limit = default); - Task> GetRolesFromPeople(string showSlug, + + /// + /// Get people's roles from a person. + /// + /// The id of the person + /// A filter function + /// A sort by method + /// How many items to return and where to start + /// A list of items that match every filters + Task> GetRolesFromPeople(int id, [Optional] Expression> where, Expression> sort, Pagination limit = default - ) => GetRolesFromPeople(showSlug, where, new Sort(sort), limit); + ) => GetRolesFromPeople(id, where, new Sort(sort), limit); + + /// + /// Get people's roles from a person. + /// + /// The slug of the person + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters + Task> GetRolesFromPeople(string slug, + Expression> where = null, + Sort sort = default, + Pagination limit = default); + + /// + /// Get people's roles from a person. + /// + /// The slug of the person + /// A filter function + /// A sort by method + /// How many items to return and where to start + /// A list of items that match every filters + Task> GetRolesFromPeople(string slug, + [Optional] Expression> where, + Expression> sort, + Pagination limit = default + ) => GetRolesFromPeople(slug, where, new Sort(sort), limit); - // Helpers + + /// + /// Setup relations between a show, a library and a collection + /// + /// The show's ID to setup relations with + /// The library's ID to setup relations with (optional) + /// The collection's ID to setup relations with (optional) Task AddShowLink(int showID, int? libraryID, int? collectionID); + + /// + /// Setup relations between a show, a library and a collection + /// + /// The show to setup relations with + /// The library to setup relations with (optional) + /// The collection to setup relations with (optional) Task AddShowLink([NotNull] Show show, Library library, Collection collection); - - // Get all - Task> GetLibraries(Expression> where = null, - Sort sort = default, - Pagination limit = default); - Task> GetCollections(Expression> where = null, - Sort sort = default, - Pagination limit = default); - Task> GetShows(Expression> where = null, - Sort sort = default, - Pagination limit = default); - Task> GetSeasons(Expression> where = null, - Sort sort = default, - Pagination limit = default); - Task> GetEpisodes(Expression> where = null, - Sort sort = default, - Pagination limit = default); - Task> GetTracks(Expression> where = null, - Sort sort = default, - Pagination limit = default); - Task> GetStudios(Expression> where = null, - Sort sort = default, - Pagination limit = default); - Task> GetPeople(Expression> where = null, - Sort sort = default, - Pagination limit = default); - Task> GetGenres(Expression> where = null, - Sort sort = default, - Pagination limit = default); - Task> GetProviders(Expression> where = null, - Sort sort = default, - Pagination limit = default); - - Task> GetLibraries([Optional] Expression> where, - Expression> sort, - Pagination limit = default - ) => GetLibraries(where, new Sort(sort), limit); - Task> GetCollections([Optional] Expression> where, - Expression> sort, - Pagination limit = default - ) => GetCollections(where, new Sort(sort), limit); - Task> GetShows([Optional] Expression> where, - Expression> sort, - Pagination limit = default - ) => GetShows(where, new Sort(sort), limit); - Task> GetTracks([Optional] Expression> where, - Expression> sort, - Pagination limit = default - ) => GetTracks(where, new Sort(sort), limit); - Task> GetStudios([Optional] Expression> where, - Expression> sort, - Pagination limit = default - ) => GetStudios(where, new Sort(sort), limit); - Task> GetPeople([Optional] Expression> where, - Expression> sort, - Pagination limit = default - ) => GetPeople(where, new Sort(sort), limit); - Task> GetGenres([Optional] Expression> where, - Expression> sort, - Pagination limit = default - ) => GetGenres(where, new Sort(sort), limit); - Task> GetProviders([Optional] Expression> where, - Expression> sort, - Pagination limit = default - ) => GetProviders(where, new Sort(sort), limit); + /// + /// Get all resources with filters + /// + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// The type of resources to load + /// A list of resources that match every filters + Task> GetAll(Expression> where = null, + Sort sort = default, + Pagination limit = default) where T : class, IResource; - // Counts - Task GetLibrariesCount(Expression> where = null); - Task GetCollectionsCount(Expression> where = null); - Task GetShowsCount(Expression> where = null); - Task GetSeasonsCount(Expression> where = null); - Task GetEpisodesCount(Expression> where = null); - Task GetTracksCount(Expression> where = null); - Task GetGenresCount(Expression> where = null); - Task GetStudiosCount(Expression> where = null); - Task GetPeopleCount(Expression> where = null); + /// + /// Get all resources with filters + /// + /// A filter function + /// A sort by function + /// How many items to return and where to start + /// The type of resources to load + /// A list of resources that match every filters + Task> GetAll([Optional] Expression> where, + Expression> sort, + Pagination limit = default) where T : class, IResource + { + return GetAll(where, new Sort(sort), limit); + } + + /// + /// Get the count of resources that match the filter + /// + /// A filter function + /// The type of resources to load + /// A list of resources that match every filters + Task GetCount(Expression> where = null) where T : class, IResource; + + /// + /// Search for a resource + /// + /// The search query + /// The type of resources + /// A list of 20 items that match the search query + Task> Search(string query) where T : class, IResource; + + /// + /// Create a new resource. + /// + /// The item to register + /// The type of resource + /// The resource registers and completed by database's informations (related items & so on) + Task Create(T item) where T : class, IResource; - // Search - Task> SearchLibraries(string searchQuery); - Task> SearchCollections(string searchQuery); - Task> SearchShows(string searchQuery); - Task> SearchSeasons(string searchQuery); - Task> SearchEpisodes(string searchQuery); - Task> SearchGenres(string searchQuery); - Task> SearchStudios(string searchQuery); - Task> SearchPeople(string searchQuery); + /// + /// Edit a resource + /// + /// The resourcce to edit, it's ID can't change. + /// Should old properties of the resource be discarded or should null values considered as not changed? + /// The type of resources + /// The resource edited and completed by database's informations (related items & so on) + Task Edit(T item, bool resetOld) where T : class, IResource; + + /// + /// Delete a resource. + /// + /// The resource to delete + /// The type of resource to delete + Task Delete(T item) where T : class, IResource; - //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); + /// + /// Delete a resource by it's ID. + /// + /// The id of the resource to delete + /// The type of resource to delete + Task Delete(int id) where T : class, IResource; - // 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); - - // Delete values - Task DeleteLibrary(Library library); - Task DeleteCollection(Collection collection); - Task DeleteShow(Show show); - Task DeleteSeason(Season season); - Task DeleteEpisode(Episode episode); - Task DeleteTrack(Track track); - Task DeleteGenre(Genre genre); - Task DeleteStudio(Studio studio); - Task DeletePeople(People people); - - //Delete by slug - Task DeleteLibrary(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 DeleteLibrary(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); + /// + /// Delete a resource by it's slug. + /// + /// The slug of the resource to delete + /// The type of resource to delete + Task Delete(string slug) where T : class, IResource; } } diff --git a/Kyoo.Common/Controllers/IMetadataProvider.cs b/Kyoo.Common/Controllers/IMetadataProvider.cs index 6cf8a6ac..ce9592f9 100644 --- a/Kyoo.Common/Controllers/IMetadataProvider.cs +++ b/Kyoo.Common/Controllers/IMetadataProvider.cs @@ -6,7 +6,7 @@ namespace Kyoo.Controllers { public interface IMetadataProvider { - ProviderID Provider { get; } + Provider Provider { get; } Task GetCollectionFromName(string name); diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Common/Controllers/IRepository.cs index 5beee98b..1caccfc5 100644 --- a/Kyoo.Common/Controllers/IRepository.cs +++ b/Kyoo.Common/Controllers/IRepository.cs @@ -23,10 +23,10 @@ namespace Kyoo.Controllers public static implicit operator Pagination(int limit) => new(limit); } - public struct Sort + public readonly struct Sort { - public Expression> Key; - public bool Descendant; + public Expression> Key { get; } + public bool Descendant { get; } public Sort(Expression> key, bool descendant = false) { @@ -46,8 +46,8 @@ namespace Kyoo.Controllers return; } - string key = sortBy.Contains(':') ? sortBy.Substring(0, sortBy.IndexOf(':')) : sortBy; - string order = sortBy.Contains(':') ? sortBy.Substring(sortBy.IndexOf(':') + 1) : null; + string key = sortBy.Contains(':') ? sortBy[..sortBy.IndexOf(':')] : sortBy; + string order = sortBy.Contains(':') ? sortBy[(sortBy.IndexOf(':') + 1)..] : null; ParameterExpression param = Expression.Parameter(typeof(T), "x"); MemberExpression property = Expression.Property(param, key); @@ -64,8 +64,13 @@ namespace Kyoo.Controllers }; } } + + public interface IBaseRepository : IDisposable, IAsyncDisposable + { + Type RepositoryType { get; } + } - public interface IRepository : IDisposable, IAsyncDisposable where T : class, IResource + public interface IRepository : IBaseRepository where T : class, IResource { Task Get(int id); Task Get(string slug); @@ -204,7 +209,7 @@ namespace Kyoo.Controllers ) => GetFromPeople(showSlug, where, new Sort(sort), limit); } - public interface IProviderRepository : IRepository + public interface IProviderRepository : IRepository { Task> GetMetadataID(Expression> where = null, Sort sort = default, diff --git a/Kyoo.Common/Controllers/IThumbnailsManager.cs b/Kyoo.Common/Controllers/IThumbnailsManager.cs index 5d2597cf..2282981a 100644 --- a/Kyoo.Common/Controllers/IThumbnailsManager.cs +++ b/Kyoo.Common/Controllers/IThumbnailsManager.cs @@ -11,7 +11,7 @@ namespace Kyoo.Controllers Task Validate(Season season, bool alwaysDownload = false); Task Validate(Episode episode, bool alwaysDownload = false); Task Validate(People actors, bool alwaysDownload = false); - Task Validate(ProviderID actors, bool alwaysDownload = false); + Task Validate(Provider actors, bool alwaysDownload = false); Task GetShowPoster([NotNull] Show show); Task GetShowLogo([NotNull] Show show); @@ -19,6 +19,6 @@ namespace Kyoo.Controllers Task GetSeasonPoster([NotNull] Season season); Task GetEpisodeThumb([NotNull] Episode episode); Task GetPeoplePoster([NotNull] People people); - Task GetProviderLogo([NotNull] ProviderID provider); + Task GetProviderLogo([NotNull] Provider provider); } } diff --git a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs index 7cae9b4d..366cb0ea 100644 --- a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs +++ b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs @@ -4,248 +4,232 @@ using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using Kyoo.Models; +using Kyoo.Models.Exceptions; namespace Kyoo.Controllers { public class LibraryManager : ILibraryManager { + /// + /// The list of repositories + /// + private readonly IBaseRepository[] _repositories; + + + public LibraryManager(IEnumerable repositories) + { + _repositories = repositories.ToArray(); + LibraryRepository = GetRepository() as ILibraryRepository; + LibraryItemRepository = GetRepository() as ILibraryItemRepository; + CollectionRepository = GetRepository() as ICollectionRepository; + ShowRepository = GetRepository() as IShowRepository; + SeasonRepository = GetRepository() as ISeasonRepository; + EpisodeRepository = GetRepository() as IEpisodeRepository; + TrackRepository = GetRepository() as ITrackRepository; + PeopleRepository = GetRepository() as IPeopleRepository; + StudioRepository = GetRepository() as IStudioRepository; + GenreRepository = GetRepository() as IGenreRepository; + ProviderRepository = GetRepository() as IProviderRepository; + } + + /// + /// The repository that handle libraries. + /// public ILibraryRepository LibraryRepository { get; } + + /// + /// The repository that handle libraries's items (a wrapper arround shows & collections). + /// public ILibraryItemRepository LibraryItemRepository { get; } + + /// + /// The repository that handle collections. + /// public ICollectionRepository CollectionRepository { get; } + + /// + /// The repository that handle shows. + /// public IShowRepository ShowRepository { get; } + + /// + /// The repository that handle seasons. + /// public ISeasonRepository SeasonRepository { get; } + + /// + /// The repository that handle episodes. + /// public IEpisodeRepository EpisodeRepository { get; } + + /// + /// The repository that handle tracks. + /// public ITrackRepository TrackRepository { get; } - public IGenreRepository GenreRepository { get; } - public IStudioRepository StudioRepository { get; } + + /// + /// The repository that handle people. + /// public IPeopleRepository PeopleRepository { get; } + + /// + /// The repository that handle studios. + /// + public IStudioRepository StudioRepository { get; } + + /// + /// The repository that handle genres. + /// + public IGenreRepository GenreRepository { get; } + + /// + /// The repository that handle providers. + /// public IProviderRepository ProviderRepository { get; } - public LibraryManager(ILibraryRepository libraryRepository, - ILibraryItemRepository libraryItemRepository, - ICollectionRepository collectionRepository, - IShowRepository showRepository, - ISeasonRepository seasonRepository, - IEpisodeRepository episodeRepository, - ITrackRepository trackRepository, - IGenreRepository genreRepository, - IStudioRepository studioRepository, - IProviderRepository providerRepository, - IPeopleRepository peopleRepository) + + /// + /// Get the resource by it's ID + /// + /// The id of the resource + /// The type of the resource + /// If the item is not found + /// The resource found + public Task Get(int id) + where T : class, IResource { - LibraryRepository = libraryRepository; - LibraryItemRepository = libraryItemRepository; - CollectionRepository = collectionRepository; - ShowRepository = showRepository; - SeasonRepository = seasonRepository; - EpisodeRepository = episodeRepository; - TrackRepository = trackRepository; - GenreRepository = genreRepository; - StudioRepository = studioRepository; - ProviderRepository = providerRepository; - PeopleRepository = peopleRepository; - } - - public void Dispose() - { - LibraryRepository.Dispose(); - CollectionRepository.Dispose(); - ShowRepository.Dispose(); - SeasonRepository.Dispose(); - EpisodeRepository.Dispose(); - TrackRepository.Dispose(); - GenreRepository.Dispose(); - StudioRepository.Dispose(); - PeopleRepository.Dispose(); - ProviderRepository.Dispose(); - } - - public async ValueTask DisposeAsync() - { - await Task.WhenAll( - LibraryRepository.DisposeAsync().AsTask(), - CollectionRepository.DisposeAsync().AsTask(), - ShowRepository.DisposeAsync().AsTask(), - SeasonRepository.DisposeAsync().AsTask(), - EpisodeRepository.DisposeAsync().AsTask(), - TrackRepository.DisposeAsync().AsTask(), - GenreRepository.DisposeAsync().AsTask(), - StudioRepository.DisposeAsync().AsTask(), - PeopleRepository.DisposeAsync().AsTask(), - ProviderRepository.DisposeAsync().AsTask() - ); + return GetRepository().Get(id); } - public Task GetLibrary(int id) + /// + /// Get the resource by it's slug + /// + /// The slug of the resource + /// The type of the resource + /// If the item is not found + /// The resource found + public Task Get(string slug) + where T : class, IResource { - return LibraryRepository.Get(id); + return GetRepository().Get(slug); } - public Task GetCollection(int id) + /// + /// Get the resource by a filter function. + /// + /// The filter function. + /// The type of the resource + /// If the item is not found + /// The first resource found that match the where function + public Task Get(Expression> where) + where T : class, IResource { - return CollectionRepository.Get(id); + return GetRepository().Get(where); } - public Task GetShow(int id) - { - return ShowRepository.Get(id); - } - - public Task GetSeason(int id) - { - return SeasonRepository.Get(id); - } - - public Task GetSeason(int showID, int seasonNumber) + /// + /// Get a season from it's showID and it's seasonNumber + /// + /// The id of the show + /// The season's number + /// If the item is not found + /// The season found + public Task Get(int showID, int seasonNumber) { return SeasonRepository.Get(showID, seasonNumber); } - - public Task GetEpisode(int id) + + /// + /// Get a season from it's show slug and it's seasonNumber + /// + /// The slug of the show + /// The season's number + /// If the item is not found + /// The season found + public Task Get(string showSlug, int seasonNumber) { - return EpisodeRepository.Get(id); + return SeasonRepository.Get(showSlug, seasonNumber); } - public Task GetEpisode(int showID, int seasonNumber, int episodeNumber) + /// + /// Get a episode from it's showID, it's seasonNumber and it's episode number. + /// + /// The id of the show + /// The season's number + /// The episode's number + /// If the item is not found + /// The episode found + public Task Get(int showID, int seasonNumber, int episodeNumber) { return EpisodeRepository.Get(showID, seasonNumber, episodeNumber); } + /// + /// Get a episode from it's show slug, it's seasonNumber and it's episode number. + /// + /// The slug of the show + /// The season's number + /// The episode's number + /// If the item is not found + /// The episode found + public Task Get(string showSlug, int seasonNumber, int episodeNumber) + { + return EpisodeRepository.Get(showSlug, seasonNumber, episodeNumber); + } + + /// + /// Get a tracck from it's slug and it's type. + /// + /// The slug of the track + /// The type (Video, Audio or Subtitle) + /// If the item is not found + /// The tracl found public Task GetTrack(string slug, StreamType type = StreamType.Unknown) { return TrackRepository.Get(slug, type); } - public Task GetGenre(int id) + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() { - return GenreRepository.Get(id); + foreach (IBaseRepository repo in _repositories) + repo.Dispose(); + GC.SuppressFinalize(this); } - public Task GetStudio(int id) + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources asynchronously. + /// + /// A task that represents the asynchronous dispose operation. + public async ValueTask DisposeAsync() { - return StudioRepository.Get(id); + await Task.WhenAll(_repositories.Select(x => x.DisposeAsync().AsTask())); } - public Task GetPeople(int id) + /// + /// Get the repository corresponding to the T item. + /// + /// The type you want + /// If the item is not found + /// The repository corresponding + public IRepository GetRepository() + where T : class, IResource { - return PeopleRepository.Get(id); - } - - public Task GetProvider(int id) - { - return ProviderRepository.Get(id); - } - - public Task GetLibrary(string slug) - { - return LibraryRepository.Get(slug); - } - - public Task GetCollection(string slug) - { - return CollectionRepository.Get(slug); - } - - public Task GetShow(string slug) - { - return ShowRepository.Get(slug); - } - - public Task GetSeason(string slug) - { - return SeasonRepository.Get(slug); - } - - public Task GetSeason(string showSlug, int seasonNumber) - { - return SeasonRepository.Get(showSlug, seasonNumber); - } - - public Task GetEpisode(string slug) - { - return EpisodeRepository.Get(slug); - } - - public Task GetEpisode(string showSlug, int seasonNumber, int episodeNumber) - { - return EpisodeRepository.Get(showSlug, seasonNumber, episodeNumber); - } - - public Task GetMovieEpisode(string movieSlug) - { - return EpisodeRepository.Get(movieSlug); - } - - public Task GetTrack(int id) - { - return TrackRepository.Get(id); - } - - public Task GetGenre(string slug) - { - return GenreRepository.Get(slug); - } - - public Task GetStudio(string slug) - { - return StudioRepository.Get(slug); - } - - public Task GetPeople(string slug) - { - return PeopleRepository.Get(slug); - } - - public Task GetProvider(string slug) - { - return ProviderRepository.Get(slug); - } - - public Task GetLibrary(Expression> where) - { - return LibraryRepository.Get(where); - } - - public Task GetCollection(Expression> where) - { - return CollectionRepository.Get(where); - } - - public Task GetShow(Expression> where) - { - return ShowRepository.Get(where); - } - - public Task GetSeason(Expression> where) - { - return SeasonRepository.Get(where); - } - - public Task GetEpisode(Expression> where) - { - return EpisodeRepository.Get(where); - } - - public Task GetTrack(Expression> where) - { - return TrackRepository.Get(where); - } - - public Task GetGenre(Expression> where) - { - return GenreRepository.Get(where); - } - - public Task GetStudio(Expression> where) - { - return StudioRepository.Get(where); - } - - public Task GetPerson(Expression> where) - { - return PeopleRepository.Get(where); + if (_repositories.FirstOrDefault(x => x.RepositoryType == typeof(T)) is IRepository ret) + return ret; + throw new ItemNotFound(); } + /// + /// Load a related resource + /// + /// The source object. + /// A getter function for the member to load + /// The type of the source object + /// The related resource's type + /// The param public Task Load(T obj, Expression> member) where T : class, IResource where T2 : class, IResource, new() @@ -255,6 +239,14 @@ namespace Kyoo.Controllers return Load(obj, Utility.GetPropertyName(member)); } + /// + /// Load a collection of related resource + /// + /// The source object. + /// A getter function for the member to load + /// The type of the source object + /// The related resource's type + /// The param public Task Load(T obj, Expression>> member) where T : class, IResource where T2 : class, new() @@ -264,14 +256,30 @@ namespace Kyoo.Controllers return Load(obj, Utility.GetPropertyName(member)); } - public async Task Load(T obj, string member) + /// + /// Load a related resource by it's name + /// + /// The source object. + /// The name of the resource to load (case sensitive) + /// The type of the source object + /// The param + public async Task Load(T obj, string memberName) where T : class, IResource { - await Load(obj as IResource, member); + await Load(obj as IResource, memberName); return obj; } - private async Task SetRelation(T1 obj, + /// + /// Set relations between to objects. + /// + /// The owner object + /// A Task to load a collection of related objects + /// A setter function to store the collection of related objects + /// A setter function to store the owner of a releated object loaded + /// The type of the owner object + /// The type of the related object + private static async Task SetRelation(T1 obj, Task> loader, Action> setter, Action inverse) @@ -282,12 +290,17 @@ namespace Kyoo.Controllers inverse(item, obj); } - public Task Load(IResource obj, string member) + /// + /// Load a related resource without specifing it's type. + /// + /// The source object. + /// The name of the resource to load (case sensitive) + public Task Load(IResource obj, string memberName) { if (obj == null) throw new ArgumentNullException(nameof(obj)); - return (obj, member) switch + return (obj, member: memberName) switch { (Library l, nameof(Library.Providers)) => ProviderRepository .GetAll(x => x.Libraries.Any(y => y.ID == obj.ID)) @@ -426,85 +439,23 @@ namespace Kyoo.Controllers .Then(x => p.Roles = x), - (ProviderID p, nameof(ProviderID.Libraries)) => LibraryRepository + (Provider p, nameof(Provider.Libraries)) => LibraryRepository .GetAll(x => x.Providers.Any(y => y.ID == obj.ID)) .Then(x => p.Libraries = x), - _ => throw new ArgumentException($"Couldn't find a way to load {member} of {obj.Slug}.") + _ => throw new ArgumentException($"Couldn't find a way to load {memberName} of {obj.Slug}.") }; } - - public Task> GetLibraries(Expression> where = null, - Sort sort = default, - Pagination page = default) - { - return LibraryRepository.GetAll(where, sort, page); - } - - public Task> GetCollections(Expression> where = null, - Sort sort = default, - Pagination page = default) - { - return CollectionRepository.GetAll(where, sort, page); - } - - public Task> GetShows(Expression> where = null, - Sort sort = default, - Pagination limit = default) - { - return ShowRepository.GetAll(where, sort, limit); - } - - public Task> GetSeasons(Expression> where = null, - Sort sort = default, - Pagination limit = default) - { - return SeasonRepository.GetAll(where, sort, limit); - } - - public Task> GetEpisodes(Expression> where = null, - Sort sort = default, - Pagination limit = default) - { - return EpisodeRepository.GetAll(where, sort, limit); - } - - public Task> GetTracks(Expression> where = null, - Sort sort = default, - Pagination page = default) - { - return TrackRepository.GetAll(where, sort, page); - } - - public Task> GetStudios(Expression> where = null, - Sort sort = default, - Pagination page = default) - { - return StudioRepository.GetAll(where, sort, page); - } - - public Task> GetPeople(Expression> where = null, - Sort sort = default, - Pagination page = default) - { - return PeopleRepository.GetAll(where, sort, page); - } - - public Task> GetGenres(Expression> where = null, - Sort sort = default, - Pagination page = default) - { - return GenreRepository.GetAll(where, sort, page); - } - - public Task> GetProviders(Expression> where = null, - Sort sort = default, - Pagination page = default) - { - return ProviderRepository.GetAll(where, sort, page); - } + /// + /// Get items (A wrapper arround shows or collections) from a library. + /// + /// The ID of the library + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters public Task> GetItemsFromLibrary(int id, Expression> where = null, Sort sort = default, @@ -513,366 +464,206 @@ namespace Kyoo.Controllers return LibraryItemRepository.GetFromLibrary(id, where, sort, limit); } - public Task> GetItemsFromLibrary(string librarySlug, - Expression> where = null, + /// + /// Get items (A wrapper arround shows or collections) from a library. + /// + /// The slug of the library + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters + public Task> GetItemsFromLibrary(string slug, + Expression> where = null, Sort sort = default, Pagination limit = default) { - return LibraryItemRepository.GetFromLibrary(librarySlug, where, sort, limit); + return LibraryItemRepository.GetFromLibrary(slug, where, sort, limit); } - - public Task> GetPeopleFromShow(int showID, + + /// + /// Get people's roles from a show. + /// + /// The ID of the show + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters + public Task> GetPeopleFromShow(int showID, Expression> where = null, Sort sort = default, Pagination limit = default) { return PeopleRepository.GetFromShow(showID, where, sort, limit); } - - public Task> GetPeopleFromShow(string showSlug, + + /// + /// Get people's roles from a show. + /// + /// The slug of the show + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters + public Task> GetPeopleFromShow(string showSlug, Expression> where = null, - Sort sort = default, + Sort sort = default, Pagination limit = default) { return PeopleRepository.GetFromShow(showSlug, where, sort, limit); } - + + /// + /// Get people's roles from a person. + /// + /// The id of the person + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters public Task> GetRolesFromPeople(int id, - Expression> where = null, - Sort sort = default, + 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, + /// + /// Get people's roles from a person. + /// + /// The slug of the person + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// A list of items that match every filters + public Task> GetRolesFromPeople(string slug, + Expression> where = null, + Sort sort = default, Pagination limit = default) { return PeopleRepository.GetFromPeople(slug, where, sort, limit); } - public Task GetLibrariesCount(Expression> where = null) - { - return LibraryRepository.GetCount(where); - } - - public Task GetCollectionsCount(Expression> where = null) - { - return CollectionRepository.GetCount(where); - } - - public Task GetShowsCount(Expression> where = null) - { - return ShowRepository.GetCount(where); - } - - public Task GetSeasonsCount(Expression> where = null) - { - return SeasonRepository.GetCount(where); - } - - public Task GetEpisodesCount(Expression> where = null) - { - return EpisodeRepository.GetCount(where); - } - - public Task GetTracksCount(Expression> where = null) - { - return TrackRepository.GetCount(where); - } - - public Task GetGenresCount(Expression> where = null) - { - return GenreRepository.GetCount(where); - } - - public Task GetStudiosCount(Expression> where = null) - { - return StudioRepository.GetCount(where); - } - - public Task GetPeopleCount(Expression> where = null) - { - return PeopleRepository.GetCount(where); - } - + /// + /// Setup relations between a show, a library and a collection + /// + /// The show's ID to setup relations with + /// The library's ID to setup relations with (optional) + /// The collection's ID to setup relations with (optional) public Task AddShowLink(int showID, int? libraryID, int? collectionID) { return ShowRepository.AddShowLink(showID, libraryID, collectionID); } + /// + /// Setup relations between a show, a library and a collection + /// + /// The show to setup relations with + /// The library to setup relations with (optional) + /// The collection to setup relations with (optional) public Task AddShowLink(Show show, Library library, Collection collection) { if (show == null) throw new ArgumentNullException(nameof(show)); - return AddShowLink(show.ID, library?.ID, collection?.ID); - } - - public Task> SearchLibraries(string searchQuery) - { - return LibraryRepository.Search(searchQuery); + return ShowRepository.AddShowLink(show.ID, library?.ID, collection?.ID); } - public Task> SearchCollections(string searchQuery) + /// + /// Get all resources with filters + /// + /// A filter function + /// Sort informations (sort order & sort by) + /// How many items to return and where to start + /// The type of resources to load + /// A list of resources that match every filters + public Task> GetAll(Expression> where = null, + Sort sort = default, + Pagination limit = default) + where T : class, IResource { - return CollectionRepository.Search(searchQuery); + return GetRepository().GetAll(where, sort, limit); } - public Task> SearchShows(string searchQuery) + /// + /// Get the count of resources that match the filter + /// + /// A filter function + /// The type of resources to load + /// A list of resources that match every filters + public Task GetCount(Expression> where = null) + where T : class, IResource { - return ShowRepository.Search(searchQuery); + return GetRepository().GetCount(where); } - public Task> SearchSeasons(string searchQuery) + /// + /// Search for a resource + /// + /// The search query + /// The type of resources + /// A list of 20 items that match the search query + public Task> Search(string query) + where T : class, IResource { - return SeasonRepository.Search(searchQuery); + return GetRepository().Search(query); } - public Task> SearchEpisodes(string searchQuery) + /// + /// Create a new resource. + /// + /// The item to register + /// The type of resource + /// The resource registers and completed by database's informations (related items & so on) + public Task Create(T item) + where T : class, IResource { - return EpisodeRepository.Search(searchQuery); + return GetRepository().Create(item); } - public Task> SearchGenres(string searchQuery) + /// + /// Edit a resource + /// + /// The resourcce to edit, it's ID can't change. + /// Should old properties of the resource be discarded or should null values considered as not changed? + /// The type of resources + /// The resource edited and completed by database's informations (related items & so on) + public Task Edit(T item, bool resetOld) + where T : class, IResource { - return GenreRepository.Search(searchQuery); + return GetRepository().Edit(item, resetOld); } - public Task> SearchStudios(string searchQuery) + /// + /// Delete a resource. + /// + /// The resource to delete + /// The type of resource to delete + public Task Delete(T item) + where T : class, IResource { - return StudioRepository.Search(searchQuery); + return GetRepository().Delete(item); } - public Task> SearchPeople(string searchQuery) + /// + /// Delete a resource by it's ID. + /// + /// The id of the resource to delete + /// The type of resource to delete + public Task Delete(int id) + where T : class, IResource { - return PeopleRepository.Search(searchQuery); - } - - public Task RegisterLibrary(Library library) - { - return LibraryRepository.Create(library); + return GetRepository().Delete(id); } - public Task RegisterCollection(Collection collection) + /// + /// Delete a resource by it's slug. + /// + /// The slug of the resource to delete + /// The type of resource to delete + public Task Delete(string slug) + where T : class, IResource { - return CollectionRepository.Create(collection); - } - - public Task RegisterShow(Show show) - { - return ShowRepository.Create(show); - } - - public Task RegisterSeason(Season season) - { - return SeasonRepository.Create(season); - } - - public Task RegisterEpisode(Episode episode) - { - return EpisodeRepository.Create(episode); - } - - public Task RegisterTrack(Track track) - { - return TrackRepository.Create(track); - } - - public Task RegisterGenre(Genre genre) - { - return GenreRepository.Create(genre); - } - - public Task RegisterStudio(Studio studio) - { - return StudioRepository.Create(studio); - } - - public Task RegisterPeople(People people) - { - return PeopleRepository.Create(people); - } - - public Task EditLibrary(Library library, bool resetOld) - { - return LibraryRepository.Edit(library, resetOld); - } - - public Task EditCollection(Collection collection, bool resetOld) - { - return CollectionRepository.Edit(collection, resetOld); - } - - public Task EditShow(Show show, bool resetOld) - { - return ShowRepository.Edit(show, resetOld); - } - - public Task EditSeason(Season season, bool resetOld) - { - return SeasonRepository.Edit(season, resetOld); - } - - public Task EditEpisode(Episode episode, bool resetOld) - { - return EpisodeRepository.Edit(episode, resetOld); - } - - public Task EditTrack(Track track, bool resetOld) - { - return TrackRepository.Edit(track, resetOld); - } - - public Task EditGenre(Genre genre, bool resetOld) - { - return GenreRepository.Edit(genre, resetOld); - } - - public Task EditStudio(Studio studio, bool resetOld) - { - return StudioRepository.Edit(studio, resetOld); - } - - public Task EditPeople(People people, bool resetOld) - { - return PeopleRepository.Edit(people, resetOld); - } - - public Task DeleteLibrary(Library library) - { - return LibraryRepository.Delete(library); - } - - public Task DeleteCollection(Collection collection) - { - return CollectionRepository.Delete(collection); - } - - public Task DeleteShow(Show show) - { - return ShowRepository.Delete(show); - } - - public Task DeleteSeason(Season season) - { - return SeasonRepository.Delete(season); - } - - public Task DeleteEpisode(Episode episode) - { - return EpisodeRepository.Delete(episode); - } - - public Task DeleteTrack(Track track) - { - return TrackRepository.Delete(track); - } - - public Task DeleteGenre(Genre genre) - { - return GenreRepository.Delete(genre); - } - - public Task DeleteStudio(Studio studio) - { - return StudioRepository.Delete(studio); - } - - public Task DeletePeople(People people) - { - return PeopleRepository.Delete(people); - } - - public Task DeleteLibrary(string library) - { - return LibraryRepository.Delete(library); - } - - public Task DeleteCollection(string collection) - { - return CollectionRepository.Delete(collection); - } - - public Task DeleteShow(string show) - { - return ShowRepository.Delete(show); - } - - public Task DeleteSeason(string season) - { - return SeasonRepository.Delete(season); - } - - public Task DeleteEpisode(string episode) - { - return EpisodeRepository.Delete(episode); - } - - public Task DeleteTrack(string track) - { - return TrackRepository.Delete(track); - } - - public Task DeleteGenre(string genre) - { - return GenreRepository.Delete(genre); - } - - public Task DeleteStudio(string studio) - { - return StudioRepository.Delete(studio); - } - - public Task DeletePeople(string people) - { - return PeopleRepository.Delete(people); - } - - public Task DeleteLibrary(int library) - { - return LibraryRepository.Delete(library); - } - - public Task DeleteCollection(int collection) - { - return CollectionRepository.Delete(collection); - } - - public Task DeleteShow(int show) - { - return ShowRepository.Delete(show); - } - - public Task DeleteSeason(int season) - { - return SeasonRepository.Delete(season); - } - - public Task DeleteEpisode(int episode) - { - return EpisodeRepository.Delete(episode); - } - - public Task DeleteTrack(int track) - { - return TrackRepository.Delete(track); - } - - public Task DeleteGenre(int genre) - { - return GenreRepository.Delete(genre); - } - - public Task DeleteStudio(int studio) - { - return StudioRepository.Delete(studio); - } - - public Task DeletePeople(int people) - { - return PeopleRepository.Delete(people); + return GetRepository().Delete(slug); } } } diff --git a/Kyoo.Common/Models/MetadataID.cs b/Kyoo.Common/Models/MetadataID.cs index 71e1946a..cc7985ac 100644 --- a/Kyoo.Common/Models/MetadataID.cs +++ b/Kyoo.Common/Models/MetadataID.cs @@ -6,7 +6,7 @@ namespace Kyoo.Models { [SerializeIgnore] public int ID { get; set; } [SerializeIgnore] public int ProviderID { get; set; } - public virtual ProviderID Provider {get; set; } + public virtual Provider Provider {get; set; } [SerializeIgnore] public int? ShowID { get; set; } [SerializeIgnore] public virtual Show Show { get; set; } @@ -25,7 +25,7 @@ namespace Kyoo.Models public MetadataID() { } - public MetadataID(ProviderID provider, string dataID, string link) + public MetadataID(Provider provider, string dataID, string link) { Provider = provider; DataID = dataID; diff --git a/Kyoo.Common/Models/Resources/Library.cs b/Kyoo.Common/Models/Resources/Library.cs index c1e17b56..86cb324d 100644 --- a/Kyoo.Common/Models/Resources/Library.cs +++ b/Kyoo.Common/Models/Resources/Library.cs @@ -11,20 +11,20 @@ namespace Kyoo.Models public string Name { get; set; } public string[] Paths { get; set; } - [EditableRelation] [LoadableRelation] public virtual ICollection Providers { get; set; } + [EditableRelation] [LoadableRelation] public virtual ICollection Providers { get; set; } [LoadableRelation] public virtual ICollection Shows { get; set; } [LoadableRelation] public virtual ICollection Collections { get; set; } #if ENABLE_INTERNAL_LINKS - [SerializeIgnore] public virtual ICollection> ProviderLinks { get; set; } + [SerializeIgnore] public virtual ICollection> ProviderLinks { get; set; } [SerializeIgnore] public virtual ICollection> ShowLinks { get; set; } [SerializeIgnore] public virtual ICollection> CollectionLinks { get; set; } #endif public Library() { } - public Library(string slug, string name, IEnumerable paths, IEnumerable providers) + public Library(string slug, string name, IEnumerable paths, IEnumerable providers) { Slug = slug; Name = name; diff --git a/Kyoo.Common/Models/Resources/ProviderID.cs b/Kyoo.Common/Models/Resources/Provider.cs similarity index 79% rename from Kyoo.Common/Models/Resources/ProviderID.cs rename to Kyoo.Common/Models/Resources/Provider.cs index 2d1ec3d1..6a19f27c 100644 --- a/Kyoo.Common/Models/Resources/ProviderID.cs +++ b/Kyoo.Common/Models/Resources/Provider.cs @@ -3,7 +3,7 @@ using Kyoo.Models.Attributes; namespace Kyoo.Models { - public class ProviderID : IResource + public class Provider : IResource { public int ID { get; set; } public string Slug { get; set; } @@ -13,20 +13,20 @@ namespace Kyoo.Models [LoadableRelation] public virtual ICollection Libraries { get; set; } #if ENABLE_INTERNAL_LINKS - [SerializeIgnore] public virtual ICollection> LibraryLinks { get; set; } + [SerializeIgnore] public virtual ICollection> LibraryLinks { get; set; } [SerializeIgnore] public virtual ICollection MetadataLinks { get; set; } #endif - public ProviderID() { } + public Provider() { } - public ProviderID(string name, string logo) + public Provider(string name, string logo) { Slug = Utility.ToSlug(name); Name = name; Logo = logo; } - public ProviderID(int id, string name, string logo) + public Provider(int id, string name, string logo) { ID = id; Slug = Utility.ToSlug(name); diff --git a/Kyoo.Common/Models/WatchItem.cs b/Kyoo.Common/Models/WatchItem.cs index ccf5f602..8ab7b5dc 100644 --- a/Kyoo.Common/Models/WatchItem.cs +++ b/Kyoo.Common/Models/WatchItem.cs @@ -109,18 +109,18 @@ namespace Kyoo.Models if (!ep.Show.IsMovie) { if (ep.EpisodeNumber > 1) - previous = await library.GetEpisode(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber - 1); + previous = await library.Get(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber - 1); else if (ep.SeasonNumber > 1) { - int count = await library.GetEpisodesCount(x => x.ShowID == ep.ShowID + int count = await library.GetCount(x => x.ShowID == ep.ShowID && x.SeasonNumber == ep.SeasonNumber - 1); - previous = await library.GetEpisode(ep.ShowID, ep.SeasonNumber - 1, count); + previous = await library.Get(ep.ShowID, ep.SeasonNumber - 1, count); } - if (ep.EpisodeNumber >= await library.GetEpisodesCount(x => x.SeasonID == ep.SeasonID)) - next = await library.GetEpisode(ep.ShowID, ep.SeasonNumber + 1, 1); + if (ep.EpisodeNumber >= await library.GetCount(x => x.SeasonID == ep.SeasonID)) + next = await library.Get(ep.ShowID, ep.SeasonNumber + 1, 1); else - next = await library.GetEpisode(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber + 1); + next = await library.Get(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber + 1); } return new WatchItem(ep.ID, diff --git a/Kyoo.CommonAPI/LocalRepository.cs b/Kyoo.CommonAPI/LocalRepository.cs index 5da8fcc0..1cea2af3 100644 --- a/Kyoo.CommonAPI/LocalRepository.cs +++ b/Kyoo.CommonAPI/LocalRepository.cs @@ -24,7 +24,9 @@ namespace Kyoo.Controllers { Database = database; } - + + public Type RepositoryType => typeof(T); + public virtual void Dispose() { Database.Dispose(); diff --git a/Kyoo.WebApp b/Kyoo.WebApp index ddf3337a..da35a725 160000 --- a/Kyoo.WebApp +++ b/Kyoo.WebApp @@ -1 +1 @@ -Subproject commit ddf3337acb766ae9e0987044ae38130d94fe60ad +Subproject commit da35a725a3e47db0994a697595aec4a10a4886e3 diff --git a/Kyoo/Controllers/Repositories/ProviderRepository.cs b/Kyoo/Controllers/Repositories/ProviderRepository.cs index 79cc80b1..2d90b889 100644 --- a/Kyoo/Controllers/Repositories/ProviderRepository.cs +++ b/Kyoo/Controllers/Repositories/ProviderRepository.cs @@ -8,10 +8,10 @@ using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers { - public class ProviderRepository : LocalRepository, IProviderRepository + public class ProviderRepository : LocalRepository, IProviderRepository { private readonly DatabaseContext _database; - protected override Expression> DefaultSort => x => x.Slug; + protected override Expression> DefaultSort => x => x.Slug; public ProviderRepository(DatabaseContext database) : base(database) @@ -19,7 +19,7 @@ namespace Kyoo.Controllers _database = database; } - public override async Task> Search(string query) + public override async Task> Search(string query) { return await _database.Providers .Where(x => EF.Functions.ILike(x.Name, $"%{query}%")) @@ -28,7 +28,7 @@ namespace Kyoo.Controllers .ToListAsync(); } - public override async Task Create(ProviderID obj) + public override async Task Create(Provider obj) { await base.Create(obj); _database.Entry(obj).State = EntityState.Added; @@ -36,7 +36,7 @@ namespace Kyoo.Controllers return obj; } - public override async Task Delete(ProviderID obj) + public override async Task Delete(Provider obj) { if (obj == null) throw new ArgumentNullException(nameof(obj)); diff --git a/Kyoo/Controllers/ThumbnailsManager.cs b/Kyoo/Controllers/ThumbnailsManager.cs index 68876274..b75e3231 100644 --- a/Kyoo/Controllers/ThumbnailsManager.cs +++ b/Kyoo/Controllers/ThumbnailsManager.cs @@ -92,7 +92,7 @@ namespace Kyoo.Controllers await DownloadImage(episode.Thumb, localPath, $"The thumbnail of {episode.Slug}"); } - public async Task Validate(ProviderID provider, bool alwaysDownload) + public async Task Validate(Provider provider, bool alwaysDownload) { if (provider.Logo == null) return; @@ -145,7 +145,7 @@ namespace Kyoo.Controllers return Task.FromResult(thumbPath.StartsWith(_peoplePath) ? thumbPath : null); } - public Task GetProviderLogo(ProviderID provider) + public Task GetProviderLogo(Provider provider) { if (provider == null) throw new ArgumentNullException(nameof(provider)); diff --git a/Kyoo/Models/DatabaseContext.cs b/Kyoo/Models/DatabaseContext.cs index 435b01f7..0538ed67 100644 --- a/Kyoo/Models/DatabaseContext.cs +++ b/Kyoo/Models/DatabaseContext.cs @@ -27,7 +27,7 @@ namespace Kyoo public DbSet Genres { get; set; } public DbSet People { get; set; } public DbSet Studios { get; set; } - public DbSet Providers { get; set; } + public DbSet Providers { get; set; } public DbSet MetadataIds { get; set; } public DbSet PeopleRoles { get; set; } @@ -74,17 +74,17 @@ namespace Kyoo .Property(t => t.IsForced) .ValueGeneratedNever(); - modelBuilder.Entity() + modelBuilder.Entity() .HasMany(x => x.Libraries) .WithMany(x => x.Providers) - .UsingEntity>( + .UsingEntity>( y => y .HasOne(x => x.First) .WithMany(x => x.ProviderLinks), y => y .HasOne(x => x.Second) .WithMany(x => x.LibraryLinks), - y => y.HasKey(Link.PrimaryKey)); + y => y.HasKey(Link.PrimaryKey)); modelBuilder.Entity() .HasMany(x => x.Libraries) @@ -160,7 +160,7 @@ namespace Kyoo modelBuilder.Entity().Property(x => x.Slug).IsRequired(); modelBuilder.Entity().Property(x => x.Slug).IsRequired(); modelBuilder.Entity().Property(x => x.Slug).IsRequired(); - modelBuilder.Entity().Property(x => x.Slug).IsRequired(); + modelBuilder.Entity().Property(x => x.Slug).IsRequired(); modelBuilder.Entity().Property(x => x.Slug).IsRequired(); modelBuilder.Entity().Property(x => x.Slug).IsRequired(); @@ -182,7 +182,7 @@ namespace Kyoo modelBuilder.Entity() .HasIndex(x => x.Slug) .IsUnique(); - modelBuilder.Entity() + modelBuilder.Entity() .HasIndex(x => x.Slug) .IsUnique(); modelBuilder.Entity() diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20210325184215_Initial.Designer.cs b/Kyoo/Models/DatabaseMigrations/Internal/20210417232515_Initial.Designer.cs similarity index 98% rename from Kyoo/Models/DatabaseMigrations/Internal/20210325184215_Initial.Designer.cs rename to Kyoo/Models/DatabaseMigrations/Internal/20210417232515_Initial.Designer.cs index b0c7add7..11722606 100644 --- a/Kyoo/Models/DatabaseMigrations/Internal/20210325184215_Initial.Designer.cs +++ b/Kyoo/Models/DatabaseMigrations/Internal/20210417232515_Initial.Designer.cs @@ -10,7 +10,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace Kyoo.Models.DatabaseMigrations.Internal { [DbContext(typeof(DatabaseContext))] - [Migration("20210325184215_Initial")] + [Migration("20210417232515_Initial")] partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -179,7 +179,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.ToTable("Link"); }); - modelBuilder.Entity("Kyoo.Models.Link", b => + modelBuilder.Entity("Kyoo.Models.Link", b => { b.Property("FirstID") .HasColumnType("integer"); @@ -191,7 +191,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.HasIndex("SecondID"); - b.ToTable("Link"); + b.ToTable("Link"); }); modelBuilder.Entity("Kyoo.Models.Link", b => @@ -320,7 +320,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.ToTable("PeopleRoles"); }); - modelBuilder.Entity("Kyoo.Models.ProviderID", b => + modelBuilder.Entity("Kyoo.Models.Provider", b => { b.Property("ID") .ValueGeneratedOnAdd() @@ -563,7 +563,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.Navigation("Second"); }); - modelBuilder.Entity("Kyoo.Models.Link", b => + modelBuilder.Entity("Kyoo.Models.Link", b => { b.HasOne("Kyoo.Models.Library", "First") .WithMany("ProviderLinks") @@ -571,7 +571,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Kyoo.Models.ProviderID", "Second") + b.HasOne("Kyoo.Models.Provider", "Second") .WithMany("LibraryLinks") .HasForeignKey("SecondID") .OnDelete(DeleteBehavior.Cascade) @@ -632,7 +632,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .HasForeignKey("PeopleID") .OnDelete(DeleteBehavior.Cascade); - b.HasOne("Kyoo.Models.ProviderID", "Provider") + b.HasOne("Kyoo.Models.Provider", "Provider") .WithMany("MetadataLinks") .HasForeignKey("ProviderID") .OnDelete(DeleteBehavior.Cascade) @@ -744,7 +744,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.Navigation("Roles"); }); - modelBuilder.Entity("Kyoo.Models.ProviderID", b => + modelBuilder.Entity("Kyoo.Models.Provider", b => { b.Navigation("LibraryLinks"); diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20210325184215_Initial.cs b/Kyoo/Models/DatabaseMigrations/Internal/20210417232515_Initial.cs similarity index 98% rename from Kyoo/Models/DatabaseMigrations/Internal/20210325184215_Initial.cs rename to Kyoo/Models/DatabaseMigrations/Internal/20210417232515_Initial.cs index f3825e97..56051cb1 100644 --- a/Kyoo/Models/DatabaseMigrations/Internal/20210325184215_Initial.cs +++ b/Kyoo/Models/DatabaseMigrations/Internal/20210417232515_Initial.cs @@ -128,7 +128,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal }); migrationBuilder.CreateTable( - name: "Link", + name: "Link", columns: table => new { FirstID = table.Column(type: "integer", nullable: false), @@ -136,15 +136,15 @@ namespace Kyoo.Models.DatabaseMigrations.Internal }, constraints: table => { - table.PrimaryKey("PK_Link", x => new { x.FirstID, x.SecondID }); + table.PrimaryKey("PK_Link", x => new { x.FirstID, x.SecondID }); table.ForeignKey( - name: "FK_Link_Libraries_FirstID", + name: "FK_Link_Libraries_FirstID", column: x => x.FirstID, principalTable: "Libraries", principalColumn: "ID", onDelete: ReferentialAction.Cascade); table.ForeignKey( - name: "FK_Link_Providers_SecondID", + name: "FK_Link_Providers_SecondID", column: x => x.SecondID, principalTable: "Providers", principalColumn: "ID", @@ -459,8 +459,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal column: "SecondID"); migrationBuilder.CreateIndex( - name: "IX_Link_SecondID", - table: "Link", + name: "IX_Link_SecondID", + table: "Link", column: "SecondID"); migrationBuilder.CreateIndex( @@ -559,7 +559,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal name: "Link"); migrationBuilder.DropTable( - name: "Link"); + name: "Link"); migrationBuilder.DropTable( name: "Link"); diff --git a/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs b/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs index 91eef22c..11d6b186 100644 --- a/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs +++ b/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs @@ -177,7 +177,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.ToTable("Link"); }); - modelBuilder.Entity("Kyoo.Models.Link", b => + modelBuilder.Entity("Kyoo.Models.Link", b => { b.Property("FirstID") .HasColumnType("integer"); @@ -189,7 +189,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.HasIndex("SecondID"); - b.ToTable("Link"); + b.ToTable("Link"); }); modelBuilder.Entity("Kyoo.Models.Link", b => @@ -318,7 +318,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.ToTable("PeopleRoles"); }); - modelBuilder.Entity("Kyoo.Models.ProviderID", b => + modelBuilder.Entity("Kyoo.Models.Provider", b => { b.Property("ID") .ValueGeneratedOnAdd() @@ -561,7 +561,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.Navigation("Second"); }); - modelBuilder.Entity("Kyoo.Models.Link", b => + modelBuilder.Entity("Kyoo.Models.Link", b => { b.HasOne("Kyoo.Models.Library", "First") .WithMany("ProviderLinks") @@ -569,7 +569,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Kyoo.Models.ProviderID", "Second") + b.HasOne("Kyoo.Models.Provider", "Second") .WithMany("LibraryLinks") .HasForeignKey("SecondID") .OnDelete(DeleteBehavior.Cascade) @@ -630,7 +630,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .HasForeignKey("PeopleID") .OnDelete(DeleteBehavior.Cascade); - b.HasOne("Kyoo.Models.ProviderID", "Provider") + b.HasOne("Kyoo.Models.Provider", "Provider") .WithMany("MetadataLinks") .HasForeignKey("ProviderID") .OnDelete(DeleteBehavior.Cascade) @@ -742,7 +742,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.Navigation("Roles"); }); - modelBuilder.Entity("Kyoo.Models.ProviderID", b => + modelBuilder.Entity("Kyoo.Models.Provider", b => { b.Navigation("LibraryLinks"); diff --git a/Kyoo/Startup.cs b/Kyoo/Startup.cs index ac05a36d..8e1485e3 100644 --- a/Kyoo/Startup.cs +++ b/Kyoo/Startup.cs @@ -147,6 +147,20 @@ namespace Kyoo }); + // TODO Add custom method to the service container and expose those methods to the plugin + // TODO Add for example a AddRepository that will automatically register the complex interface, the IRepository and the IBaseRepository + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/Kyoo/Tasks/Crawler.cs b/Kyoo/Tasks/Crawler.cs index 41028ce9..b6ab53de 100644 --- a/Kyoo/Tasks/Crawler.cs +++ b/Kyoo/Tasks/Crawler.cs @@ -33,7 +33,7 @@ namespace Kyoo.Controllers { using IServiceScope serviceScope = _serviceProvider.CreateScope(); await using ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService(); - return (await libraryManager!.GetLibraries()).Select(x => x.Slug); + return (await libraryManager!.GetAll()).Select(x => x.Slug); } public int? Progress() @@ -58,23 +58,23 @@ namespace Kyoo.Controllers using IServiceScope serviceScope = _serviceProvider.CreateScope(); await using ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService(); - foreach (Show show in await libraryManager!.GetShows()) + foreach (Show show in await libraryManager!.GetAll()) if (!Directory.Exists(show.Path)) - await libraryManager.DeleteShow(show); + await libraryManager.Delete(show); - ICollection episodes = await libraryManager.GetEpisodes(); + ICollection episodes = await libraryManager.GetAll(); foreach (Episode episode in episodes) if (!File.Exists(episode.Path)) - await libraryManager.DeleteEpisode(episode); + await libraryManager.Delete(episode); - ICollection tracks = await libraryManager.GetTracks(); + ICollection tracks = await libraryManager.GetAll(); foreach (Track track in tracks) if (!File.Exists(track.Path)) - await libraryManager.DeleteTrack(track); + await libraryManager.Delete(track); ICollection libraries = argument == null - ? await libraryManager.GetLibraries() - : new [] { await libraryManager.GetLibrary(argument)}; + ? await libraryManager.GetAll() + : new [] { await libraryManager.Get(argument)}; if (argument != null && libraries.First() == null) throw new ArgumentException($"No library found with the name {argument}"); @@ -160,7 +160,7 @@ namespace Kyoo.Controllers } string episodePath = match.Groups["Episode"].Value; - Episode episode = await libraryManager!.GetEpisode(x => x.Path.StartsWith(episodePath)); + Episode episode = await libraryManager!.Get(x => x.Path.StartsWith(episodePath)); if (episode == null) { @@ -180,7 +180,7 @@ namespace Kyoo.Controllers Episode = episode }; - await libraryManager.RegisterTrack(track); + await libraryManager.Create(track); Console.WriteLine($"Registering subtitle at: {path}."); } @@ -215,7 +215,7 @@ namespace Kyoo.Controllers bool isMovie = seasonNumber == -1 && episodeNumber == -1 && absoluteNumber == -1; Show show = await GetShow(libraryManager, showName, showPath, isMovie, library); if (isMovie) - await libraryManager!.RegisterEpisode(await GetMovie(show, path)); + await libraryManager!.Create(await GetMovie(show, path)); else { Season season = await GetSeason(libraryManager, show, seasonNumber, library); @@ -226,7 +226,7 @@ namespace Kyoo.Controllers absoluteNumber, path, library); - await libraryManager!.RegisterEpisode(episode); + await libraryManager!.Create(episode); } await libraryManager.AddShowLink(show, library, collection); @@ -250,19 +250,19 @@ namespace Kyoo.Controllers { if (string.IsNullOrEmpty(collectionName)) return null; - Collection collection = await libraryManager.GetCollection(Utility.ToSlug(collectionName)); + Collection collection = await libraryManager.Get(Utility.ToSlug(collectionName)); if (collection != null) return collection; collection = await _metadataProvider.GetCollectionFromName(collectionName, library); try { - await libraryManager.RegisterCollection(collection); + await libraryManager.Create(collection); return collection; } catch (DuplicatedItemException) { - return await libraryManager.GetCollection(collection.Slug); + return await libraryManager.Get(collection.Slug); } } @@ -272,7 +272,7 @@ namespace Kyoo.Controllers bool isMovie, Library library) { - Show old = await libraryManager.GetShow(x => x.Path == showPath); + Show old = await libraryManager.Get(x => x.Path == showPath); if (old != null) { await libraryManager.Load(old, x => x.ExternalIDs); @@ -284,18 +284,18 @@ namespace Kyoo.Controllers try { - show = await libraryManager.RegisterShow(show); + show = await libraryManager.Create(show); } catch (DuplicatedItemException) { - old = await libraryManager.GetShow(show.Slug); + old = await libraryManager.Get(show.Slug); if (old.Path == showPath) { await libraryManager.Load(old, x => x.ExternalIDs); return old; } show.Slug += $"-{show.StartYear}"; - await libraryManager.RegisterShow(show); + await libraryManager.Create(show); } await _thumbnailsManager.Validate(show); return show; @@ -308,18 +308,18 @@ namespace Kyoo.Controllers { if (seasonNumber == -1) return default; - Season season = await libraryManager.GetSeason(show.Slug, seasonNumber); + Season season = await libraryManager.Get(show.Slug, seasonNumber); if (season == null) { season = await _metadataProvider.GetSeason(show, seasonNumber, library); try { - await libraryManager.RegisterSeason(season); + await libraryManager.Create(season); await _thumbnailsManager.Validate(season); } catch (DuplicatedItemException) { - season = await libraryManager.GetSeason(show.Slug, season.SeasonNumber); + season = await libraryManager.Get(show.Slug, season.SeasonNumber); } } season.Show = show; diff --git a/Kyoo/Tasks/ExtractMetadata.cs b/Kyoo/Tasks/ExtractMetadata.cs index 73ed031b..d9f47e43 100644 --- a/Kyoo/Tasks/ExtractMetadata.cs +++ b/Kyoo/Tasks/ExtractMetadata.cs @@ -45,22 +45,22 @@ namespace Kyoo.Tasks case "show": case "shows": Show show = await (int.TryParse(slug, out id) - ? _library!.GetShow(id) - : _library!.GetShow(slug)); + ? _library!.Get(id) + : _library!.Get(slug)); await ExtractShow(show, thumbs, subs, token); break; case "season": case "seasons": Season season = await (int.TryParse(slug, out id) - ? _library!.GetSeason(id) - : _library!.GetSeason(slug)); + ? _library!.Get(id) + : _library!.Get(slug)); await ExtractSeason(season, thumbs, subs, token); break; case "episode": case "episodes": Episode episode = await (int.TryParse(slug, out id) - ? _library!.GetEpisode(id) - : _library!.GetEpisode(slug)); + ? _library!.Get(id) + : _library!.Get(slug)); await ExtractEpisode(episode, thumbs, subs); break; } @@ -105,7 +105,7 @@ namespace Kyoo.Tasks .Where(x => x.Type != StreamType.Attachment) .Concat(episode.Tracks.Where(x => x.IsExternal)) .ToList(); - await _library.EditEpisode(episode, false); + await _library.Edit(episode, false); } } diff --git a/Kyoo/Views/CollectionApi.cs b/Kyoo/Views/CollectionApi.cs index 5bba0650..0d5b0be5 100644 --- a/Kyoo/Views/CollectionApi.cs +++ b/Kyoo/Views/CollectionApi.cs @@ -35,12 +35,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetShows( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Collections.Any(y => y.ID == id)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetCollection(id) == null) + if (!resources.Any() && await _libraryManager.Get(id) == null) return NotFound(); return Page(resources, limit); } @@ -61,12 +61,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetShows( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Collections.Any(y => y.Slug == slug)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetCollection(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } @@ -87,12 +87,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetLibraries( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Collections.Any(y => y.ID == id)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetCollection(id) == null) + if (!resources.Any() && await _libraryManager.Get(id) == null) return NotFound(); return Page(resources, limit); } @@ -113,12 +113,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetLibraries( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Collections.Any(y => y.Slug == slug)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetCollection(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } diff --git a/Kyoo/Views/EpisodeApi.cs b/Kyoo/Views/EpisodeApi.cs index c0c01a18..7bc76af7 100644 --- a/Kyoo/Views/EpisodeApi.cs +++ b/Kyoo/Views/EpisodeApi.cs @@ -35,42 +35,42 @@ namespace Kyoo.Api [Authorize(Policy = "Read")] public async Task> GetShow(int episodeID) { - return await _libraryManager.GetShow(x => x.Episodes.Any(y => y.ID == episodeID)); + return await _libraryManager.Get(x => x.Episodes.Any(y => y.ID == episodeID)); } [HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}/show")] [Authorize(Policy = "Read")] - public async Task> GetShow(string showSlug) + public async Task> GetShow(string showSlug, int seasonNumber, int episodeNumber) { - return await _libraryManager.GetShow(showSlug); + return await _libraryManager.Get(showSlug); } [HttpGet("{showID:int}-{seasonNumber:int}e{episodeNumber:int}/show")] [Authorize(Policy = "Read")] - public async Task> GetShow(int showID, int _) + public async Task> GetShow(int showID, int seasonNumber, int episodeNumber) { - return await _libraryManager.GetShow(showID); + return await _libraryManager.Get(showID); } [HttpGet("{episodeID:int}/season")] [Authorize(Policy = "Read")] public async Task> GetSeason(int episodeID) { - return await _libraryManager.GetSeason(x => x.Episodes.Any(y => y.ID == episodeID)); + return await _libraryManager.Get(x => x.Episodes.Any(y => y.ID == episodeID)); } [HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}/season")] [Authorize(Policy = "Read")] - public async Task> GetSeason(string showSlug, int seasonNuber) + public async Task> GetSeason(string showSlug, int seasonNumber, int episodeNumber) { - return await _libraryManager.GetSeason(showSlug, seasonNuber); + return await _libraryManager.Get(showSlug, seasonNumber); } [HttpGet("{showID:int}-{seasonNumber:int}e{episodeNumber:int}/season")] [Authorize(Policy = "Read")] - public async Task> GetSeason(int showID, int seasonNumber) + public async Task> GetSeason(int showID, int seasonNumber, int episodeNumber) { - return await _libraryManager.GetSeason(showID, seasonNumber); + return await _libraryManager.Get(showID, seasonNumber); } [HttpGet("{episodeID:int}/track")] @@ -84,12 +84,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetTracks( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Episode.ID == episodeID), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetEpisode(episodeID) == null) + if (!resources.Any() && await _libraryManager.Get(episodeID) == null) return NotFound(); return Page(resources, limit); } @@ -112,14 +112,14 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetTracks( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Episode.ShowID == showID && x.Episode.SeasonNumber == seasonNumber && x.Episode.EpisodeNumber == episodeNumber), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetEpisode(showID, seasonNumber, episodeNumber) == null) + if (!resources.Any() && await _libraryManager.Get(showID, seasonNumber, episodeNumber) == null) return NotFound(); return Page(resources, limit); } @@ -142,13 +142,14 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetTracks(ApiHelper.ParseWhere(where, x => x.Episode.Show.Slug == showSlug + ICollection resources = await _libraryManager.GetAll( + ApiHelper.ParseWhere(where, x => x.Episode.Show.Slug == showSlug && x.Episode.SeasonNumber == seasonNumber && x.Episode.EpisodeNumber == episodeNumber), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber) == null) + if (!resources.Any() && await _libraryManager.Get(showSlug, seasonNumber, episodeNumber) == null) return NotFound(); return Page(resources, limit); } @@ -162,7 +163,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public async Task GetThumb(int id) { - Episode episode = await _libraryManager.GetEpisode(id); + Episode episode = await _libraryManager.Get(id); if (episode == null) return NotFound(); return _files.FileResult(await _thumbnails.GetEpisodeThumb(episode)); @@ -172,7 +173,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public async Task GetThumb(string slug) { - Episode episode = await _libraryManager.GetEpisode(slug); + Episode episode = await _libraryManager.Get(slug); if (episode == null) return NotFound(); return _files.FileResult(await _thumbnails.GetEpisodeThumb(episode)); diff --git a/Kyoo/Views/GenreApi.cs b/Kyoo/Views/GenreApi.cs index 29393e97..ab40f20b 100644 --- a/Kyoo/Views/GenreApi.cs +++ b/Kyoo/Views/GenreApi.cs @@ -36,12 +36,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetShows( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Genres.Any(y => y.ID == id)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetGenre(id) == null) + if (!resources.Any() && await _libraryManager.Get(id) == null) return NotFound(); return Page(resources, limit); } @@ -62,12 +62,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetShows( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Genres.Any(y => y.Slug == slug)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetGenre(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } diff --git a/Kyoo/Views/LibraryApi.cs b/Kyoo/Views/LibraryApi.cs index ba9ad3d0..93081db6 100644 --- a/Kyoo/Views/LibraryApi.cs +++ b/Kyoo/Views/LibraryApi.cs @@ -47,12 +47,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetShows( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Libraries.Any(y => y.ID == id)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetLibrary(id) == null) + if (!resources.Any() && await _libraryManager.Get(id) == null) return NotFound(); return Page(resources, limit); } @@ -73,12 +73,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetShows( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Libraries.Any(y => y.Slug == slug)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetLibrary(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } @@ -99,12 +99,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetCollections( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Libraries.Any(y => y.ID == id)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetLibrary(id) == null) + if (!resources.Any() && await _libraryManager.Get(id) == null) return NotFound(); return Page(resources, limit); } @@ -125,12 +125,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetCollections( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Libraries.Any(y => y.Slug == slug)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetLibrary(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } @@ -156,7 +156,7 @@ namespace Kyoo.Api new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetLibrary(id) == null) + if (!resources.Any() && await _libraryManager.Get(id) == null) return NotFound(); return Page(resources, limit); } @@ -182,7 +182,7 @@ namespace Kyoo.Api new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetLibrary(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } diff --git a/Kyoo/Views/PeopleApi.cs b/Kyoo/Views/PeopleApi.cs index bfcb8a29..8f80b6f2 100644 --- a/Kyoo/Views/PeopleApi.cs +++ b/Kyoo/Views/PeopleApi.cs @@ -90,7 +90,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public async Task GetPeopleIcon(int id) { - People people = await _libraryManager.GetPeople(id); + People people = await _libraryManager.Get(id); return _files.FileResult(await _thumbs.GetPeoplePoster(people)); } @@ -98,7 +98,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public async Task GetPeopleIcon(string slug) { - People people = await _libraryManager.GetPeople(slug); + People people = await _libraryManager.Get(slug); return _files.FileResult(await _thumbs.GetPeoplePoster(people)); } } diff --git a/Kyoo/Views/ProviderApi.cs b/Kyoo/Views/ProviderApi.cs index 2d3aab3d..050f2681 100644 --- a/Kyoo/Views/ProviderApi.cs +++ b/Kyoo/Views/ProviderApi.cs @@ -11,7 +11,7 @@ namespace Kyoo.Api [Route("api/provider")] [Route("api/providers")] [ApiController] - public class ProviderAPI : CrudApi + public class ProviderAPI : CrudApi { private readonly IThumbnailsManager _thumbnails; private readonly ILibraryManager _libraryManager; @@ -32,7 +32,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public async Task GetLogo(int id) { - ProviderID provider = await _libraryManager.GetProvider(id); + Provider provider = await _libraryManager.Get(id); return _files.FileResult(await _thumbnails.GetProviderLogo(provider)); } @@ -40,7 +40,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public async Task GetLogo(string slug) { - ProviderID provider = await _libraryManager.GetProvider(slug); + Provider provider = await _libraryManager.Get(slug); return _files.FileResult(await _thumbnails.GetProviderLogo(provider)); } } diff --git a/Kyoo/Views/SearchApi.cs b/Kyoo/Views/SearchApi.cs index c253adfd..008bf0f5 100644 --- a/Kyoo/Views/SearchApi.cs +++ b/Kyoo/Views/SearchApi.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Mvc; namespace Kyoo.Api { - [Route("api/search")] + [Route("api/search/{query}")] [ApiController] public class SearchApi : ControllerBase { @@ -18,67 +18,67 @@ namespace Kyoo.Api _libraryManager = libraryManager; } - [HttpGet("{query}")] + [HttpGet] [Authorize(Policy="Read")] public async Task> Search(string query) { return new SearchResult { Query = query, - Collections = await _libraryManager.SearchCollections(query), - Shows = await _libraryManager.SearchShows(query), - Episodes = await _libraryManager.SearchEpisodes(query), - People = await _libraryManager.SearchPeople(query), - Genres = await _libraryManager.SearchGenres(query), - Studios = await _libraryManager.SearchStudios(query) + Collections = await _libraryManager.Search(query), + Shows = await _libraryManager.Search(query), + Episodes = await _libraryManager.Search(query), + People = await _libraryManager.Search(query), + Genres = await _libraryManager.Search(query), + Studios = await _libraryManager.Search(query) }; } - [HttpGet("{query}/collection")] - [HttpGet("{query}/collections")] + [HttpGet("collection")] + [HttpGet("collections")] [Authorize(Policy="Read")] public Task> SearchCollections(string query) { - return _libraryManager.SearchCollections(query); + return _libraryManager.Search(query); } - [HttpGet("{query}/show")] - [HttpGet("{query}/shows")] + [HttpGet("show")] + [HttpGet("shows")] [Authorize(Policy="Read")] public Task> SearchShows(string query) { - return _libraryManager.SearchShows(query); + return _libraryManager.Search(query); } - [HttpGet("{query}/episode")] - [HttpGet("{query}/episodes")] + [HttpGet("episode")] + [HttpGet("episodes")] [Authorize(Policy="Read")] public Task> SearchEpisodes(string query) { - return _libraryManager.SearchEpisodes(query); + return _libraryManager.Search(query); } - [HttpGet("{query}/people")] + [HttpGet("people")] [Authorize(Policy="Read")] public Task> SearchPeople(string query) { - return _libraryManager.SearchPeople(query); + return _libraryManager.Search(query); } - [HttpGet("{query}/genre")] - [HttpGet("{query}/genres")] + [HttpGet("genre")] + [HttpGet("genres")] [Authorize(Policy="Read")] public Task> SearchGenres(string query) { - return _libraryManager.SearchGenres(query); + return _libraryManager.Search(query); } - [HttpGet("{query}/studio")] - [HttpGet("{query}/studios")] + [HttpGet("studio")] + [HttpGet("studios")] [Authorize(Policy="Read")] public Task> SearchStudios(string query) { - return _libraryManager.SearchStudios(query); + return _libraryManager.Search(query); } } } \ No newline at end of file diff --git a/Kyoo/Views/SeasonApi.cs b/Kyoo/Views/SeasonApi.cs index bc43cad5..4ca19c29 100644 --- a/Kyoo/Views/SeasonApi.cs +++ b/Kyoo/Views/SeasonApi.cs @@ -42,12 +42,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetEpisodes( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.SeasonID == seasonID), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetSeason(seasonID) == null) + if (!resources.Any() && await _libraryManager.Get(seasonID) == null) return NotFound(); return Page(resources, limit); } @@ -69,13 +69,13 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetEpisodes( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Show.Slug == showSlug && x.SeasonNumber == seasonNumber), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetSeason(showSlug, seasonNumber) == null) + if (!resources.Any() && await _libraryManager.Get(showSlug, seasonNumber) == null) return NotFound(); return Page(resources, limit); } @@ -97,12 +97,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetEpisodes( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.ShowID == showID && x.SeasonNumber == seasonNumber), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetSeason(showID, seasonNumber) == null) + if (!resources.Any() && await _libraryManager.Get(showID, seasonNumber) == null) return NotFound(); return Page(resources, limit); } @@ -116,28 +116,28 @@ namespace Kyoo.Api [Authorize(Policy = "Read")] public async Task> GetShow(int seasonID) { - return await _libraryManager.GetShow(x => x.Seasons.Any(y => y.ID == seasonID)); + return await _libraryManager.Get(x => x.Seasons.Any(y => y.ID == seasonID)); } [HttpGet("{showSlug}-s{seasonNumber:int}/show")] [Authorize(Policy = "Read")] - public async Task> GetShow(string showSlug, int _) + public async Task> GetShow(string showSlug, int seasonNumber) { - return await _libraryManager.GetShow(showSlug); + return await _libraryManager.Get(showSlug); } [HttpGet("{showID:int}-s{seasonNumber:int}/show")] [Authorize(Policy = "Read")] - public async Task> GetShow(int showID, int _) + public async Task> GetShow(int showID, int seasonNumber) { - return await _libraryManager.GetShow(showID); + return await _libraryManager.Get(showID); } [HttpGet("{id:int}/thumb")] [Authorize(Policy="Read")] public async Task GetThumb(int id) { - Season season = await _libraryManager.GetSeason(id); + Season season = await _libraryManager.Get(id); await _libraryManager.Load(season, x => x.Show); return _files.FileResult(await _thumbs.GetSeasonPoster(season)); } @@ -146,7 +146,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public async Task GetThumb(string slug) { - Season season = await _libraryManager.GetSeason(slug); + Season season = await _libraryManager.Get(slug); await _libraryManager.Load(season, x => x.Show); return _files.FileResult(await _thumbs.GetSeasonPoster(season)); } diff --git a/Kyoo/Views/ShowApi.cs b/Kyoo/Views/ShowApi.cs index 703f8c45..fc8c28f7 100644 --- a/Kyoo/Views/ShowApi.cs +++ b/Kyoo/Views/ShowApi.cs @@ -44,12 +44,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetSeasons( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.ShowID == showID), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(showID) == null) + if (!resources.Any() && await _libraryManager.Get(showID) == null) return NotFound(); return Page(resources, limit); } @@ -70,12 +70,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetSeasons( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Show.Slug == slug), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } @@ -96,12 +96,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetEpisodes( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.ShowID == showID), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(showID) == null) + if (!resources.Any() && await _libraryManager.Get(showID) == null) return NotFound(); return Page(resources, limit); } @@ -122,12 +122,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetEpisodes( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Show.Slug == slug), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } @@ -152,7 +152,7 @@ namespace Kyoo.Api new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(showID) == null) + if (!resources.Any() && await _libraryManager.Get(showID) == null) return NotFound(); return Page(resources, limit); } @@ -177,7 +177,7 @@ namespace Kyoo.Api new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } @@ -198,12 +198,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetGenres( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Shows.Any(y => y.ID == showID)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(showID) == null) + if (!resources.Any() && await _libraryManager.Get(showID) == null) return NotFound(); return Page(resources, limit); } @@ -224,12 +224,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetGenres( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Shows.Any(y => y.Slug == slug)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } @@ -245,7 +245,7 @@ namespace Kyoo.Api { try { - return await _libraryManager.GetStudio(x => x.Shows.Any(y => y.ID == showID)); + return await _libraryManager.Get(x => x.Shows.Any(y => y.ID == showID)); } catch (ItemNotFound) { @@ -259,7 +259,7 @@ namespace Kyoo.Api { try { - return await _libraryManager.GetStudio(x => x.Shows.Any(y => y.Slug == slug)); + return await _libraryManager.Get(x => x.Shows.Any(y => y.Slug == slug)); } catch (ItemNotFound) { @@ -278,12 +278,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetLibraries( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Shows.Any(y => y.ID == showID)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(showID) == null) + if (!resources.Any() && await _libraryManager.Get(showID) == null) return NotFound(); return Page(resources, limit); } @@ -304,12 +304,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetLibraries( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Shows.Any(y => y.Slug == slug)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } @@ -330,12 +330,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetCollections( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Shows.Any(y => y.ID == showID)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(showID) == null) + if (!resources.Any() && await _libraryManager.Get(showID) == null) return NotFound(); return Page(resources, limit); } @@ -356,12 +356,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetCollections( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Shows.Any(y => y.Slug == slug)), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetShow(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } @@ -376,7 +376,7 @@ namespace Kyoo.Api [Authorize(Policy = "Read")] public async Task>> GetFonts(string slug) { - Show show = await _libraryManager.GetShow(slug); + Show show = await _libraryManager.Get(slug); if (show == null) return NotFound(); string path = Path.Combine(_files.GetExtraDirectory(show), "Attachments"); @@ -390,7 +390,7 @@ namespace Kyoo.Api [Authorize(Policy = "Read")] public async Task GetFont(string showSlug, string slug) { - Show show = await _libraryManager.GetShow(showSlug); + Show show = await _libraryManager.Get(showSlug); if (show == null) return NotFound(); string path = Path.Combine(_files.GetExtraDirectory(show), "Attachments", slug); @@ -401,7 +401,7 @@ namespace Kyoo.Api [Authorize(Policy = "Read")] public async Task GetPoster(string slug) { - Show show = await _libraryManager.GetShow(slug); + Show show = await _libraryManager.Get(slug); if (show == null) return NotFound(); return _files.FileResult(await _thumbs.GetShowPoster(show)); @@ -411,7 +411,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public async Task GetLogo(string slug) { - Show show = await _libraryManager.GetShow(slug); + Show show = await _libraryManager.Get(slug); if (show == null) return NotFound(); return _files.FileResult(await _thumbs.GetShowLogo(show)); @@ -421,7 +421,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public async Task GetBackdrop(string slug) { - Show show = await _libraryManager.GetShow(slug); + Show show = await _libraryManager.Get(slug); if (show == null) return NotFound(); return _files.FileResult(await _thumbs.GetShowBackdrop(show)); diff --git a/Kyoo/Views/StudioApi.cs b/Kyoo/Views/StudioApi.cs index a0cf872e..45f46829 100644 --- a/Kyoo/Views/StudioApi.cs +++ b/Kyoo/Views/StudioApi.cs @@ -35,12 +35,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetShows( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.StudioID == id), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetStudio(id) == null) + if (!resources.Any() && await _libraryManager.Get(id) == null) return NotFound(); return Page(resources, limit); } @@ -61,12 +61,12 @@ namespace Kyoo.Api { try { - ICollection resources = await _libraryManager.GetShows( + ICollection resources = await _libraryManager.GetAll( ApiHelper.ParseWhere(where, x => x.Studio.Slug == slug), new Sort(sortBy), new Pagination(limit, afterID)); - if (!resources.Any() && await _libraryManager.GetStudio(slug) == null) + if (!resources.Any() && await _libraryManager.Get(slug) == null) return NotFound(); return Page(resources, limit); } diff --git a/Kyoo/Views/TrackApi.cs b/Kyoo/Views/TrackApi.cs index 689e904b..79bced62 100644 --- a/Kyoo/Views/TrackApi.cs +++ b/Kyoo/Views/TrackApi.cs @@ -29,7 +29,7 @@ namespace Kyoo.Api { try { - return await _libraryManager.GetEpisode(x => x.Tracks.Any(y => y.ID == id)); + return await _libraryManager.Get(x => x.Tracks.Any(y => y.ID == id)); } catch (ItemNotFound) { @@ -45,7 +45,7 @@ namespace Kyoo.Api { // TODO This won't work with the local repository implementation. // TODO Implement something like this (a dotnet-ef's QueryCompilationContext): https://stackoverflow.com/questions/62687811/how-can-i-convert-a-custom-function-to-a-sql-expression-for-entity-framework-cor - return await _libraryManager.GetEpisode(x => x.Tracks.Any(y => y.Slug == slug)); + return await _libraryManager.Get(x => x.Tracks.Any(y => y.Slug == slug)); } catch (ItemNotFound) { diff --git a/Kyoo/Views/VideoApi.cs b/Kyoo/Views/VideoApi.cs index 1e6651b5..13c53e40 100644 --- a/Kyoo/Views/VideoApi.cs +++ b/Kyoo/Views/VideoApi.cs @@ -4,6 +4,7 @@ using Kyoo.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using System.Threading.Tasks; +using Kyoo.Models.Exceptions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.Filters; @@ -40,92 +41,59 @@ namespace Kyoo.Api ctx.HttpContext.Response.Headers.Add("Expires", "0"); } - - [HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}")] - [HttpGet("direct/{showSlug}-s{seasonNumber:int}e{episodeNumber:int}")] - [Authorize(Policy="Play")] - public async Task DirectEpisode(string showSlug, int seasonNumber, int episodeNumber) - { - if (seasonNumber < 0 || episodeNumber < 0) - return BadRequest(new {error = "Season number or episode number can not be negative."}); - - Episode episode = await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber); - if (episode == null) - return NotFound(); - return _files.FileResult(episode.Path, true); - } - [HttpGet("{movieSlug}")] - [HttpGet("direct/{movieSlug}")] + [HttpGet("{slug}")] + [HttpGet("direct/{slug}")] [Authorize(Policy="Play")] - public async Task DirectMovie(string movieSlug) + public async Task Direct(string slug) { - Episode episode = await _libraryManager.GetMovieEpisode(movieSlug); - - if (episode == null) + try + { + Episode episode = await _libraryManager.Get(slug); + return _files.FileResult(episode.Path, true); + } + catch (ItemNotFound) + { return NotFound(); - return _files.FileResult(episode.Path, true); - } - - - [HttpGet("transmux/{showSlug}-s{seasonNumber:int}e{episodeNumber:int}/master.m3u8")] - [Authorize(Policy="Play")] - public async Task TransmuxEpisode(string showSlug, int seasonNumber, int episodeNumber) - { - if (seasonNumber < 0 || episodeNumber < 0) - return BadRequest(new {error = "Season number or episode number can not be negative."}); - - Episode episode = await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber); - if (episode == null) - return NotFound(); - string path = await _transcoder.Transmux(episode); - if (path == null) - return StatusCode(500); - return _files.FileResult(path, true); - } - - [HttpGet("transmux/{movieSlug}/master.m3u8")] - [Authorize(Policy="Play")] - public async Task TransmuxMovie(string movieSlug) - { - Episode episode = await _libraryManager.GetMovieEpisode(movieSlug); - - if (episode == null) - return NotFound(); - string path = await _transcoder.Transmux(episode); - if (path == null) - return StatusCode(500); - return _files.FileResult(path, true); + } } - [HttpGet("transcode/{showSlug}-s{seasonNumber:int}e{episodeNumber:int}/master.m3u8")] + [HttpGet("transmux/{slug}/master.m3u8")] [Authorize(Policy="Play")] - public async Task TranscodeEpisode(string showSlug, int seasonNumber, int episodeNumber) + public async Task Transmux(string slug) { - if (seasonNumber < 0 || episodeNumber < 0) - return BadRequest(new {error = "Season number or episode number can not be negative."}); - - Episode episode = await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber); - if (episode == null) - return NotFound(); - string path = await _transcoder.Transcode(episode); - if (path == null) - return StatusCode(500); - return _files.FileResult(path, true); - } - - [HttpGet("transcode/{movieSlug}/master.m3u8")] - [Authorize(Policy="Play")] - public async Task TranscodeMovie(string movieSlug) - { - Episode episode = await _libraryManager.GetMovieEpisode(movieSlug); + try + { + Episode episode = await _libraryManager.Get(slug); + string path = await _transcoder.Transmux(episode); - if (episode == null) + if (path == null) + return StatusCode(500); + return _files.FileResult(path, true); + } + catch (ItemNotFound) + { return NotFound(); - string path = await _transcoder.Transcode(episode); - if (path == null) - return StatusCode(500); - return _files.FileResult(path, true); + } + } + + [HttpGet("transcode/{slug}/master.m3u8")] + [Authorize(Policy="Play")] + public async Task Transcode(string slug) + { + try + { + Episode episode = await _libraryManager.Get(slug); + string path = await _transcoder.Transcode(episode); + + if (path == null) + return StatusCode(500); + return _files.FileResult(path, true); + } + catch (ItemNotFound) + { + return NotFound(); + } } diff --git a/Kyoo/Views/WatchApi.cs b/Kyoo/Views/WatchApi.cs index fec777bc..9d95d9ae 100644 --- a/Kyoo/Views/WatchApi.cs +++ b/Kyoo/Views/WatchApi.cs @@ -17,21 +17,11 @@ namespace Kyoo.Api _libraryManager = libraryManager; } - [HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}")] + [HttpGet("{slug}")] [Authorize(Policy="Read")] - public async Task> GetWatchItem(string showSlug, int seasonNumber, int episodeNumber) + public async Task> GetWatchItem(string slug) { - Episode item = await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber); - if (item == null) - return NotFound(); - return await WatchItem.FromEpisode(item, _libraryManager); - } - - [HttpGet("{movieSlug}")] - [Authorize(Policy="Read")] - public async Task> GetWatchItem(string movieSlug) - { - Episode item = await _libraryManager.GetMovieEpisode(movieSlug); + Episode item = await _libraryManager.Get(slug); if (item == null) return NotFound(); return await WatchItem.FromEpisode(item, _libraryManager);