private async Task <string> GetPlayoutItemPath(PlayoutItem playoutItem) { MediaVersion version = playoutItem.MediaItem.GetHeadVersion(); MediaFile file = version.MediaFiles.Head(); string path = file.Path; return(playoutItem.MediaItem switch { PlexMovie plexMovie => await _plexPathReplacementService.GetReplacementPlexPath( plexMovie.LibraryPathId, path), PlexEpisode plexEpisode => await _plexPathReplacementService.GetReplacementPlexPath( plexEpisode.LibraryPathId, path), JellyfinMovie jellyfinMovie => await _jellyfinPathReplacementService.GetReplacementJellyfinPath( jellyfinMovie.LibraryPathId, path), JellyfinEpisode jellyfinEpisode => await _jellyfinPathReplacementService.GetReplacementJellyfinPath( jellyfinEpisode.LibraryPathId, path), EmbyMovie embyMovie => await _embyPathReplacementService.GetReplacementEmbyPath( embyMovie.LibraryPathId, path), EmbyEpisode embyEpisode => await _embyPathReplacementService.GetReplacementEmbyPath( embyEpisode.LibraryPathId, path), _ => path });
public async Task <Either <BaseError, Unit> > ScanLibrary( string address, string apiKey, EmbyLibrary library, string ffmpegPath, string ffprobePath, CancellationToken cancellationToken) { List <EmbyPathReplacement> pathReplacements = await _mediaSourceRepository.GetEmbyPathReplacements(library.MediaSourceId); string GetLocalPath(EmbyMovie movie) { return(_pathReplacementService.GetReplacementEmbyPath( pathReplacements, movie.GetHeadVersion().MediaFiles.Head().Path, false)); } return(await ScanLibrary( _embyMovieRepository, new EmbyConnectionParameters(address, apiKey), library, GetLocalPath, ffmpegPath, ffprobePath, false, cancellationToken)); }
private async Task <Either <BaseError, Unit> > ProcessSeasons( string address, string apiKey, EmbyLibrary library, string ffmpegPath, string ffprobePath, List <EmbyPathReplacement> pathReplacements, EmbyShow show, List <EmbyItemEtag> existingSeasons, List <EmbySeason> seasons, CancellationToken cancellationToken) { foreach (EmbySeason incoming in seasons) { if (cancellationToken.IsCancellationRequested) { return(new ScanCanceled()); } Option <EmbyItemEtag> maybeExisting = existingSeasons.Find(ie => ie.ItemId == incoming.ItemId); if (maybeExisting.IsNone) { incoming.LibraryPathId = library.Paths.Head().Id; _logger.LogDebug( "INSERT: Item id is new for show {Show} season {Season}", show.ShowMetadata.Head().Title, incoming.SeasonMetadata.Head().Title); if (await _televisionRepository.AddSeason(show, incoming)) { incoming.Show = show; await _searchIndex.AddItems(_searchRepository, new List <MediaItem> { incoming }); } } foreach (EmbyItemEtag existing in maybeExisting) { if (existing.Etag != incoming.Etag) { _logger.LogDebug( "UPDATE: Etag has changed for show {Show} season {Season}", show.ShowMetadata.Head().Title, incoming.SeasonMetadata.Head().Title); incoming.ShowId = show.Id; incoming.LibraryPathId = library.Paths.Head().Id; foreach (EmbySeason updated in await _televisionRepository.Update(incoming)) { incoming.Show = show; foreach (MediaItem toIndex in await _searchRepository.GetItemToIndex(updated.Id)) { await _searchIndex.UpdateItems(_searchRepository, new List <MediaItem> { toIndex }); } } } } List <EmbyItemEtag> existingEpisodes = await _televisionRepository.GetExistingEpisodes(library, incoming.ItemId); Either <BaseError, List <EmbyEpisode> > maybeEpisodes = await _embyApiClient.GetEpisodeLibraryItems(address, apiKey, incoming.ItemId); foreach (BaseError error in maybeEpisodes.LeftToSeq()) { _logger.LogWarning( "Error synchronizing emby library {Path}: {Error}", library.Name, error.Value); } foreach (List <EmbyEpisode> episodes in maybeEpisodes.RightToSeq()) { var validEpisodes = new List <EmbyEpisode>(); foreach (EmbyEpisode episode in episodes) { string localPath = _pathReplacementService.GetReplacementEmbyPath( pathReplacements, episode.MediaVersions.Head().MediaFiles.Head().Path, false); if (!_localFileSystem.FileExists(localPath)) { _logger.LogWarning( "Skipping emby episode that does not exist at {Path}", localPath); } else { validEpisodes.Add(episode); } } Either <BaseError, Unit> scanResult = await ProcessEpisodes( show.ShowMetadata.Head().Title, incoming.SeasonMetadata.Head().Title, library, ffmpegPath, ffprobePath, pathReplacements, incoming, existingEpisodes, validEpisodes, cancellationToken); foreach (ScanCanceled error in scanResult.LeftToSeq().OfType <ScanCanceled>()) { return(error); } foreach (Unit _ in scanResult.RightToSeq()) { var incomingEpisodeIds = episodes.Map(s => s.ItemId).ToList(); var episodeIds = existingEpisodes .Filter(i => !incomingEpisodeIds.Contains(i.ItemId)) .Map(m => m.ItemId) .ToList(); List <int> missingEpisodeIds = await _televisionRepository.RemoveMissingEpisodes(library, episodeIds); await _searchIndex.RemoveItems(missingEpisodeIds); _searchIndex.Commit(); } } } return(Unit.Default); }