public async Task <Either <BaseError, Unit> > ScanLibrary( PlexConnection connection, PlexServerAuthToken token, PlexLibrary library, string ffmpegPath, string ffprobePath, bool deepScan, CancellationToken cancellationToken) { List <PlexPathReplacement> pathReplacements = await _mediaSourceRepository.GetPlexPathReplacements(library.MediaSourceId); string GetLocalPath(PlexMovie movie) { return(_plexPathReplacementService.GetReplacementPlexPath( pathReplacements, movie.GetHeadVersion().MediaFiles.Head().Path, false)); } return(await ScanLibrary( _plexMovieRepository, new PlexConnectionParameters(connection, token), library, GetLocalPath, ffmpegPath, ffprobePath, deepScan, cancellationToken)); }
private async Task <Either <BaseError, Unit> > ScanLibrary( PlexConnection connection, PlexServerAuthToken token, PlexLibrary library, string ffmpegPath, string ffprobePath, bool deepScan, List <PlexShow> showEntries, CancellationToken cancellationToken) { List <PlexItemEtag> existingShows = await _plexTelevisionRepository.GetExistingPlexShows(library); List <PlexPathReplacement> pathReplacements = await _mediaSourceRepository .GetPlexPathReplacements(library.MediaSourceId); foreach (PlexShow incoming in showEntries) { if (cancellationToken.IsCancellationRequested) { return(new ScanCanceled()); } decimal percentCompletion = (decimal)showEntries.IndexOf(incoming) / showEntries.Count; await _mediator.Publish(new LibraryScanProgress(library.Id, percentCompletion), cancellationToken); // TODO: figure out how to rebuild playlists Either <BaseError, MediaItemScanResult <PlexShow> > maybeShow = await _televisionRepository .GetOrAddPlexShow(library, incoming) .BindT(existing => UpdateMetadata(existing, incoming, library, connection, token, deepScan)) .BindT(existing => UpdateArtwork(existing, incoming)); if (maybeShow.IsLeft) { foreach (BaseError error in maybeShow.LeftToSeq()) { _logger.LogWarning( "Error processing plex show at {Key}: {Error}", incoming.Key, error.Value); } continue; } foreach (MediaItemScanResult <PlexShow> result in maybeShow.RightToSeq()) { Either <BaseError, Unit> scanResult = await ScanSeasons( library, pathReplacements, result.Item, connection, token, ffmpegPath, ffprobePath, deepScan, cancellationToken); foreach (ScanCanceled error in scanResult.LeftToSeq().OfType <ScanCanceled>()) { return(error); } await _plexTelevisionRepository.SetPlexEtag(result.Item, incoming.Etag); // TODO: if any seasons are unavailable or not found, flag show as unavailable/not found if (result.IsAdded) { await _searchIndex.AddItems(_searchRepository, new List <MediaItem> { result.Item }); } else if (result.IsUpdated) { await _searchIndex.UpdateItems( _searchRepository, new List <MediaItem> { result.Item }); } } } // trash items that are no longer present on the media server var fileNotFoundKeys = existingShows.Map(m => m.Key).Except(showEntries.Map(m => m.Key)).ToList(); List <int> ids = await _plexTelevisionRepository.FlagFileNotFoundShows(library, fileNotFoundKeys); await _searchIndex.RebuildItems(_searchRepository, ids); await _mediator.Publish(new LibraryScanProgress(library.Id, 0), cancellationToken); return(Unit.Default); }