diff options
| author | Shadowghost <Ghost_of_Stone@web.de> | 2026-02-08 17:22:52 +0100 |
|---|---|---|
| committer | Shadowghost <Ghost_of_Stone@web.de> | 2026-02-08 17:22:52 +0100 |
| commit | 71594b4a9a1fa91fbb03e6e8f79090465619bd9c (patch) | |
| tree | bec80f2a36a1fd3840df150ee5064af015316163 /MediaBrowser.Controller/Entities | |
| parent | bb6c3b4eecee46a0a6222ffe17657cabc7da97f4 (diff) | |
Fix multiple version resolution
Diffstat (limited to 'MediaBrowser.Controller/Entities')
| -rw-r--r-- | MediaBrowser.Controller/Entities/Movies/Movie.cs | 52 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Video.cs | 70 |
2 files changed, 34 insertions, 88 deletions
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 8f06d18d63..e8817a29cf 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -85,58 +85,6 @@ namespace MediaBrowser.Controller.Entities.Movies return info; } - protected override async Task RefreshMetadataForVersions(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken) - { - var newOptions = new MetadataRefreshOptions(options) - { - SearchResult = null - }; - - var id = LibraryManager.GetNewItemId(path, typeof(Movie)); - - // Check if the file still exists - if (!FileSystem.FileExists(path)) - { - // File was removed - clean up any orphaned database entry - if (LibraryManager.GetItemById(id) is Movie orphanedMovie && orphanedMovie.OwnerId.Equals(Id)) - { - Logger.LogInformation("Alternate version file no longer exists, removing orphaned item: {Path}", path); - LibraryManager.DeleteItem(orphanedMovie, new DeleteOptions { DeleteFileLocation = false }); - } - - return; - } - - if (LibraryManager.GetItemById(id) is not Movie movie) - { - // Pass parent and collectionType so the resolver creates a Movie - // instead of a generic Video - var parentFolder = GetParent() as Folder; - var collectionType = GetParents().OfType<ICollectionFolder>().FirstOrDefault()?.CollectionType; - movie = LibraryManager.ResolvePath( - FileSystem.GetFileSystemInfo(path), - parentFolder, - collectionType: collectionType) as Movie; - - newOptions.ForceSave = true; - } - - if (movie is null) - { - return; - } - - if (movie.OwnerId.Equals(Guid.Empty)) - { - movie.OwnerId = Id; - } - - await RefreshMetadataForOwnedItem(movie, copyTitleMetadata, newOptions, cancellationToken).ConfigureAwait(false); - - // Create LinkedChild entry for this local alternate version - LibraryManager.UpsertLinkedChild(Id, movie.Id, LinkedChildType.LocalAlternateVersion); - } - /// <inheritdoc /> public override bool BeforeMetadataRefresh(bool replaceAllMetadata) { diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index e06875b64c..02b3b31d3b 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -453,38 +453,45 @@ namespace MediaBrowser.Controller.Entities // The additional parts won't have additional parts themselves if (IsFileProtocol && SupportsOwnedItems) { - if (!IsStacked) - { - RefreshLinkedAlternateVersions(); - - if (LocalAlternateVersions.Length > 0) - { - // Check if LinkedChildren are in sync before processing - var existingLinkCount = LibraryManager.GetLocalAlternateVersionIds(this).Count(); - var tasks = LocalAlternateVersions - .Select(i => RefreshMetadataForVersions(options, false, i, cancellationToken)); + // Check if LinkedChildren are in sync before processing + var existingVersionCount = LibraryManager.GetLocalAlternateVersionIds(this).Count(); + var tasks = LocalAlternateVersions + .Select(i => RefreshMetadataForVersions(options, false, i, cancellationToken)); - await Task.WhenAll(tasks).ConfigureAwait(false); + await Task.WhenAll(tasks).ConfigureAwait(false); - if (existingLinkCount != LocalAlternateVersions.Length) - { - hasChanges = true; - } - } + if (existingVersionCount != LocalAlternateVersions.Length) + { + hasChanges = true; } } return hasChanges; } - protected virtual async Task RefreshMetadataForVersions(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken) + private async Task RefreshMetadataForVersions(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken) { + // Ensure the alternate version exists with the correct type (e.g. Movie, not Video) + // before refreshing. This must happen here rather than in RefreshMetadataForOwnedVideo + // because that method is also used for stacked parts which should keep their resolved type. + var id = LibraryManager.GetNewItemId(path, GetType()); + if (LibraryManager.GetItemById(id) is not Video && FileSystem.FileExists(path)) + { + var parentFolder = GetParent() as Folder; + var collectionType = LibraryManager.GetContentType(this); + var altVideo = LibraryManager.ResolveAlternateVersion(path, GetType(), parentFolder, collectionType); + if (altVideo is not null) + { + altVideo.OwnerId = Id; + LibraryManager.CreateItem(altVideo, GetParent()); + } + } + await RefreshMetadataForOwnedVideo(options, copyTitleMetadata, path, cancellationToken).ConfigureAwait(false); // Create LinkedChild entry for this local alternate version // This ensures the relationship exists in the database even if the alternate version // was created after the primary video was first saved - var id = LibraryManager.GetNewItemId(path, GetType()); if (LibraryManager.GetItemById(id) is Video video) { LibraryManager.UpsertLinkedChild(Id, video.Id, LinkedChildType.LocalAlternateVersion); @@ -516,18 +523,21 @@ namespace MediaBrowser.Controller.Entities if (LibraryManager.GetItemById(id) is not Video video) { var parentFolder = GetParent() as Folder; - var collectionType = GetParents().OfType<ICollectionFolder>().FirstOrDefault()?.CollectionType; + var collectionType = LibraryManager.GetContentType(this); video = LibraryManager.ResolvePath( FileSystem.GetFileSystemInfo(path), parentFolder, collectionType: collectionType) as Video; - newOptions.ForceSave = true; - } + if (video is null) + { + return; + } - if (video is null) - { - return; + video.Id = id; + video.OwnerId = Id; + LibraryManager.CreateItem(video, parentFolder); + newOptions.ForceSave = true; } if (video.OwnerId.IsEmpty()) @@ -538,18 +548,6 @@ namespace MediaBrowser.Controller.Entities await RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, cancellationToken).ConfigureAwait(false); } - private void RefreshLinkedAlternateVersions() - { - foreach (var child in LinkedAlternateVersions) - { - // Reset the cached value - if (child.ItemId.IsNullOrEmpty()) - { - child.ItemId = null; - } - } - } - /// <inheritdoc /> public override async Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken) { |
