Browse Source

Merge pull request #11921 from Shadowghost/fix-identify-over-nfo

Fix identify over NFO and replace all when NFO saving enabled
Joshua M. Boniface 1 year ago
parent
commit
bfcc09db8a

+ 8 - 0
MediaBrowser.Controller/Providers/IProviderManager.cs

@@ -140,6 +140,14 @@ namespace MediaBrowser.Controller.Providers
         IEnumerable<IMetadataProvider<T>> GetMetadataProviders<T>(BaseItem item, LibraryOptions libraryOptions)
             where T : BaseItem;
 
+        /// <summary>
+        /// Gets the metadata savers for the provided item.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="libraryOptions">The library options.</param>
+        /// <returns>The metadata savers.</returns>
+        IEnumerable<IMetadataSaver> GetMetadataSavers(BaseItem item, LibraryOptions libraryOptions);
+
         /// <summary>
         /// Gets all metadata plugins.
         /// </summary>

+ 2 - 1
MediaBrowser.Providers/Manager/ItemImageProvider.cs

@@ -428,7 +428,8 @@ namespace MediaBrowser.Providers.Manager
                 var type = _singularImages[i];
                 var image = GetFirstLocalImageInfoByType(images, type);
 
-                if (image is not null)
+                // Only use local images if we are not replacing and saving
+                if (image is not null && !(item.IsSaveLocalMetadataEnabled() && refreshOptions.ReplaceAllImages))
                 {
                     var currentImage = item.GetImageInfo(type, 0);
                     // if image file is stored with media, don't replace that later

+ 53 - 46
MediaBrowser.Providers/Manager/MetadataService.cs

@@ -154,7 +154,8 @@ namespace MediaBrowser.Providers.Manager
 
                     id.IsAutomated = refreshOptions.IsAutomated;
 
-                    var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, ImageProvider, cancellationToken).ConfigureAwait(false);
+                    var hasMetadataSavers = ProviderManager.GetMetadataSavers(item, libraryOptions).Any();
+                    var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, ImageProvider, hasMetadataSavers, cancellationToken).ConfigureAwait(false);
 
                     updateType |= result.UpdateType;
                     if (result.Failures > 0)
@@ -639,6 +640,7 @@ namespace MediaBrowser.Providers.Manager
             MetadataRefreshOptions options,
             ICollection<IMetadataProvider> providers,
             ItemImageProvider imageService,
