Example #1
0
        public static TvShowDirectoryLayout CreateDownloadLayoutTvShow(PlexTvShow show, ApplicationOptions settings,
                                                                       int layout)
        {
            var dirLayout = new TvShowDirectoryLayout();

            if (layout == MF_PLEX_STANDARD_LAYOUT)
            {
                var basePath   = settings.Generic.DownloadDirectory + @"\TV\";
                var season     = show.Season;
                var title      = show.TvShowName.ToClean();
                var seasonPath = basePath + title + @"\" + season;
                var titlePath  = basePath + title;

                if (!Directory.Exists(basePath))
                {
                    Directory.CreateDirectory(basePath);
                }
                if (!Directory.Exists(titlePath))
                {
                    Directory.CreateDirectory(titlePath);
                }
                if (!Directory.Exists(seasonPath))
                {
                    Directory.CreateDirectory(seasonPath);
                }
                dirLayout.TitlePath  = titlePath;
                dirLayout.SeasonPath = seasonPath;
                dirLayout.BasePath   = basePath;
            }

            return(dirLayout);
        }
Example #2
0
        public async Task <IReadOnlyCollection <Season> > GetSeasonsAsync(PlexTvShow tvShow, PlexServer server)
        {
            var seasonMetadata = await _plexClient.GetChildrenMetadata(
                server.AccessToken,
                server.Host,
                int.Parse(tvShow.Key));

            return(await Task.WhenAll(seasonMetadata.MediaContainer.Metadata.Select(GetSeasonsFromMetadataAsync)));

            async Task <Season> GetSeasonsFromMetadataAsync(Metadata metadata)
            {
                var episodesMetadata = await _plexClient.GetChildrenMetadata(
                    server.AccessToken,
                    server.Host,
                    int.Parse(metadata.RatingKey));

                var episodes = episodesMetadata.MediaContainer.Metadata.Select(
                    m => new Episode
                {
                    Title         = m.Title,
                    SeasonNumber  = m.ParentIndex,
                    EpisodeNumber = m.Index
                });

                return(new Season {
                    SeasonNumber = metadata.Index, Episodes = episodes.ToList()
                });
            }
        }
        public static DataTable TvAttributesFromObject(PlexTvShow content, bool silent = false)
        {
            var table = new DataTable("TvAttributes");
            var columnAttributeName  = new DataColumn("Name", typeof(string));
            var columnAttributeValue = new DataColumn("Value");

            table.Columns.AddRange(
                new[]
            {
                columnAttributeName,
                columnAttributeValue
            });
            try
            {
                var season        = new[] { "Season Name", content.Season };
                var episodeCount  = new[] { "Episode Count", content.EpisodesInSeason.ToString() };
                var seasonNumber  = new[] { "Season #", content.SeasonNumber.ToString() };
                var episodeNumber = new[] { "Episode #", content.EpisodeNumber.ToString() };
                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[]
                {
                    season,
                    episodeCount,
                    seasonNumber,
                    episodeNumber,
                    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);
        }
Example #4
0
        public async Task <List <PlexTvShowSeason> > GetSeasonsAsync(string serverAuthToken, string plexFullHost, PlexTvShow plexTvShow)
        {
            var result = await _plexApi.GetSeasonsAsync(serverAuthToken, plexFullHost, plexTvShow.Key);

            return(result != null?_mapper.Map <List <PlexTvShowSeason> >(result.MediaContainer.Metadata) : new List <PlexTvShowSeason>());
        }
Example #5
0
        //TV OBJECT BUILDER
        public static PlexTvShow GetTvObjectFromIndex(int index, bool waitWindow = true)
        {
            try
            {
                if (waitWindow)
                {
                    return((PlexTvShow)WaitWindow.WaitWindow.Show(GetTvObjectFromIndex_Callback, @"Getting metadata", index));
                }

                var obj = new PlexTvShow();
                LoggingHelpers.RecordGeneralEntry(@"Content Parse Started");
                LoggingHelpers.RecordGeneralEntry(@"Grabbing Titles");

                var metadata = XmlMetadataContent.GetEpisodeMetadata(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);

                        var s = XmlMetadataIntegers.GetParentIndex(metadata.Xml);
                        var e = XmlMetadataIntegers.GetIndex(metadata.Xml);

                        obj.Season            = XmlMetadataStrings.GetParentTitle(metadata.Xml);
                        obj.EpisodesInSeason  = DataProvider.EpisodesProvider.GetRawTable().Rows.Count;
                        obj.EpisodeNumber     = e > 0 ? e : 1; //episode numbers start at 1, not 0; enforce this.
                        obj.SeasonNumber      = s > 0 ? s : 1; //season numbers start at 1, not 0; enforce this.
                        obj.TvShowName        = XmlMetadataStrings.GetGrandparentTitle(metadata.Xml);
                        obj.StreamResolution  = XmlMetadataObjects.GetContentResolution(metadata.Xml);
                        obj.Actors            = XmlMetadataObjects.GetActorsFromMetadata(metadata.Xml);
                        obj.StreamIndex       = index;
                        obj.Synopsis          = XmlMetadataStrings.GetContentSynopsis(metadata.Xml);
                        obj.StreamInformation = dlInfo;

                        //apply the raw metadata to the object (it won't get serialised)
                        obj.RawMetadata = metadata.Xml;

                        //This works, but it shouldn't - I feel like it shouldn't.

                        //Check if the season information is valid (must have a number).
                        //Sometimes, seasons don't get named correctly. For example, 'Specials' rather than 'Season 1'.
                        //This is one method of validation for a correctly named 'Season' of a show.
                        //In addition, if the verification method fails for a season number check, it returns -1 (season numbers start at 1+),
                        //so it makes sense to check for above zero season indices as well.
                        var valid    = obj.Season.ToLower().StartsWith(@"season") && s > 0;
                        var notation = valid ? obj.Notation : obj.Season; //apply default notation only if it's a valid season name, otherwise just use the name itself.
                        var fileName = $"{obj.TvShowName} - {notation} - {obj.StreamInformation.ContentTitle}.{dlInfo.Container}";

                        //override the filename generated above with the correct Plex formatting generated by the PlexTvShow object.
                        obj.StreamInformation.FileName = fileName.ToClean();
                    }
                    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 TV 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, "TVObjectError");
                return(null);
            }
        }