Fix local JPG primary image for video being overwritten by screen grabber (#9552)

This commit is contained in:
SenorSmartyPants 2023-05-10 18:46:55 -05:00 committed by GitHub
parent ffac062489
commit 11d7c00de9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 19 deletions

View file

@ -32,6 +32,7 @@ namespace MediaBrowser.Providers.Manager
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IProviderManager _providerManager; private readonly IProviderManager _providerManager;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private static readonly ImageType[] AllImageTypes = Enum.GetValues<ImageType>();
/// <summary> /// <summary>
/// Image types that are only one per item. /// Image types that are only one per item.
@ -90,11 +91,12 @@ namespace MediaBrowser.Providers.Manager
/// </summary> /// </summary>
/// <param name="item">The <see cref="BaseItem"/> to validate images for.</param> /// <param name="item">The <see cref="BaseItem"/> to validate images for.</param>
/// <param name="providers">The providers to use, must include <see cref="ILocalImageProvider"/>(s) for local scanning.</param> /// <param name="providers">The providers to use, must include <see cref="ILocalImageProvider"/>(s) for local scanning.</param>
/// <param name="directoryService">The directory service for <see cref="ILocalImageProvider"/>s to use.</param> /// <param name="refreshOptions">The refresh options.</param>
/// <returns><c>true</c> if changes were made to the item; otherwise <c>false</c>.</returns> /// <returns><c>true</c> if changes were made to the item; otherwise <c>false</c>.</returns>
public bool ValidateImages(BaseItem item, IEnumerable<IImageProvider> providers, IDirectoryService directoryService) public bool ValidateImages(BaseItem item, IEnumerable<IImageProvider> providers, ImageRefreshOptions refreshOptions)
{ {
var hasChanges = false; var hasChanges = false;
IDirectoryService directoryService = refreshOptions?.DirectoryService;
if (item is not Photo) if (item is not Photo)
{ {
@ -102,7 +104,7 @@ namespace MediaBrowser.Providers.Manager
.SelectMany(i => i.GetImages(item, directoryService)) .SelectMany(i => i.GetImages(item, directoryService))
.ToList(); .ToList();
if (MergeImages(item, images)) if (MergeImages(item, images, refreshOptions))
{ {
hasChanges = true; hasChanges = true;
} }
@ -381,15 +383,36 @@ namespace MediaBrowser.Providers.Manager
item.RemoveImages(images); item.RemoveImages(images);
} }
/// <summary>
/// Merges a list of images into the provided item, validating existing images and replacing them or adding new images as necessary.
/// </summary>
/// <param name="refreshOptions">The refresh options.</param>
/// <param name="dontReplaceImages">List of imageTypes to remove from ReplaceImages.</param>
public void UpdateReplaceImages(ImageRefreshOptions refreshOptions, ICollection<ImageType> dontReplaceImages)
{
if (refreshOptions is not null)
{
if (refreshOptions.ReplaceAllImages)
{
refreshOptions.ReplaceAllImages = false;
refreshOptions.ReplaceImages = AllImageTypes.ToList();
}
refreshOptions.ReplaceImages = refreshOptions.ReplaceImages.Except(dontReplaceImages).ToList();
}
}
/// <summary> /// <summary>
/// Merges a list of images into the provided item, validating existing images and replacing them or adding new images as necessary. /// Merges a list of images into the provided item, validating existing images and replacing them or adding new images as necessary.
/// </summary> /// </summary>
/// <param name="item">The <see cref="BaseItem"/> to modify.</param> /// <param name="item">The <see cref="BaseItem"/> to modify.</param>
/// <param name="images">The new images to place in <c>item</c>.</param> /// <param name="images">The new images to place in <c>item</c>.</param>
/// <param name="refreshOptions">The refresh options.</param>
/// <returns><c>true</c> if changes were made to the item; otherwise <c>false</c>.</returns> /// <returns><c>true</c> if changes were made to the item; otherwise <c>false</c>.</returns>
public bool MergeImages(BaseItem item, IReadOnlyList<LocalImageInfo> images) public bool MergeImages(BaseItem item, IReadOnlyList<LocalImageInfo> images, ImageRefreshOptions refreshOptions)
{ {
var changed = item.ValidateImages(); var changed = item.ValidateImages();
var foundImageTypes = new List<ImageType>();
for (var i = 0; i < _singularImages.Length; i++) for (var i = 0; i < _singularImages.Length; i++)
{ {
@ -399,6 +422,11 @@ namespace MediaBrowser.Providers.Manager
if (image is not null) if (image is not null)
{ {
var currentImage = item.GetImageInfo(type, 0); var currentImage = item.GetImageInfo(type, 0);
// if image file is stored with media, don't replace that later
if (item.ContainingFolderPath is not null && item.ContainingFolderPath.Contains(Path.GetDirectoryName(image.FileInfo.FullName), StringComparison.OrdinalIgnoreCase))
{
foundImageTypes.Add(type);
}
if (currentImage is null || !string.Equals(currentImage.Path, image.FileInfo.FullName, StringComparison.OrdinalIgnoreCase)) if (currentImage is null || !string.Equals(currentImage.Path, image.FileInfo.FullName, StringComparison.OrdinalIgnoreCase))
{ {
@ -425,6 +453,12 @@ namespace MediaBrowser.Providers.Manager
if (UpdateMultiImages(item, images, ImageType.Backdrop)) if (UpdateMultiImages(item, images, ImageType.Backdrop))
{ {
changed = true; changed = true;
foundImageTypes.Add(ImageType.Backdrop);
}
if (foundImageTypes.Count > 0)
{
UpdateReplaceImages(refreshOptions, foundImageTypes);
} }
return changed; return changed;

View file

@ -26,8 +26,6 @@ namespace MediaBrowser.Providers.Manager
where TItemType : BaseItem, IHasLookupInfo<TIdType>, new() where TItemType : BaseItem, IHasLookupInfo<TIdType>, new()
where TIdType : ItemLookupInfo, new() where TIdType : ItemLookupInfo, new()
{ {
private static readonly ImageType[] AllImageTypes = Enum.GetValues<ImageType>();
protected MetadataService(IServerConfigurationManager serverConfigurationManager, ILogger<MetadataService<TItemType, TIdType>> logger, IProviderManager providerManager, IFileSystem fileSystem, ILibraryManager libraryManager) protected MetadataService(IServerConfigurationManager serverConfigurationManager, ILogger<MetadataService<TItemType, TIdType>> logger, IProviderManager providerManager, IFileSystem fileSystem, ILibraryManager libraryManager)
{ {
ServerConfigurationManager = serverConfigurationManager; ServerConfigurationManager = serverConfigurationManager;
@ -110,7 +108,7 @@ namespace MediaBrowser.Providers.Manager
try try
{ {
// Always validate images and check for new locally stored ones. // Always validate images and check for new locally stored ones.
if (ImageProvider.ValidateImages(item, allImageProviders.OfType<ILocalImageProvider>(), refreshOptions.DirectoryService)) if (ImageProvider.ValidateImages(item, allImageProviders.OfType<ILocalImageProvider>(), refreshOptions))
{ {
updateType |= ItemUpdateType.ImageUpdate; updateType |= ItemUpdateType.ImageUpdate;
} }
@ -674,8 +672,7 @@ namespace MediaBrowser.Providers.Manager
} }
var hasLocalMetadata = false; var hasLocalMetadata = false;
var replaceImages = AllImageTypes.ToList(); var foundImageTypes = new List<ImageType>();
var localImagesFound = false;
foreach (var provider in providers.OfType<ILocalMetadataProvider<TItemType>>()) foreach (var provider in providers.OfType<ILocalMetadataProvider<TItemType>>())
{ {
@ -703,9 +700,8 @@ namespace MediaBrowser.Providers.Manager
await ProviderManager.SaveImage(item, remoteImage.Url, remoteImage.Type, null, cancellationToken).ConfigureAwait(false); await ProviderManager.SaveImage(item, remoteImage.Url, remoteImage.Type, null, cancellationToken).ConfigureAwait(false);
refreshResult.UpdateType |= ItemUpdateType.ImageUpdate; refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
// remove imagetype that has just been downloaded // remember imagetype that has just been downloaded
replaceImages.Remove(remoteImage.Type); foundImageTypes.Add(remoteImage.Type);
localImagesFound = true;
} }
catch (HttpRequestException ex) catch (HttpRequestException ex)
{ {
@ -713,13 +709,12 @@ namespace MediaBrowser.Providers.Manager
} }
} }
if (localImagesFound) if (foundImageTypes.Count > 0)
{ {
options.ReplaceAllImages = false; imageService.UpdateReplaceImages(options, foundImageTypes);
options.ReplaceImages = replaceImages;
} }
if (imageService.MergeImages(item, localItem.Images)) if (imageService.MergeImages(item, localItem.Images, options))
{ {
refreshResult.UpdateType |= ItemUpdateType.ImageUpdate; refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
} }

View file

@ -94,7 +94,7 @@ namespace Jellyfin.Providers.Tests.Manager
public void MergeImages_EmptyItemNewImagesEmpty_NoChange() public void MergeImages_EmptyItemNewImagesEmpty_NoChange()
{ {
var itemImageProvider = GetItemImageProvider(null, null); var itemImageProvider = GetItemImageProvider(null, null);
var changed = itemImageProvider.MergeImages(new Video(), Array.Empty<LocalImageInfo>()); var changed = itemImageProvider.MergeImages(new Video(), Array.Empty<LocalImageInfo>(), new ImageRefreshOptions(Mock.Of<IDirectoryService>()));
Assert.False(changed); Assert.False(changed);
} }
@ -108,7 +108,7 @@ namespace Jellyfin.Providers.Tests.Manager
var images = GetImages(imageType, imageCount, false); var images = GetImages(imageType, imageCount, false);
var itemImageProvider = GetItemImageProvider(null, null); var itemImageProvider = GetItemImageProvider(null, null);
var changed = itemImageProvider.MergeImages(item, images); var changed = itemImageProvider.MergeImages(item, images, new ImageRefreshOptions(Mock.Of<IDirectoryService>()));
Assert.True(changed); Assert.True(changed);
// adds for types that allow multiple, replaces singular type images // adds for types that allow multiple, replaces singular type images
@ -151,7 +151,7 @@ namespace Jellyfin.Providers.Tests.Manager
var images = GetImages(imageType, imageCount, true); var images = GetImages(imageType, imageCount, true);
var itemImageProvider = GetItemImageProvider(null, fileSystem); var itemImageProvider = GetItemImageProvider(null, fileSystem);
var changed = itemImageProvider.MergeImages(item, images); var changed = itemImageProvider.MergeImages(item, images, new ImageRefreshOptions(Mock.Of<IDirectoryService>()));
if (updateTime) if (updateTime)
{ {