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
        });
예제 #2
0
        public static async Task SingleEpisodeCheck(bool useImdb, IQueryable <JellyfinEpisode> allEpisodes, EpisodeRequests episode,
                                                    SeasonRequests season, JellyfinContent item, bool useTheMovieDb, bool useTvDb)
        {
            JellyfinEpisode epExists = null;

            if (useImdb)
            {
                epExists = await allEpisodes.FirstOrDefaultAsync(x =>
                                                                 x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
                                                                 x.Series.ImdbId == item.ImdbId);
            }

            if (useTheMovieDb)
            {
                epExists = await allEpisodes.FirstOrDefaultAsync(x =>
                                                                 x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
                                                                 x.Series.TheMovieDbId == item.TheMovieDbId);
            }

            if (useTvDb)
            {
                epExists = await allEpisodes.FirstOrDefaultAsync(x =>
                                                                 x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
                                                                 x.Series.TvDbId == item.TvDbId);
            }

            if (epExists != null)
            {
                episode.Available = true;
            }
        }
예제 #3
0
        public async Task <JellyfinEpisode> Add(JellyfinEpisode content)
        {
            await Db.JellyfinEpisode.AddAsync(content);

            await InternalSaveChanges();

            return(content);
        }
예제 #4
0
 private async Task <Either <BaseError, bool> > UpdateSubtitles(JellyfinEpisode episode, string localPath)
 {
     try
     {
         return(await _localSubtitlesProvider.UpdateSubtitles(episode, localPath, false));
     }
     catch (Exception ex)
     {
         return(BaseError.New(ex.ToString()));
     }
 }
예제 #5
0
    private async Task <Either <BaseError, Unit> > ProcessEpisodes(
        string showName,
        string seasonName,
        JellyfinLibrary library,
        string ffmpegPath,
        string ffprobePath,
        List <JellyfinPathReplacement> pathReplacements,
        JellyfinSeason season,
        List <JellyfinItemEtag> existingEpisodes,
        List <JellyfinEpisode> episodes,
        CancellationToken cancellationToken)
    {
        foreach (JellyfinEpisode incoming in episodes)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(new ScanCanceled());
            }

            JellyfinEpisode incomingEpisode  = incoming;
            var             updateStatistics = false;

            Option <JellyfinItemEtag> maybeExisting = existingEpisodes.Find(ie => ie.ItemId == incoming.ItemId);
            if (maybeExisting.IsNone)
            {
                try
                {
                    updateStatistics       = true;
                    incoming.LibraryPathId = library.Paths.Head().Id;

                    _logger.LogDebug(
                        "INSERT: Item id is new for show {Show} season {Season} episode {Episode}",
                        showName,
                        seasonName,
                        incoming.EpisodeMetadata.HeadOrNone().Map(em => em.EpisodeNumber));

                    if (await _televisionRepository.AddEpisode(season, incoming))
                    {
                        await _searchIndex.AddItems(_searchRepository, new List <MediaItem> {
                            incoming
                        });
                    }
                }
                catch (Exception ex)
                {
                    updateStatistics = false;
                    _logger.LogError(
                        ex,
                        "Error adding episode {Path}",
                        incoming.MediaVersions.Head().MediaFiles.Head().Path);
                }
            }

            foreach (JellyfinItemEtag existing in maybeExisting)
            {
                try
                {
                    if (existing.Etag != incoming.Etag)
                    {
                        _logger.LogDebug(
                            "UPDATE: Etag has changed for show {Show} season {Season} episode {Episode}",
                            showName,
                            seasonName,
                            incoming.EpisodeMetadata.HeadOrNone().Map(em => em.EpisodeNumber));

                        updateStatistics       = true;
                        incoming.SeasonId      = season.Id;
                        incoming.LibraryPathId = library.Paths.Head().Id;

                        Option <JellyfinEpisode> maybeUpdated = await _televisionRepository.Update(incoming);

                        foreach (JellyfinEpisode updated in maybeUpdated)
                        {
                            await _searchIndex.UpdateItems(_searchRepository, new List <MediaItem> {
                                updated
                            });

                            incomingEpisode = updated;
                        }
                    }
                }
                catch (Exception ex)
                {
                    updateStatistics = false;
                    _logger.LogError(
                        ex,
                        "Error updating episode {Path}",
                        incoming.MediaVersions.Head().MediaFiles.Head().Path);
                }
            }

            if (updateStatistics)
            {
                string localPath = _pathReplacementService.GetReplacementJellyfinPath(
                    pathReplacements,
                    incoming.MediaVersions.Head().MediaFiles.Head().Path,
                    false);

                _logger.LogDebug("Refreshing {Attribute} for {Path}", "Statistics", localPath);
                Either <BaseError, bool> refreshResult =
                    await _localStatisticsProvider.RefreshStatistics(
                        ffmpegPath,
                        ffprobePath,
                        incomingEpisode,
                        localPath);

                if (refreshResult.Map(t => t).IfLeft(false))
                {
                    refreshResult = await UpdateSubtitles(incomingEpisode, localPath);
                }

                foreach (BaseError error in refreshResult.LeftToSeq())
                {
                    _logger.LogWarning(
                        "Unable to refresh {Attribute} for media item {Path}. Error: {Error}",
                        "Statistics",
                        localPath,
                        error.Value);
                }
            }
        }

        return(Unit.Default);
    }