コード例 #1
0
        public async Task <Either <BaseError, MediaItemScanResult <PlexMovie> > > GetOrAdd(
            PlexLibrary library,
            PlexMovie item)
        {
            await using TvContext context = _dbContextFactory.CreateDbContext();
            Option <PlexMovie> maybeExisting = await context.PlexMovies
                                               .AsNoTracking()
                                               .Include(i => i.MovieMetadata)
                                               .ThenInclude(mm => mm.Genres)
                                               .Include(i => i.MovieMetadata)
                                               .ThenInclude(mm => mm.Tags)
                                               .Include(i => i.MovieMetadata)
                                               .ThenInclude(mm => mm.Studios)
                                               .Include(i => i.MovieMetadata)
                                               .ThenInclude(mm => mm.Artwork)
                                               .Include(i => i.MediaVersions)
                                               .ThenInclude(mv => mv.MediaFiles)
                                               .Include(i => i.LibraryPath)
                                               .ThenInclude(lp => lp.Library)
                                               .OrderBy(i => i.Key)
                                               .SingleOrDefaultAsync(i => i.Key == item.Key);

            return(await maybeExisting.Match(
                       plexMovie =>
                       Right <BaseError, MediaItemScanResult <PlexMovie> >(
                           new MediaItemScanResult <PlexMovie>(plexMovie)
            {
                IsAdded = true
            }).AsTask(),
                       async() => await AddPlexMovie(context, library, item)));
        }
    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
        });
コード例 #3
0
        private async Task <Either <BaseError, MediaItemScanResult <PlexMovie> > > AddPlexMovie(
            TvContext context,
            PlexLibrary library,
            PlexMovie item)
        {
            try
            {
                item.LibraryPathId = library.Paths.Head().Id;

                await context.PlexMovies.AddAsync(item);

                await context.SaveChangesAsync();

                await context.Entry(item).Reference(i => i.LibraryPath).LoadAsync();

                await context.Entry(item.LibraryPath).Reference(lp => lp.Library).LoadAsync();

                return(new MediaItemScanResult <PlexMovie>(item)
                {
                    IsAdded = true
                });
            }
            catch (Exception ex)
            {
                return(BaseError.New(ex.ToString()));
            }
        }
コード例 #4
0
        private async Task <Either <BaseError, MediaItemScanResult <PlexMovie> > > UpdateStatistics(
            MediaItemScanResult <PlexMovie> result,
            PlexMovie incoming,
            PlexConnection connection,
            PlexServerAuthToken token)
        {
            PlexMovie    existing        = result.Item;
            MediaVersion existingVersion = existing.MediaVersions.Head();
            MediaVersion incomingVersion = incoming.MediaVersions.Head();

            if (incomingVersion.DateUpdated > existingVersion.DateUpdated ||
                string.IsNullOrWhiteSpace(existingVersion.SampleAspectRatio))
            {
                Either <BaseError, MediaVersion> maybeStatistics =
                    await _plexServerApiClient.GetStatistics(incoming.Key.Split("/").Last(), connection, token);

                await maybeStatistics.Match(
                    async mediaVersion =>
                {
                    existingVersion.SampleAspectRatio = mediaVersion.SampleAspectRatio ?? "1:1";
                    existingVersion.VideoScanKind     = mediaVersion.VideoScanKind;
                    existingVersion.DateUpdated       = incomingVersion.DateUpdated;

                    await _metadataRepository.UpdatePlexStatistics(existingVersion);
                },
                    _ => Task.CompletedTask);
            }

            return(result);
        }
コード例 #5
0
        private PlexMovie GetObjectFromIndexWorker(int index)
        {
            PlexMovie obj = new PlexMovie();

            DownloadInfo dlInfo = getContentDownloadInfo(index);

            obj.StreamInformation = dlInfo;
            obj.StreamIndex       = index;
            return(obj);
        }
コード例 #6
0
ファイル: Player.cs プロジェクト: mitchscobell/PlexDL
        private static PlexMovie GetObjectFromIndexWorker(int index)
        {
            var obj = new PlexMovie();

            var dlInfo = GetContentDownloadInfo(index);

            obj.StreamInformation = dlInfo;
            obj.StreamIndex       = index;
            return(obj);
        }
