diff --git a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs index 6fbffa72..9974dab8 100644 --- a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs +++ b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs @@ -261,6 +261,14 @@ namespace Kyoo.Controllers return obj; } + private async Task SetRelation(T1 obj, Task> loader, Action> setter, Action inverse) + { + ICollection loaded = await loader; + setter(obj, loaded); + foreach (T2 item in loaded) + inverse(item, obj); + } + public Task Load(IResource obj, string member) { if (obj == null) @@ -270,42 +278,57 @@ namespace Kyoo.Controllers { (Library l, nameof(Library.Providers)) => ProviderRepository .GetAll(x => x.Libraries.Any(y => y.ID == obj.ID)) - .Then(x => l.Providers = x), + .Then(x => l.Providers = x), + (Library l, nameof(Library.Shows)) => ShowRepository .GetAll(x => x.Libraries.Any(y => y.ID == obj.ID)) .Then(x => l.Shows = x), + (Library l, nameof(Library.Collections)) => CollectionRepository .GetAll(x => x.Libraries.Any(y => y.ID == obj.ID)) .Then(x => l.Collections = x), + (Collection c, nameof(Library.Shows)) => ShowRepository .GetAll(x => x.Collections.Any(y => y.ID == obj.ID)) .Then(x => c.Shows = x), + (Collection c, nameof(Collection.Libraries)) => LibraryRepository .GetAll(x => x.Collections.Any(y => y.ID == obj.ID)) .Then(x => c.Libraries = x), - (Show s, nameof(Show.ExternalIDs)) => ProviderRepository - .GetMetadataID(x => x.ShowID == obj.ID) - .Then(x => s.ExternalIDs = x), + + (Show s, nameof(Show.ExternalIDs)) => SetRelation(s, + ProviderRepository.GetMetadataID(x => x.ShowID == obj.ID), + (x, y) => x.ExternalIDs = y, + (x, y) => x.Show = y), + (Show s, nameof(Show.Genres)) => GenreRepository .GetAll(x => x.Shows.Any(y => y.ID == obj.ID)) .Then(x => s.Genres = x), + (Show s, nameof(Show.People)) => PeopleRepository .GetFromShow(obj.ID) .Then(x => s.People = x), - (Show s, nameof(Show.Seasons)) => SeasonRepository - .GetAll(x => x.Show.ID == obj.ID) - .Then(x => s.Seasons = x), - (Show s, nameof(Show.Episodes)) => EpisodeRepository - .GetAll(x => x.Show.ID == obj.ID) - .Then(x => s.Episodes = x), + + (Show s, nameof(Show.Seasons)) => SetRelation(s, + SeasonRepository.GetAll(x => x.Show.ID == obj.ID), + (x, y) => x.Seasons = y, + (x, y) => { x.Show = y; x.ShowID = y.ID; }), + + (Show s, nameof(Show.Episodes)) => SetRelation(s, + EpisodeRepository.GetAll(x => x.Show.ID == obj.ID), + (x, y) => x.Episodes = y, + (x, y) => { x.Show = y; x.ShowID = y.ID; }), + (Show s, nameof(Show.Libraries)) => LibraryRepository .GetAll(x => x.Shows.Any(y => y.ID == obj.ID)) .Then(x => s.Libraries = x), + (Show s, nameof(Show.Collections)) => CollectionRepository .GetAll(x => x.Shows.Any(y => y.ID == obj.ID)) .Then(x => s.Collections = x), + (Show s, nameof(Show.Studio)) => StudioRepository .Get(x => x.Shows.Any(y => y.ID == obj.ID)) .Then(x => @@ -314,12 +337,17 @@ namespace Kyoo.Controllers s.StudioID = x?.ID ?? 0; }), - (Season s, nameof(Season.ExternalIDs)) => ProviderRepository - .GetMetadataID(x => x.SeasonID == obj.ID) - .Then(x => s.ExternalIDs = x), - (Season s, nameof(Season.Episodes)) => EpisodeRepository - .GetAll(x => x.Season.ID == obj.ID) - .Then(x => s.Episodes = x), + + (Season s, nameof(Season.ExternalIDs)) => SetRelation(s, + ProviderRepository.GetMetadataID(x => x.SeasonID == obj.ID), + (x, y) => x.ExternalIDs = y, + (x, y) => { x.Season = y; x.SeasonID = y.ID; }), + + (Season s, nameof(Season.Episodes)) => SetRelation(s, + EpisodeRepository.GetAll(x => x.Season.ID == obj.ID), + (x, y) => x.Episodes = y, + (x, y) => { x.Season = y; x.SeasonID = y.ID; }), + (Season s, nameof(Season.Show)) => ShowRepository .Get(x => x.Seasons.Any(y => y.ID == obj.ID)) .Then(x => @@ -328,12 +356,17 @@ namespace Kyoo.Controllers s.ShowID = x?.ID ?? 0; }), - (Episode e, nameof(Episode.ExternalIDs)) => ProviderRepository - .GetMetadataID(x => x.EpisodeID == obj.ID) - .Then(x => e.ExternalIDs = x), - (Episode e, nameof(Episode.Tracks)) => TrackRepository - .GetAll(x => x.Episode.ID == obj.ID) - .Then(x => e.Tracks = x), + + (Episode e, nameof(Episode.ExternalIDs)) => SetRelation(e, + ProviderRepository.GetMetadataID(x => x.EpisodeID == obj.ID), + (x, y) => x.ExternalIDs = y, + (x, y) => { x.Episode = y; x.EpisodeID = y.ID; }), + + (Episode e, nameof(Episode.Tracks)) => SetRelation(e, + TrackRepository.GetAll(x => x.Episode.ID == obj.ID), + (x, y) => x.Tracks = y, + (x, y) => { x.Episode = y; x.EpisodeID = y.ID; }), + (Episode e, nameof(Episode.Show)) => ShowRepository .Get(x => x.Episodes.Any(y => y.ID == obj.ID)) .Then(x => @@ -341,6 +374,7 @@ namespace Kyoo.Controllers e.Show = x; e.ShowID = x?.ID ?? 0; }), + (Episode e, nameof(Episode.Season)) => SeasonRepository .Get(x => x.Episodes.Any(y => y.ID == e.ID)) .Then(x => @@ -349,6 +383,7 @@ namespace Kyoo.Controllers e.SeasonID = x?.ID ?? 0; }), + (Track t, nameof(Track.Episode)) => EpisodeRepository .Get(x => x.Tracks.Any(y => y.ID == obj.ID)) .Then(x => @@ -357,24 +392,31 @@ namespace Kyoo.Controllers t.EpisodeID = x?.ID ?? 0; }), + (Genre g, nameof(Genre.Shows)) => ShowRepository .GetAll(x => x.Genres.Any(y => y.ID == obj.ID)) .Then(x => g.Shows = x), + (Studio s, nameof(Studio.Shows)) => ShowRepository .GetAll(x => x.Studio.ID == obj.ID) .Then(x => s.Shows = x), - (People p, nameof(People.ExternalIDs)) => ProviderRepository - .GetMetadataID(x => x.PeopleID == obj.ID) - .Then(x => p.ExternalIDs = x), + + (People p, nameof(People.ExternalIDs)) => SetRelation(p, + ProviderRepository.GetMetadataID(x => x.PeopleID == obj.ID), + (x, y) => x.ExternalIDs = y, + (x, y) => { x.People = y; x.PeopleID = y.ID; }), + (People p, nameof(People.Roles)) => PeopleRepository .GetFromPeople(obj.ID) .Then(x => p.Roles = x), + (ProviderID p, nameof(ProviderID.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}.") }; diff --git a/Kyoo.Common/Models/WatchItem.cs b/Kyoo.Common/Models/WatchItem.cs index e007e04c..0fe617da 100644 --- a/Kyoo.Common/Models/WatchItem.cs +++ b/Kyoo.Common/Models/WatchItem.cs @@ -89,7 +89,7 @@ namespace Kyoo.Models public static async Task FromEpisode(Episode ep, ILibraryManager library) { - Show show = await library.GetShow(ep.ShowID); // TODO load only the title, the slug & the IsMovie with the library manager. + Show show = await library.GetShow(ep.ShowID); Episode previous = null; Episode next = null; @@ -110,6 +110,7 @@ namespace Kyoo.Models next = await library.GetEpisode(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber + 1); } + await library.Load(ep, x => x.Tracks); return new WatchItem(ep.ID, show.Title, show.Slug, @@ -118,9 +119,9 @@ namespace Kyoo.Models ep.Title, ep.ReleaseDate, ep.Path, - await library.GetTrack(x => x.EpisodeID == ep.ID && x.Type == StreamType.Video), - await library.GetTracks(x => x.EpisodeID == ep.ID && x.Type == StreamType.Audio), - await library.GetTracks(x => x.EpisodeID == ep.ID && x.Type == StreamType.Subtitle)) + ep.Tracks.FirstOrDefault(x => x.Type == StreamType.Video), + ep.Tracks.Where(x => x.Type == StreamType.Audio), + ep.Tracks.Where(x => x.Type == StreamType.Subtitle)) { IsMovie = show.IsMovie, PreviousEpisode = previous, @@ -137,7 +138,7 @@ namespace Kyoo.Models PathIO.GetFileNameWithoutExtension(episodePath) + ".txt" ); if (!File.Exists(path)) - return new Chapter[0]; + return Array.Empty(); try { return (await File.ReadAllLinesAsync(path)) @@ -151,7 +152,7 @@ namespace Kyoo.Models catch { await Console.Error.WriteLineAsync($"Invalid chapter file at {path}"); - return new Chapter[0]; + return Array.Empty(); } } } diff --git a/Kyoo/Views/WebClient b/Kyoo/Views/WebClient index 09edd091..35e6a601 160000 --- a/Kyoo/Views/WebClient +++ b/Kyoo/Views/WebClient @@ -1 +1 @@ -Subproject commit 09edd091b9bc75b697da4dc16eeaf9aadb9d4b05 +Subproject commit 35e6a601edc494d1bea142fd419c7750c18d21d9