From d036156eb472f887cf4ad01cd56aba3793843873 Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Sat, 13 Mar 2021 09:43:00 -0600 Subject: [PATCH] synchronize genre from plex --- ErsatzTV.Core/Plex/PlexMovieLibraryScanner.cs | 56 ++++++++++++++----- .../Data/Repositories/MovieRepository.cs | 1 + .../Plex/Models/PlexGenreResponse.cs | 9 +++ .../Plex/Models/PlexMetadataResponse.cs | 1 + .../Plex/PlexServerApiClient.cs | 3 +- 5 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 ErsatzTV.Infrastructure/Plex/Models/PlexGenreResponse.cs diff --git a/ErsatzTV.Core/Plex/PlexMovieLibraryScanner.cs b/ErsatzTV.Core/Plex/PlexMovieLibraryScanner.cs index cba58716b..6fa61ae90 100644 --- a/ErsatzTV.Core/Plex/PlexMovieLibraryScanner.cs +++ b/ErsatzTV.Core/Plex/PlexMovieLibraryScanner.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Plex; @@ -38,19 +39,26 @@ namespace ErsatzTV.Core.Plex await entries.Match( async movieEntries => { - foreach (PlexMovie entry in movieEntries) + foreach (PlexMovie incoming in movieEntries) { // TODO: optimize dbcontext use here, do we need tracking? can we make partial updates with dapper? // TODO: figure out how to rebuild playlists Either maybeMovie = await _movieRepository - .GetOrAdd(plexMediaSourceLibrary, entry) - .BindT(UpdateIfNeeded); + .GetOrAdd(plexMediaSourceLibrary, incoming) + .BindT(existing => UpdateStatistics(existing, incoming)) + .BindT(existing => UpdateMetadata(existing, incoming)) + .BindT(existing => UpdateArtwork(existing, incoming)); - maybeMovie.IfLeft( - error => _logger.LogWarning( - "Error processing plex movie at {Key}: {Error}", - entry.Key, - error.Value)); + await maybeMovie.Match( + async movie => await _movieRepository.Update(movie), + error => + { + _logger.LogWarning( + "Error processing plex movie at {Key}: {Error}", + incoming.Key, + error.Value); + return Task.CompletedTask; + }); } }, error => @@ -68,10 +76,32 @@ namespace ErsatzTV.Core.Plex return Unit.Default; } - private Task> UpdateIfNeeded(PlexMovie plexMovie) => - // .BindT(movie => UpdateStatistics(movie, ffprobePath).MapT(_ => movie)) - // .BindT(UpdateMetadata) - // .BindT(UpdatePoster); - Right(plexMovie).AsTask(); + private Task> UpdateStatistics(PlexMovie existing, PlexMovie incoming) => + Right(existing).AsTask(); + + private Task> UpdateMetadata(PlexMovie existing, PlexMovie incoming) + { + MovieMetadata existingMetadata = existing.MovieMetadata.Head(); + MovieMetadata incomingMetadata = incoming.MovieMetadata.Head(); + + foreach (Genre genre in existingMetadata.Genres + .Filter(g => incomingMetadata.Genres.All(g2 => g2.Name != g.Name)) + .ToList()) + { + existingMetadata.Genres.Remove(genre); + } + + foreach (Genre genre in incomingMetadata.Genres + .Filter(g => existingMetadata.Genres.All(g2 => g2.Name != g.Name)) + .ToList()) + { + existingMetadata.Genres.Add(genre); + } + + return Right(existing).AsTask(); + } + + private Task> UpdateArtwork(PlexMovie existing, PlexMovie incoming) => + Right(existing).AsTask(); } } diff --git a/ErsatzTV.Infrastructure/Data/Repositories/MovieRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/MovieRepository.cs index dd51f0d1b..471ddf1b7 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/MovieRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/MovieRepository.cs @@ -76,6 +76,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories Option maybeExisting = await context.PlexMovies .AsNoTracking() .Include(i => i.MovieMetadata) + .ThenInclude(mm => mm.Genres) .Include(i => i.MediaVersions) .ThenInclude(mv => mv.MediaFiles) .OrderBy(i => i.Key) diff --git a/ErsatzTV.Infrastructure/Plex/Models/PlexGenreResponse.cs b/ErsatzTV.Infrastructure/Plex/Models/PlexGenreResponse.cs new file mode 100644 index 000000000..e06e57bad --- /dev/null +++ b/ErsatzTV.Infrastructure/Plex/Models/PlexGenreResponse.cs @@ -0,0 +1,9 @@ +namespace ErsatzTV.Infrastructure.Plex.Models +{ + public class PlexGenreResponse + { + public int Id { get; set; } + public string Filter { get; set; } + public string Tag { get; set; } + } +} diff --git a/ErsatzTV.Infrastructure/Plex/Models/PlexMetadataResponse.cs b/ErsatzTV.Infrastructure/Plex/Models/PlexMetadataResponse.cs index 293505e36..772e7eea7 100644 --- a/ErsatzTV.Infrastructure/Plex/Models/PlexMetadataResponse.cs +++ b/ErsatzTV.Infrastructure/Plex/Models/PlexMetadataResponse.cs @@ -15,5 +15,6 @@ namespace ErsatzTV.Infrastructure.Plex.Models public int AddedAt { get; set; } public int UpdatedAt { get; set; } public List Media { get; set; } + public List Genre { get; set; } } } diff --git a/ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs b/ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs index 9a014aebd..37106baca 100644 --- a/ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs +++ b/ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs @@ -99,7 +99,8 @@ namespace ErsatzTV.Infrastructure.Plex Year = response.Year, Tagline = response.Tagline, DateAdded = dateAdded, - DateUpdated = lastWriteTime + DateUpdated = lastWriteTime, + Genres = response.Genre.Map(g => new Genre { Name = g.Tag }).ToList() }; if (!string.IsNullOrWhiteSpace(response.Thumb))