mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
Improve parsers
This commit is contained in:
parent
dd254eddac
commit
cd0592ea8f
@ -182,8 +182,7 @@ namespace Emby.Naming.Common
|
|||||||
|
|
||||||
CleanStrings = new[]
|
CleanStrings = new[]
|
||||||
{
|
{
|
||||||
@"[ _\,\.\(\)\[\]\-](HDR|HDC|UHD|UltraHD|4k|ac3|dts|custom|dc|divx|divx5|dsr|dsrip|dutch|dvd|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|cd[1-9]|r3|r5|bd5|se|svcd|swedish|german|read.nfo|nfofix|unrated|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|2160p|hrhd|hrhdtv|hddvd|bluray|x264|h264|xvid|xvidvd|xxx|www.www|\[.*\])([ _\,\.\(\)\[\]\-]|$)",
|
@"[ _\,\.\(\)\[\]\-](3d|sbs|tab|hsbs|htab|mvc|HDR|HDC|UHD|UltraHD|4k|ac3|dts|custom|dc|divx|divx5|dsr|dsrip|dutch|dvd|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|cd[1-9]|r3|r5|bd5|se|svcd|swedish|german|read.nfo|nfofix|unrated|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|2160p|hrhd|hrhdtv|hddvd|bluray|x264|h264|xvid|xvidvd|xxx|www.www|\[.*\])([ _\,\.\(\)\[\]\-]|$)",
|
||||||
@"[ _\,\.\(\)\[\]\-](3d|sbs|tab|hsbs|htab|mvc|\[.*\])([ _\,\.\(\)\[\]\-]|$)",
|
|
||||||
@"(\[.*\])"
|
@"(\[.*\])"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
#pragma warning disable SA1600
|
#pragma warning disable SA1600
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Emby.Naming.Common;
|
using Emby.Naming.Common;
|
||||||
|
|
||||||
@ -21,14 +21,28 @@ namespace Emby.Naming.Video
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CleanDateTimeResult Clean(string name)
|
public CleanDateTimeResult Clean(string name)
|
||||||
=> _options.CleanDateTimeRegexes.Select(i => Clean(name, i))
|
|
||||||
.FirstOrDefault(i => i.HasChanged) ??
|
|
||||||
new CleanDateTimeResult { Name = name };
|
|
||||||
|
|
||||||
private static CleanDateTimeResult Clean(string name, Regex expression)
|
|
||||||
{
|
{
|
||||||
var result = new CleanDateTimeResult();
|
var regexes = _options.CleanDateTimeRegexes;
|
||||||
|
var len = regexes.Length;
|
||||||
|
CleanDateTimeResult result = new CleanDateTimeResult(name);
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
if (TryClean(name, regexes[i], ref result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryClean(string name, Regex expression, ref CleanDateTimeResult result)
|
||||||
|
{
|
||||||
var match = expression.Match(name);
|
var match = expression.Match(name);
|
||||||
|
|
||||||
if (match.Success
|
if (match.Success
|
||||||
@ -37,13 +51,11 @@ namespace Emby.Naming.Video
|
|||||||
&& match.Groups[2].Success
|
&& match.Groups[2].Success
|
||||||
&& int.TryParse(match.Groups[2].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year))
|
&& int.TryParse(match.Groups[2].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year))
|
||||||
{
|
{
|
||||||
name = match.Groups[1].Value.TrimEnd();
|
result = new CleanDateTimeResult(match.Groups[1].Value.TrimEnd(), year);
|
||||||
result.Year = year;
|
return true;
|
||||||
result.HasChanged = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Name = name;
|
return false;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,33 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
#pragma warning disable SA1600
|
#pragma warning disable SA1600
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
namespace Emby.Naming.Video
|
namespace Emby.Naming.Video
|
||||||
{
|
{
|
||||||
public class CleanDateTimeResult
|
public readonly struct CleanDateTimeResult
|
||||||
{
|
{
|
||||||
|
public CleanDateTimeResult(string name, int? year)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Year = year;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CleanDateTimeResult(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Year = null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name.
|
/// Gets the name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The name.</value>
|
/// <value>The name.</value>
|
||||||
public string Name { get; set; }
|
public string Name { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the year.
|
/// Gets the year.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The year.</value>
|
/// <value>The year.</value>
|
||||||
public int? Year { get; set; }
|
public int? Year { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance has changed.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance has changed; otherwise, <c>false</c>.</value>
|
|
||||||
public bool HasChanged { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
#pragma warning disable SA1600
|
#pragma warning disable SA1600
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
@ -11,42 +13,33 @@ namespace Emby.Naming.Video
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class CleanStringParser
|
public static class CleanStringParser
|
||||||
{
|
{
|
||||||
public static CleanStringResult Clean(string name, IEnumerable<Regex> expressions)
|
public static bool TryClean(string name, IReadOnlyList<Regex> expressions, out ReadOnlySpan<char> newName)
|
||||||
{
|
{
|
||||||
var hasChanged = false;
|
var len = expressions.Count;
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
foreach (var exp in expressions)
|
|
||||||
{
|
{
|
||||||
var result = Clean(name, exp);
|
if (TryClean(name, expressions[i], out newName))
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(result.Name))
|
|
||||||
{
|
{
|
||||||
name = result.Name;
|
return true;
|
||||||
hasChanged = hasChanged || result.HasChanged;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CleanStringResult
|
newName = ReadOnlySpan<char>.Empty;
|
||||||
{
|
return false;
|
||||||
Name = name,
|
|
||||||
HasChanged = hasChanged
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CleanStringResult Clean(string name, Regex expression)
|
private static bool TryClean(string name, Regex expression, out ReadOnlySpan<char> newName)
|
||||||
{
|
{
|
||||||
var result = new CleanStringResult();
|
|
||||||
|
|
||||||
var match = expression.Match(name);
|
var match = expression.Match(name);
|
||||||
|
int index = match.Index;
|
||||||
if (match.Success)
|
if (match.Success && index != 0)
|
||||||
{
|
{
|
||||||
result.HasChanged = true;
|
newName = name.AsSpan().Slice(0, match.Index);
|
||||||
name = name.Substring(0, match.Index);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Name = name;
|
newName = string.Empty;
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
#pragma warning disable SA1600
|
|
||||||
|
|
||||||
namespace Emby.Naming.Video
|
|
||||||
{
|
|
||||||
public class CleanStringResult
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The name.</value>
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance has changed.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance has changed; otherwise, <c>false</c>.</value>
|
|
||||||
public bool HasChanged { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -94,9 +94,10 @@ namespace Emby.Naming.Video
|
|||||||
{
|
{
|
||||||
var cleanDateTimeResult = CleanDateTime(name);
|
var cleanDateTimeResult = CleanDateTime(name);
|
||||||
|
|
||||||
if (extraResult.ExtraType == null)
|
if (extraResult.ExtraType == null
|
||||||
|
&& TryCleanString(cleanDateTimeResult.Name, out ReadOnlySpan<char> newName))
|
||||||
{
|
{
|
||||||
name = CleanString(cleanDateTimeResult.Name).Name;
|
name = newName.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
year = cleanDateTimeResult.Year;
|
year = cleanDateTimeResult.Year;
|
||||||
@ -130,9 +131,9 @@ namespace Emby.Naming.Video
|
|||||||
return _options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
|
return _options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CleanStringResult CleanString(string name)
|
public bool TryCleanString(string name, out ReadOnlySpan<char> newName)
|
||||||
{
|
{
|
||||||
return CleanStringParser.Clean(name, _options.CleanStringRegexes);
|
return CleanStringParser.TryClean(name, _options.CleanStringRegexes, out newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CleanDateTimeResult CleanDateTime(string name)
|
public CleanDateTimeResult CleanDateTime(string name)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Emby.Naming.Common;
|
using System;
|
||||||
|
using Emby.Naming.Common;
|
||||||
using Emby.Naming.Video;
|
using Emby.Naming.Video;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -30,8 +31,15 @@ namespace Jellyfin.Naming.Tests.Video
|
|||||||
// FIXME: [InlineData("After The Sunset - [0004].mkv", "After The Sunset")]
|
// FIXME: [InlineData("After The Sunset - [0004].mkv", "After The Sunset")]
|
||||||
public void CleanStringTest(string input, string expectedName)
|
public void CleanStringTest(string input, string expectedName)
|
||||||
{
|
{
|
||||||
var result = new VideoResolver(_namingOptions).CleanString(input);
|
if (new VideoResolver(_namingOptions).TryCleanString(input, out ReadOnlySpan<char> newName))
|
||||||
Assert.Equal(expectedName, result.Name);
|
{
|
||||||
|
// TODO: compare spans when XUnit supports it
|
||||||
|
Assert.Equal(expectedName, newName.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal(expectedName, input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user