From f720545d67cffc57d6580c5255232f0f4504622b Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Thu, 7 May 2020 03:42:38 +0200 Subject: [PATCH] Reworking the whole library manager --- Kyoo.Common/Controllers/ILibraryManager.cs | 110 ++- Kyoo.Common/Controllers/ITranscoder.cs | 4 +- Kyoo.Common/Models/Collection.cs | 18 +- Kyoo.Common/Models/Episode.cs | 4 +- Kyoo.Common/Models/Library.cs | 2 + Kyoo.Common/Models/PeopleLink.cs | 2 +- Kyoo.Common/Models/Track.cs | 2 +- Kyoo.Common/Utility.cs | 21 +- Kyoo/Controllers/LibraryManager.cs | 777 +++++++++++---------- Kyoo/Controllers/Transcoder/Transcoder.cs | 38 +- Kyoo/Tasks/Crawler.cs | 10 +- Kyoo/Views/API/LibrariesAPI.cs | 2 +- Kyoo/Views/API/PeopleAPI.cs | 7 +- Kyoo/Views/API/ShowsAPI.cs | 4 +- Kyoo/Views/API/ThumbnailAPI.cs | 6 +- Kyoo/Views/API/VideoAPI.cs | 10 +- 16 files changed, 521 insertions(+), 496 deletions(-) diff --git a/Kyoo.Common/Controllers/ILibraryManager.cs b/Kyoo.Common/Controllers/ILibraryManager.cs index 36489881..6605b04c 100644 --- a/Kyoo.Common/Controllers/ILibraryManager.cs +++ b/Kyoo.Common/Controllers/ILibraryManager.cs @@ -1,76 +1,70 @@ using Kyoo.Models; using System.Collections.Generic; +using System.Threading.Tasks; namespace Kyoo.Controllers { public interface ILibraryManager { - //Read values - Studio GetStudio(long showID); - IEnumerable GetPeople(long showID); - IEnumerable GetGenreForShow(long showID); - IEnumerable GetSeasons(long showID); - int GetSeasonCount(string showSlug, long seasonNumber); - IEnumerable GetShowsInCollection(long collectionID); - IEnumerable GetShowsInLibrary(long libraryID); - IEnumerable GetShowsByPeople(string peopleSlug); - IEnumerable GetLibrariesPath(); - - //Internal read - (Track video, IEnumerable audios, IEnumerable subtitles) GetStreams(long episodeID, string showSlug); - Track GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag, bool forced); - Track GetSubtitleById(long id); - - //Public read - IEnumerable GetShows(); - IEnumerable SearchShows(string searchQuery); - IEnumerable SearchCollections(string searchQuery); + // Get by slug Library GetLibrary(string librarySlug); - Library GetLibraryForShow(string showSlug); - IEnumerable GetLibraries(); - IEnumerable GetStudios(); - Show GetShowBySlug(string slug); - Show GetShow(string path); - Season GetSeason(string showSlug, long seasonNumber); - IEnumerable GetEpisodes(string showSlug); - IEnumerable GetEpisodes(string showSlug, long seasonNumber); - Episode GetEpisode(string showSlug, long seasonNumber, long episodeNumber); - WatchItem GetWatchItem(string showSlug, long seasonNumber, long episodeNumber, bool complete = true); - WatchItem GetMovieWatchItem(string movieSlug); - People GetPeopleBySlug(string slug); - IEnumerable GetGenres(); - Genre GetGenreBySlug(string slug); - Studio GetStudioBySlug(string slug); Collection GetCollection(string slug); - IEnumerable GetAllEpisodes(); + Show GetShow(string slug); + Episode GetEpisode(string showSlug, long seasonNumber, long episodeNumber); + Episode GetMovieEpisode(string movieSlug); + Genre GetGenre(string slug); + Studio GetStudio(string slug); + People GetPeople(string slug); + + // Get all + IEnumerable GetLibraries(); + IEnumerable GetShows(); + IEnumerable GetEpisodes(); + IEnumerable GetStudios(); + IEnumerable GetGenres(); + + // Other get helpers + Show GetShowByPath(string path); + IEnumerable GetLibrariesPath(); + + // Search + IEnumerable SearchCollections(string searchQuery); + IEnumerable SearchShows(string searchQuery); IEnumerable SearchEpisodes(string searchQuery); - IEnumerable SearchPeople(string searchQuery); IEnumerable SearchGenres(string searchQuery); IEnumerable SearchStudios(string searchQuery); - - //Check if value exists - bool IsCollectionRegistered(string collectionSlug, out long collectionID); - bool IsShowRegistered(string showPath, out long showID); - bool IsSeasonRegistered(long showID, long seasonNumber, out long seasonID); - bool IsEpisodeRegistered(string episodePath, out long episodeID); + IEnumerable SearchPeople(string searchQuery); //Register values - long RegisterLibrary(Library library); - long RegisterCollection(Collection collection); - long RegisterShow(Show show); - long EditShow(Show show); - long RegisterMovie(Episode movie); - long RegisterSeason(Season season); - long EditSeason(Season season); - long RegisterEpisode(Episode episode); - long EditEpisode(Episode episode); - long RegisterTrack(Track track); + void Register(object obj); void RegisterShowLinks(Library library, Collection collection, Show show); - IEnumerable ValidateExternalIDs(IEnumerable ids); + Task SaveChanges(); + + // Edit values + void Edit(Library library, bool resetOld); + void Edit(Collection collection, bool resetOld); + void Edit(Show show, bool resetOld); + void Edit(Season season, bool resetOld); + void Edit(Episode episode, bool resetOld); + void Edit(Track track, bool resetOld); + void Edit(People people, bool resetOld); + void Edit(Studio studio, bool resetOld); + void Edit(Genre genre, bool resetOld); - void RemoveShow(long showID); - void RemoveSeason(long seasonID); - void RemoveEpisode(long episodeID); - void ClearSubtitles(long episodeID); + // Validate values + Library Validate(Library library); + Collection Validate(Collection collection); + Show Validate(Show show); + Season Validate(Season season); + Episode Validate(Episode episode); + People Validate(People people); + Studio Validate(Studio studio); + Genre Validate(Genre genre); + IEnumerable Validate(IEnumerable id); + + // Remove values + void RemoveShow(Show show); + void RemoveSeason(Season season); + void RemoveEpisode(Episode episode); } } diff --git a/Kyoo.Common/Controllers/ITranscoder.cs b/Kyoo.Common/Controllers/ITranscoder.cs index add1a303..b2e1ef96 100644 --- a/Kyoo.Common/Controllers/ITranscoder.cs +++ b/Kyoo.Common/Controllers/ITranscoder.cs @@ -7,10 +7,10 @@ namespace Kyoo.Controllers public interface ITranscoder { // Should transcode to a mp4 container (same video/audio format if possible, no subtitles). - Task Transmux(WatchItem episode); + Task Transmux(Episode episode); // Should transcode to a mp4 container with a h264 video format and a AAC audio format, no subtitles. - Task Transcode(WatchItem episode); + Task Transcode(Episode episode); // Get video and audio tracks infos (codec, name, language...) Task GetTrackInfo(string path); diff --git a/Kyoo.Common/Models/Collection.cs b/Kyoo.Common/Models/Collection.cs index ca1cf29c..928992ce 100644 --- a/Kyoo.Common/Models/Collection.cs +++ b/Kyoo.Common/Models/Collection.cs @@ -12,7 +12,7 @@ namespace Kyoo.Models public string Poster { get; set; } public string Overview { get; set; } [JsonIgnore] public string ImgPrimary { get; set; } - public IEnumerable Shows; + public virtual IEnumerable Shows { get; set; } public Collection() { } @@ -38,17 +38,11 @@ namespace Kyoo.Models return this; if (ID == -1) ID = collection.ID; - if (Slug == null) - Slug = collection.Slug; - if (Name == null) - Name = collection.Name; - if (Poster == null) - Poster = collection.Poster; - if (Overview == null) - Overview = collection.Overview; - if (ImgPrimary == null) - ImgPrimary = collection.ImgPrimary; - Shows = Utility.MergeLists(Shows, collection.Shows, (x, y) => x.Slug == y.Slug); + Slug ??= collection.Slug; + Name ??= collection.Name; + Poster ??= collection.Poster; + Overview ??= collection.Overview; + ImgPrimary ??= collection.ImgPrimary; return this; } } diff --git a/Kyoo.Common/Models/Episode.cs b/Kyoo.Common/Models/Episode.cs index eab94cc9..6f9118df 100644 --- a/Kyoo.Common/Models/Episode.cs +++ b/Kyoo.Common/Models/Episode.cs @@ -28,13 +28,13 @@ namespace Kyoo.Models [JsonIgnore] public virtual IEnumerable Tracks { get; set; } public string ShowTitle => Show.Title; // Used in the API response only - public string Link => GetSlug(Show.Slug, SeasonNumber, EpisodeNumber); + public string Slug => GetSlug(Show.Slug, SeasonNumber, EpisodeNumber); public string Thumb { get { if (Show != null) - return "thumb/" + Link; + return "thumb/" + Slug; return ImgPrimary; } } diff --git a/Kyoo.Common/Models/Library.cs b/Kyoo.Common/Models/Library.cs index 883a2f37..d6a7e702 100644 --- a/Kyoo.Common/Models/Library.cs +++ b/Kyoo.Common/Models/Library.cs @@ -10,6 +10,8 @@ namespace Kyoo.Models public string Name { get; set; } public string[] Paths { get; set; } public virtual IEnumerable Providers { get; set; } + [JsonIgnore] public virtual IEnumerable Shows { get; set; } + [JsonIgnore] public virtual IEnumerable Collections { get; set; } public Library() { } diff --git a/Kyoo.Common/Models/PeopleLink.cs b/Kyoo.Common/Models/PeopleLink.cs index e3aaf8a8..ef6ef3af 100644 --- a/Kyoo.Common/Models/PeopleLink.cs +++ b/Kyoo.Common/Models/PeopleLink.cs @@ -6,7 +6,7 @@ namespace Kyoo.Models public class PeopleLink { [JsonIgnore] public long ID { get; set; } - [JsonIgnore] public string PeopleID { get; set; } + [JsonIgnore] public long PeopleID { get; set; } [JsonIgnore] public virtual People People { get; set; } public string Slug diff --git a/Kyoo.Common/Models/Track.cs b/Kyoo.Common/Models/Track.cs index 045bedd4..7dc52ba3 100644 --- a/Kyoo.Common/Models/Track.cs +++ b/Kyoo.Common/Models/Track.cs @@ -93,7 +93,7 @@ namespace Kyoo.Models { if (Type != StreamType.Subtitle) return null; - string link = "/subtitle/" + Episode.Link + "." + Language; + string link = "/subtitle/" + Episode.Slug + "." + Language; if (IsForced) link += "-forced"; switch (Codec) diff --git a/Kyoo.Common/Utility.cs b/Kyoo.Common/Utility.cs index 4ef3c2d7..8a52fee2 100644 --- a/Kyoo.Common/Utility.cs +++ b/Kyoo.Common/Utility.cs @@ -80,7 +80,9 @@ namespace Kyoo continue; object value = property.GetValue(second); - object defaultValue = property.PropertyType.IsValueType ? Activator.CreateInstance(property.PropertyType) : null; + object defaultValue = property.PropertyType.IsValueType + ? Activator.CreateInstance(property.PropertyType) + : null; if (value?.Equals(defaultValue) == false) property.SetValue(first, value); @@ -88,5 +90,22 @@ namespace Kyoo return first; } + + public static T Nullify(T obj) + { + Type type = typeof(T); + foreach (PropertyInfo property in type.GetProperties()) + { + if (!property.CanWrite) + continue; + + object defaultValue = property.PropertyType.IsValueType + ? Activator.CreateInstance(property.PropertyType) + : null; + property.SetValue(obj, defaultValue); + } + + return obj; + } } } \ No newline at end of file diff --git a/Kyoo/Controllers/LibraryManager.cs b/Kyoo/Controllers/LibraryManager.cs index 67fcf4c8..09338aa4 100644 --- a/Kyoo/Controllers/LibraryManager.cs +++ b/Kyoo/Controllers/LibraryManager.cs @@ -1,8 +1,8 @@ using System; using Kyoo.Models; -using Kyoo.Models.Watch; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Kyoo.Models.Exceptions; using Microsoft.EntityFrameworkCore; @@ -18,340 +18,358 @@ namespace Kyoo.Controllers _database = database; } - #region Read the database - public IEnumerable GetLibraries() - { - return _database.Libraries; - } - - public Library GetLibraryForShow(string showSlug) - { - return _database.LibraryLinks.FirstOrDefault(x => x.Show.Slug == showSlug)?.Library; - } - - public IEnumerable GetLibrariesPath() - { - IEnumerable paths = new List(); - return Enumerable.Aggregate(_database.Libraries, paths, (current, lib) => current.Concat(lib.Paths)); - } - - public (Track video, IEnumerable audios, IEnumerable subtitles) GetStreams(long episodeID, string episodeSlug) - { - IEnumerable tracks = _database.Tracks.Where(track => track.EpisodeID == episodeID); - return (tracks.FirstOrDefault(x => x.Type == StreamType.Video), - tracks.Where(x => x.Type == StreamType.Audio), - tracks.Where(track => track.Type == StreamType.Subtitle)); - } - - public Track GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag, bool forced) - { - long? showID = _database.Shows.FirstOrDefault(x => x.Slug == showSlug)?.ID; - if (showID == null) - return null; - return (from track in _database.Tracks where track.Episode.ShowID == showID - && track.Episode.SeasonNumber == seasonNumber - && track.Episode.EpisodeNumber == episodeNumber - && track.Language == languageTag select track).FirstOrDefault(); - } - - public Track GetSubtitleById(long id) - { - return (from track in _database.Tracks where track.ID == id select track).FirstOrDefault(); - } - + #region GetBySlug public Library GetLibrary(string librarySlug) { - return (from library in _database.Libraries where library.Slug == librarySlug select library).FirstOrDefault(); + return _database.Libraries.FirstOrDefault(library => library.Slug == librarySlug); } - - public IEnumerable GetShows() + + public Collection GetCollection(string slug) { - return _database.LibraryLinks.AsEnumerable().Select(x => x.Show ?? x.Collection.AsShow()) - .OrderBy(x => x.Title); + return _database.Collections.FirstOrDefault(col => col.Slug == slug); } - public IEnumerable SearchShows(string searchQuery) - { - return _database.Shows.FromSqlInterpolated($"SELECT * FROM Shows WHERE Shows.Title LIKE {"%" + searchQuery + "%"} OR Shows.Aliases LIKE {"%" + searchQuery + "%"}") - .OrderBy(x => x.Title).Take(20); - } - - public Show GetShowBySlug(string slug) + public Show GetShow(string slug) { return _database.Shows.FirstOrDefault(show => show.Slug == slug); } - public Show GetShow(string path) - { - return (from show in _database.Shows where show.Path == path select show).FirstOrDefault(); - } - - public IEnumerable GetSeasons(long showID) - { - return (from season in _database.Seasons where season.ShowID == showID select season) - .OrderBy(x => x.SeasonNumber); - } - - public Season GetSeason(string showSlug, long seasonNumber) - { - return (from season in _database.Seasons - where season.SeasonNumber == seasonNumber - && season.Show.Slug == showSlug - select season).FirstOrDefault(); - } - - public int GetSeasonCount(string showSlug, long seasonNumber) - { - return (from season in _database.Seasons - where season.SeasonNumber == seasonNumber - && season.Show.Slug == showSlug - select season).FirstOrDefault()?.Episodes.Count() ?? 0; - } - - public IEnumerable GetEpisodes(string showSlug) - { - return _database.Episodes.Where(episode => episode.Show.Slug == showSlug); - } - - public IEnumerable GetEpisodes(string showSlug, long seasonNumber) - { - return _database.Episodes.Where(x => x.SeasonNumber == seasonNumber - && x.Show.Slug == showSlug) - .OrderBy(x => x.EpisodeNumber); - } - - public IEnumerable GetEpisodes(long showID, long seasonNumber) - { - return _database.Episodes.Where(x => x.ShowID == showID - && x.SeasonNumber == seasonNumber); - } - public Episode GetEpisode(string showSlug, long seasonNumber, long episodeNumber) { return _database.Episodes.FirstOrDefault(x => x.EpisodeNumber == episodeNumber - && x.SeasonNumber == seasonNumber - && x.Show.Slug == showSlug); + && x.SeasonNumber == seasonNumber + && x.Show.Slug == showSlug); } - - public WatchItem GetWatchItem(string showSlug, long seasonNumber, long episodeNumber, bool complete = true) + + public Episode GetMovieEpisode(string movieSlug) { - WatchItem item = _database.Episodes.Where(x => x.SeasonNumber == seasonNumber - && x.EpisodeNumber == episodeNumber - && x.Show.Slug == showSlug) - .Select(x => new WatchItem(x)).FirstOrDefault(); - - if (item == null) - return null; - - (item.Video, item.Audios, item.Subtitles) = GetStreams(item.EpisodeID, item.Link); - - if (episodeNumber > 1) - item.PreviousEpisode = Episode.GetSlug(showSlug, seasonNumber, episodeNumber - 1); - else if (seasonNumber > 1) - item.PreviousEpisode = Episode.GetSlug(showSlug, seasonNumber - 1, GetSeasonCount(showSlug, seasonNumber - 1)); - - if (episodeNumber >= GetSeasonCount(showSlug, seasonNumber)) - item.NextEpisode = GetEpisode(showSlug, seasonNumber + 1, 1); - else - item.NextEpisode = GetEpisode(showSlug, seasonNumber, episodeNumber + 1); - - return item; + return _database.Episodes.FirstOrDefault(x => x.Show.Slug == movieSlug); } - public WatchItem GetMovieWatchItem(string movieSlug) + public Genre GetGenre(string slug) { - Show movie = _database.Shows.FirstOrDefault(x => x.Slug == movieSlug); - if (movie == null) - return null; - Episode episode = _database.Episodes.FirstOrDefault(x => x.ShowID == movie.ID); - if (episode == null) - return null; - WatchItem item = new WatchItem(movie.ID, - movie.Title, - movie.Slug, - -1, - -1, - movie.Title, - null, - episode.Path); - item.Link = movie.Slug; - item.IsMovie = true; - (item.Video, item.Audios, item.Subtitles) = GetStreams(item.EpisodeID, item.Link); - return item; + return _database.Genres.FirstOrDefault(genre => genre.Slug == slug); } - public IEnumerable GetPeople(long showID) + public Studio GetStudio(string slug) { - return from link in _database.PeopleLinks where link.ShowID == showID orderby link.People.ImgPrimary == null, link.Name select link; + return _database.Studios.FirstOrDefault(studio => studio.Slug == slug); } - public People GetPeopleBySlug(string slug) + public People GetPeople(string slug) { - return (from people in _database.Peoples where people.Slug == slug select people).FirstOrDefault(); + return _database.Peoples.FirstOrDefault(people => people.Slug == slug); } - + #endregion + + #region GetAll + public IEnumerable GetLibraries() + { + return _database.Libraries; + } + + public IEnumerable GetShows() + { + return _database.LibraryLinks.AsEnumerable().Select(x => x.Show ?? x.Collection.AsShow()); + } + + public IEnumerable GetEpisodes() + { + return _database.Episodes; + } + public IEnumerable GetGenres() { return _database.Genres; } - public IEnumerable GetGenreForShow(long showID) - { - return (from show in _database.Shows where show.ID == showID select show.Genres).FirstOrDefault(); - } - - public Genre GetGenreBySlug(string slug) - { - return (from genre in _database.Genres where genre.Slug == slug select genre).FirstOrDefault(); - } - public IEnumerable GetStudios() { return _database.Studios; } + #endregion - public Studio GetStudio(long showID) + #region GetHelper + public IEnumerable GetLibrariesPath() { - return (from show in _database.Shows where show.ID == showID select show.Studio).FirstOrDefault(); + IEnumerable paths = new List(); + return Enumerable.Aggregate(_database.Libraries, paths, (current, lib) => current.Concat(lib.Paths)); } - - public Studio GetStudioBySlug(string slug) + + public Show GetShowByPath(string path) { - return (from studio in _database.Studios where studio.Slug == slug select studio).FirstOrDefault(); + return _database.Shows.FirstOrDefault(show => show.Path == path); } + #endregion - public Collection GetCollection(string slug) + #region Search + public IEnumerable SearchCollections(string searchQuery) { - Collection collection = _database.Collections.FirstOrDefault(col => col.Slug == slug); - if (collection != null) - collection.Shows = GetShowsInCollection(collection.ID); - return collection; + return _database.Collections.Where(collection => EF.Functions.Like(collection.Name, $"%{searchQuery}%")) + .Take(20); } - - public IEnumerable GetShowsInCollection(long collectionID) + + public IEnumerable SearchShows(string searchQuery) { - return from link in _database.CollectionLinks where link.CollectionID == collectionID select link.Show; + return _database.Shows.FromSqlInterpolated($@"SELECT * FROM Shows WHERE Shows.Title LIKE {$"%{searchQuery}%"} + OR Shows.Aliases LIKE {$"%{searchQuery}%"}").Take(20); } - - public IEnumerable GetShowsInLibrary(long libraryID) - { - return (from link in _database.LibraryLinks where link.LibraryID == libraryID select link) - .AsEnumerable() - .Select(link => link.Show ?? link.Collection.AsShow()) - .OrderBy(x => x.Title); - } - - public IEnumerable GetShowsByPeople(string peopleSlug) - { - return (from link in _database.PeopleLinks where link.PeopleID == peopleSlug select link.Show).OrderBy(x => x.Title); - } - - public IEnumerable GetAllEpisodes() - { - return _database.Episodes; - } - + public IEnumerable SearchEpisodes(string searchQuery) { return _database.Episodes.Where(x => EF.Functions.Like(x.Title, $"%{searchQuery}%")).Take(20); } - - public IEnumerable SearchCollections(string searchQuery) - { - return (from collection in _database.Collections where EF.Functions.Like(collection.Name, $"%{searchQuery}%") select collection) - .OrderBy(x => x.Name).Take(20); - } - - public IEnumerable SearchPeople(string searchQuery) - { - return (from people in _database.Peoples where EF.Functions.Like(people.Name, $"%{searchQuery}%") select people) - .OrderBy(x => x.ImgPrimary == null) - .ThenBy(x => x.Name) - .Take(20); - } - + public IEnumerable SearchGenres(string searchQuery) { - return (from genre in _database.Genres where EF.Functions.Like(genre.Name, $"%{searchQuery}%") select genre) + return _database.Genres.Where(genre => EF.Functions.Like(genre.Name, $"%{searchQuery}%")) .Take(20); } public IEnumerable SearchStudios(string searchQuery) { - return (from studio in _database.Studios where EF.Functions.Like(studio.Name, $"%{searchQuery}%") select studio) + return _database.Studios.Where(studio => EF.Functions.Like(studio.Name, $"%{searchQuery}%")) + .Take(20); + } + + public IEnumerable SearchPeople(string searchQuery) + { + return _database.Peoples.Where(people => EF.Functions.Like(people.Name, $"%{searchQuery}%")) + .OrderBy(x => x.ImgPrimary == null) + .ThenBy(x => x.Name) .Take(20); } #endregion - #region Check if items exists - public bool IsCollectionRegistered(string collectionSlug, out long collectionID) + #region Register + public void Register(object obj) { - Collection col = (from collection in _database.Collections where collection.Slug == collectionSlug select collection).FirstOrDefault(); - collectionID = col?.ID ?? -1; - return collectionID != -1; + if (obj == null) + return; + _database.Entry(obj).State = EntityState.Added; } - - public bool IsShowRegistered(string showPath, out long showID) + + public void RegisterShowLinks(Library library, Collection collection, Show show) { - Show tmp = (from show in _database.Shows where show.Path == showPath select show).FirstOrDefault(); - showID = tmp?.ID ?? -1; - return showID != -1; + if (collection != null) + { + _database.LibraryLinks.AddIfNotExist(new LibraryLink {LibraryID = library.ID, CollectionID = collection.ID}, x => x.LibraryID == library.ID && x.CollectionID == collection.ID && x.ShowID == null); + _database.CollectionLinks.AddIfNotExist(new CollectionLink { CollectionID = collection.ID, ShowID = show.ID}, x => x.CollectionID == collection.ID && x.ShowID == show.ID); + } + else + _database.LibraryLinks.AddIfNotExist(new LibraryLink {LibraryID = library.ID, ShowID = show.ID}, x => x.LibraryID == library.ID && x.CollectionID == null && x.ShowID == show.ID); } - - public bool IsSeasonRegistered(long showID, long seasonNumber, out long seasonID) + + public Task SaveChanges() { - Season tmp = (from season in _database.Seasons where season.SeasonNumber == seasonNumber && season.ShowID == showID select season).FirstOrDefault(); - seasonID = tmp?.ID ?? -1; - return seasonID != -1; - } - - public bool IsEpisodeRegistered(string episodePath, out long episodeID) - { - Episode tmp = (from episode in _database.Episodes where episode.Path == episodePath select episode).FirstOrDefault(); - episodeID = tmp?.ID ?? -1; - return episodeID != -1; - } - - public long GetOrCreateGenre(Genre genre) - { - Genre existingGenre = GetGenreBySlug(genre.Slug); - - if (existingGenre != null) - return existingGenre.ID; - - _database.Genres.Add(genre); - _database.SaveChanges(); - return genre.ID; - } - - public long GetOrCreateStudio(Studio studio) - { - Studio existingStudio = GetStudioBySlug(studio.Slug); - - if (existingStudio != null) - return existingStudio.ID; - - _database.Studios.Add(studio); - _database.SaveChanges(); - return studio.ID; + return _database.SaveChangesAsync(); } #endregion - #region Write Into The Database - public long RegisterCollection(Collection collection) + #region Edit + + public void Edit(Library edited, bool resetOld) { - if (collection == null) - return 0; - if (_database.Entry(collection).State == EntityState.Detached) - _database.Collections.Add(collection); - _database.SaveChanges(); - return collection.ID; + Edit(() => + { + var query = _database.Libraries + .Include(x => x.Providers); + Library old = _database.Entry(edited).IsKeySet + ? query.FirstOrDefault(x => x.ID == edited.ID) + : query.FirstOrDefault(x => x.Slug == edited.Slug); + + if (old == null) + throw new ItemNotFound($"No library could be found with the id {edited.ID} or the slug {edited.Slug}"); + + if (resetOld) + Utility.Nullify(old); + Utility.Complete(old, edited); + Validate(old); + }); + } + + public void Edit(Collection edited, bool resetOld) + { + Edit(() => + { + var query = _database.Collections; + Collection old = _database.Entry(edited).IsKeySet + ? query.FirstOrDefault(x => x.ID == edited.ID) + : query.FirstOrDefault(x => x.Slug == edited.Slug); + + if (old == null) + throw new ItemNotFound($"No collection could be found with the id {edited.ID} or the slug {edited.Slug}"); + + if (resetOld) + Utility.Nullify(old); + Utility.Complete(old, edited); + Validate(old); + }); } - public long RegisterLibrary(Library library) + public void Edit(Show edited, bool resetOld) + { + Edit(() => + { + var query = _database.Shows + .Include(x => x.GenreLinks) + .Include(x => x.People) + .Include(x => x.ExternalIDs); + Show old = _database.Entry(edited).IsKeySet + ? query.FirstOrDefault(x => x.ID == edited.ID) + : query.FirstOrDefault(x => x.Slug == edited.Slug); + + if (old == null) + throw new ItemNotFound($"No show could be found with the id {edited.ID} or the slug {edited.Slug}"); + + if (resetOld) + Utility.Nullify(old); + Utility.Complete(old, edited); + Validate(old); + }); + } + + public void Edit(Season edited, bool resetOld) + { + Edit(() => + { + var query = _database.Seasons + .Include(x => x.ExternalIDs) + .Include(x => x.Episodes); + Season old = _database.Entry(edited).IsKeySet + ? query.FirstOrDefault(x => x.ID == edited.ID) + : query.FirstOrDefault(x => x.Slug == edited.Slug); + + if (old == null) + throw new ItemNotFound($"No season could be found with the id {edited.ID} or the slug {edited.Slug}"); + + if (resetOld) + Utility.Nullify(old); + Utility.Complete(old, edited); + Validate(old); + }); + } + + public void Edit(Episode edited, bool resetOld) + { + Edit(() => + { + var query = _database.Episodes + .Include(x => x.ExternalIDs) + .Include(x => x.Season) + .Include(x => x.Tracks); + Episode old = _database.Entry(edited).IsKeySet + ? query.FirstOrDefault(x => x.ID == edited.ID) + : query.FirstOrDefault(x => x.Slug == edited.Slug); + + if (old == null) + throw new ItemNotFound($"No episode could be found with the id {edited.ID} or the slug {edited.Slug}"); + + if (resetOld) + Utility.Nullify(old); + Utility.Complete(old, edited); + Validate(old); + }); + } + + public void Edit(Track edited, bool resetOld) + { + Edit(() => + { + Track old = _database.Tracks.FirstOrDefault(x => x.ID == edited.ID); + + if (old == null) + throw new ItemNotFound($"No library track could be found with the id {edited.ID}"); + + if (resetOld) + Utility.Nullify(old); + Utility.Complete(old, edited); + }); + } + + public void Edit(People edited, bool resetOld) + { + Edit(() => + { + var query = _database.Peoples + .Include(x => x.ExternalIDs); + People old = _database.Entry(edited).IsKeySet + ? query.FirstOrDefault(x => x.ID == edited.ID) + : query.FirstOrDefault(x => x.Slug == edited.Slug); + + if (old == null) + throw new ItemNotFound($"No people could be found with the id {edited.ID} or the slug {edited.Slug}"); + + if (resetOld) + Utility.Nullify(old); + Utility.Complete(old, edited); + Validate(old); + }); + } + + public void Edit(Studio edited, bool resetOld) + { + Edit(() => + { + var query = _database.Studios; + Studio old = _database.Entry(edited).IsKeySet + ? query.FirstOrDefault(x => x.ID == edited.ID) + : query.FirstOrDefault(x => x.Slug == edited.Slug); + + if (old == null) + throw new ItemNotFound($"No studio could be found with the id {edited.ID} or the slug {edited.Slug}"); + + if (resetOld) + Utility.Nullify(old); + Utility.Complete(old, edited); + Validate(old); + }); + } + + public void Edit(Genre edited, bool resetOld) + { + Edit(() => + { + var query = _database.Genres; + Genre old = _database.Entry(edited).IsKeySet + ? query.FirstOrDefault(x => x.ID == edited.ID) + : query.FirstOrDefault(x => x.Slug == edited.Slug); + + if (old == null) + throw new ItemNotFound($"No genre could be found with the id {edited.ID} or the slug {edited.Slug}"); + + if (resetOld) + Utility.Nullify(old); + Utility.Complete(old, edited); + Validate(old); + }); + } + + private void Edit(Action applyFunction) + { + _database.ChangeTracker.LazyLoadingEnabled = false; + _database.ChangeTracker.AutoDetectChangesEnabled = false; + + try + { + applyFunction.Invoke(); + + _database.ChangeTracker.DetectChanges(); + _database.SaveChanges(); + } + finally + { + _database.ChangeTracker.LazyLoadingEnabled = true; + _database.ChangeTracker.AutoDetectChangesEnabled = true; + } + } + #endregion + + #region ValidateValue + public Library Validate(Library library) { if (library == null) - return 0; + return null; library.Providers = library.Providers.Select(x => { x.Provider = _database.Providers.FirstOrDefault(y => y.Name == x.Name); @@ -359,22 +377,125 @@ namespace Kyoo.Controllers x.ProviderID = x.Provider.ID; return x; }).Where(x => x.Provider != null).ToList(); - if (_database.Entry(library).State == EntityState.Detached) - _database.Libraries.Add(library); - _database.SaveChanges(); - return library.ID; + return library; } - public long RegisterShow(Show show) + public Collection Validate(Collection collection) + { + if (collection == null) + return null; + if (collection.Slug == null) + collection.Slug = Utility.ToSlug(collection.Name); + return collection; + } + + public Show Validate(Show show) { if (show == null) - return 0; - if (_database.Entry(show).State == EntityState.Detached) - _database.Shows.Add(show); - _database.SaveChanges(); - return show.ID; + return null; + + show.Studio = Validate(show.Studio); + + show.GenreLinks = show.GenreLinks?.Select(x => + { + x.Genre = Validate(x.Genre); + x.GenreID = x.Genre.ID; + return x; + }).ToList(); + + show.People = show.People?.Select(x => + { + x.People = Validate(x.People); + x.PeopleID = x.People.ID; + return x; + }).ToList(); + + show.Seasons = show.Seasons?.Select(x => + { + return _database.Seasons.FirstOrDefault(y => y.ShowID == x.ShowID + && y.SeasonNumber == x.SeasonNumber) ?? Validate(x); + }).ToList(); + show.Episodes = show.Episodes?.Select(x => + { + return _database.Episodes.FirstOrDefault(y => y.ShowID == x.ShowID + && y.SeasonNumber == x.SeasonNumber + && y.EpisodeNumber == x.EpisodeNumber) ?? Validate(x); + }).ToList(); + + show.ExternalIDs = Validate(show.ExternalIDs); + return show; } + public Season Validate(Season season) + { + if (season == null) + return null; + + season.Episodes = season.Episodes?.Select(x => + { + return _database.Episodes.FirstOrDefault(y => y.ShowID == x.ShowID + && y.SeasonNumber == x.SeasonNumber + && y.EpisodeNumber == x.EpisodeNumber) ?? Validate(x); + }).ToList(); + season.ExternalIDs = Validate(season.ExternalIDs); + return season; + } + + public Episode Validate(Episode episode) + { + if (episode == null) + return null; + + Season old = _database.Seasons.FirstOrDefault(x => x.ShowID == episode.ShowID + && x.SeasonNumber == episode.SeasonNumber); + if (old != null) + episode.Season = old; + else + episode.Season.ExternalIDs = Validate(episode.Season.ExternalIDs); + episode.ExternalIDs = Validate(episode.ExternalIDs); + return episode; + } + + public Studio Validate(Studio studio) + { + if (studio == null) + return null; + if (studio.Slug == null) + studio.Slug = Utility.ToSlug(studio.Name); + return _database.Studios.FirstOrDefault(x => x.Slug == studio.Slug) ?? studio; + } + + public People Validate(People people) + { + if (people == null) + return null; + if (people.Slug == null) + people.Slug = Utility.ToSlug(people.Name); + People old = _database.Peoples.FirstOrDefault(y => y.Slug == people.Slug); + if (old != null) + return old; + people.ExternalIDs = Validate(people.ExternalIDs); + return people; + } + + public Genre Validate(Genre genre) + { + if (genre.Slug == null) + genre.Slug = Utility.ToSlug(genre.Name); + return _database.Genres.FirstOrDefault(y => y.Slug == genre.Slug) ?? genre; + } + + public IEnumerable Validate(IEnumerable ids) + { + return ids?.Select(x => + { + x.Provider = _database.Providers.FirstOrDefault(y => y.Name == x.Provider.Name) ?? x.Provider; + x.ProviderID = x.Provider.ID; + return x; + }).GroupBy(x => x.Provider.Name).Select(x => x.First()).ToList(); + } + #endregion + public long EditShow(Show edited) { if (edited == null) @@ -397,45 +518,6 @@ namespace Kyoo.Controllers Utility.Complete(show, edited); - if (edited.Studio != null) - { - if (edited.Studio.Slug == null) - edited.Studio.Slug = Utility.ToSlug(edited.Studio.Name); - Studio tmp = _database.Studios.FirstOrDefault(x => x.Slug == edited.Studio.Slug); - if (tmp != null) - show.Studio = tmp; - } - - show.GenreLinks = edited.GenreLinks?.Select(x => - { - if (x.Genre.Slug == null) - x.Genre.Slug = Utility.ToSlug(x.Genre.Name); - x.Genre = _database.Genres.FirstOrDefault(y => y.Slug == x.Genre.Slug) ?? x.Genre; - x.GenreID = x.Genre.ID; - return x; - }).ToList(); - show.People = edited.People?.Select(x => - { - People people = _database.Peoples.FirstOrDefault(y => y.Slug == x.People.Slug); - if (people != null) - x.People = people; - else - x.People.ExternalIDs = ValidateExternalIDs(x.People.ExternalIDs); - return x; - }).ToList(); - show.Seasons = edited.Seasons?.Select(x => - { - return _database.Seasons.FirstOrDefault(y => y.ShowID == x.ShowID - && y.SeasonNumber == x.SeasonNumber) ?? x; - }).ToList(); - show.Episodes = edited.Episodes?.Select(x => - { - return _database.Episodes.FirstOrDefault(y => y.ShowID == x.ShowID - && y.SeasonNumber == x.SeasonNumber - && y.EpisodeNumber == x.EpisodeNumber) ?? x; - }).ToList(); - show.ExternalIDs = ValidateExternalIDs(show.ExternalIDs); - _database.ChangeTracker.DetectChanges(); _database.SaveChanges(); } @@ -447,17 +529,7 @@ namespace Kyoo.Controllers return edited.ID; } - - public IEnumerable ValidateExternalIDs(IEnumerable ids) - { - return ids?.Select(x => - { - x.Provider = _database.Providers.FirstOrDefault(y => y.Name == x.Provider.Name) ?? x.Provider; - x.ProviderID = x.Provider.ID; - return x; - }).GroupBy(x => x.Provider.Name).Select(x => x.First()).ToList(); - } - + public long RegisterMovie(Episode movie) { if (movie == null) @@ -500,13 +572,7 @@ namespace Kyoo.Controllers Utility.Complete(season, edited); - season.Episodes = edited.Episodes?.Select(x => - { - return _database.Episodes.FirstOrDefault(y => y.ShowID == x.ShowID - && y.SeasonNumber == x.SeasonNumber - && y.EpisodeNumber == x.EpisodeNumber) ?? x; - }).ToList(); - season.ExternalIDs = ValidateExternalIDs(season.ExternalIDs); + _database.ChangeTracker.DetectChanges(); _database.SaveChanges(); @@ -551,13 +617,7 @@ namespace Kyoo.Controllers Utility.Complete(episode, edited); - if (episode.SeasonNumber != -1) - { - episode.Season = _database.Seasons.FirstOrDefault(x => x.ShowID == episode.ShowID - && x.SeasonNumber == edited.SeasonNumber) ?? episode.Season; - episode.Season.ExternalIDs = ValidateExternalIDs(episode.Season.ExternalIDs); - } - episode.ExternalIDs = ValidateExternalIDs(episode.ExternalIDs); + _database.ChangeTracker.DetectChanges(); _database.SaveChanges(); @@ -571,43 +631,26 @@ namespace Kyoo.Controllers return edited.ID; } - public long RegisterTrack(Track track) + #region Remove + public void RemoveShow(Show show) { - _database.Tracks.Add(track); - _database.SaveChanges(); - return track.ID; + if (_database.Entry(show).State == EntityState.Detached) + _database.Shows.Attach(show); + _database.Shows.Remove(show); } - public void RegisterShowLinks(Library library, Collection collection, Show show) + public void RemoveSeason(Season season) { - if (collection != null) - { - _database.LibraryLinks.AddIfNotExist(new LibraryLink {LibraryID = library.ID, CollectionID = collection.ID}, x => x.LibraryID == library.ID && x.CollectionID == collection.ID && x.ShowID == null); - _database.CollectionLinks.AddIfNotExist(new CollectionLink { CollectionID = collection.ID, ShowID = show.ID}, x => x.CollectionID == collection.ID && x.ShowID == show.ID); - } - else - _database.LibraryLinks.AddIfNotExist(new LibraryLink {LibraryID = library.ID, ShowID = show.ID}, x => x.LibraryID == library.ID && x.CollectionID == null && x.ShowID == show.ID); - _database.SaveChanges(); - } - - public void RemoveShow(long showID) - { - _database.Shows.Remove(new Show {ID = showID}); + if (_database.Entry(season).State == EntityState.Detached) + _database.Seasons.Attach(season); + _database.Seasons.Remove(season); } - public void RemoveSeason(long seasonID) + public void RemoveEpisode(Episode episode) { - _database.Seasons.Remove(new Season {ID = seasonID}); - } - - public void RemoveEpisode(long episodeID) - { - _database.Episodes.Remove(new Episode {ID = episodeID}); - } - - public void ClearSubtitles(long episodeID) - { - _database.Tracks.RemoveRange(_database.Tracks.Where(x => x.EpisodeID == episodeID)); + if (_database.Entry(episode).State == EntityState.Detached) + _database.Episodes.Attach(episode); + _database.Episodes.Remove(episode); } #endregion } diff --git a/Kyoo/Controllers/Transcoder/Transcoder.cs b/Kyoo/Controllers/Transcoder/Transcoder.cs index f596eb48..46c540c6 100644 --- a/Kyoo/Controllers/Transcoder/Transcoder.cs +++ b/Kyoo/Controllers/Transcoder/Transcoder.cs @@ -47,24 +47,22 @@ namespace Kyoo.Controllers }); } - public async Task Transmux(WatchItem episode) + public async Task Transmux(Episode episode) { - string folder = Path.Combine(_transmuxPath, episode.Link); - string manifest = Path.Combine(folder, episode.Link + ".m3u8"); + string folder = Path.Combine(_transmuxPath, episode.Slug); + string manifest = Path.Combine(folder, episode.Slug + ".m3u8"); float playableDuration = 0; bool transmuxFailed = false; try { Directory.CreateDirectory(folder); - Debug.WriteLine("&Transmuxing " + episode.Link + " at " + episode.Path + ", outputPath: " + folder); - if (File.Exists(manifest)) return manifest; } catch (UnauthorizedAccessException) { - Console.Error.WriteLine($"Access to the path {manifest} is denied. Please change your transmux path in the config."); + await Console.Error.WriteLineAsync($"Access to the path {manifest} is denied. Please change your transmux path in the config."); return null; } Task.Run(() => @@ -76,35 +74,9 @@ namespace Kyoo.Controllers return transmuxFailed ? null : manifest; } - public async Task Transcode(WatchItem episode) + public Task Transcode(Episode episode) { return null; // Not implemented yet. - string folder = Path.Combine(_transcodePath, episode.Link); - string manifest = Path.Combine(folder, episode.Link + ".m3u8"); - float playableDuration = 0; - bool transcodeFailed = false; - - try - { - Directory.CreateDirectory(folder); - Debug.WriteLine("&Transcoding " + episode.Link + " at " + episode.Path + ", outputPath: " + folder); - - if (File.Exists(manifest)) - return manifest; - } - catch (UnauthorizedAccessException) - { - Console.Error.WriteLine($"Access to the path {manifest} is denied. Please change your transmux path in the config."); - return null; - } - - Task.Run(() => - { - transcodeFailed = TranscoderAPI.transcode(episode.Path, manifest.Replace('\\', '/'), out playableDuration) != 0; - }); - while (playableDuration < 10 || (!File.Exists(manifest) && !transcodeFailed)) - await Task.Delay(10); - return transcodeFailed ? null : manifest; } } } diff --git a/Kyoo/Tasks/Crawler.cs b/Kyoo/Tasks/Crawler.cs index 306b3e6c..c46105b2 100644 --- a/Kyoo/Tasks/Crawler.cs +++ b/Kyoo/Tasks/Crawler.cs @@ -49,7 +49,7 @@ namespace Kyoo.Controllers try { - IEnumerable episodes = _libraryManager.GetAllEpisodes(); + IEnumerable episodes = _libraryManager.GetEpisodes(); IEnumerable libraries = argument == null ? _libraryManager.GetLibraries() : new [] {_libraryManager.GetLibrary(argument)}; @@ -127,7 +127,7 @@ namespace Kyoo.Controllers private async Task GetShow(string showTitle, string showPath, bool isMovie, Library library) { - Show show = _libraryManager.GetShow(showPath); + Show show = _libraryManager.GetShowByPath(showPath); if (show != null) return show; show = await _metadataProvider.SearchShow(showTitle, isMovie, library); @@ -135,7 +135,7 @@ namespace Kyoo.Controllers show.People = (await _metadataProvider.GetPeople(show, library)).GroupBy(x => x.Slug).Select(x => x.First()) .Select(x => { - People existing = _libraryManager.GetPeopleBySlug(x.Slug); + People existing = _libraryManager.GetPeople(x.Slug); if (existing != null) return new PeopleLink(existing, show, x.Role, x.Type); x.People.ExternalIDs = _libraryManager.ValidateExternalIDs(x.People.ExternalIDs); @@ -144,12 +144,12 @@ namespace Kyoo.Controllers show.People = await _thumbnailsManager.Validate(show.People); show.Genres = show.Genres?.Select(x => { - Genre existing = _libraryManager.GetGenreBySlug(x.Slug); + Genre existing = _libraryManager.GetGenre(x.Slug); return existing ?? x; }); show.ExternalIDs = _libraryManager.ValidateExternalIDs(show.ExternalIDs); if (show.Studio != null) - show.Studio = _libraryManager.GetStudioBySlug(show.Studio.Slug) ?? show.Studio; + show.Studio = _libraryManager.GetStudio(show.Studio.Slug) ?? show.Studio; await _thumbnailsManager.Validate(show); return show; } diff --git a/Kyoo/Views/API/LibrariesAPI.cs b/Kyoo/Views/API/LibrariesAPI.cs index 3b4fabb4..544252a0 100644 --- a/Kyoo/Views/API/LibrariesAPI.cs +++ b/Kyoo/Views/API/LibrariesAPI.cs @@ -56,7 +56,7 @@ namespace Kyoo.Api if (library == null) return NotFound(); - return _libraryManager.GetShowsInLibrary(library.ID).ToList(); + return library.Shows.Concat(library.Collections.Select(x => x.AsShow())).ToList(); } } } \ No newline at end of file diff --git a/Kyoo/Views/API/PeopleAPI.cs b/Kyoo/Views/API/PeopleAPI.cs index 274bcbfe..25ef79eb 100644 --- a/Kyoo/Views/API/PeopleAPI.cs +++ b/Kyoo/Views/API/PeopleAPI.cs @@ -1,4 +1,5 @@ -using Kyoo.Controllers; +using System.Linq; +using Kyoo.Controllers; using Kyoo.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -20,13 +21,13 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public ActionResult GetPeople(string peopleSlug) { - People people = _libraryManager.GetPeopleBySlug(peopleSlug); + People people = _libraryManager.GetPeople(peopleSlug); if (people == null) return NotFound(); Collection collection = new Collection(people.Slug, people.Name, null, null) { - Shows = _libraryManager.GetShowsByPeople(people.Slug), + Shows = people.Roles.Select(x => x.Show), Poster = "peopleimg/" + people.Slug }; return collection; diff --git a/Kyoo/Views/API/ShowsAPI.cs b/Kyoo/Views/API/ShowsAPI.cs index bff47836..71385fd3 100644 --- a/Kyoo/Views/API/ShowsAPI.cs +++ b/Kyoo/Views/API/ShowsAPI.cs @@ -45,7 +45,7 @@ namespace Kyoo.Api [JsonDetailed] public ActionResult GetShow(string slug) { - Show show = _libraryManager.GetShowBySlug(slug); + Show show = _libraryManager.GetShow(slug); if (show == null) return NotFound(); @@ -96,7 +96,7 @@ namespace Kyoo.Api [Authorize(Policy = "Write")] public async Task DownloadImages(string slug) { - Show show = _libraryManager.GetShowBySlug(slug); + Show show = _libraryManager.GetShow(slug); if (show == null) return NotFound(); await _thumbnailsManager.Validate(show, true); diff --git a/Kyoo/Views/API/ThumbnailAPI.cs b/Kyoo/Views/API/ThumbnailAPI.cs index 5aff643c..22b376e8 100644 --- a/Kyoo/Views/API/ThumbnailAPI.cs +++ b/Kyoo/Views/API/ThumbnailAPI.cs @@ -22,7 +22,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public IActionResult GetShowThumb(string showSlug) { - string path = _libraryManager.GetShowBySlug(showSlug)?.Path; + string path = _libraryManager.GetShow(showSlug)?.Path; if (path == null) return NotFound(); @@ -37,7 +37,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public IActionResult GetShowLogo(string showSlug) { - string path = _libraryManager.GetShowBySlug(showSlug)?.Path; + string path = _libraryManager.GetShow(showSlug)?.Path; if (path == null) return NotFound(); @@ -52,7 +52,7 @@ namespace Kyoo.Api [Authorize(Policy="Read")] public IActionResult GetShowBackdrop(string showSlug) { - string path = _libraryManager.GetShowBySlug(showSlug)?.Path; + string path = _libraryManager.GetShow(showSlug)?.Path; if (path == null) return NotFound(); diff --git a/Kyoo/Views/API/VideoAPI.cs b/Kyoo/Views/API/VideoAPI.cs index 4b72fab0..c1fd57b0 100644 --- a/Kyoo/Views/API/VideoAPI.cs +++ b/Kyoo/Views/API/VideoAPI.cs @@ -29,7 +29,7 @@ namespace Kyoo.Api [Authorize(Policy="Play")] public IActionResult Index(string showSlug, long seasonNumber, long episodeNumber) { - WatchItem episode = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); + Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber); if (episode != null && System.IO.File.Exists(episode.Path)) return PhysicalFile(episode.Path, "video/x-matroska", true); @@ -40,7 +40,7 @@ namespace Kyoo.Api [Authorize(Policy="Play")] public async Task Transmux(string showSlug, long seasonNumber, long episodeNumber) { - WatchItem episode = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); + Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber); if (episode == null || !System.IO.File.Exists(episode.Path)) return NotFound(); @@ -63,7 +63,7 @@ namespace Kyoo.Api [Authorize(Policy="Play")] public async Task Transcode(string showSlug, long seasonNumber, long episodeNumber) { - WatchItem episode = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); + Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber); if (episode == null || !System.IO.File.Exists(episode.Path)) return NotFound(); @@ -98,7 +98,7 @@ namespace Kyoo.Api [Authorize(Policy="Play")] public async Task Transmux(string movieSlug) { - WatchItem episode = _libraryManager.GetMovieWatchItem(movieSlug); + Episode episode = _libraryManager.GetMovieEpisode(movieSlug); if (episode == null || !System.IO.File.Exists(episode.Path)) return NotFound(); @@ -112,7 +112,7 @@ namespace Kyoo.Api [Authorize(Policy="Play")] public async Task Transcode(string movieSlug) { - WatchItem episode = _libraryManager.GetMovieWatchItem(movieSlug); + Episode episode = _libraryManager.GetMovieEpisode(movieSlug); if (episode == null || !System.IO.File.Exists(episode.Path)) return NotFound();