aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-02-05 00:17:44 +0100
committerShadowghost <Ghost_of_Stone@web.de>2026-02-05 01:41:07 +0100
commita0346fe5b70a434860f973086be176ecc2018a52 (patch)
tree9e005d17c7d7712ccf65527fae7c009ef5d0967c /MediaBrowser.Controller/Entities
parentaedd2b04a2687adfcc52db96aa3fb7b2ad94fdcc (diff)
Fix multiple version handling
Diffstat (limited to 'MediaBrowser.Controller/Entities')
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs11
-rw-r--r--MediaBrowser.Controller/Entities/Movies/Movie.cs19
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs33
3 files changed, 59 insertions, 4 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index f1c1555842..3f04b1ffae 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -1430,10 +1430,15 @@ namespace MediaBrowser.Controller.Entities
});
foreach (var removedExtra in removedExtras)
{
- LibraryManager.DeleteItem(removedExtra, new DeleteOptions()
+ // Only delete items that are actual extras (have ExtraType set)
+ // Items with OwnerId but no ExtraType might be alternate versions, not extras
+ if (removedExtra.ExtraType.HasValue)
{
- DeleteFileLocation = false
- });
+ LibraryManager.DeleteItem(removedExtra, new DeleteOptions()
+ {
+ DeleteFileLocation = false
+ });
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 797f44e2d5..5ab149a49d 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -9,8 +9,10 @@ using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
+using Microsoft.Extensions.Logging;
namespace MediaBrowser.Controller.Entities.Movies
{
@@ -91,6 +93,20 @@ namespace MediaBrowser.Controller.Entities.Movies
};
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)
{
movie = LibraryManager.ResolvePath(FileSystem.GetFileSystemInfo(path)) as Movie;
@@ -109,6 +125,9 @@ namespace MediaBrowser.Controller.Entities.Movies
}
await RefreshMetadataForOwnedItem(movie, copyTitleMetadata, newOptions, cancellationToken).ConfigureAwait(false);
+
+ // Create LinkedChild entry for this local alternate version
+ LibraryManager.UpsertLinkedChild(Id, movie.Id, LinkedChildType.LocalAlternateVersion);
}
/// <inheritdoc />
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 1ddc193359..21aa50b49d 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -19,6 +19,7 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
+using Microsoft.Extensions.Logging;
namespace MediaBrowser.Controller.Entities
{
@@ -428,6 +429,17 @@ namespace MediaBrowser.Controller.Entities
{
var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
+ // Clean up LocalAlternateVersions - remove paths that no longer exist
+ if (LocalAlternateVersions.Length > 0)
+ {
+ var validPaths = LocalAlternateVersions.Where(FileSystem.FileExists).ToArray();
+ if (validPaths.Length != LocalAlternateVersions.Length)
+ {
+ LocalAlternateVersions = validPaths;
+ hasChanges = true;
+ }
+ }
+
if (IsStacked)
{
var tasks = AdditionalParts
@@ -467,7 +479,21 @@ namespace MediaBrowser.Controller.Entities
SearchResult = null
};
- var id = LibraryManager.GetNewItemId(path, typeof(Video));
+ var id = LibraryManager.GetNewItemId(path, GetType());
+
+ // Check if the file still exists
+ if (!FileSystem.FileExists(path))
+ {
+ // File was removed - clean up any orphaned database entry
+ if (LibraryManager.GetItemById(id) is Video orphanedVideo && orphanedVideo.OwnerId.Equals(Id))
+ {
+ Logger.LogInformation("Owned video file no longer exists, removing orphaned item: {Path}", path);
+ LibraryManager.DeleteItem(orphanedVideo, new DeleteOptions { DeleteFileLocation = false });
+ }
+
+ return;
+ }
+
if (LibraryManager.GetItemById(id) is not Video video)
{
video = LibraryManager.ResolvePath(FileSystem.GetFileSystemInfo(path)) as Video;
@@ -486,6 +512,11 @@ namespace MediaBrowser.Controller.Entities
}
await RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, 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
+ LibraryManager.UpsertLinkedChild(Id, video.Id, LinkedChildType.LocalAlternateVersion);
}
private void RefreshLinkedAlternateVersions()