aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Providers/Manager
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Providers/Manager')
-rw-r--r--MediaBrowser.Providers/Manager/ImageSaver.cs8
-rw-r--r--MediaBrowser.Providers/Manager/ItemImageProvider.cs6
-rw-r--r--MediaBrowser.Providers/Manager/MetadataService.cs17
-rw-r--r--MediaBrowser.Providers/Manager/ProviderManager.cs171
-rw-r--r--MediaBrowser.Providers/Manager/ProviderUtils.cs2
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;
}