using System.Collections.Generic; using System.Threading.Tasks; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Plex; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; using Microsoft.Extensions.Logging; using static LanguageExt.Prelude; namespace ErsatzTV.Core.Plex { public class PlexMovieLibraryScanner : IPlexMovieLibraryScanner { private readonly ILogger _logger; private readonly IMovieRepository _movieRepository; private readonly IPlexServerApiClient _plexServerApiClient; public PlexMovieLibraryScanner( IPlexServerApiClient plexServerApiClient, IMovieRepository movieRepository, ILogger logger) { _plexServerApiClient = plexServerApiClient; _movieRepository = movieRepository; _logger = logger; } public async Task> ScanLibrary( PlexConnection connection, PlexServerAuthToken token, PlexLibrary plexMediaSourceLibrary) { Either> entries = await _plexServerApiClient.GetLibraryContents( plexMediaSourceLibrary, connection, token); await entries.Match( async movieEntries => { foreach (PlexMovie entry 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); maybeMovie.IfLeft( error => _logger.LogWarning( "Error processing plex movie at {Key}: {Error}", entry.Key, error.Value)); } }, error => { _logger.LogWarning( "Error synchronizing plex library {Path}: {Error}", plexMediaSourceLibrary.Name, error.Value); return Task.CompletedTask; }); // need plex media item model that can be used to lookup by unique id (metadata key?) return Unit.Default; } private Task> UpdateIfNeeded(PlexMovie plexMovie) => // .BindT(movie => UpdateStatistics(movie, ffprobePath).MapT(_ => movie)) // .BindT(UpdateMetadata) // .BindT(UpdatePoster); Right(plexMovie).AsTask(); } }