//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); } }
//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); } }