mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-10-26 16:45:09 +00:00
Merge pull request #17931 from Shadowghost/fix-version-decimal
Fix decimal point handling in version names
This commit is contained in:
2 files changed
+61
-3
No files matched your search
@@ -1411,7 +1411,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// token shared by the descriptors but separated only by spaces (e.g. a common "2160p ") is
|
||||
/// kept in the label, falling back to a space only when no structural delimiter is shared. The
|
||||
/// separators mirror the version delimiters recognised by the naming layer (Emby.Naming
|
||||
/// VideoFlagDelimiters).
|
||||
/// VideoFlagDelimiters), except that a dot between digits is a decimal point rather than a
|
||||
/// delimiter, so numeric version labels stay whole.
|
||||
/// </summary>
|
||||
/// <param name="fileNames">The version file names without extension; must contain at least one entry.</param>
|
||||
/// <returns>The shared prefix retreated to a separator boundary, or an empty string when none is shared.</returns>
|
||||
@@ -1445,9 +1446,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
if (!prefixIsWholeName)
|
||||
{
|
||||
// Retreat to the last structural delimiter ('-', '_', '.').
|
||||
// Retreat to the last structural delimiter ('-', '_', '.'), skipping dots that are
|
||||
// decimal points within a number rather than delimiters (see IsDecimalPoint).
|
||||
var cut = prefix.Length;
|
||||
while (cut > 0 && Array.IndexOf(VersionDelimiters, prefix[cut - 1]) < 0)
|
||||
while (cut > 0
|
||||
&& (Array.IndexOf(VersionDelimiters, prefix[cut - 1]) < 0
|
||||
|| IsDecimalPoint(prefix, cut - 1, fileNames)))
|
||||
{
|
||||
cut--;
|
||||
}
|
||||
@@ -1467,6 +1471,31 @@ namespace MediaBrowser.Controller.Entities
|
||||
return prefix;
|
||||
}
|
||||
|
||||
private static bool IsDecimalPoint(string prefix, int index, IReadOnlyList<string> fileNames)
|
||||
{
|
||||
if (index == 0 || prefix[index] != '.' || !char.IsDigit(prefix[index - 1]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index + 1 < prefix.Length)
|
||||
{
|
||||
return char.IsDigit(prefix[index + 1]);
|
||||
}
|
||||
|
||||
// The dot ends the prefix, so the character after it is the first one that differs between
|
||||
// the versions: only a decimal point when every version continues the number.
|
||||
for (var i = 0; i < fileNames.Count; i++)
|
||||
{
|
||||
if (fileNames[i].Length <= index + 1 || !char.IsDigit(fileNames[i][index + 1]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Task RefreshMetadata(CancellationToken cancellationToken)
|
||||
{
|
||||
return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken);
|
||||
|
||||
@@ -185,6 +185,17 @@ public class BaseItemTests
|
||||
"Blade Runner (1982) [EE by ADM] [480p HEVC AAC]",
|
||||
"[Final Cut] [1080p HEVC AAC]",
|
||||
"[EE by ADM] [480p HEVC AAC]")]
|
||||
// Numeric version labels: the dot between the digits is a decimal point, not a delimiter, so the
|
||||
// prefix retreats past it to the '-' instead of leaving "0" / "11".
|
||||
[InlineData(
|
||||
"Evangelion 1.0 You Are (Not) Alone (2007) - 1.0",
|
||||
"Evangelion 1.0 You Are (Not) Alone (2007) - 1.11",
|
||||
"1.0",
|
||||
"1.11")]
|
||||
// Numeric labels with no structural delimiter at all fall back to the space boundary.
|
||||
[InlineData("Movie (2007) 1.0", "Movie (2007) 1.11", "1.0", "1.11")]
|
||||
// A dot followed by a non-digit is still a delimiter, even after a digit.
|
||||
[InlineData("Movie - Part 1.HDR", "Movie - Part 1.SDR", "HDR", "SDR")]
|
||||
public void GetMediaSourceName_CommonPrefix_Valid(string primaryName, string altName, string expectedPrimary, string expectedAlt)
|
||||
{
|
||||
var primaryPath = "/Shows/Demo/Season 01/" + primaryName + ".mkv";
|
||||
@@ -215,6 +226,24 @@ public class BaseItemTests
|
||||
Assert.Equal(expectedAlt, videoAlt.GetMediaSourceName(videoAlt, commonPrefix));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCommonVersionPrefix_NumericLabels_KeepsWholeNumber()
|
||||
{
|
||||
// Three versions labelled "1.0", "1.01" and "1.11": the common prefix stops inside the version
|
||||
// number, so it must retreat past the decimal point to the '-' delimiter.
|
||||
string[] fileNames =
|
||||
[
|
||||
"Evangelion 1.0 You Are (Not) Alone (2007) - 1.0",
|
||||
"Evangelion 1.0 You Are (Not) Alone (2007) - 1.01",
|
||||
"Evangelion 1.0 You Are (Not) Alone (2007) - 1.11"
|
||||
];
|
||||
|
||||
var prefix = BaseItem.GetCommonVersionPrefix(fileNames);
|
||||
|
||||
Assert.Equal("Evangelion 1.0 You Are (Not) Alone (2007) -", prefix);
|
||||
Assert.Equal(["1.0", "1.01", "1.11"], fileNames.Select(n => n[prefix.Length..].TrimStart(' ')));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetAlternateVersion_ReturnsMatchingLocalVersion()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user