コード例 #7
0
        public static DataTable MovieAttributesFromObject(PlexMovie content, bool silent = false)
        {
            var table = new DataTable("MovieAttributes");
            var columnAttributeName  = new DataColumn("Name", typeof(string));
            var columnAttributeValue = new DataColumn("Value");

            table.Columns.AddRange(
                new[]
            {
                columnAttributeName,
                columnAttributeValue
            });
            try
            {
                var genre      = new[] { "Genre", content.ContentGenre };
                var runtime    = new[] { "Runtime", Methods.CalculateTime(content.StreamInformation.ContentDuration) };
                var resolution = new[] { "Resolution", content.StreamResolution.ResolutionString() };
                var frameRate  = new[] { "Frame-rate", FormatFramerate(content) };
                var size       = new[] { "File size", Methods.FormatBytes(content.StreamInformation.ByteLength) };
                var container  = new[] { "Container", content.StreamInformation.Container };

                var newRows = new[]
                {
                    genre,
                    runtime,
                    resolution,
                    frameRate,
                    size,
                    container
                };

                foreach (object[] row in newRows)
                {
                    table.Rows.Add(row);
                }
            }
            catch (Exception ex)
            {
                LoggingHelpers.RecordException(ex.Message, "AttributeTableError");
                if (!silent)
                {
                    UIMessages.Error("Error occurred whilst building content attribute table:\n\n" + ex, @"Data Error");
                }
            }

            return(table);
        }
