diff options
Diffstat (limited to 'MediaBrowser.Providers/Manager')
| -rw-r--r-- | MediaBrowser.Providers/Manager/ImageSaver.cs | 8 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Manager/ItemImageProvider.cs | 6 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Manager/MetadataService.cs | 17 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Manager/ProviderManager.cs | 171 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Manager/ProviderUtils.cs | 2 |
5 files changed, 181 insertions, 23 deletions
diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index a8e16e4ae..22178434f 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -82,14 +82,6 @@ namespace MediaBrowser.Providers.Manager { saveLocally = true; } - if (item is IItemByName) - { - var hasDualAccess = item as IHasDualAccess; - if (hasDualAccess == null || hasDualAccess.IsAccessedByName) - { - saveLocally = true; - } - } if (type != ImageType.Primary && item is Episode) { diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index 66b0f9259..3c75aa20a 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -135,17 +135,17 @@ namespace MediaBrowser.Providers.Manager { if (!string.IsNullOrEmpty(response.Path)) { - var mimeType = "image/" + Path.GetExtension(response.Path).TrimStart('.').ToLower(); + var mimeType = MimeTypes.GetMimeType(response.Path); var stream = _fileSystem.GetFileStream(response.Path, FileMode.Open, FileAccess.Read, FileShare.Read, true); - await _providerManager.SaveImage(item, stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false); + await _providerManager.SaveImage(item, stream, mimeType, imageType, null, response.InternalCacheKey, cancellationToken).ConfigureAwait(false); } else { var mimeType = "image/" + response.Format.ToString().ToLower(); - await _providerManager.SaveImage(item, response.Stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false); + await _providerManager.SaveImage(item, response.Stream, mimeType, imageType, null, response.InternalCacheKey, cancellationToken).ConfigureAwait(false); } downloadedImages.Add(imageType); diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index ab6cb89a6..ab9525636 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -87,7 +87,7 @@ namespace MediaBrowser.Providers.Manager return ProviderRepo.GetMetadataStatus(item.Id) ?? new MetadataStatus { ItemId = item.Id }; } - public async Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken) + public async Task<ItemUpdateType> RefreshMetadata(IHasMetadata item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken) { var itemOfType = (TItemType)item; var config = ProviderManager.GetMetadataOptions(item); @@ -163,7 +163,8 @@ namespace MediaBrowser.Providers.Manager } } - updateType = updateType | (await BeforeSave(itemOfType, item.DateLastSaved == default(DateTime) || refreshOptions.ReplaceAllMetadata, updateType).ConfigureAwait(false)); + var beforeSaveResult = await BeforeSave(itemOfType, item.DateLastSaved == default(DateTime) || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh, updateType).ConfigureAwait(false); + updateType = updateType | beforeSaveResult; // Save if changes were made, or it's never been saved before if (refreshOptions.ForceSave || updateType > ItemUpdateType.None || item.DateLastSaved == default(DateTime) || refreshOptions.ReplaceAllMetadata) @@ -184,6 +185,8 @@ namespace MediaBrowser.Providers.Manager } await AfterMetadataRefresh(itemOfType, refreshOptions, cancellationToken).ConfigureAwait(false); + + return updateType; } private readonly Task _cachedTask = Task.FromResult(true); @@ -397,7 +400,10 @@ namespace MediaBrowser.Providers.Manager refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport; // Only one local provider allowed per item - hasLocalMetadata = true; + if (IsFullLocalMetadata(localItem.Item)) + { + hasLocalMetadata = true; + } successfulProviderCount++; break; } @@ -473,6 +479,11 @@ namespace MediaBrowser.Providers.Manager return refreshResult; } + protected virtual bool IsFullLocalMetadata(TItemType item) + { + return true; + } + private async Task ImportUserData(TItemType item, List<UserItemData> userDataList, CancellationToken cancellationToken) { var hasUserData = item as IHasUserData; diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 823c34a75..c9ae47ad0 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -26,7 +26,7 @@ namespace MediaBrowser.Providers.Manager /// <summary> /// Class ProviderManager /// </summary> - public class ProviderManager : IProviderManager + public class ProviderManager : IProviderManager, IDisposable { /// <summary> /// The _logger @@ -63,6 +63,8 @@ namespace MediaBrowser.Providers.Manager private IExternalId[] _externalIds; + private readonly Func<ILibraryManager> _libraryManagerFactory; + /// <summary> /// Initializes a new instance of the <see cref="ProviderManager" /> class. /// </summary> @@ -71,7 +73,7 @@ namespace MediaBrowser.Providers.Manager /// <param name="libraryMonitor">The directory watchers.</param> /// <param name="logManager">The log manager.</param> /// <param name="fileSystem">The file system.</param> - public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths) + public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory) { _logger = logManager.GetLogger("ProviderManager"); _httpClient = httpClient; @@ -79,6 +81,7 @@ namespace MediaBrowser.Providers.Manager _libraryMonitor = libraryMonitor; _fileSystem = fileSystem; _appPaths = appPaths; + _libraryManagerFactory = libraryManagerFactory; } /// <summary> @@ -108,7 +111,7 @@ namespace MediaBrowser.Providers.Manager _externalIds = externalIds.OrderBy(i => i.Name).ToArray(); } - public Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken) + public Task<ItemUpdateType> RefreshSingleItem(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken) { var service = _metadataServices.FirstOrDefault(i => i.CanRefresh(item)); @@ -118,7 +121,7 @@ namespace MediaBrowser.Providers.Manager } _logger.Error("Unable to find a metadata service for item of type " + item.GetType().Name); - return Task.FromResult(true); + return Task.FromResult(ItemUpdateType.None); } public async Task SaveImage(IHasImages item, string url, SemaphoreSlim resourcePool, ImageType type, int? imageIndex, CancellationToken cancellationToken) @@ -309,7 +312,7 @@ namespace MediaBrowser.Providers.Manager if (provider is IRemoteMetadataProvider) { - if (!ConfigurationManager.Configuration.EnableInternetProviders) + if (!item.IsInternetMetadataEnabled()) { return false; } @@ -357,7 +360,7 @@ namespace MediaBrowser.Providers.Manager if (provider is IRemoteImageProvider) { - if (!ConfigurationManager.Configuration.EnableInternetProviders) + if (!item.IsInternetMetadataEnabled()) { return false; } @@ -512,7 +515,7 @@ namespace MediaBrowser.Providers.Manager Type = MetadataPluginType.LocalMetadataProvider })); - if (ConfigurationManager.Configuration.EnableInternetProviders) + if (item.IsInternetMetadataEnabled()) { // Fetchers list.AddRange(providers.Where(i => (i is IRemoteMetadataProvider)).Select(i => new MetadataPlugin @@ -544,7 +547,7 @@ namespace MediaBrowser.Providers.Manager Type = MetadataPluginType.LocalImageProvider })); - var enableInternet = ConfigurationManager.Configuration.EnableInternetProviders; + var enableInternet = item.IsInternetMetadataEnabled(); // Fetchers list.AddRange(imageProviders.Where(i => i is IDynamicImageProvider || (enableInternet && i is IRemoteImageProvider)).Select(i => new MetadataPlugin @@ -841,5 +844,157 @@ namespace MediaBrowser.Providers.Manager }); } + + private readonly ConcurrentQueue<Tuple<Guid, MetadataRefreshOptions>> _refreshQueue = + new ConcurrentQueue<Tuple<Guid, MetadataRefreshOptions>>(); + + private readonly object _refreshTimerLock = new object(); + private Timer _refreshTimer; + + public void QueueRefresh(Guid id, MetadataRefreshOptions options) + { + if (_disposed) + { + return; + } + + _refreshQueue.Enqueue(new Tuple<Guid, MetadataRefreshOptions>(id, options)); + StartRefreshTimer(); + } + + private void StartRefreshTimer() + { + lock (_refreshTimerLock) + { + if (_refreshTimer == null) + { + _refreshTimer = new Timer(RefreshTimerCallback, null, 100, Timeout.Infinite); + } + } + } + + private void StopRefreshTimer() + { + lock (_refreshTimerLock) + { + if (_refreshTimer != null) + { + _refreshTimer.Dispose(); + _refreshTimer = null; + } + } + } + + private async void RefreshTimerCallback(object state) + { + Tuple<Guid, MetadataRefreshOptions> refreshItem; + var libraryManager = _libraryManagerFactory(); + + while (_refreshQueue.TryDequeue(out refreshItem)) + { + if (_disposed) + { + return; + } + + var item = libraryManager.GetItemById(refreshItem.Item1); + if (item != null) + { + try + { + var artist = item as MusicArtist; + var task = artist == null + ? RefreshItem(item, refreshItem.Item2, CancellationToken.None) + : RefreshArtist(artist, refreshItem.Item2); + + await task.ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error refreshing item", ex); + } + } + } + + StopRefreshTimer(); + } + + private async Task RefreshItem(BaseItem item, MetadataRefreshOptions options, CancellationToken cancellationToken) + { + await item.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false); + + if (item.IsFolder) + { + // Collection folders don't validate their children so we'll have to simulate that here + var collectionFolder = item as CollectionFolder; + + if (collectionFolder != null) + { + await RefreshCollectionFolderChildren(options, collectionFolder).ConfigureAwait(false); + } + else + { + var folder = (Folder)item; + + await folder.ValidateChildren(new Progress<double>(), cancellationToken, options).ConfigureAwait(false); + } + } + } + + private async Task RefreshCollectionFolderChildren(MetadataRefreshOptions options, CollectionFolder collectionFolder) + { + foreach (var child in collectionFolder.Children.ToList()) + { + await child.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false); + + if (child.IsFolder) + { + var folder = (Folder)child; + + await folder.ValidateChildren(new Progress<double>(), CancellationToken.None).ConfigureAwait(false); + } + } + } + + private async Task RefreshArtist(MusicArtist item, MetadataRefreshOptions options) + { + var cancellationToken = CancellationToken.None; + + var albums = _libraryManagerFactory().RootFolder + .GetRecursiveChildren() + .OfType<MusicAlbum>() + .Where(i => i.HasAnyArtist(item.Name)) + .ToList(); + + var musicArtists = albums + .Select(i => i.Parent) + .OfType<MusicArtist>() + .ToList(); + + var musicArtistRefreshTasks = musicArtists.Select(i => i.ValidateChildren(new Progress<double>(), cancellationToken, options, true)); + + await Task.WhenAll(musicArtistRefreshTasks).ConfigureAwait(false); + + try + { + await item.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error refreshing library", ex); + } + } + + public Task RefreshFullItem(IHasMetadata item, MetadataRefreshOptions options, + CancellationToken cancellationToken) + { + return RefreshItem((BaseItem)item, options, cancellationToken); + } + + private bool _disposed; + public void Dispose() + { + _disposed = true; + } } }
\ No newline at end of file diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs index 155cd208f..aa92cc280 100644 --- a/MediaBrowser.Providers/Manager/ProviderUtils.cs +++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs @@ -252,7 +252,7 @@ namespace MediaBrowser.Providers.Manager if (sourceHasAlbumArtist != null && targetHasAlbumArtist != null) { - if (replaceData || targetHasAlbumArtist.AlbumArtists.Count > 0) + if (replaceData || targetHasAlbumArtist.AlbumArtists.Count == 0) { targetHasAlbumArtist.AlbumArtists = sourceHasAlbumArtist.AlbumArtists; } |
