From 090b610eb131eb416ce3e4527dc9b568bf130c14 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sun, 23 Aug 2026 09:27:26 +0200 Subject: Fix person metadata not being fetched on demand or by the people task --- Jellyfin.Api/Controllers/UserLibraryController.cs | 37 +++++++++++++++-------- MediaBrowser.Providers/Manager/MetadataService.cs | 5 ++- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs index ea134a4619..da03032249 100644 --- a/Jellyfin.Api/Controllers/UserLibraryController.cs +++ b/Jellyfin.Api/Controllers/UserLibraryController.cs @@ -34,6 +34,8 @@ namespace Jellyfin.Api.Controllers; [Tags("Library")] public class UserLibraryController : BaseJellyfinApiController { + private static readonly TimeSpan RefreshOnDemandTimeout = TimeSpan.FromSeconds(3); + private readonly IUserManager _userManager; private readonly IUserDataManager _userDataRepository; private readonly ILibraryManager _libraryManager; @@ -79,7 +81,7 @@ public class UserLibraryController : BaseJellyfinApiController /// An containing the item. [HttpGet("Items/{itemId}")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetItem( + public async Task> GetItem( [FromQuery] Guid? userId, [FromRoute, Required] Guid itemId) { @@ -98,7 +100,7 @@ public class UserLibraryController : BaseJellyfinApiController return NotFound(); } - QueueRefreshOnDemandIfNeeded(item); + await RefreshOnDemandIfNeeded(item).ConfigureAwait(false); var dtoOptions = new DtoOptions(); @@ -116,7 +118,7 @@ public class UserLibraryController : BaseJellyfinApiController [ProducesResponseType(StatusCodes.Status200OK)] [Obsolete("Kept for backwards compatibility")] [ApiExplorerSettings(IgnoreApi = true)] - public ActionResult GetItemLegacy( + public Task> GetItemLegacy( [FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId) => GetItem(userId, itemId); @@ -643,7 +645,7 @@ public class UserLibraryController : BaseJellyfinApiController limit, groupItems); - private void QueueRefreshOnDemandIfNeeded(BaseItem item) + private async Task RefreshOnDemandIfNeeded(BaseItem item) { if (item is not Person) { @@ -656,15 +658,24 @@ public class UserLibraryController : BaseJellyfinApiController return; } - _providerManager.QueueRefresh( - item.Id, - new MetadataRefreshOptions(new DirectoryService(_fileSystem)) - { - MetadataRefreshMode = MetadataRefreshMode.FullRefresh, - ImageRefreshMode = MetadataRefreshMode.FullRefresh, - ForceSave = true - }, - RefreshPriority.High); + var options = new MetadataRefreshOptions(new DirectoryService(_fileSystem)) + { + MetadataRefreshMode = MetadataRefreshMode.FullRefresh, + ImageRefreshMode = MetadataRefreshMode.FullRefresh, + ForceSave = true + }; + + using var timeout = CancellationTokenSource.CreateLinkedTokenSource(HttpContext.RequestAborted); + timeout.CancelAfter(RefreshOnDemandTimeout); + + try + { + await item.RefreshMetadata(options, timeout.Token).ConfigureAwait(false); + } + catch (OperationCanceledException) when (!HttpContext.RequestAborted.IsCancellationRequested) + { + _providerManager.QueueRefresh(item.Id, options, RefreshPriority.High); + } } /// diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index d11db8f531..1b43bc23fa 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -209,7 +209,10 @@ namespace MediaBrowser.Providers.Manager } } - if (hasRefreshedMetadata && hasRefreshedImages) + var attemptedFetch = refreshOptions.MetadataRefreshMode > MetadataRefreshMode.ValidationOnly + || refreshOptions.ImageRefreshMode > MetadataRefreshMode.ValidationOnly; + + if (hasRefreshedMetadata && hasRefreshedImages && attemptedFetch) { item.DateLastRefreshed = DateTime.UtcNow; updateType |= item.OnMetadataChanged(); -- cgit v1.2.3