コード例 #8
0
        private async Task <string> GetPlayoutItemPath(PlayoutItem playoutItem)
        {
            MediaVersion version = playoutItem.MediaItem switch
            {
                Movie m => m.MediaVersions.Head(),
                Episode e => e.MediaVersions.Head(),
                         _ => throw new ArgumentOutOfRangeException(nameof(playoutItem))
            };

            MediaFile file = version.MediaFiles.Head();
            string    path = file.Path;

            return(playoutItem.MediaItem switch
            {
                PlexMovie plexMovie => await GetReplacementPlexPath(plexMovie.LibraryPathId, path),
                PlexEpisode plexEpisode => await GetReplacementPlexPath(plexEpisode.LibraryPathId, path),
                _ => path
            });
コード例 #9
0
        private async Task <Either <BaseError, MediaItemScanResult <PlexMovie> > > UpdateArtwork(
            MediaItemScanResult <PlexMovie> result,
            PlexMovie incoming)
        {
            PlexMovie     existing         = result.Item;
            MovieMetadata existingMetadata = existing.MovieMetadata.Head();
            MovieMetadata incomingMetadata = incoming.MovieMetadata.Head();

            if (incomingMetadata.DateUpdated > existingMetadata.DateUpdated)
            {
                await UpdateArtworkIfNeeded(existingMetadata, incomingMetadata, ArtworkKind.Poster);
                await UpdateArtworkIfNeeded(existingMetadata, incomingMetadata, ArtworkKind.FanArt);

                await _metadataRepository.MarkAsUpdated(existingMetadata, incomingMetadata.DateUpdated);
            }

            return(result);
        }
コード例 #10
0
 private void PrevTitle()
 {
     if (StreamingContent.StreamIndex != 0)
     {
         PlexMovie next = GetObjectFromIndex(StreamingContent.StreamIndex - 1);
         StreamingContent = next;
         string FormTitle = StreamingContent.StreamInformation.ContentTitle;
         this.Text = FormTitle;
         this.Refresh();
         //MessageBox.Show(StreamingContent.StreamIndex + "\n" + TitlesTable.Rows.Count);
     }
     else
     {
         PlexMovie next = GetObjectFromIndex(TitlesTable.Rows.Count - 1);
         StreamingContent = next;
         string FormTitle = StreamingContent.StreamInformation.ContentTitle;
         this.Text = FormTitle;
         this.Refresh();
         //MessageBox.Show(StreamingContent.StreamIndex + "\n" + TitlesTable.Rows.Count);
     }
 }
コード例 #11
0
 private void NextTitle()
 {
     if (((StreamingContent.StreamIndex + 1) < TitlesTable.Rows.Count))
     {
         PlexMovie next = GetObjectFromIndex(StreamingContent.StreamIndex + 1);
         StreamingContent = next;
         string FormTitle = StreamingContent.StreamInformation.ContentTitle;
         this.Text = FormTitle;
         this.Refresh();
         //MessageBox.Show(StreamingContent.StreamIndex + "\n" + TitlesTable.Rows.Count);
     }
     else if ((StreamingContent.StreamIndex + 1) == TitlesTable.Rows.Count)
     {
         PlexMovie next = GetObjectFromIndex(0);
         StreamingContent = next;
         string FormTitle = StreamingContent.StreamInformation.ContentTitle;
         this.Text = FormTitle;
         this.Refresh();
         //MessageBox.Show(StreamingContent.StreamIndex + "\n" + TitlesTable.Rows.Count);
     }
 }
コード例 #12
0
        private PlexMovie GetObjectFromIndex(int index)
        {
            PlexMovie result = (PlexMovie)PlexDL.WaitWindow.WaitWindow.Show(GetObjectFromIndexCallback, "Getting Metadata", new object[] { index });

            return(result);
        }
コード例 #13
0
        //MOVIE OBJECT BUILDER
        public static PlexMovie GetMovieObjectFromIndex(int index, bool waitWindow = true)
        {
            try
            {
                if (waitWindow)
                {
                    return((PlexMovie)WaitWindow.WaitWindow.Show(GetMovieObjectFromIndex_Callback, @"Getting metadata", index));
                }

                var obj = new PlexMovie();
                LoggingHelpers.RecordGeneralEntry(@"Content Parse Started");
                LoggingHelpers.RecordGeneralEntry(@"Grabbing Titles");
                var metadata = XmlMetadataContent.GetContentMetadata(index);

                LoggingHelpers.RecordGeneralEntry(@"Checking XML validity");
                if (Methods.PlexXmlValid(metadata.Xml))
                {
                    LoggingHelpers.RecordGeneralEntry(@"XML Valid");

                    var dlInfo = DownloadInfoGatherers.GetContentDownloadInfo(metadata.Xml);

                    if (dlInfo != null)
                    {
                        LoggingHelpers.RecordGeneralEntry(@"Assembling Object");

                        obj.ApiUri            = metadata.ApiUri;
                        obj.ContentGenre      = XmlMetadataStrings.GetContentGenre(metadata.Xml);
                        obj.StreamInformation = dlInfo;
                        obj.StreamResolution  = XmlMetadataObjects.GetContentResolution(metadata.Xml);
                        obj.Actors            = XmlMetadataObjects.GetActorsFromMetadata(metadata.Xml);
                        obj.StreamIndex       = index;
                        obj.Synopsis          = XmlMetadataStrings.GetContentSynopsis(metadata.Xml);

                        //apply the raw metadata to the object (it won't get serialised)
                        obj.RawMetadata = metadata.Xml;
                    }
                    else
                    {
                        UIMessages.Error(
                            @"Failed to get contextual information; an unknown error occurred. Check the exception log for more information.",
                            @"Data Error");
                        LoggingHelpers.RecordException(
                            @"DownloadInfo invalid. This may be an internal error; please report this issue on GitHub.",
                            @"ContextDownloadInfoNull");
                        LoggingHelpers.RecordGeneralEntry("DownloadInfo is invalid (no stream contextual information)");
                    }
                }
                else
                {
                    LoggingHelpers.RecordGeneralEntry("XML Invalid");
                }

                LoggingHelpers.RecordGeneralEntry("Returned assembled Movie object");
                return(obj);
            }
            catch (ThreadAbortException)
            {
                //literally nothing; this gets raised when a cancellation happens.
                return(null);
            }
            catch (Exception ex)
            {
                UIMessages.Error("Content metadata error:\n\n" + ex, @"Data Error");
                LoggingHelpers.RecordException(ex.Message, @"MovieObjectError");
                return(null);
            }
        }
コード例 #14
0
        private async Task <Either <BaseError, MediaItemScanResult <PlexMovie> > > UpdateMetadata(
            MediaItemScanResult <PlexMovie> result,
            PlexMovie incoming)
        {
            PlexMovie     existing         = result.Item;
            MovieMetadata existingMetadata = existing.MovieMetadata.Head();
            MovieMetadata incomingMetadata = incoming.MovieMetadata.Head();

            if (incomingMetadata.DateUpdated > existingMetadata.DateUpdated)
            {
                foreach (Genre genre in existingMetadata.Genres
                         .Filter(g => incomingMetadata.Genres.All(g2 => g2.Name != g.Name))
                         .ToList())
                {
                    existingMetadata.Genres.Remove(genre);
                    if (await _metadataRepository.RemoveGenre(genre))
                    {
                        result.IsUpdated = true;
                    }
                }

                foreach (Genre genre in incomingMetadata.Genres
                         .Filter(g => existingMetadata.Genres.All(g2 => g2.Name != g.Name))
                         .ToList())
                {
                    existingMetadata.Genres.Add(genre);
                    if (await _movieRepository.AddGenre(existingMetadata, genre))
                    {
                        result.IsUpdated = true;
                    }
                }

                foreach (Studio studio in existingMetadata.Studios
                         .Filter(s => incomingMetadata.Studios.All(s2 => s2.Name != s.Name))
                         .ToList())
                {
                    existingMetadata.Studios.Remove(studio);
                    if (await _metadataRepository.RemoveStudio(studio))
                    {
                        result.IsUpdated = true;
                    }
                }

                foreach (Studio studio in incomingMetadata.Studios
                         .Filter(s => existingMetadata.Studios.All(s2 => s2.Name != s.Name))
                         .ToList())
                {
                    existingMetadata.Studios.Add(studio);
                    if (await _movieRepository.AddStudio(existingMetadata, studio))
                    {
                        result.IsUpdated = true;
                    }
                }

                if (incomingMetadata.SortTitle != existingMetadata.SortTitle)
                {
                    existingMetadata.SortTitle = incomingMetadata.SortTitle;
                    if (await _movieRepository.UpdateSortTitle(existingMetadata))
                    {
                        result.IsUpdated = true;
                    }
                }

                await _metadataRepository.MarkAsUpdated(existingMetadata, incomingMetadata.DateUpdated);

                // TODO: update other metadata?
            }

            return(result);
        }