+            bool isSavingMetadata,
             CancellationToken cancellationToken)
         {
             var refreshResult = new RefreshResult
@@ -669,69 +671,74 @@ namespace MediaBrowser.Providers.Manager
             temp.Item.Id = item.Id;
 
             var foundImageTypes = new List<ImageType>();
-            foreach (var provider in providers.OfType<ILocalMetadataProvider<TItemType>>())
-            {
-                var providerName = provider.GetType().Name;
-                Logger.LogDebug("Running {Provider} for {Item}", providerName, logName);
 
-                var itemInfo = new ItemInfo(item);
-
-                try
+            // Do not execute local providers if we are identifying or replacing with local metadata saving enabled
+            if (options.SearchResult is null && !(isSavingMetadata && options.ReplaceAllMetadata))
+            {
+                foreach (var provider in providers.OfType<ILocalMetadataProvider<TItemType>>())
                 {
-                    var localItem = await provider.GetMetadata(itemInfo, options.DirectoryService, cancellationToken).ConfigureAwait(false);
+                    var providerName = provider.GetType().Name;
+                    Logger.LogDebug("Running {Provider} for {Item}", providerName, logName);
+
+                    var itemInfo = new ItemInfo(item);
 
-                    if (localItem.HasMetadata)
+                    try
                     {
-                        foreach (var remoteImage in localItem.RemoteImages)
+                        var localItem = await provider.GetMetadata(itemInfo, options.DirectoryService, cancellationToken).ConfigureAwait(false);
+
+                        if (localItem.HasMetadata)
                         {
-                            try
+                            foreach (var remoteImage in localItem.RemoteImages)
                             {
-                                if (item.ImageInfos.Any(x => x.Type == remoteImage.Type)
-                                    && !options.IsReplacingImage(remoteImage.Type))
+                                try
                                 {
-                                    continue;
-                                }
+                                    if (item.ImageInfos.Any(x => x.Type == remoteImage.Type)
+                                        && !options.IsReplacingImage(remoteImage.Type))
+                                    {
+                                        continue;
+                                    }
 
-                                await ProviderManager.SaveImage(item, remoteImage.Url, remoteImage.Type, null, cancellationToken).ConfigureAwait(false);
-                                refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
+                                    await ProviderManager.SaveImage(item, remoteImage.Url, remoteImage.Type, null, cancellationToken).ConfigureAwait(false);
+                                    refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
 
-                                // remember imagetype that has just been downloaded
-                                foundImageTypes.Add(remoteImage.Type);
+                                    // remember imagetype that has just been downloaded
+                                    foundImageTypes.Add(remoteImage.Type);
+                                }
+                                catch (HttpRequestException ex)
+                                {
+                                    Logger.LogError(ex, "Could not save {ImageType} image: {Url}", Enum.GetName(remoteImage.Type), remoteImage.Url);
+                                }
                             }
-                            catch (HttpRequestException ex)
+
+                            if (foundImageTypes.Count > 0)
                             {
-                                Logger.LogError(ex, "Could not save {ImageType} image: {Url}", Enum.GetName(remoteImage.Type), remoteImage.Url);
+                                imageService.UpdateReplaceImages(options, foundImageTypes);
                             }
-                        }
 
-                        if (foundImageTypes.Count > 0)
-                        {
-                            imageService.UpdateReplaceImages(options, foundImageTypes);
-                        }
+                            if (imageService.MergeImages(item, localItem.Images, options))
+                            {
+                                refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
+                            }
 
-                        if (imageService.MergeImages(item, localItem.Images, options))
-                        {
-                            refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
-                        }
+                            MergeData(localItem, temp, Array.Empty<MetadataField>(), false, true);
+                            refreshResult.UpdateType |= ItemUpdateType.MetadataImport;
 
-                        MergeData(localItem, temp, Array.Empty<MetadataField>(), false, true);
-                        refreshResult.UpdateType |= ItemUpdateType.MetadataImport;
+                            break;
+                        }
 
-                        break;
+                        Logger.LogDebug("{Provider} returned no metadata for {Item}", providerName, logName);
                     }
+                    catch (OperationCanceledException)
+                    {
+                        throw;
+                    }
+                    catch (Exception ex)
+                    {
+                        Logger.LogError(ex, "Error in {Provider}", provider.Name);
 
-                    Logger.LogDebug("{Provider} returned no metadata for {Item}", providerName, logName);
-                }
-                catch (OperationCanceledException)
-                {
-                    throw;
-                }
-                catch (Exception ex)
-                {
-                    Logger.LogError(ex, "Error in {Provider}", provider.Name);
-
-                    // If a local provider fails, consider that a failure
-                    refreshResult.ErrorMessage = ex.Message;
+                        // If a local provider fails, consider that a failure
+                        refreshResult.ErrorMessage = ex.Message;
+                    }
                 }
             }
 

+ 6 - 0
MediaBrowser.Providers/Manager/ProviderManager.cs

@@ -418,6 +418,12 @@ namespace MediaBrowser.Providers.Manager
             return GetMetadataProvidersInternal<T>(item, libraryOptions, globalMetadataOptions, false, false);
         }
 
+        /// <inheritdoc />
+        public IEnumerable<IMetadataSaver> GetMetadataSavers(BaseItem item, LibraryOptions libraryOptions)
+        {
+            return _savers.Where(i => IsSaverEnabledForItem(i, item, libraryOptions, ItemUpdateType.MetadataEdit, false));
+        }
+
         private IEnumerable<IMetadataProvider<T>> GetMetadataProvidersInternal<T>(BaseItem item, LibraryOptions libraryOptions, MetadataOptions globalMetadataOptions, bool includeDisabled, bool forceEnableInternetMetadata)
             where T : BaseItem
         {

+ 7 - 3
tests/Jellyfin.Providers.Tests/Manager/ItemImageProviderTests.cs

@@ -575,18 +575,22 @@ namespace Jellyfin.Providers.Tests.Manager
             // Has to exist for querying DateModified time on file, results stored but not checked so not populating
             BaseItem.FileSystem ??= Mock.Of<IFileSystem>();
 
-            var item = new Video();
+            var item = new Mock<Video>
+            {
+                CallBase = true
+            };
+            item.Setup(m => m.IsSaveLocalMetadataEnabled()).Returns(false);
 
             var path = validPaths ? _testDataImagePath.Format : "invalid path {0}";
             for (int i = 0; i < count; i++)
             {
-                item.SetImagePath(type, i, new FileSystemMetadata
+                item.Object.SetImagePath(type, i, new FileSystemMetadata
                 {
                     FullName = string.Format(CultureInfo.InvariantCulture, path, i),
                 });
             }
 
-            return item;
+            return item.Object;
         }
 
         private static ILocalImageProvider GetImageProvider(ImageType type, int count, bool validPaths)