diff options
Diffstat (limited to 'MediaBrowser.Providers')
| -rw-r--r-- | MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs | 42 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Manager/MetadataService.cs | 28 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Music/AlbumMetadataService.cs | 76 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Music/ArtistMetadataService.cs | 37 | ||||
| -rw-r--r-- | MediaBrowser.Providers/TV/DummySeasonProvider.cs | 65 | ||||
| -rw-r--r-- | MediaBrowser.Providers/TV/MissingEpisodeProvider.cs | 4 | ||||
| -rw-r--r-- | MediaBrowser.Providers/TV/SeasonMetadataService.cs | 14 | ||||
| -rw-r--r-- | MediaBrowser.Providers/TV/SeriesMetadataService.cs | 21 | ||||
| -rw-r--r-- | MediaBrowser.Providers/TV/SeriesPostScanTask.cs | 2 |
9 files changed, 193 insertions, 96 deletions
diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs index 5afaaa875..5e16ed69c 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs @@ -12,6 +12,7 @@ using MediaBrowser.Providers.Manager; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Providers.BoxSets { @@ -51,31 +52,34 @@ namespace MediaBrowser.Providers.BoxSets } } - protected override ItemUpdateType BeforeSave(BoxSet item) + protected override async Task<ItemUpdateType> BeforeSave(BoxSet item, bool isFullRefresh, ItemUpdateType currentUpdateType) { - var updateType = base.BeforeSave(item); + var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false); - if (!item.LockedFields.Contains(MetadataFields.OfficialRating)) + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) { - var currentOfficialRating = item.OfficialRating; + if (!item.LockedFields.Contains(MetadataFields.OfficialRating)) + { + var currentOfficialRating = item.OfficialRating; - // Gather all possible ratings - var ratings = item.RecursiveChildren - .Concat(item.GetLinkedChildren()) - .Where(i => i is Movie || i is Series) - .Select(i => i.OfficialRating) - .Where(i => !string.IsNullOrEmpty(i)) - .Distinct(StringComparer.OrdinalIgnoreCase) - .Select(i => new Tuple<string, int?>(i, _iLocalizationManager.GetRatingLevel(i))) - .OrderBy(i => i.Item2 ?? 1000) - .Select(i => i.Item1); + // Gather all possible ratings + var ratings = item.RecursiveChildren + .Concat(item.GetLinkedChildren()) + .Where(i => i is Movie || i is Series) + .Select(i => i.OfficialRating) + .Where(i => !string.IsNullOrEmpty(i)) + .Distinct(StringComparer.OrdinalIgnoreCase) + .Select(i => new Tuple<string, int?>(i, _iLocalizationManager.GetRatingLevel(i))) + .OrderBy(i => i.Item2 ?? 1000) + .Select(i => i.Item1); - item.OfficialRating = ratings.FirstOrDefault() ?? item.OfficialRating; + item.OfficialRating = ratings.FirstOrDefault() ?? item.OfficialRating; - if (!string.Equals(currentOfficialRating ?? string.Empty, item.OfficialRating ?? string.Empty, - StringComparison.OrdinalIgnoreCase)) - { - updateType = updateType | ItemUpdateType.MetadataEdit; + if (!string.Equals(currentOfficialRating ?? string.Empty, item.OfficialRating ?? string.Empty, + StringComparison.OrdinalIgnoreCase)) + { + updateType = updateType | ItemUpdateType.MetadataEdit; + } } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index e27c39df1..f55eddfcf 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -163,14 +163,13 @@ namespace MediaBrowser.Providers.Manager } } - updateType = updateType | BeforeSave(itemOfType); - - var providersHadChanges = updateType > ItemUpdateType.None; + updateType = updateType | (await BeforeSave(itemOfType, item.DateLastSaved == default(DateTime) || refreshOptions.ReplaceAllMetadata, updateType).ConfigureAwait(false)); // Save if changes were made, or it's never been saved before - if (refreshOptions.ForceSave || providersHadChanges || item.DateLastSaved == default(DateTime) || refreshOptions.ReplaceAllMetadata) + if (refreshOptions.ForceSave || updateType > ItemUpdateType.None || item.DateLastSaved == default(DateTime) || refreshOptions.ReplaceAllMetadata) { - if (refreshOptions.ForceSave || providersHadChanges || refreshOptions.ReplaceAllMetadata) + // If any of these properties are set then make sure the updateType is not None, just to force everything to save + if (refreshOptions.ForceSave || refreshOptions.ReplaceAllMetadata) { updateType = updateType | ItemUpdateType.MetadataDownload; } @@ -179,7 +178,7 @@ namespace MediaBrowser.Providers.Manager await SaveItem(itemOfType, updateType, cancellationToken); } - if (providersHadChanges || refreshResult.IsDirty) + if (updateType > ItemUpdateType.None || refreshResult.IsDirty) { await SaveProviderResult(itemOfType, refreshResult, refreshOptions.DirectoryService).ConfigureAwait(false); } @@ -194,14 +193,17 @@ namespace MediaBrowser.Providers.Manager } } + private readonly Task<ItemUpdateType> _cachedResult = Task.FromResult(ItemUpdateType.None); /// <summary> /// Befores the save. /// </summary> /// <param name="item">The item.</param> + /// <param name="isFullRefresh">if set to <c>true</c> [is full refresh].</param> + /// <param name="currentUpdateType">Type of the current update.</param> /// <returns>ItemUpdateType.</returns> - protected virtual ItemUpdateType BeforeSave(TItemType item) + protected virtual Task<ItemUpdateType> BeforeSave(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) { - return ItemUpdateType.None; + return _cachedResult; } /// <summary> @@ -549,11 +551,6 @@ namespace MediaBrowser.Providers.Manager } } - if (refreshResult.Successes > 0) - { - AfterRemoteRefresh(temp); - } - return refreshResult; } @@ -570,11 +567,6 @@ namespace MediaBrowser.Providers.Manager } } - protected virtual void AfterRemoteRefresh(TItemType item) - { - - } - private async Task<TIdType> CreateInitialLookupInfo(TItemType item, CancellationToken cancellationToken) { var info = item.GetLookupInfo(); diff --git a/MediaBrowser.Providers/Music/AlbumMetadataService.cs b/MediaBrowser.Providers/Music/AlbumMetadataService.cs index 6e3a5bf06..64dcd913d 100644 --- a/MediaBrowser.Providers/Music/AlbumMetadataService.cs +++ b/MediaBrowser.Providers/Music/AlbumMetadataService.cs @@ -9,6 +9,7 @@ using MediaBrowser.Providers.Manager; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Providers.Music { @@ -36,59 +37,62 @@ namespace MediaBrowser.Providers.Music } } - protected override ItemUpdateType BeforeSave(MusicAlbum item) + protected override async Task<ItemUpdateType> BeforeSave(MusicAlbum item, bool isFullRefresh, ItemUpdateType currentUpdateType) { - var updateType = base.BeforeSave(item); + var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false); - var songs = item.RecursiveChildren.OfType<Audio>().ToList(); - - if (!item.IsLocked) + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) { - if (!item.LockedFields.Contains(MetadataFields.Genres)) + if (!item.IsLocked) { - var currentList = item.Genres.ToList(); - - item.Genres = songs.SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); + var songs = item.RecursiveChildren.OfType<Audio>().ToList(); - if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) + if (!item.LockedFields.Contains(MetadataFields.Genres)) { - updateType = updateType | ItemUpdateType.MetadataEdit; - } - } + var currentList = item.Genres.ToList(); - if (!item.LockedFields.Contains(MetadataFields.Studios)) - { - var currentList = item.Studios.ToList(); + item.Genres = songs.SelectMany(i => i.Genres) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); - item.Studios = songs.SelectMany(i => i.Studios) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); + if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) + { + updateType = updateType | ItemUpdateType.MetadataEdit; + } + } - if (currentList.Count != item.Studios.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Studios.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) + if (!item.LockedFields.Contains(MetadataFields.Studios)) { - updateType = updateType | ItemUpdateType.MetadataEdit; - } - } + var currentList = item.Studios.ToList(); - if (!item.LockedFields.Contains(MetadataFields.Name)) - { - var name = songs.Select(i => i.Album).FirstOrDefault(i => !string.IsNullOrEmpty(i)); + item.Studios = songs.SelectMany(i => i.Studios) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); - if (!string.IsNullOrEmpty(name)) - { - if (!string.Equals(item.Name, name, StringComparison.Ordinal)) + if (currentList.Count != item.Studios.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Studios.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) { - item.Name = name; updateType = updateType | ItemUpdateType.MetadataEdit; } } - } - updateType = updateType | SetAlbumArtistFromSongs(item, songs); - updateType = updateType | SetArtistsFromSongs(item, songs); - updateType = updateType | SetDateFromSongs(item, songs); + if (!item.LockedFields.Contains(MetadataFields.Name)) + { + var name = songs.Select(i => i.Album).FirstOrDefault(i => !string.IsNullOrEmpty(i)); + + if (!string.IsNullOrEmpty(name)) + { + if (!string.Equals(item.Name, name, StringComparison.Ordinal)) + { + item.Name = name; + updateType = updateType | ItemUpdateType.MetadataEdit; + } + } + } + + updateType = updateType | SetAlbumArtistFromSongs(item, songs); + updateType = updateType | SetArtistsFromSongs(item, songs); + updateType = updateType | SetDateFromSongs(item, songs); + } } return updateType; diff --git a/MediaBrowser.Providers/Music/ArtistMetadataService.cs b/MediaBrowser.Providers/Music/ArtistMetadataService.cs index a73d82992..77ae9eec9 100644 --- a/MediaBrowser.Providers/Music/ArtistMetadataService.cs +++ b/MediaBrowser.Providers/Music/ArtistMetadataService.cs @@ -9,13 +9,17 @@ using MediaBrowser.Providers.Manager; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Providers.Music { public class ArtistMetadataService : MetadataService<MusicArtist, ArtistInfo> { - public ArtistMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager) + private readonly ILibraryManager _libraryManager; + + public ArtistMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager) { + _libraryManager = libraryManager; } /// <summary> @@ -31,28 +35,33 @@ namespace MediaBrowser.Providers.Music ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); } - protected override ItemUpdateType BeforeSave(MusicArtist item) + protected override async Task<ItemUpdateType> BeforeSave(MusicArtist item, bool isFullRefresh, ItemUpdateType currentUpdateType) { - var updateType = base.BeforeSave(item); + var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false); - if (!item.IsAccessedByName && !item.IsLocked) + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) { - if (!item.LockedFields.Contains(MetadataFields.Genres)) + if (!item.IsLocked) { - var songs = item.RecursiveChildren.OfType<Audio>().ToList(); + var taggedItems = item.IsAccessedByName ? + item.GetTaggedItems(_libraryManager.RootFolder.RecursiveChildren.Where(i => i is IHasArtist && !i.IsFolder)).ToList() : + item.RecursiveChildren.Where(i => i is IHasArtist && !i.IsFolder).ToList(); - var currentList = item.Genres.ToList(); + if (!item.LockedFields.Contains(MetadataFields.Genres)) + { + var currentList = item.Genres.ToList(); - item.Genres = songs.SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); + item.Genres = taggedItems.SelectMany(i => i.Genres) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); - if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) - { - updateType = updateType | ItemUpdateType.MetadataEdit; + if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) + { + updateType = updateType | ItemUpdateType.MetadataEdit; + } } } - } + } return updateType; } diff --git a/MediaBrowser.Providers/TV/DummySeasonProvider.cs b/MediaBrowser.Providers/TV/DummySeasonProvider.cs index 294c7e20f..5bf40de0f 100644 --- a/MediaBrowser.Providers/TV/DummySeasonProvider.cs +++ b/MediaBrowser.Providers/TV/DummySeasonProvider.cs @@ -1,10 +1,11 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; -using System; using System.Globalization; using System.Linq; using System.Threading; @@ -17,18 +18,22 @@ namespace MediaBrowser.Providers.TV private readonly IServerConfigurationManager _config; private readonly ILogger _logger; private readonly ILocalizationManager _localization; + private readonly ILibraryManager _libraryManager; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - public DummySeasonProvider(IServerConfigurationManager config, ILogger logger, ILocalizationManager localization) + public DummySeasonProvider(IServerConfigurationManager config, ILogger logger, ILocalizationManager localization, ILibraryManager libraryManager) { _config = config; _logger = logger; _localization = localization; + _libraryManager = libraryManager; } public async Task Run(Series series, CancellationToken cancellationToken) { + await RemoveObsoleteSeasons(series).ConfigureAwait(false); + var hasNewSeasons = await AddDummySeasonFolders(series, cancellationToken).ConfigureAwait(false); if (hasNewSeasons) @@ -117,5 +122,61 @@ namespace MediaBrowser.Providers.TV return season; } + + private async Task<bool> RemoveObsoleteSeasons(Series series) + { + var existingSeasons = series.Children.OfType<Season>().ToList(); + + var physicalSeasons = existingSeasons + .Where(i => i.LocationType != LocationType.Virtual) + .ToList(); + + var virtualSeasons = existingSeasons + .Where(i => i.LocationType == LocationType.Virtual) + .ToList(); + + var episodes = series.RecursiveChildren.OfType<Episode>().ToList(); + + var seasonsToRemove = virtualSeasons + .Where(i => + { + if (i.IndexNumber.HasValue) + { + var seasonNumber = i.IndexNumber.Value; + + // If there's a physical season with the same number, delete it + if (physicalSeasons.Any(p => p.IndexNumber.HasValue && (p.IndexNumber.Value == seasonNumber))) + { + return true; + } + + // If there are no episodes with this season number, delete it + if (episodes.All(e => !e.ParentIndexNumber.HasValue || e.ParentIndexNumber.Value != seasonNumber)) + { + return true; + } + + return false; + } + + // Season does not have a number + // Remove if there are no episodes directly in series without a season number + return episodes.All(s => s.ParentIndexNumber.HasValue || !s.IsInSeasonFolder); + }) + .ToList(); + + var hasChanges = false; + + foreach (var seasonToRemove in seasonsToRemove) + { + _logger.Info("Removing virtual season {0} {1}", seasonToRemove.Series.Name, seasonToRemove.IndexNumber); + + await _libraryManager.DeleteItem(seasonToRemove).ConfigureAwait(false); + + hasChanges = true; + } + + return hasChanges; + } } } diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index 707fa6e21..53b60c1b8 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -361,7 +361,7 @@ namespace MediaBrowser.Providers.TV // Season does not have a number // Remove if there are no episodes directly in series without a season number - return i.Season.Series.RecursiveChildren.OfType<Episode>().All(s => s.ParentIndexNumber.HasValue || s.IsInSeasonFolder); + return i.Season.Series.RecursiveChildren.OfType<Episode>().All(s => s.ParentIndexNumber.HasValue || !s.IsInSeasonFolder); }) .ToList(); @@ -394,7 +394,7 @@ namespace MediaBrowser.Providers.TV if (season == null) { - var provider = new DummySeasonProvider(_config, _logger, _localization); + var provider = new DummySeasonProvider(_config, _logger, _localization, _libraryManager); season = await provider.AddSeason(series, seasonNumber, cancellationToken).ConfigureAwait(false); } diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs index 2510d4785..8955b224e 100644 --- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs @@ -6,7 +6,9 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; +using System; using System.Collections.Generic; +using System.Threading.Tasks; namespace MediaBrowser.Providers.TV { @@ -29,14 +31,20 @@ namespace MediaBrowser.Providers.TV ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); } - protected override void AfterRemoteRefresh(Season item) + protected override async Task<ItemUpdateType> BeforeSave(Season item, bool isFullRefresh, ItemUpdateType currentUpdateType) { - base.AfterRemoteRefresh(item); + var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false); if (item.IndexNumber.HasValue && item.IndexNumber.Value == 0) { - item.Name = ServerConfigurationManager.Configuration.SeasonZeroDisplayName; + if (!string.Equals(item.Name, ServerConfigurationManager.Configuration.SeasonZeroDisplayName, StringComparison.OrdinalIgnoreCase)) + { + item.Name = ServerConfigurationManager.Configuration.SeasonZeroDisplayName; + updateType = updateType | ItemUpdateType.MetadataEdit; + } } + + return updateType; } } } diff --git a/MediaBrowser.Providers/TV/SeriesMetadataService.cs b/MediaBrowser.Providers/TV/SeriesMetadataService.cs index 713d46347..62e5ff4fc 100644 --- a/MediaBrowser.Providers/TV/SeriesMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeriesMetadataService.cs @@ -2,18 +2,26 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Providers.TV { public class SeriesMetadataService : MetadataService<Series, SeriesInfo> { - public SeriesMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager) + private readonly ILocalizationManager _localization; + private readonly ILibraryManager _libraryManager; + + public SeriesMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILocalizationManager localization, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager) { + _localization = localization; + _libraryManager = libraryManager; } /// <summary> @@ -53,5 +61,16 @@ namespace MediaBrowser.Providers.TV target.DisplaySpecialsWithSeasons = source.DisplaySpecialsWithSeasons; } } + + protected override async Task<ItemUpdateType> BeforeSave(Series item, bool isFullRefresh, ItemUpdateType currentUpdateType) + { + var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false); + + //var provider = new DummySeasonProvider(ServerConfigurationManager, Logger, _localization, _libraryManager); + + //await provider.Run(item, CancellationToken.None).ConfigureAwait(false); + + return updateType; + } } } diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index 222438485..2506b53ad 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.TV .OfType<Series>() .ToList(); - var provider = new DummySeasonProvider(_config, _logger, _localization); + var provider = new DummySeasonProvider(_config, _logger, _localization, _libraryManager); foreach (var series in seriesList) { |
