| 
					
				 | 
			
			
				@@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.TV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private readonly ILibraryManager _libraryManager; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private readonly ILocalizationManager _localization; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private readonly CultureInfo _usCulture = new CultureInfo("en-US"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public MissingEpisodeProvider(ILogger logger, IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -78,11 +78,11 @@ namespace MediaBrowser.Providers.TV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         int seasonNumber; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if (int.TryParse(parts[1], NumberStyles.Integer, UsCulture, out seasonNumber)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (int.TryParse(parts[1], NumberStyles.Integer, _usCulture, out seasonNumber)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             int episodeNumber; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            if (int.TryParse(parts[2], NumberStyles.Integer, UsCulture, out episodeNumber)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            if (int.TryParse(parts[2], NumberStyles.Integer, _usCulture, out episodeNumber)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 return new Tuple<int, int>(seasonNumber, episodeNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -103,12 +103,6 @@ namespace MediaBrowser.Providers.TV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 .ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var hasNewEpisodes = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var hasNewSeasons = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            foreach (var series in group) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                hasNewSeasons = await AddDummySeasonFolders(series, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (_config.Configuration.EnableInternetProviders) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -121,7 +115,7 @@ namespace MediaBrowser.Providers.TV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (hasNewSeasons || hasNewEpisodes || anySeasonsRemoved || anyEpisodesRemoved) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (hasNewEpisodes || anySeasonsRemoved || anyEpisodesRemoved) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 foreach (var series in group) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -160,55 +154,6 @@ namespace MediaBrowser.Providers.TV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// For series with episodes directly under the series folder, this adds dummy seasons to enable regular browsing and metadata 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <param name="series"></param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <param name="cancellationToken"></param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <returns></returns> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private async Task<bool> AddDummySeasonFolders(Series series, CancellationToken cancellationToken) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var episodesInSeriesFolder = series.RecursiveChildren 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .OfType<Episode>() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .Where(i => !i.IsInSeasonFolder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .ToList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var hasChanges = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // Loop through the unique season numbers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            foreach (var seasonNumber in episodesInSeriesFolder.Select(i => i.ParentIndexNumber ?? -1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .Where(i => i >= 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .Distinct() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .ToList()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var hasSeason = series.Children.OfType<Season>() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    .Any(i => i.IndexNumber.HasValue && i.IndexNumber.Value == seasonNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (!hasSeason) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    await AddSeason(series, seasonNumber, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    hasChanges = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // Unknown season - create a dummy season to put these under 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (episodesInSeriesFolder.Any(i => !i.ParentIndexNumber.HasValue)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var hasSeason = series.Children.OfType<Season>() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    .Any(i => !i.IndexNumber.HasValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (!hasSeason) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    await AddSeason(series, null, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    hasChanges = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return hasChanges; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// Adds the missing episodes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// </summary> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -449,10 +394,11 @@ namespace MediaBrowser.Providers.TV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (season == null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                season = await AddSeason(series, seasonNumber, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var provider = new DummySeasonProvider(_config, _logger, _localization); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                season = await provider.AddSeason(series, seasonNumber, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var name = string.Format("Episode {0}", episodeNumber.ToString(UsCulture)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var name = string.Format("Episode {0}", episodeNumber.ToString(_usCulture)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var episode = new Episode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -461,7 +407,7 @@ namespace MediaBrowser.Providers.TV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ParentIndexNumber = seasonNumber, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 Parent = season, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 DisplayMediaType = typeof(Episode).Name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Id = (series.Id + seasonNumber.ToString(UsCulture) + name).GetMBId(typeof(Episode)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Id = (series.Id + seasonNumber.ToString(_usCulture) + name).GetMBId(typeof(Episode)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             await season.AddChild(episode, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -471,39 +417,6 @@ namespace MediaBrowser.Providers.TV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// Adds the season. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <param name="series">The series.</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <param name="seasonNumber">The season number.</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <param name="cancellationToken">The cancellation token.</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <returns>Task{Season}.</returns> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private async Task<Season> AddSeason(Series series,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            int? seasonNumber,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            CancellationToken cancellationToken) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var seasonName = seasonNumber == 0 ?  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                _config.Configuration.SeasonZeroDisplayName : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                (seasonNumber.HasValue ? string.Format(_localization.GetLocalizedString("NameSeasonNumber"), seasonNumber.Value.ToString(UsCulture)) : _localization.GetLocalizedString("NameSeasonUnknown")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            _logger.Info("Creating Season {0} entry for {1}", seasonName, series.Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var season = new Season 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Name = seasonName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                IndexNumber = seasonNumber, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Parent = series, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                DisplayMediaType = typeof(Season).Name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Id = (series.Id + (seasonNumber ?? -1).ToString(UsCulture) + seasonName).GetMBId(typeof(Season)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            await series.AddChild(season, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            await season.RefreshMetadata(new MetadataRefreshOptions(), cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return season; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// Gets the existing episode. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// </summary> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -551,7 +464,7 @@ namespace MediaBrowser.Providers.TV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private DateTime? GetAirDate(string seriesDataPath, int seasonNumber, int episodeNumber) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // First open up the tvdb xml file and make sure it has valid data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var filename = string.Format("episode-{0}-{1}.xml", seasonNumber.ToString(UsCulture), episodeNumber.ToString(UsCulture)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var filename = string.Format("episode-{0}-{1}.xml", seasonNumber.ToString(_usCulture), episodeNumber.ToString(_usCulture)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var xmlPath = Path.Combine(seriesDataPath, filename); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |