Don't read episode markers in episode titles as a multi-episode range
This commit is contained in:
@@ -158,7 +158,9 @@ namespace Emby.Naming.TV
|
||||
if (nextIndex >= name.Length
|
||||
|| !"0123456789iIpP".Contains(name[nextIndex], StringComparison.Ordinal))
|
||||
{
|
||||
if (int.TryParse(endingNumberGroup.ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out num))
|
||||
// A range cannot end before it starts, so a lower number belongs to the episode title rather than to a range.
|
||||
if (int.TryParse(endingNumberGroup.ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out num)
|
||||
&& num >= result.EpisodeNumber)
|
||||
{
|
||||
result.EndingEpisodeNumber = num;
|
||||
}
|
||||
@@ -226,7 +228,7 @@ namespace Emby.Naming.TV
|
||||
info.SeriesName = result.SeriesName;
|
||||
}
|
||||
|
||||
if (!info.EndingEpisodeNumber.HasValue && info.EpisodeNumber.HasValue)
|
||||
if (!info.EndingEpisodeNumber.HasValue && result.EndingEpisodeNumber >= info.EpisodeNumber)
|
||||
{
|
||||
info.EndingEpisodeNumber = result.EndingEpisodeNumber;
|
||||
}
|
||||
|
||||
@@ -44,18 +44,16 @@ public class EpisodeMetadataService : MetadataService<Episode, EpisodeInfo>
|
||||
{
|
||||
var updatedType = base.BeforeSaveInternal(item, isFullRefresh, updateType);
|
||||
|
||||
// An episode cannot end before it starts. Providers and nfo files occasionally report the range
|
||||
// transposed, which makes clients render the episode number backwards. Both numbers describe the
|
||||
// same set of episodes either way, so restore their order instead of dropping the range.
|
||||
if (item.IndexNumber.HasValue && item.IndexNumberEnd < item.IndexNumber)
|
||||
// An episode cannot end before it starts.
|
||||
if (item.IndexNumberEnd < item.IndexNumber)
|
||||
{
|
||||
Logger.LogWarning(
|
||||
"Correcting reversed episode range {IndexNumber}-{IndexNumberEnd} for {Path}",
|
||||
item.IndexNumber,
|
||||
"Discarding episode range end {IndexNumberEnd} preceding episode number {IndexNumber} for {Path}",
|
||||
item.IndexNumberEnd,
|
||||
item.IndexNumber,
|
||||
item.Path);
|
||||
|
||||
(item.IndexNumber, item.IndexNumberEnd) = (item.IndexNumberEnd, item.IndexNumber);
|
||||
item.IndexNumberEnd = null;
|
||||
updatedType |= ItemUpdateType.MetadataImport;
|
||||
}
|
||||
else if (item.IndexNumberEnd.HasValue && !item.IndexNumber.HasValue)
|
||||
|
||||
@@ -74,6 +74,9 @@ namespace Jellyfin.Naming.Tests.TV
|
||||
[InlineData("Season 5/S05E23 11-59 [HDTV-1080p][x265 AC3].mkv", null)]
|
||||
[InlineData("Season 5/S05E23 11-59 [HDTV-1080p][HEVC AC3].mkv", null)]
|
||||
[InlineData("Season 1/S01E01 1-23-45 [Bluray-1080p][AV1 Opus].mkv", null)]
|
||||
// Episode markers in the episode title must not be read as an episode range
|
||||
[InlineData("Season 03/Star Trek Enterprise (2001) - S03E21 - E2 (1080p BluRay x265).mkv", null)]
|
||||
[InlineData("Season 02/Series Name (2001) - S02E10 - E5 [WEBRip-1080p].mkv", null)]
|
||||
public void TestGetEndingEpisodeNumberFromFile(string filename, int? endingEpisodeNumber)
|
||||
{
|
||||
var result = _episodePathParser.Parse(filename, false);
|
||||
|
||||
@@ -104,9 +104,10 @@ public sealed class EpisodeMetadataServiceTests : IDisposable
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(2, 1)] // e.g. an nfo with its episodedetails blocks in descending order
|
||||
[InlineData(2, 1)]
|
||||
[InlineData(22, 21)]
|
||||
public void BeforeSave_ReversedEpisodeRange_RestoresOrder(int indexNumber, int indexNumberEnd)
|
||||
[InlineData(21, 2)] // e.g. "Series - S03E21 - E2 (1080p BluRay x265).mkv", where "E2" is the episode title
|
||||
public void BeforeSave_ReversedEpisodeRange_ClearsIndexNumberEnd(int indexNumber, int indexNumberEnd)
|
||||
{
|
||||
var item = new Episode
|
||||
{
|
||||
@@ -116,9 +117,9 @@ public sealed class EpisodeMetadataServiceTests : IDisposable
|
||||
|
||||
var updateType = _service.BeforeSave(item);
|
||||
|
||||
// The range still covers the same episodes, it is just no longer transposed
|
||||
Assert.Equal(indexNumberEnd, item.IndexNumber);
|
||||
Assert.Equal(indexNumber, item.IndexNumberEnd);
|
||||
// The episode number identifies the item, so it is kept and the impossible range is dropped
|
||||
Assert.Equal(indexNumber, item.IndexNumber);
|
||||
Assert.Null(item.IndexNumberEnd);
|
||||
Assert.True(updateType.HasFlag(ItemUpdateType.MetadataImport));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user