Fix extras naming and version assignment

This commit is contained in:
Shadowghost
2026-07-27 11:48:15 +02:00
parent dbc796b0b0
commit 79a55327dc
9 changed files with 562 additions and 59 deletions
+74
View File
@@ -751,6 +751,80 @@ namespace MediaBrowser.Controller.Entities
.ToArray();
}
/// <inheritdoc />
protected override Guid[] GetOwnedVersionIds()
{
// Only the versions that live beside this one in the folder this scan covers. Linked
// versions are items of their own and maintain their extras themselves.
return [Id, .. LibraryManager.GetLocalAlternateVersionIds(this)];
}
/// <inheritdoc />
protected override Guid GetOwnerIdForExtra(BaseItem extra)
{
if (string.IsNullOrEmpty(extra.Path))
{
return Id;
}
var extraDirectory = System.IO.Path.GetDirectoryName(extra.Path.AsSpan());
var extraFileName = System.IO.Path.GetFileNameWithoutExtension(extra.Path.AsSpan());
var ownerId = Id;
var matchedLength = MatchedVersionNameLength(Path, extraDirectory, extraFileName);
foreach (var versionId in LibraryManager.GetLocalAlternateVersionIds(this))
{
var version = LibraryManager.GetItemById(versionId);
if (version is null)
{
continue;
}
// "Movie - [2160p]-trailer.mkv" belongs to "Movie - [2160p].mkv" rather than to the
// primary version, whose name it also starts with when the primary is plain "Movie.mkv"
var length = MatchedVersionNameLength(version.Path, extraDirectory, extraFileName);
if (length > matchedLength)
{
matchedLength = length;
ownerId = versionId;
}
}
return ownerId;
}
/// <summary>
/// Gets how much of an extra's file name is the name of the given version file, or 0 when the
/// extra is not named after it.
/// </summary>
/// <param name="versionPath">The path of the version.</param>
/// <param name="extraDirectory">The directory the extra lives in.</param>
/// <param name="extraFileName">The file name of the extra, without extension.</param>
/// <returns>The length of the match.</returns>
private static int MatchedVersionNameLength(string versionPath, ReadOnlySpan<char> extraDirectory, ReadOnlySpan<char> extraFileName)
{
if (string.IsNullOrEmpty(versionPath)
|| !System.IO.Path.GetDirectoryName(versionPath.AsSpan()).Equals(extraDirectory, StringComparison.OrdinalIgnoreCase))
{
return 0;
}
var versionFileName = System.IO.Path.GetFileNameWithoutExtension(versionPath.AsSpan());
if (versionFileName.IsEmpty || !extraFileName.StartsWith(versionFileName, StringComparison.OrdinalIgnoreCase))
{
return 0;
}
// The version name has to end where the extra's own name begins, so that a version
// named "Movie - 4K" does not claim the extras of "Movie - 4Kish"
var remainder = extraFileName[versionFileName.Length..];
return !remainder.IsEmpty && (remainder[0] == ' ' || Array.IndexOf(VersionDelimiters, remainder[0]) >= 0)
? versionFileName.Length
: 0;
}
protected override IEnumerable<(BaseItem Item, MediaSourceType MediaSourceType)> GetAllItemsForMediaSources()
{
var primary = PrimaryVersionId.HasValue