diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-02-10 13:39:41 -0500 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-02-10 13:39:41 -0500 |
| commit | 013d5a467e046c63d69c793b13f468a52a446568 (patch) | |
| tree | 8a7b7e5ca955f062ac11aeed28d7e0f93ae97f07 | |
| parent | 44bb192ce0e286ced703394f733ca033b489ebc5 (diff) | |
restored external subtitle support
75 files changed, 559 insertions, 451 deletions
diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index 98897b9d1..d8ecc3685 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -143,7 +143,6 @@ namespace MediaBrowser.Api DisableSaversForType(typeof(Game), config); DisableSaversForType(typeof(GameSystem), config); DisableSaversForType(typeof(Movie), config); - DisableSaversForType(typeof(Trailer), config); DisableSaversForType(typeof(BoxSet), config); DisableSaversForType(typeof(Book), config); DisableSaversForType(typeof(Series), config); diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index f791f1608..363b0a81b 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -57,7 +57,7 @@ namespace MediaBrowser.Controller.Entities public List<string> PhysicalLocationsList { get; set; } - protected override IEnumerable<FileSystemInfo> GetFileSystemChildren(DirectoryService directoryService) + protected override IEnumerable<FileSystemInfo> GetFileSystemChildren(IDirectoryService directoryService) { return CreateResolveArgs().FileSystemChildren; } @@ -119,7 +119,7 @@ namespace MediaBrowser.Controller.Entities /// Get the children of this folder from the actual file system /// </summary> /// <returns>IEnumerable{BaseItem}.</returns> - protected override IEnumerable<BaseItem> GetNonCachedChildren(DirectoryService directoryService) + protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService) { return base.GetNonCachedChildren(directoryService).Concat(_virtualChildren); } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 87551ef7b..2b5570a80 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -52,7 +52,7 @@ namespace MediaBrowser.Controller.Entities.Audio } private readonly Task _cachedTask = Task.FromResult(true); - protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, DirectoryService directoryService) + protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) { if (IsAccessedByName) { diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 72e7f5bf1..38f40ea48 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -563,6 +563,8 @@ namespace MediaBrowser.Controller.Entities { var locationType = LocationType; + var requiresSave = false; + if (IsFolder || Parent != null) { options.DirectoryService = options.DirectoryService ?? new DirectoryService(Logger); @@ -571,13 +573,34 @@ namespace MediaBrowser.Controller.Entities GetFileSystemChildren(options.DirectoryService).ToList() : new List<FileSystemInfo>(); - await BeforeRefreshMetadata(options, files, cancellationToken).ConfigureAwait(false); + var ownedItemsChanged = await RefreshedOwnedItems(options, files, cancellationToken).ConfigureAwait(false); + + if (ownedItemsChanged) + { + requiresSave = true; + } } + var dateLastSaved = DateLastSaved; + await ProviderManager.RefreshMetadata(this, options, cancellationToken).ConfigureAwait(false); + + // If it wasn't saved by the provider process, save now + if (requiresSave && dateLastSaved == DateLastSaved) + { + await UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); + } } - protected virtual async Task BeforeRefreshMetadata(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) + /// <summary> + /// Refreshes owned items such as trailers, theme videos, special features, etc. + /// Returns true or false indicating if changes were found. + /// </summary> + /// <param name="options"></param> + /// <param name="fileSystemChildren"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> + protected virtual async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) { var themeSongsChanged = false; @@ -605,13 +628,10 @@ namespace MediaBrowser.Controller.Entities } } - if (themeSongsChanged || themeVideosChanged || localTrailersChanged) - { - options.ForceSave = true; - } + return themeSongsChanged || themeVideosChanged || localTrailersChanged; } - protected virtual IEnumerable<FileSystemInfo> GetFileSystemChildren(DirectoryService directoryService) + protected virtual IEnumerable<FileSystemInfo> GetFileSystemChildren(IDirectoryService directoryService) { var path = ContainingFolderPath; @@ -1205,7 +1225,7 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Validates that images within the item are still on the file system /// </summary> - public bool ValidateImages(DirectoryService directoryService) + public bool ValidateImages(IDirectoryService directoryService) { var allDirectories = ImageInfos.Select(i => System.IO.Path.GetDirectoryName(i.Path)).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); var allFiles = allDirectories.SelectMany(directoryService.GetFiles).Select(i => i.FullName).ToList(); @@ -1390,5 +1410,22 @@ namespace MediaBrowser.Controller.Entities ParentIndexNumber = ParentIndexNumber }; } + + /// <summary> + /// This is called before any metadata refresh and returns ItemUpdateType indictating if changes were made, and what. + /// </summary> + /// <returns>ItemUpdateType.</returns> + public virtual ItemUpdateType BeforeMetadataRefresh() + { + var updateType = ItemUpdateType.None; + + if (string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Path)) + { + Name = System.IO.Path.GetFileNameWithoutExtension(Path); + updateType = updateType | ItemUpdateType.MetadataEdit; + } + + return updateType; + } } } diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index eb442bf6f..25f42538c 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -61,7 +61,7 @@ namespace MediaBrowser.Controller.Entities public List<string> PhysicalLocationsList { get; set; } - protected override IEnumerable<FileSystemInfo> GetFileSystemChildren(DirectoryService directoryService) + protected override IEnumerable<FileSystemInfo> GetFileSystemChildren(IDirectoryService directoryService) { return CreateResolveArgs().FileSystemChildren; } @@ -119,8 +119,9 @@ namespace MediaBrowser.Controller.Entities /// <param name="recursive">if set to <c>true</c> [recursive].</param> /// <param name="refreshChildMetadata">if set to <c>true</c> [refresh child metadata].</param> /// <param name="refreshOptions">The refresh options.</param> + /// <param name="directoryService">The directory service.</param> /// <returns>Task.</returns> - protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, DirectoryService directoryService) + protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) { CreateResolveArgs(); ResetDynamicChildren(); diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 933cf758c..f0b044d43 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -319,7 +319,7 @@ namespace MediaBrowser.Controller.Entities return ValidateChildrenWithCancellationSupport(progress, cancellationToken, recursive, true, metadataRefreshOptions, metadataRefreshOptions.DirectoryService); } - private async Task ValidateChildrenWithCancellationSupport(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, DirectoryService directoryService) + private async Task ValidateChildrenWithCancellationSupport(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) { cancellationToken.ThrowIfCancellationRequested(); @@ -373,7 +373,7 @@ namespace MediaBrowser.Controller.Entities /// <param name="refreshOptions">The refresh options.</param> /// <param name="directoryService">The directory service.</param> /// <returns>Task.</returns> - protected async virtual Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, DirectoryService directoryService) + protected async virtual Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) { var locationType = LocationType; @@ -593,7 +593,7 @@ namespace MediaBrowser.Controller.Entities /// <param name="progress">The progress.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - private async Task ValidateSubFolders(IList<Folder> children, DirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken) + private async Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken) { var list = children; var childCount = list.Count; @@ -679,7 +679,7 @@ namespace MediaBrowser.Controller.Entities /// Get the children of this folder from the actual file system /// </summary> /// <returns>IEnumerable{BaseItem}.</returns> - protected virtual IEnumerable<BaseItem> GetNonCachedChildren(DirectoryService directoryService) + protected virtual IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService) { return LibraryManager.ResolvePaths<BaseItem>(GetFileSystemChildren(directoryService), this); } @@ -927,17 +927,21 @@ namespace MediaBrowser.Controller.Entities return item; } - protected override Task BeforeRefreshMetadata(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) + protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) { + var changesFound = false; + if (SupportsShortcutChildren && LocationType == LocationType.FileSystem) { if (RefreshLinkedChildren(fileSystemChildren)) { - options.ForceSave = true; + changesFound = true; } } - return base.BeforeRefreshMetadata(options, fileSystemChildren, cancellationToken); + var baseHasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false); + + return baseHasChanges || changesFound; } /// <summary> diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs index 053938f33..eee169363 100644 --- a/MediaBrowser.Controller/Entities/IHasImages.cs +++ b/MediaBrowser.Controller/Entities/IHasImages.cs @@ -1,8 +1,8 @@ -using System.IO; -using MediaBrowser.Controller.Providers; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; +using System.IO; using System.Threading.Tasks; namespace MediaBrowser.Controller.Entities @@ -109,7 +109,7 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Validates the images and returns true or false indicating if any were removed. /// </summary> - bool ValidateImages(DirectoryService directoryService); + bool ValidateImages(IDirectoryService directoryService); /// <summary> /// Gets a value indicating whether this instance is owned item. @@ -166,5 +166,16 @@ namespace MediaBrowser.Controller.Entities { item.SetImagePath(imageType, 0, file); } + + /// <summary> + /// Sets the image path. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="imageType">Type of the image.</param> + /// <param name="file">The file.</param> + public static void SetImagePath(this IHasImages item, ImageType imageType, string file) + { + item.SetImagePath(imageType, new FileInfo(file)); + } } } diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index 1a1956c56..0285b6749 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -1,9 +1,9 @@ -using System; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Entities; +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Entities { @@ -49,5 +49,11 @@ namespace MediaBrowser.Controller.Entities /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken); + + /// <summary> + /// This is called before any metadata refresh and returns ItemUpdateType indictating if changes were made, and what. + /// </summary> + /// <returns>ItemUpdateType.</returns> + ItemUpdateType BeforeMetadataRefresh(); } } diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 50cf31068..8eba21df0 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -96,9 +96,9 @@ namespace MediaBrowser.Controller.Entities.Movies return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.GetUserDataKey(); } - protected override async Task BeforeRefreshMetadata(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) + protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) { - await base.BeforeRefreshMetadata(options, fileSystemChildren, cancellationToken).ConfigureAwait(false); + var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false); // Must have a parent to have special features // In other words, it must be part of the Parent/Child tree @@ -108,9 +108,11 @@ namespace MediaBrowser.Controller.Entities.Movies if (specialFeaturesChanged) { - options.ForceSave = true; + hasChanges = true; } } + + return hasChanges; } private async Task<bool> RefreshSpecialFeatures(MetadataRefreshOptions options, IEnumerable<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 5413aa885..39c11569a 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -1,5 +1,7 @@ -using MediaBrowser.Controller.Providers; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; using System.Linq; @@ -260,5 +262,54 @@ namespace MediaBrowser.Controller.Entities.TV return id; } + + public override ItemUpdateType BeforeMetadataRefresh() + { + var updateType = base.BeforeMetadataRefresh(); + + var locationType = LocationType; + if (locationType == LocationType.FileSystem || locationType == LocationType.Offline) + { + if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path)) + { + IndexNumber = IndexNumber ?? TVUtils.GetEpisodeNumberFromFile(Path, Parent is Season); + + // If a change was made record it + if (IndexNumber.HasValue) + { + updateType = updateType | ItemUpdateType.MetadataImport; + } + } + + if (!IndexNumberEnd.HasValue && !string.IsNullOrEmpty(Path)) + { + IndexNumberEnd = IndexNumberEnd ?? TVUtils.GetEndingEpisodeNumberFromFile(Path); + + // If a change was made record it + if (IndexNumberEnd.HasValue) + { + updateType = updateType | ItemUpdateType.MetadataImport; + } + } + } + + if (!ParentIndexNumber.HasValue) + { + var season = Season; + + if (season != null) + { + ParentIndexNumber = season.IndexNumber; + } + + // If a change was made record it + if (ParentIndexNumber.HasValue) + { + updateType = updateType | ItemUpdateType.MetadataImport; + } + } + + return updateType; + } } } diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index ba79a95cc..830ccb8a2 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Localization; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; @@ -243,9 +244,40 @@ namespace MediaBrowser.Controller.Entities.TV } } + /// <summary> + /// Gets the lookup information. + /// </summary> + /// <returns>SeasonInfo.</returns> public SeasonInfo GetLookupInfo() { return GetItemLookupInfo<SeasonInfo>(); } + + /// <summary> + /// This is called before any metadata refresh and returns ItemUpdateType indictating if changes were made, and what. + /// </summary> + /// <returns>ItemUpdateType.</returns> + public override ItemUpdateType BeforeMetadataRefresh() + { + var updateType = base.BeforeMetadataRefresh(); + + var locationType = LocationType; + + if (locationType == LocationType.FileSystem || locationType == LocationType.Offline) + { + if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path)) + { + IndexNumber = IndexNumber ?? TVUtils.GetSeasonNumberFromPath(Path); + + // If a change was made record it + if (IndexNumber.HasValue) + { + updateType = updateType | ItemUpdateType.MetadataImport; + } + } + } + + return updateType; + } } } diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index 4128c5d95..9afcdfe67 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Controller.Entities /// Get the children of this folder from the actual file system /// </summary> /// <returns>IEnumerable{BaseItem}.</returns> - protected override IEnumerable<BaseItem> GetNonCachedChildren(DirectoryService directoryService) + protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService) { return base.GetNonCachedChildren(directoryService).Concat(LibraryManager.RootFolder.VirtualChildren); } diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index e2275fde7..e778b38bd 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -27,9 +27,16 @@ namespace MediaBrowser.Controller.Entities PlayableStreamFileNames = new List<string>(); AdditionalPartIds = new List<Guid>(); Tags = new List<string>(); + SubtitleFiles = new List<string>(); } /// <summary> + /// Gets or sets the subtitle paths. + /// </summary> + /// <value>The subtitle paths.</value> + public List<string> SubtitleFiles { get; set; } + + /// <summary> /// Gets or sets a value indicating whether this instance has subtitles. /// </summary> /// <value><c>true</c> if this instance has subtitles; otherwise, <c>false</c>.</value> @@ -156,9 +163,9 @@ namespace MediaBrowser.Controller.Entities } } - protected override async Task BeforeRefreshMetadata(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) + protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) { - await base.BeforeRefreshMetadata(options, fileSystemChildren, cancellationToken).ConfigureAwait(false); + var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false); // Must have a parent to have additional parts // In other words, it must be part of the Parent/Child tree @@ -169,9 +176,11 @@ namespace MediaBrowser.Controller.Entities if (additionalPartsChanged) { - options.ForceSave = true; + hasChanges = true; } } + + return hasChanges; } /// <summary> diff --git a/MediaBrowser.Controller/Library/ItemUpdateType.cs b/MediaBrowser.Controller/Library/ItemUpdateType.cs index 31a00d7b4..cf6263356 100644 --- a/MediaBrowser.Controller/Library/ItemUpdateType.cs +++ b/MediaBrowser.Controller/Library/ItemUpdateType.cs @@ -5,7 +5,7 @@ namespace MediaBrowser.Controller.Library [Flags] public enum ItemUpdateType { - Unspecified = 1, + None = 1, MetadataImport = 2, ImageUpdate = 4, MetadataDownload = 8, diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs index 961f3acc7..828d662f6 100644 --- a/MediaBrowser.Controller/Providers/DirectoryService.cs +++ b/MediaBrowser.Controller/Providers/DirectoryService.cs @@ -6,7 +6,16 @@ using MediaBrowser.Model.Logging; namespace MediaBrowser.Controller.Providers { - public class DirectoryService + public interface IDirectoryService + { + List<FileSystemInfo> GetFileSystemEntries(string path); + IEnumerable<FileInfo> GetFiles(string path); + IEnumerable<DirectoryInfo> GetDirectories(string path); + FileInfo GetFile(string path); + DirectoryInfo GetDirectory(string path); + } + + public class DirectoryService : IDirectoryService { private readonly ILogger _logger; diff --git a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs index 7cf9e961e..c98810cbc 100644 --- a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs @@ -12,6 +12,6 @@ namespace MediaBrowser.Controller.Providers public interface ICustomMetadataProvider<TItemType> : IMetadataProvider<TItemType>, ICustomMetadataProvider where TItemType : IHasMetadata { - Task<ItemUpdateType> FetchAsync(TItemType item, CancellationToken cancellationToken); + Task<ItemUpdateType> FetchAsync(TItemType item, IDirectoryService directoryService, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/Providers/IHasChangeMonitor.cs b/MediaBrowser.Controller/Providers/IHasChangeMonitor.cs index ada2cbc6c..aa0b0e3c9 100644 --- a/MediaBrowser.Controller/Providers/IHasChangeMonitor.cs +++ b/MediaBrowser.Controller/Providers/IHasChangeMonitor.cs @@ -9,8 +9,9 @@ namespace MediaBrowser.Controller.Providers /// Determines whether the specified item has changed. /// </summary> /// <param name="item">The item.</param> + /// <param name="directoryService">The directory service.</param> /// <param name="date">The date.</param> /// <returns><c>true</c> if the specified item has changed; otherwise, <c>false</c>.</returns> - bool HasChanged(IHasMetadata item, DateTime date); + bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date); } } diff --git a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs index cd139bb14..11b8897e7 100644 --- a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs +++ b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Providers public interface ILocalImageFileProvider : ILocalImageProvider { - List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService); + List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService); } public class LocalImageInfo diff --git a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs index 3ab26ad66..780aa6a56 100644 --- a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs +++ b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Model.Logging; -using System; +using System; namespace MediaBrowser.Controller.Providers { @@ -17,13 +16,12 @@ namespace MediaBrowser.Controller.Providers /// </summary> [Obsolete] public bool ForceSave { get; set; } - - public DirectoryService DirectoryService { get; set; } } public class ImageRefreshOptions { public ImageRefreshMode ImageRefreshMode { get; set; } + public IDirectoryService DirectoryService { get; set; } public ImageRefreshOptions() { diff --git a/MediaBrowser.Model/Configuration/MetadataOptions.cs b/MediaBrowser.Model/Configuration/MetadataOptions.cs index f914a2d21..9fdcf045e 100644 --- a/MediaBrowser.Model/Configuration/MetadataOptions.cs +++ b/MediaBrowser.Model/Configuration/MetadataOptions.cs @@ -15,6 +15,7 @@ namespace MediaBrowser.Model.Configuration public ImageOption[] ImageOptions { get; set; } public string[] DisabledMetadataSavers { get; set; } + public string[] LocalMetadataReaders { get; set; } public MetadataOptions() : this(3, 1280) @@ -35,6 +36,7 @@ namespace MediaBrowser.Model.Configuration ImageOptions = imageOptions.ToArray(); DisabledMetadataSavers = new string[] { }; + LocalMetadataReaders = new string[] { }; } public int GetLimit(ImageType type) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index df80b465f..0e93246c9 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -265,11 +265,6 @@ namespace MediaBrowser.Model.Configuration MetadataOptions = options.ToArray(); } - - public MetadataOptions GetMetadataOptions(string type) - { - return MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)); - } } public enum ImageSavingConvention diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index af3c62396..c6bb6a7e1 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -32,6 +32,8 @@ namespace MediaBrowser.Model.Dto /// <value>The date created.</value> public DateTime? DateCreated { get; set; } + public DateTime? DateLastMediaAdded { get; set; } + public int? AirsBeforeSeasonNumber { get; set; } public int? AirsAfterSeasonNumber { get; set; } public int? AirsBeforeEpisodeNumber { get; set; } diff --git a/MediaBrowser.Model/Entities/MetadataProviders.cs b/MediaBrowser.Model/Entities/MetadataProviders.cs index ec7e14a6d..e86773789 100644 --- a/MediaBrowser.Model/Entities/MetadataProviders.cs +++ b/MediaBrowser.Model/Entities/MetadataProviders.cs @@ -6,40 +6,40 @@ namespace MediaBrowser.Model.Entities /// </summary> public enum MetadataProviders { - Gamesdb, + Gamesdb = 1, /// <summary> /// The imdb /// </summary> - Imdb, + Imdb = 2, /// <summary> /// The TMDB /// </summary> - Tmdb, + Tmdb = 3, /// <summary> /// The TVDB /// </summary> - Tvdb, + Tvdb = 4, /// <summary> /// The tvcom /// </summary> - Tvcom, + Tvcom = 5, /// <summary> /// The rotten tomatoes /// </summary> - RottenTomatoes, + RottenTomatoes = 6, /// <summary> /// Tmdb Collection Id /// </summary> - TmdbCollection, - MusicBrainzAlbum, - MusicBrainzAlbumArtist, - MusicBrainzArtist, - MusicBrainzReleaseGroup, - Zap2It, - NesBox, - NesBoxRom, - TvRage, - AudioDbArtist, - AudioDbAlbum + TmdbCollection = 7, + MusicBrainzAlbum = 8, + MusicBrainzAlbumArtist = 9, + MusicBrainzArtist = 10, + MusicBrainzReleaseGroup = 11, + Zap2It = 12, + NesBox = 13, + NesBoxRom = 14, + TvRage = 15, + AudioDbArtist = 16, + AudioDbAlbum = 17 } } diff --git a/MediaBrowser.Model/Providers/ImageProviderInfo.cs b/MediaBrowser.Model/Providers/ImageProviderInfo.cs index 1b8a2816a..4b5a07805 100644 --- a/MediaBrowser.Model/Providers/ImageProviderInfo.cs +++ b/MediaBrowser.Model/Providers/ImageProviderInfo.cs @@ -10,11 +10,5 @@ /// </summary> /// <value>The name.</value> public string Name { get; set; } - - /// <summary> - /// Gets or sets the order. - /// </summary> - /// <value>The order.</value> - public int Order { get; set; } } } diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index e16da857b..f5640227e 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -42,6 +42,11 @@ namespace MediaBrowser.Model.Querying DateCreated, /// <summary> + /// The date last media added + /// </summary> + DateLastMediaAdded, + + /// <summary> /// Item display preferences /// </summary> DisplayPreferencesId, diff --git a/MediaBrowser.Providers/All/InternalMetadataFolderImageProvider.cs b/MediaBrowser.Providers/All/InternalMetadataFolderImageProvider.cs index a5a714dd8..c264b0c58 100644 --- a/MediaBrowser.Providers/All/InternalMetadataFolderImageProvider.cs +++ b/MediaBrowser.Providers/All/InternalMetadataFolderImageProvider.cs @@ -61,7 +61,7 @@ namespace MediaBrowser.Providers.All } } - public List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService) + public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService) { var path = _config.ApplicationPaths.GetInternalMetadataPath(item.Id); diff --git a/MediaBrowser.Providers/All/LocalImageProvider.cs b/MediaBrowser.Providers/All/LocalImageProvider.cs index f54975a69..983600397 100644 --- a/MediaBrowser.Providers/All/LocalImageProvider.cs +++ b/MediaBrowser.Providers/All/LocalImageProvider.cs @@ -57,7 +57,7 @@ namespace MediaBrowser.Providers.All return false; } - private IEnumerable<FileSystemInfo> GetFiles(IHasImages item, bool includeDirectories, DirectoryService directoryService) + private IEnumerable<FileSystemInfo> GetFiles(IHasImages item, bool includeDirectories, IDirectoryService directoryService) { if (item.LocationType != LocationType.FileSystem) { @@ -77,7 +77,7 @@ namespace MediaBrowser.Providers.All .Where(i => BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase)); } - public List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService) + public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService) { var files = GetFiles(item, true, directoryService).ToList(); @@ -88,12 +88,12 @@ namespace MediaBrowser.Providers.All return list; } - public List<LocalImageInfo> GetImages(IHasImages item, string path, DirectoryService directoryService) + public List<LocalImageInfo> GetImages(IHasImages item, string path, IDirectoryService directoryService) { return GetImages(item, new[] { path }, directoryService); } - public List<LocalImageInfo> GetImages(IHasImages item, IEnumerable<string> paths, DirectoryService directoryService) + public List<LocalImageInfo> GetImages(IHasImages item, IEnumerable<string> paths, IDirectoryService directoryService) { var files = paths.SelectMany(directoryService.GetFiles) .Where(i => @@ -113,7 +113,7 @@ namespace MediaBrowser.Providers.All return list; } - private void PopulateImages(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, bool supportParentSeriesFiles, DirectoryService directoryService) + private void PopulateImages(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, bool supportParentSeriesFiles, IDirectoryService directoryService) { var imagePrefix = string.Empty; @@ -185,7 +185,7 @@ namespace MediaBrowser.Providers.All } } - private void PopulateBackdrops(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, DirectoryService directoryService) + private void PopulateBackdrops(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, IDirectoryService directoryService) { PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", ImageType.Backdrop); @@ -212,7 +212,7 @@ namespace MediaBrowser.Providers.All } } - private void PopulateBackdropsFromExtraFanart(string path, List<LocalImageInfo> images, DirectoryService directoryService) + private void PopulateBackdropsFromExtraFanart(string path, List<LocalImageInfo> images, IDirectoryService directoryService) { var imageFiles = directoryService.GetFiles(path) .Where(i => @@ -262,7 +262,7 @@ namespace MediaBrowser.Providers.All } private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private void PopulateSeasonImagesFromSeriesFolder(Season season, List<LocalImageInfo> images, DirectoryService directoryService) + private void PopulateSeasonImagesFromSeriesFolder(Season season, List<LocalImageInfo> images, IDirectoryService directoryService) { var seasonNumber = season.IndexNumber; diff --git a/MediaBrowser.Providers/BaseXmlProvider.cs b/MediaBrowser.Providers/BaseXmlProvider.cs index 60ae8333a..b80f27259 100644 --- a/MediaBrowser.Providers/BaseXmlProvider.cs +++ b/MediaBrowser.Providers/BaseXmlProvider.cs @@ -39,6 +39,10 @@ namespace MediaBrowser.Providers { result.HasMetadata = false; } + catch (DirectoryNotFoundException) + { + result.HasMetadata = false; + } finally { XmlProviderUtils.XmlParsingResourcePool.Release(); @@ -56,7 +60,7 @@ namespace MediaBrowser.Providers protected abstract FileInfo GetXmlFile(ItemInfo info); - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { var file = GetXmlFile(new ItemInfo { IsInMixedFolder = item.IsInMixedFolder, Path = item.Path }); diff --git a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs index 8514c1932..e990ddd65 100644 --- a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs +++ b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs @@ -85,10 +85,12 @@ namespace MediaBrowser.Providers.BoxSets private BoxSet GetItem(RootObject obj) { - var item = new BoxSet(); + var item = new BoxSet + { + Name = obj.name, + Overview = obj.overview + }; - item.Name = obj.name; - item.Overview = obj.overview; item.SetProviderId(MetadataProviders.Tmdb, obj.id.ToString(_enUs)); return item; diff --git a/MediaBrowser.Providers/Folders/CollectionFolderImageProvider.cs b/MediaBrowser.Providers/Folders/CollectionFolderImageProvider.cs index a55c42e4b..04fe042c8 100644 --- a/MediaBrowser.Providers/Folders/CollectionFolderImageProvider.cs +++ b/MediaBrowser.Providers/Folders/CollectionFolderImageProvider.cs @@ -27,7 +27,7 @@ namespace MediaBrowser.Providers.Folders } } - public List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService) + public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService) { var collectionFolder = (CollectionFolder)item; diff --git a/MediaBrowser.Providers/Folders/ImagesByNameImageProvider.cs b/MediaBrowser.Providers/Folders/ImagesByNameImageProvider.cs index daefe25ac..7dc934573 100644 --- a/MediaBrowser.Providers/Folders/ImagesByNameImageProvider.cs +++ b/MediaBrowser.Providers/Folders/ImagesByNameImageProvider.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.Folders } } - public List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService) + public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService) { var name = _fileSystem.GetValidFilename(item.Name); diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index 95e6d5611..8f72e601b 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Providers.Manager _fileSystem = fileSystem; } - public bool ValidateImages(IHasImages item, IEnumerable<IImageProvider> providers, DirectoryService directoryService) + public bool ValidateImages(IHasImages item, IEnumerable<IImageProvider> providers, IDirectoryService directoryService) { var hasChanges = item.ValidateImages(directoryService); @@ -53,7 +53,7 @@ namespace MediaBrowser.Providers.Manager public async Task<RefreshResult> RefreshImages(IHasImages item, IEnumerable<IImageProvider> imageProviders, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, CancellationToken cancellationToken) { - var result = new RefreshResult { UpdateType = ItemUpdateType.Unspecified }; + var result = new RefreshResult { UpdateType = ItemUpdateType.None }; var providers = GetImageProviders(item, imageProviders).ToList(); diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 93879d826..d64c98d5b 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -4,11 +4,11 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -73,7 +73,7 @@ namespace MediaBrowser.Providers.Manager var itemOfType = (TItemType)item; var config = ProviderManager.GetMetadataOptions(item); - var updateType = ItemUpdateType.Unspecified; + var updateType = ItemUpdateType.None; var refreshResult = GetLastResult(item.Id); refreshResult.LastErrorMessage = string.Empty; refreshResult.LastStatus = ProviderRefreshStatus.Success; @@ -106,7 +106,7 @@ namespace MediaBrowser.Providers.Manager if (providers.Count > 0 || !refreshResult.DateLastMetadataRefresh.HasValue) { - updateType = updateType | BeforeMetadataRefresh(itemOfType); + updateType = updateType | item.BeforeMetadataRefresh(); } if (providers.Count > 0) @@ -138,15 +138,10 @@ namespace MediaBrowser.Providers.Manager updateType = updateType | BeforeSave(itemOfType); - var providersHadChanges = updateType > ItemUpdateType.Unspecified; + var providersHadChanges = updateType > ItemUpdateType.None; if (refreshOptions.ForceSave || providersHadChanges) { - if (string.IsNullOrEmpty(item.Name)) - { - throw new InvalidOperationException(item.GetType().Name + " has no name: " + item.Path); - } - // Save to database await SaveItem(itemOfType, updateType, cancellationToken); } @@ -158,23 +153,13 @@ namespace MediaBrowser.Providers.Manager } /// <summary> - /// Befores the metadata refresh. - /// </summary> - /// <param name="item">The item.</param> - /// <returns>ItemUpdateType.</returns> - protected virtual ItemUpdateType BeforeMetadataRefresh(TItemType item) - { - return ItemUpdateType.Unspecified; - } - - /// <summary> /// Befores the save. /// </summary> /// <param name="item">The item.</param> /// <returns>ItemUpdateType.</returns> protected virtual ItemUpdateType BeforeSave(TItemType item) { - return ItemUpdateType.Unspecified; + return ItemUpdateType.None; } /// <summary> @@ -198,15 +183,37 @@ namespace MediaBrowser.Providers.Manager var currentItem = item; var providersWithChanges = providers.OfType<IHasChangeMonitor>() - .Where(i => i.HasChanged(currentItem, currentItem.DateLastSaved)) + .Where(i => i.HasChanged(currentItem, options.DirectoryService, currentItem.DateLastSaved)) + .Cast<IMetadataProvider<TItemType>>() .ToList(); - // If local providers are the only ones with changes, then just run those - if (providersWithChanges.All(i => i is ILocalMetadataProvider)) + if (providersWithChanges.Count == 0) + { + providers = new List<IMetadataProvider<TItemType>>(); + } + else { - providers = providersWithChanges.Count == 0 ? - new List<IMetadataProvider<TItemType>>() : - providers.Where(i => i is ILocalMetadataProvider).ToList(); + providers = providers.Where(i => + { + // If any provider reports a change, always run local ones as well + if (i is ILocalMetadataProvider) + { + return true; + } + + var anyRemoteProvidersChanged = providersWithChanges.OfType<IRemoteMetadataProvider>() + .Any(); + + // If any remote providers changed, run them all so that priorities can be honored + if (i is IRemoteMetadataProvider) + { + return anyRemoteProvidersChanged; + } + + // Run custom providers if they report a change or any remote providers change + return anyRemoteProvidersChanged || providersWithChanges.Contains(i); + + }).ToList(); } } @@ -227,7 +234,7 @@ namespace MediaBrowser.Providers.Manager var currentItem = item; providers = providers.OfType<IHasChangeMonitor>() - .Where(i => i.HasChanged(currentItem, dateLastImageRefresh.Value)) + .Where(i => i.HasChanged(currentItem, options.DirectoryService, dateLastImageRefresh.Value)) .Cast<IImageProvider>() .ToList(); } @@ -249,7 +256,7 @@ namespace MediaBrowser.Providers.Manager { var refreshResult = new RefreshResult { - UpdateType = ItemUpdateType.Unspecified, + UpdateType = ItemUpdateType.None, Providers = providers.Select(i => i.GetType().FullName.GetMD5()).ToList() }; @@ -316,26 +323,26 @@ namespace MediaBrowser.Providers.Manager await ExecuteRemoteProviders(item, temp, providers.OfType<IRemoteMetadataProvider<TItemType, TIdType>>(), refreshResult, cancellationToken).ConfigureAwait(false); } - if (refreshResult.UpdateType > ItemUpdateType.Unspecified) + if (refreshResult.UpdateType > ItemUpdateType.None) { MergeData(temp, item, item.LockedFields, true, true); } foreach (var provider in providers.OfType<ICustomMetadataProvider<TItemType>>()) { - await RunCustomProvider(provider, item, refreshResult, cancellationToken).ConfigureAwait(false); + await RunCustomProvider(provider, item, options.DirectoryService, refreshResult, cancellationToken).ConfigureAwait(false); } return refreshResult; } - private async Task RunCustomProvider(ICustomMetadataProvider<TItemType> provider, TItemType item, RefreshResult refreshResult, CancellationToken cancellationToken) + private async Task RunCustomProvider(ICustomMetadataProvider<TItemType> provider, TItemType item, IDirectoryService directoryService, RefreshResult refreshResult, CancellationToken cancellationToken) { Logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name); try { - refreshResult.UpdateType = refreshResult.UpdateType | await provider.FetchAsync(item, cancellationToken).ConfigureAwait(false); + refreshResult.UpdateType = refreshResult.UpdateType | await provider.FetchAsync(item, directoryService, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index a6817cf32..604953909 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -279,8 +279,7 @@ namespace MediaBrowser.Providers.Manager { return GetRemoteImageProviders(item).Select(i => new ImageProviderInfo { - Name = i.Name, - Order = GetOrder(item, i) + Name = i.Name }); } @@ -298,21 +297,39 @@ namespace MediaBrowser.Providers.Manager return false; } - }).OrderBy(i => GetOrder(item, i)); + }).OrderBy(GetOrder); } public IEnumerable<IMetadataProvider<T>> GetMetadataProviders<T>(IHasMetadata item) where T : IHasMetadata { - return GetMetadataProvidersInternal<T>(item, false); + var options = GetMetadataOptions(item); + + return GetMetadataProvidersInternal<T>(item, options, false); } - private IEnumerable<IMetadataProvider<T>> GetMetadataProvidersInternal<T>(IHasMetadata item, bool includeDisabled) + private IEnumerable<IMetadataProvider<T>> GetMetadataProvidersInternal<T>(IHasMetadata item, MetadataOptions options, bool includeDisabled) where T : IHasMetadata { return _metadataProviders.OfType<IMetadataProvider<T>>() .Where(i => CanRefresh(i, item, includeDisabled)) - .OrderBy(i => GetOrder(item, i)); + .OrderBy(i => + { + // See if there's a user-defined order + if (i is ILocalMetadataProvider) + { + var index = Array.IndexOf(options.LocalMetadataReaders, i.Name); + + if (index != -1) + { + return index; + } + } + + // Not configured. Just return some high number to put it at the end. + return 100; + }) + .ThenBy(GetOrder); } private IEnumerable<IRemoteImageProvider> GetRemoteImageProviders(IHasImages item) @@ -354,10 +371,9 @@ namespace MediaBrowser.Providers.Manager /// <summary> /// Gets the order. /// </summary> - /// <param name="item">The item.</param> /// <param name="provider">The provider.</param> /// <returns>System.Int32.</returns> - private int GetOrder(IHasImages item, IImageProvider provider) + private int GetOrder(IImageProvider provider) { var hasOrder = provider as IHasOrder; @@ -372,19 +388,18 @@ namespace MediaBrowser.Providers.Manager /// <summary> /// Gets the order. /// </summary> - /// <param name="item">The item.</param> /// <param name="provider">The provider.</param> /// <returns>System.Int32.</returns> - private int GetOrder(IHasMetadata item, IMetadataProvider provider) + private int GetOrder(IMetadataProvider provider) { var hasOrder = provider as IHasOrder; - if (hasOrder == null) + if (hasOrder != null) { - return 0; + return hasOrder.Order; } - return hasOrder.Order; + return 0; } public IEnumerable<MetadataPluginSummary> GetAllMetadataPlugins() @@ -432,6 +447,8 @@ namespace MediaBrowser.Providers.Manager Parent = new Folder() }; + var options = GetMetadataOptions(dummy); + var summary = new MetadataPluginSummary { ItemType = typeof(T).Name @@ -439,7 +456,7 @@ namespace MediaBrowser.Providers.Manager var imageProviders = GetImageProviders(dummy).ToList(); - AddMetadataPlugins(summary.Plugins, dummy); + AddMetadataPlugins(summary.Plugins, dummy, options); AddImagePlugins(summary.Plugins, dummy, imageProviders); summary.SupportedImageTypes = imageProviders.OfType<IRemoteImageProvider>() @@ -450,10 +467,10 @@ namespace MediaBrowser.Providers.Manager return summary; } - private void AddMetadataPlugins<T>(List<MetadataPlugin> list, T item) + private void AddMetadataPlugins<T>(List<MetadataPlugin> list, T item, MetadataOptions options) where T : IHasMetadata { - var providers = GetMetadataProvidersInternal<T>(item, true).ToList(); + var providers = GetMetadataProvidersInternal<T>(item, options, true).ToList(); // Locals list.AddRange(providers.Where(i => (i is ILocalMetadataProvider)).Select(i => new MetadataPlugin @@ -496,16 +513,21 @@ namespace MediaBrowser.Providers.Manager })); } - private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>(); - public MetadataOptions GetMetadataOptions(IHasMetadata item) { var type = item.GetType().Name; + + if (item is Trailer) + { + type = typeof(Movie).Name; + } + return ConfigurationManager.Configuration.MetadataOptions .FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) ?? new MetadataOptions(); } - + + private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>(); /// <summary> /// Saves the metadata. /// </summary> @@ -517,7 +539,7 @@ namespace MediaBrowser.Providers.Manager foreach (var saver in _savers.Where(i => IsSaverEnabledForItem(i, item, updateType, true))) { _logger.Debug("Saving {0} to {1}.", item.Path ?? item.Name, saver.Name); - + var fileSaver = saver as IMetadataFileSaver; if (fileSaver != null) diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 5f1299e31..772f60163 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -159,7 +159,7 @@ namespace MediaBrowser.Providers.MediaInfo return item.LocationType == LocationType.FileSystem && item is Audio; } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { return item.DateModified > date; } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs index 6eca3c0bc..951996a9f 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs @@ -13,10 +13,11 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Serialization; using System; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Serialization; +using System.Linq; namespace MediaBrowser.Providers.MediaInfo { @@ -46,47 +47,47 @@ namespace MediaBrowser.Providers.MediaInfo get { return "ffprobe"; } } - public Task<ItemUpdateType> FetchAsync(Episode item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(Episode item, IDirectoryService directoryService, CancellationToken cancellationToken) { - return FetchVideoInfo(item, cancellationToken); + return FetchVideoInfo(item, directoryService, cancellationToken); } - public Task<ItemUpdateType> FetchAsync(MusicVideo item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(MusicVideo item, IDirectoryService directoryService, CancellationToken cancellationToken) { - return FetchVideoInfo(item, cancellationToken); + return FetchVideoInfo(item, directoryService, cancellationToken); } - public Task<ItemUpdateType> FetchAsync(Movie item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(Movie item, IDirectoryService directoryService, CancellationToken cancellationToken) { - return FetchVideoInfo(item, cancellationToken); + return FetchVideoInfo(item, directoryService, cancellationToken); } - public Task<ItemUpdateType> FetchAsync(AdultVideo item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(AdultVideo item, IDirectoryService directoryService, CancellationToken cancellationToken) { - return FetchVideoInfo(item, cancellationToken); + return FetchVideoInfo(item, directoryService, cancellationToken); } - public Task<ItemUpdateType> FetchAsync(LiveTvVideoRecording item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(LiveTvVideoRecording item, IDirectoryService directoryService, CancellationToken cancellationToken) { - return FetchVideoInfo(item, cancellationToken); + return FetchVideoInfo(item, directoryService, cancellationToken); } - public Task<ItemUpdateType> FetchAsync(Trailer item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(Trailer item, IDirectoryService directoryService, CancellationToken cancellationToken) { - return FetchVideoInfo(item, cancellationToken); + return FetchVideoInfo(item, directoryService, cancellationToken); } - public Task<ItemUpdateType> FetchAsync(Video item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(Video item, IDirectoryService directoryService, CancellationToken cancellationToken) { - return FetchVideoInfo(item, cancellationToken); + return FetchVideoInfo(item, directoryService, cancellationToken); } - public Task<ItemUpdateType> FetchAsync(Audio item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(Audio item, IDirectoryService directoryService, CancellationToken cancellationToken) { return FetchAudioInfo(item, cancellationToken); } - public Task<ItemUpdateType> FetchAsync(LiveTvAudioRecording item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(LiveTvAudioRecording item, IDirectoryService directoryService, CancellationToken cancellationToken) { return FetchAudioInfo(item, cancellationToken); } @@ -103,8 +104,8 @@ namespace MediaBrowser.Providers.MediaInfo _json = json; } - private readonly Task<ItemUpdateType> _cachedTask = Task.FromResult(ItemUpdateType.Unspecified); - public Task<ItemUpdateType> FetchVideoInfo<T>(T item, CancellationToken cancellationToken) + private readonly Task<ItemUpdateType> _cachedTask = Task.FromResult(ItemUpdateType.None); + public Task<ItemUpdateType> FetchVideoInfo<T>(T item, IDirectoryService directoryService, CancellationToken cancellationToken) where T : Video { if (item.LocationType != LocationType.FileSystem) @@ -124,7 +125,7 @@ namespace MediaBrowser.Providers.MediaInfo var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json); - return prober.ProbeVideo(item, cancellationToken); + return prober.ProbeVideo(item, directoryService, cancellationToken); } public Task<ItemUpdateType> FetchAudioInfo<T>(T item, CancellationToken cancellationToken) @@ -140,9 +141,26 @@ namespace MediaBrowser.Providers.MediaInfo return prober.Probe(item, cancellationToken); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { - return item.DateModified > date; + if (item.DateModified > date) + { + return true; + } + + if (item.LocationType == LocationType.FileSystem) + { + var video = item as Video; + + if (video != null) + { + var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json); + + return !video.SubtitleFiles.SequenceEqual(prober.GetSubtitleFiles(video, directoryService).Select(i => i.FullName).OrderBy(i => i), StringComparer.OrdinalIgnoreCase); + } + } + + return false; } public int Order diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index f5b8496cb..074bcfdff 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.MediaInfo; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; @@ -45,7 +46,7 @@ namespace MediaBrowser.Providers.MediaInfo _json = json; } - public async Task<ItemUpdateType> ProbeVideo<T>(T item, CancellationToken cancellationToken) + public async Task<ItemUpdateType> ProbeVideo<T>(T item, IDirectoryService directoryService, CancellationToken cancellationToken) where T : Video { var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false); @@ -72,7 +73,7 @@ namespace MediaBrowser.Providers.MediaInfo cancellationToken.ThrowIfCancellationRequested(); - await Fetch(item, cancellationToken, result, isoMount).ConfigureAwait(false); + await Fetch(item, cancellationToken, result, isoMount, directoryService).ConfigureAwait(false); } finally @@ -125,7 +126,7 @@ namespace MediaBrowser.Providers.MediaInfo return result; } - protected async Task Fetch(Video video, CancellationToken cancellationToken, InternalMediaInfoResult data, IIsoMount isoMount) + protected async Task Fetch(Video video, CancellationToken cancellationToken, InternalMediaInfoResult data, IIsoMount isoMount, IDirectoryService directoryService) { if (data.format != null) { @@ -148,7 +149,7 @@ namespace MediaBrowser.Providers.MediaInfo FetchBdInfo(video, chapters, mediaStreams, inputPath, cancellationToken); } - AddExternalSubtitles(video, mediaStreams); + AddExternalSubtitles(video, mediaStreams, directoryService); FetchWtvInfo(video, data); @@ -342,76 +343,104 @@ namespace MediaBrowser.Providers.MediaInfo } } + public IEnumerable<FileInfo> GetSubtitleFiles(Video video, IDirectoryService directoryService) + { + var containingPath = video.ContainingFolderPath; + + if (string.IsNullOrEmpty(containingPath)) + { + throw new ArgumentException(string.Format("Cannot search for items that don't have a path: {0} {1}", video.Name, video.Id)); + } + + var files = directoryService.GetFiles(containingPath); + + var videoFileNameWithoutExtension = Path.GetFileNameWithoutExtension(video.Path); + + return files.Where(i => + { + if (!i.Attributes.HasFlag(FileAttributes.Directory) && + SubtitleExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase)) + { + var fullName = i.FullName; + + var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fullName); + + if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + if (fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + }); + } + /// <summary> /// Adds the external subtitles. /// </summary> /// <param name="video">The video.</param> /// <param name="currentStreams">The current streams.</param> - private void AddExternalSubtitles(Video video, List<MediaStream> currentStreams) + private void AddExternalSubtitles(Video video, List<MediaStream> currentStreams, IDirectoryService directoryService) { - //var useParent = !video.ResolveArgs.IsDirectory; - - //if (useParent && video.Parent == null) - //{ - // return; - //} - - //var fileSystemChildren = useParent - // ? video.Parent.ResolveArgs.FileSystemChildren - // : video.ResolveArgs.FileSystemChildren; - - //var startIndex = currentStreams.Count; - //var streams = new List<MediaStream>(); - - //var videoFileNameWithoutExtension = Path.GetFileNameWithoutExtension(video.Path); - - //foreach (var file in fileSystemChildren - // .Where(f => !f.Attributes.HasFlag(FileAttributes.Directory) && SubtitleExtensions.Contains(Path.GetExtension(f.FullName), StringComparer.OrdinalIgnoreCase))) - //{ - // var fullName = file.FullName; - - // var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fullName); - - // // If the subtitle file matches the video file name - // if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase)) - // { - // streams.Add(new MediaStream - // { - // Index = startIndex++, - // Type = MediaStreamType.Subtitle, - // IsExternal = true, - // Path = fullName, - // Codec = Path.GetExtension(fullName).ToLower().TrimStart('.') - // }); - // } - // else if (fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase)) - // { - // // Support xbmc naming conventions - 300.spanish.srt - // var language = fileNameWithoutExtension.Split('.').LastOrDefault(); - - // // Try to translate to three character code - // // Be flexible and check against both the full and three character versions - // var culture = _localization.GetCultures() - // .FirstOrDefault(i => string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.ThreeLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase)); - - // if (culture != null) - // { - // language = culture.ThreeLetterISOLanguageName; - // } - - // streams.Add(new MediaStream - // { - // Index = startIndex++, - // Type = MediaStreamType.Subtitle, - // IsExternal = true, - // Path = fullName, - // Codec = Path.GetExtension(fullName).ToLower().TrimStart('.'), - // Language = language - // }); - // } - //} - - //currentStreams.AddRange(streams); + var files = GetSubtitleFiles(video, directoryService); + + var startIndex = currentStreams.Count; + var streams = new List<MediaStream>(); + + var videoFileNameWithoutExtension = Path.GetFileNameWithoutExtension(video.Path); + + foreach (var file in files) + { + var fullName = file.FullName; + + var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fullName); + + // If the subtitle file matches the video file name + if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase)) + { + streams.Add(new MediaStream + { + Index = startIndex++, + Type = MediaStreamType.Subtitle, + IsExternal = true, + Path = fullName, + Codec = Path.GetExtension(fullName).ToLower().TrimStart('.') + }); + } + else if (fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase)) + { + // Support xbmc naming conventions - 300.spanish.srt + var language = fileNameWithoutExtension.Split('.').LastOrDefault(); + + // Try to translate to three character code + // Be flexible and check against both the full and three character versions + var culture = _localization.GetCultures() + .FirstOrDefault(i => string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.ThreeLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase)); + + if (culture != null) + { + language = culture.ThreeLetterISOLanguageName; + } + + streams.Add(new MediaStream + { + Index = startIndex++, + Type = MediaStreamType.Subtitle, + IsExternal = true, + Path = fullName, + Codec = Path.GetExtension(fullName).ToLower().TrimStart('.'), + Language = language + }); + } + } + + video.SubtitleFiles = streams.Select(i => i.Path).OrderBy(i => i).ToList(); + + currentStreams.AddRange(streams); } /// <summary> diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index 8c62f6be4..c230f65f9 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -126,7 +126,7 @@ namespace MediaBrowser.Providers.MediaInfo return item.LocationType == LocationType.FileSystem && item is Video; } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { return item.DateModified > date; } diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs index ba3b468d4..26395e9cc 100644 --- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs +++ b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs @@ -345,7 +345,7 @@ namespace MediaBrowser.Providers.Movies }); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { if (!_config.Configuration.EnableFanArtUpdates) { diff --git a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs index 5699093e4..8a38e294c 100644 --- a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs @@ -208,7 +208,7 @@ namespace MediaBrowser.Providers.Movies }); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { return MovieDbProvider.Current.HasChanged(item, date); } diff --git a/MediaBrowser.Providers/Music/AlbumMetadataService.cs b/MediaBrowser.Providers/Music/AlbumMetadataService.cs index 410441fc8..0a3359156 100644 --- a/MediaBrowser.Providers/Music/AlbumMetadataService.cs +++ b/MediaBrowser.Providers/Music/AlbumMetadataService.cs @@ -99,7 +99,7 @@ namespace MediaBrowser.Providers.Music private ItemUpdateType SetAlbumArtistFromSongs(MusicAlbum item, IEnumerable<Audio> songs) { - var updateType = ItemUpdateType.Unspecified; + var updateType = ItemUpdateType.None; var albumArtist = songs .Select(i => i.AlbumArtist) @@ -119,7 +119,7 @@ namespace MediaBrowser.Providers.Music private ItemUpdateType SetArtistsFromSongs(MusicAlbum item, IEnumerable<Audio> songs) { - var updateType = ItemUpdateType.Unspecified; + var updateType = ItemUpdateType.None; var currentList = item.Artists.ToList(); @@ -137,7 +137,7 @@ namespace MediaBrowser.Providers.Music private ItemUpdateType SetDateFromSongs(MusicAlbum item, List<Audio> songs) { - var updateType = ItemUpdateType.Unspecified; + var updateType = ItemUpdateType.None; var date = songs.Select(i => i.PremiereDate) .FirstOrDefault(i => i.HasValue); diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs index f268cc910..8479b0c6e 100644 --- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs @@ -357,7 +357,7 @@ namespace MediaBrowser.Providers.Music }); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { if (!_config.Configuration.EnableFanArtUpdates) { diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs index 8e27d6891..9b32ff4f2 100644 --- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs @@ -374,7 +374,7 @@ namespace MediaBrowser.Providers.Music }); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { if (!_config.Configuration.EnableFanArtUpdates) { diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index 5ef747674..8f870d25a 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -27,18 +27,18 @@ namespace MediaBrowser.Providers.Omdb get { return "IMDb via The Open Movie Database"; } } - public Task<ItemUpdateType> FetchAsync(Series item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(Series item, IDirectoryService directoryService, CancellationToken cancellationToken) { return new OmdbProvider(_jsonSerializer, _httpClient).Fetch(item, cancellationToken); } - public Task<ItemUpdateType> FetchAsync(Movie item, CancellationToken cancellationToken) + public Task<ItemUpdateType> FetchAsync(Movie item, IDirectoryService directoryService, CancellationToken cancellationToken) { return new OmdbProvider(_jsonSerializer, _httpClient).Fetch(item, cancellationToken); } - private readonly Task<ItemUpdateType> _cachedTask = Task.FromResult(ItemUpdateType.Unspecified); - public Task<ItemUpdateType> FetchAsync(Trailer item, CancellationToken cancellationToken) + private readonly Task<ItemUpdateType> _cachedTask = Task.FromResult(ItemUpdateType.None); + public Task<ItemUpdateType> FetchAsync(Trailer item, IDirectoryService directoryService, CancellationToken cancellationToken) { if (item.IsLocalTrailer) { diff --git a/MediaBrowser.Providers/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Omdb/OmdbProvider.cs index bc1be2dd6..8eabc5164 100644 --- a/MediaBrowser.Providers/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbProvider.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Providers.Omdb if (string.IsNullOrEmpty(imdbId)) { - return ItemUpdateType.Unspecified; + return ItemUpdateType.None; } var imdbParam = imdbId.StartsWith("tt", StringComparison.OrdinalIgnoreCase) ? imdbId : "tt" + imdbId; diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index e1c3221ee..f439f4bc5 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.People return; } - var url = string.Format(@"http://api.themoviedb.org/3/person/{1}?api_key={0}&append_to_response=credits,images", MovieDbProvider.ApiKey, id); + var url = string.Format(@"http://api.themoviedb.org/3/person/{1}?api_key={0}&append_to_response=credits,images,external_ids", MovieDbProvider.ApiKey, id); using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions { @@ -267,6 +267,14 @@ namespace MediaBrowser.Providers.People public List<Profile> profiles { get; set; } } + public class ExternalIds + { + public string imdb_id { get; set; } + public string freebase_mid { get; set; } + public string freebase_id { get; set; } + public int tvrage_id { get; set; } + } + public class PersonResult { public bool adult { get; set; } @@ -283,6 +291,7 @@ namespace MediaBrowser.Providers.People public string profile_path { get; set; } public Credits credits { get; set; } public Images images { get; set; } + public ExternalIds external_ids { get; set; } } #endregion diff --git a/MediaBrowser.Providers/Savers/AlbumXmlSaver.cs b/MediaBrowser.Providers/Savers/AlbumXmlSaver.cs index a1595bce1..91d01a2c6 100644 --- a/MediaBrowser.Providers/Savers/AlbumXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/AlbumXmlSaver.cs @@ -1,25 +1,16 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; -using MediaBrowser.Model.Entities; namespace MediaBrowser.Providers.Savers { class AlbumXmlSaver : IMetadataFileSaver { - private readonly IServerConfigurationManager _config; - - public AlbumXmlSaver(IServerConfigurationManager config) - { - _config = config; - } - public string Name { get diff --git a/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs b/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs index 5a7b85205..a19a2cc4a 100644 --- a/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs @@ -1,11 +1,7 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; -using MediaBrowser.Providers.Music; -using System; using System.Collections.Generic; using System.IO; using System.Text; @@ -15,13 +11,6 @@ namespace MediaBrowser.Providers.Savers { class ArtistXmlSaver : IMetadataFileSaver { - private readonly IServerConfigurationManager _config; - - public ArtistXmlSaver(IServerConfigurationManager config) - { - _config = config; - } - public string Name { get diff --git a/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs b/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs index 7b142b68e..59e112b04 100644 --- a/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs @@ -1,25 +1,16 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; namespace MediaBrowser.Providers.Savers { public class BoxSetXmlSaver : IMetadataFileSaver { - private readonly IServerConfigurationManager _config; - - public BoxSetXmlSaver(IServerConfigurationManager config) - { - _config = config; - } - public string Name { get diff --git a/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs b/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs index 7da6c25c1..25aea69c4 100644 --- a/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs @@ -1,12 +1,11 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; -using MediaBrowser.Model.Entities; namespace MediaBrowser.Providers.Savers { diff --git a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs index af73791c9..124a29571 100644 --- a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs @@ -1,24 +1,28 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; -using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Security; using System.Text; using System.Threading; -using MediaBrowser.Model.Entities; namespace MediaBrowser.Providers.Savers { public class EpisodeXmlSaver : IMetadataFileSaver { - private readonly IServerConfigurationManager _config; private readonly IItemRepository _itemRepository; + private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + + public EpisodeXmlSaver(IItemRepository itemRepository) + { + _itemRepository = itemRepository; + } + /// <summary> /// Determines whether [is enabled for] [the specified item]. /// </summary> @@ -53,14 +57,6 @@ namespace MediaBrowser.Providers.Savers } } - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - - public EpisodeXmlSaver(IServerConfigurationManager config, IItemRepository itemRepository) - { - _config = config; - _itemRepository = itemRepository; - } - /// <summary> /// Saves the specified item. /// </summary> diff --git a/MediaBrowser.Providers/Savers/FolderXmlSaver.cs b/MediaBrowser.Providers/Savers/FolderXmlSaver.cs index 40e1ab019..f37658c64 100644 --- a/MediaBrowser.Providers/Savers/FolderXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/FolderXmlSaver.cs @@ -1,27 +1,18 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; -using MediaBrowser.Model.Entities; namespace MediaBrowser.Providers.Savers { public class FolderXmlSaver : IMetadataFileSaver { - private readonly IServerConfigurationManager _config; - - public FolderXmlSaver(IServerConfigurationManager config) - { - _config = config; - } - public string Name { get diff --git a/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs b/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs index 020f8987c..3c949314d 100644 --- a/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs @@ -1,25 +1,16 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.IO; using System.Security; using System.Text; using System.Threading; -using MediaBrowser.Model.Entities; namespace MediaBrowser.Providers.Savers { public class GameSystemXmlSaver : IMetadataFileSaver { - private readonly IServerConfigurationManager _config; - - public GameSystemXmlSaver(IServerConfigurationManager config) - { - _config = config; - } - public string Name { get diff --git a/MediaBrowser.Providers/Savers/GameXmlSaver.cs b/MediaBrowser.Providers/Savers/GameXmlSaver.cs index 6f50cfda8..3758a3c7b 100644 --- a/MediaBrowser.Providers/Savers/GameXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/GameXmlSaver.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; using System.Collections.Generic; @@ -16,13 +15,6 @@ namespace MediaBrowser.Providers.Savers /// </summary> public class GameXmlSaver : IMetadataFileSaver { - private readonly IServerConfigurationManager _config; - - public GameXmlSaver(IServerConfigurationManager config) - { - _config = config; - } - public string Name { get diff --git a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs index 851c81f54..2b5fed41c 100644 --- a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs @@ -1,18 +1,15 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Security; using System.Text; using System.Threading; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; namespace MediaBrowser.Providers.Savers { @@ -21,12 +18,10 @@ namespace MediaBrowser.Providers.Savers /// </summary> public class MovieXmlSaver : IMetadataFileSaver { - private readonly IServerConfigurationManager _config; private readonly IItemRepository _itemRepository; - public MovieXmlSaver(IServerConfigurationManager config, IItemRepository itemRepository) + public MovieXmlSaver(IItemRepository itemRepository) { - _config = config; _itemRepository = itemRepository; } diff --git a/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs b/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs index f8d4549cf..de3d1b68e 100644 --- a/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs @@ -1,25 +1,16 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; -using MediaBrowser.Model.Entities; namespace MediaBrowser.Providers.Savers { public class SeasonXmlSaver : IMetadataFileSaver { - private readonly IServerConfigurationManager _config; - - public SeasonXmlSaver(IServerConfigurationManager config) - { - _config = config; - } - public string Name { get diff --git a/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs b/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs index df0a87c35..5d947f8c5 100644 --- a/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; @@ -13,13 +12,6 @@ namespace MediaBrowser.Providers.Savers { public class SeriesXmlSaver : IMetadataFileSaver { - private readonly IServerConfigurationManager _config; - - public SeriesXmlSaver(IServerConfigurationManager config) - { - _config = config; - } - public string Name { get diff --git a/MediaBrowser.Providers/TV/EpisodeLocalImageProvider.cs b/MediaBrowser.Providers/TV/EpisodeLocalImageProvider.cs index 8a3af13d8..4f806d834 100644 --- a/MediaBrowser.Providers/TV/EpisodeLocalImageProvider.cs +++ b/MediaBrowser.Providers/TV/EpisodeLocalImageProvider.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.Providers.TV return item is Episode && item.LocationType == LocationType.FileSystem; } - public List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService) + public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService) { var parentPath = Path.GetDirectoryName(item.Path); diff --git a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs index 94d166273..4b6ac04bc 100644 --- a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs +++ b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs @@ -1,26 +1,19 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; using System.Collections.Generic; -using System.IO; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Providers.TV { public class EpisodeMetadataService : MetadataService<Episode, EpisodeInfo> { - private readonly ILibraryManager _libraryManager; - - public EpisodeMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager) + public EpisodeMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) { - _libraryManager = libraryManager; } /// <summary> @@ -70,50 +63,5 @@ namespace MediaBrowser.Providers.TV target.IndexNumberEnd = source.IndexNumberEnd; } } - - protected override ItemUpdateType BeforeMetadataRefresh(Episode item) - { - var updateType = base.BeforeMetadataRefresh(item); - - var locationType = item.LocationType; - if (locationType == LocationType.FileSystem || locationType == LocationType.Offline) - { - var currentIndexNumber = item.IndexNumber; - var currentIndexNumberEnd = item.IndexNumberEnd; - var currentParentIndexNumber = item.ParentIndexNumber; - - var filename = Path.GetFileName(item.Path); - - item.IndexNumber = item.IndexNumber ?? TVUtils.GetEpisodeNumberFromFile(item.Path, item.Parent is Season); - item.IndexNumberEnd = item.IndexNumberEnd ?? TVUtils.GetEndingEpisodeNumberFromFile(item.Path); - - if (!item.ParentIndexNumber.HasValue) - { - var season = item.Season; - - if (season != null) - { - item.ParentIndexNumber = season.IndexNumber; - } - } - - if ((currentIndexNumber ?? -1) != (item.IndexNumber ?? -1)) - { - updateType = updateType | ItemUpdateType.MetadataImport; - } - - if ((currentIndexNumberEnd ?? -1) != (item.IndexNumberEnd ?? -1)) - { - updateType = updateType | ItemUpdateType.MetadataImport; - } - - if ((currentParentIndexNumber ?? -1) != (item.ParentIndexNumber ?? -1)) - { - updateType = updateType | ItemUpdateType.MetadataImport; - } - } - - return updateType; - } } } diff --git a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs index 62f7a985a..6f8da573d 100644 --- a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs @@ -275,7 +275,7 @@ namespace MediaBrowser.Providers.TV }); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { if (!_config.Configuration.EnableFanArtUpdates) { diff --git a/MediaBrowser.Providers/TV/FanartSeriesProvider.cs b/MediaBrowser.Providers/TV/FanartSeriesProvider.cs index 85a2944f3..f18189a2a 100644 --- a/MediaBrowser.Providers/TV/FanartSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/FanartSeriesProvider.cs @@ -423,7 +423,7 @@ namespace MediaBrowser.Providers.TV } } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { if (!_config.Configuration.EnableFanArtUpdates) { diff --git a/MediaBrowser.Providers/TV/MovieDbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/MovieDbSeriesImageProvider.cs index 3a98d95e4..9795b7b11 100644 --- a/MediaBrowser.Providers/TV/MovieDbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/MovieDbSeriesImageProvider.cs @@ -203,7 +203,7 @@ namespace MediaBrowser.Providers.TV }); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { return MovieDbSeriesProvider.Current.HasChanged(item, date); } diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs index e76ad9075..4c0149d2e 100644 --- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs @@ -1,25 +1,19 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; 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 SeasonMetadataService : MetadataService<Season, SeasonInfo> { - private readonly ILibraryManager _libraryManager; - - public SeasonMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager) + public SeasonMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) { - _libraryManager = libraryManager; } /// <summary> @@ -34,20 +28,5 @@ namespace MediaBrowser.Providers.TV { ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); } - - protected override ItemUpdateType BeforeMetadataRefresh(Season item) - { - var updateType = base.BeforeMetadataRefresh(item); - - var currentIndexNumber = item.IndexNumber; - - item.IndexNumber = item.IndexNumber ?? TVUtils.GetSeasonNumberFromPath(item.Path); - - if ((currentIndexNumber ?? -1) != (item.IndexNumber ?? -1)) - { - updateType = updateType | ItemUpdateType.MetadataImport; - } - return updateType; - } } } diff --git a/MediaBrowser.Providers/TV/SeriesMetadataService.cs b/MediaBrowser.Providers/TV/SeriesMetadataService.cs index bc9f543cf..beb9ab595 100644 --- a/MediaBrowser.Providers/TV/SeriesMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeriesMetadataService.cs @@ -8,8 +8,6 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; using System.Collections.Generic; using System.Linq; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Providers.TV { diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs index 7d8f9e186..0830b6713 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs @@ -192,7 +192,7 @@ namespace MediaBrowser.Providers.TV }); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { if (item.LocationType != LocationType.Virtual) { diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index d0b405017..0c9712cae 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -66,7 +66,7 @@ namespace MediaBrowser.Providers.TV return Task.FromResult(result); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { // Only enable for virtual items if (item.LocationType != LocationType.Virtual) diff --git a/MediaBrowser.Providers/TV/TvdbPrescanTask.cs b/MediaBrowser.Providers/TV/TvdbPrescanTask.cs index a9edeee0e..4164a05ba 100644 --- a/MediaBrowser.Providers/TV/TvdbPrescanTask.cs +++ b/MediaBrowser.Providers/TV/TvdbPrescanTask.cs @@ -98,8 +98,19 @@ namespace MediaBrowser.Providers.TV string newUpdateTime; - var existingDirectories = Directory.EnumerateDirectories(path).Select(Path.GetFileName).ToList(); - + var existingDirectories = Directory.EnumerateDirectories(path) + .Select(Path.GetFileName) + .ToList(); + + var seriesIdsInLibrary = _libraryManager.RootFolder.RecursiveChildren + .OfType<Series>() + .Select(i => i.GetProviderId(MetadataProviders.Tvdb)) + .Where(i => !string.IsNullOrEmpty(i)) + .ToList(); + + var missingSeries = seriesIdsInLibrary.Except(existingDirectories, StringComparer.OrdinalIgnoreCase) + .ToList(); + // If this is our first time, update all series if (string.IsNullOrEmpty(lastUpdateTime)) { @@ -116,6 +127,8 @@ namespace MediaBrowser.Providers.TV newUpdateTime = GetUpdateTime(stream); } + existingDirectories.AddRange(missingSeries); + await UpdateSeries(existingDirectories, path, null, progress, cancellationToken).ConfigureAwait(false); } else @@ -130,7 +143,10 @@ namespace MediaBrowser.Providers.TV var nullableUpdateValue = lastUpdateValue == 0 ? (long?)null : lastUpdateValue; - await UpdateSeries(seriesToUpdate.Item1, path, nullableUpdateValue, progress, cancellationToken).ConfigureAwait(false); + var listToUpdate = seriesToUpdate.Item1.ToList(); + listToUpdate.AddRange(missingSeries); + + await UpdateSeries(listToUpdate, path, nullableUpdateValue, progress, cancellationToken).ConfigureAwait(false); } File.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8); diff --git a/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs index 5216d84c5..e4756ea71 100644 --- a/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs @@ -340,7 +340,7 @@ namespace MediaBrowser.Providers.TV }); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { if (item.LocationType != LocationType.Virtual) { diff --git a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs index 3e1664f85..765d17aa7 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs @@ -337,7 +337,7 @@ namespace MediaBrowser.Providers.TV }); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { if (!_config.Configuration.EnableTvDbUpdates) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs index 9fdca568e..9a1373460 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs @@ -103,7 +103,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv get { return 0; } } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalDays >= 1; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs index 1dd6eb272..cb7635b45 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs @@ -103,7 +103,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv get { return 0; } } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalHours >= 6; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs index 0ba760768..be8955d16 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs @@ -103,7 +103,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv get { return 0; } } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) { return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalHours >= 3; } diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index d24b1425a..a0540f78d 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common.Internal</id> - <version>3.0.324</version> + <version>3.0.325</version> <title>MediaBrowser.Common.Internal</title> <authors>Luke</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description> <copyright>Copyright © Media Browser 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.324" /> + <dependency id="MediaBrowser.Common" version="3.0.325" /> <dependency id="NLog" version="2.1.0" /> <dependency id="SimpleInjector" version="2.4.1" /> <dependency id="sharpcompress" version="0.10.2" /> diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 92939185f..4813ea39b 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common</id> - <version>3.0.324</version> + <version>3.0.325</version> <title>MediaBrowser.Common</title> <authors>Media Browser Team</authors> <owners>ebr,Luke,scottisafool</owners> diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index c208cb725..3a08bb75a 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>MediaBrowser.Server.Core</id> - <version>3.0.324</version> + <version>3.0.325</version> <title>Media Browser.Server.Core</title> <authors>Media Browser Team</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains core components required to build plugins for Media Browser Server.</description> <copyright>Copyright © Media Browser 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.324" /> + <dependency id="MediaBrowser.Common" version="3.0.325" /> </dependencies> </metadata> <files> |
