diff --git a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs index 90fd6e269..1fb18334a 100644 --- a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs +++ b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs @@ -30,6 +30,7 @@ namespace MediaBrowser.Controller.Providers ReplaceAllImages = copy.ReplaceAllImages; ReplaceImages = copy.ReplaceImages; SearchResult = copy.SearchResult; + IsIdentify = copy.IsIdentify; if (copy.RefreshPaths != null && copy.RefreshPaths.Length > 0) { diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index 5f18578e4..542be1caa 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -61,6 +61,30 @@ namespace MediaBrowser.Providers.Manager _fileSystem = fileSystem; } + /// + /// Removes all existing images from the provided item. + /// + /// The to remove images from. + /// true if changes were made to the item; otherwise false. + public bool RemoveImages(BaseItem item) + { + var singular = new List(); + for (var i = 0; i < _singularImages.Length; i++) + { + var currentImage = item.GetImageInfo(_singularImages[i], 0); + if (currentImage != null) + { + singular.Add(currentImage); + } + } + + var oldBackdropImages = item.GetImages(ImageType.Backdrop).ToArray(); + var toRemove = singular.Concat(oldBackdropImages).ToArray(); + PruneImages(item, toRemove); + + return toRemove.Length > 0; + } + /// /// Verifies existing images have valid paths and adds any new local images provided. /// diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 80ee32030..0b62b5cbc 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -98,6 +98,15 @@ namespace MediaBrowser.Providers.Manager var allImageProviders = ((ProviderManager)ProviderManager).GetImageProviders(item, refreshOptions).ToList(); + // If replacing images with identify purge existing images. + if (refreshOptions.IsIdentify && refreshOptions.ReplaceAllImages) + { + if (ImageProvider.RemoveImages(item)) + { + updateType |= ItemUpdateType.ImageUpdate; + } + } + // Start by validating images try { diff --git a/tests/Jellyfin.Providers.Tests/Manager/ItemImageProviderTests.cs b/tests/Jellyfin.Providers.Tests/Manager/ItemImageProviderTests.cs index af273390b..f466f5fbc 100644 --- a/tests/Jellyfin.Providers.Tests/Manager/ItemImageProviderTests.cs +++ b/tests/Jellyfin.Providers.Tests/Manager/ItemImageProviderTests.cs @@ -171,6 +171,35 @@ namespace Jellyfin.Providers.Tests.Manager } } + [Theory] + [InlineData(ImageType.Primary, 0)] + [InlineData(ImageType.Primary, 1)] + [InlineData(ImageType.Backdrop, 2)] + public void RemoveImages_DeletesImages_WhenFound(ImageType imageType, int imageCount) + { + var item = GetItemWithImages(imageType, imageCount, false); + + var mockFileSystem = new Mock(MockBehavior.Strict); + if (imageCount > 0) + { + mockFileSystem.Setup(fs => fs.DeleteFile("invalid path 0")) + .Verifiable(); + } + + if (imageCount > 1) + { + mockFileSystem.Setup(fs => fs.DeleteFile("invalid path 1")) + .Verifiable(); + } + + var itemImageProvider = GetItemImageProvider(Mock.Of(), mockFileSystem); + var result = itemImageProvider.RemoveImages(item); + + Assert.Equal(imageCount != 0, result); + Assert.Empty(item.GetImages(imageType)); + mockFileSystem.Verify(); + } + [Theory] [InlineData(ImageType.Primary, 1, false)] [InlineData(ImageType.Backdrop, 2, false)]