|
@@ -10,12 +10,17 @@ namespace Emby.Naming.TV
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
public static partial class SeasonPathParser
|
|
public static partial class SeasonPathParser
|
|
|
{
|
|
{
|
|
|
|
|
+ private static readonly Regex CleanNameRegex = new(@"[ ._\-\[\]]", RegexOptions.Compiled);
|
|
|
|
|
+
|
|
|
[GeneratedRegex(@"^\s*((?<seasonnumber>(?>\d+))(?:st|nd|rd|th|\.)*(?!\s*[Ee]\d+))\s*(?:[[시즌]*|[シーズン]*|[sS](?:eason|æson|aison|taffel|eries|tagione|äsong|eizoen|easong|ezon|ezona|ezóna|ezonul)*|[tT](?:emporada)*|[kK](?:ausi)*|[Сс](?:езон)*)\s*(?<rightpart>.*)$", RegexOptions.IgnoreCase)]
|
|
[GeneratedRegex(@"^\s*((?<seasonnumber>(?>\d+))(?:st|nd|rd|th|\.)*(?!\s*[Ee]\d+))\s*(?:[[시즌]*|[シーズン]*|[sS](?:eason|æson|aison|taffel|eries|tagione|äsong|eizoen|easong|ezon|ezona|ezóna|ezonul)*|[tT](?:emporada)*|[kK](?:ausi)*|[Сс](?:езон)*)\s*(?<rightpart>.*)$", RegexOptions.IgnoreCase)]
|
|
|
private static partial Regex ProcessPre();
|
|
private static partial Regex ProcessPre();
|
|
|
|
|
|
|
|
- [GeneratedRegex(@"^\s*(?:[[시즌]*|[シーズン]*|[sS](?:eason|æson|aison|taffel|eries|tagione|äsong|eizoen|easong|ezon|ezona|ezóna|ezonul)*|[tT](?:emporada)*|[kK](?:ausi)*|[Сс](?:езон)*)\s*(?<seasonnumber>(?>\d+)(?!\s*[Ee]\d+))(?<rightpart>.*)$", RegexOptions.IgnoreCase)]
|
|
|
|
|
|
|
+ [GeneratedRegex(@"^\s*(?:[[시즌]*|[シーズン]*|[sS](?:eason|æson|aison|taffel|eries|tagione|äsong|eizoen|easong|ezon|ezona|ezóna|ezonul)*|[tT](?:emporada)*|[kK](?:ausi)*|[Сс](?:езон)*)\s*(?<seasonnumber>\d+?)(?=\d{3,4}p|[^\d]|$)(?!\s*[Ee]\d)(?<rightpart>.*)$", RegexOptions.IgnoreCase)]
|
|
|
private static partial Regex ProcessPost();
|
|
private static partial Regex ProcessPost();
|
|
|
|
|
|
|
|
|
|
+ [GeneratedRegex(@"[sS](\d{1,4})(?!\d|[eE]\d)(?=\.|_|-|\[|\]|\s|$)", RegexOptions.None)]
|
|
|
|
|
+ private static partial Regex SeasonPrefix();
|
|
|
|
|
+
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// Attempts to parse season number from path.
|
|
/// Attempts to parse season number from path.
|
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -56,44 +61,34 @@ namespace Emby.Naming.TV
|
|
|
bool supportSpecialAliases,
|
|
bool supportSpecialAliases,
|
|
|
bool supportNumericSeasonFolders)
|
|
bool supportNumericSeasonFolders)
|
|
|
{
|
|
{
|
|
|
- string filename = Path.GetFileName(path);
|
|
|
|
|
- filename = Regex.Replace(filename, "[ ._-]", string.Empty);
|
|
|
|
|
|
|
+ var fileName = Path.GetFileName(path);
|
|
|
|
|
|
|
|
- if (parentFolderName is not null)
|
|
|
|
|
|
|
+ var seasonPrefixMatch = SeasonPrefix().Match(fileName);
|
|
|
|
|
+ if (seasonPrefixMatch.Success &&
|
|
|
|
|
+ int.TryParse(seasonPrefixMatch.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val))
|
|
|
{
|
|
{
|
|
|
- parentFolderName = Regex.Replace(parentFolderName, "[ ._-]", string.Empty);
|
|
|
|
|
- filename = filename.Replace(parentFolderName, string.Empty, StringComparison.OrdinalIgnoreCase);
|
|
|
|
|
|
|
+ return (val, true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (supportSpecialAliases)
|
|
|
|
|
- {
|
|
|
|
|
- if (string.Equals(filename, "specials", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
- {
|
|
|
|
|
- return (0, true);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ string filename = CleanNameRegex.Replace(fileName, string.Empty);
|
|
|
|
|
|
|
|
- if (string.Equals(filename, "extras", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
- {
|
|
|
|
|
- return (0, true);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (parentFolderName is not null)
|
|
|
|
|
+ {
|
|
|
|
|
+ var cleanParent = CleanNameRegex.Replace(parentFolderName, string.Empty);
|
|
|
|
|
+ filename = filename.Replace(cleanParent, string.Empty, StringComparison.OrdinalIgnoreCase);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (supportNumericSeasonFolders)
|
|
|
|
|
|
|
+ if (supportSpecialAliases &&
|
|
|
|
|
+ (filename.Equals("specials", StringComparison.OrdinalIgnoreCase) ||
|
|
|
|
|
+ filename.Equals("extras", StringComparison.OrdinalIgnoreCase)))
|
|
|
{
|
|
{
|
|
|
- if (int.TryParse(filename, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val))
|
|
|
|
|
- {
|
|
|
|
|
- return (val, true);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return (0, true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (filename.Length > 0 && (filename[0] == 'S' || filename[0] == 's'))
|
|
|
|
|
|
|
+ if (supportNumericSeasonFolders &&
|
|
|
|
|
+ int.TryParse(filename, NumberStyles.Integer, CultureInfo.InvariantCulture, out val))
|
|
|
{
|
|
{
|
|
|
- var testFilename = filename.AsSpan()[1..];
|
|
|
|
|
-
|
|
|
|
|
- if (int.TryParse(testFilename, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val))
|
|
|
|
|
- {
|
|
|
|
|
- return (val, true);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return (val, true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
var preMatch = ProcessPre().Match(filename);
|
|
var preMatch = ProcessPre().Match(filename);
|