Inject show name for bare-number episode filenames
Previously, only S01E01-style episode codes triggered show-name injection from the folder name. Plain numbered filenames (e.g. "11 - Title.mkv") with a release tag sourced only from the folder (e.g. "[DmonHiro] Digimon Tamers (BD, 1080p)") were left untouched apart from the tag prefix. Also fixes ExtractShowName to strip trailing parenthetical metadata blocks like "(BD, 1080p)", which previously leaked into the derived show name.
This commit is contained in:
+2
-2
@@ -9,8 +9,8 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<AssemblyName>Futonizer</AssemblyName>
|
<AssemblyName>Futonizer</AssemblyName>
|
||||||
<RootNamespace>Futonizer</RootNamespace>
|
<RootNamespace>Futonizer</RootNamespace>
|
||||||
<Version>1.0.13</Version>
|
<Version>1.0.14</Version>
|
||||||
<FileVersion>1.0.13.0</FileVersion>
|
<FileVersion>1.0.14.0</FileVersion>
|
||||||
<ApplicationIcon>Assets\app.ico</ApplicationIcon>
|
<ApplicationIcon>Assets\app.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,14 @@ public static class FileNameHelper
|
|||||||
private static readonly Regex EpisodeStartRegex =
|
private static readonly Regex EpisodeStartRegex =
|
||||||
new(@"^(\d+|S\d+E\d+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
new(@"^(\d+|S\d+E\d+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
|
// Bare leading episode number with no tag of its own on the file (the
|
||||||
|
// release tag, if any, comes only from the folder), e.g. "11 - Title.mkv",
|
||||||
|
// "06_Title.mkv", "06.Title.mkv". Requires a separator right after the
|
||||||
|
// digits so resolution/quality tokens glued to more characters (e.g.
|
||||||
|
// "1080p") aren't mistaken for an episode number lead-in.
|
||||||
|
private static readonly Regex BareLeadingEpisodeNumberRegex =
|
||||||
|
new(@"^\d{1,3}(?=[\s._-])", RegexOptions.Compiled);
|
||||||
|
|
||||||
// Individual metadata-token patterns used to find where the show name ends
|
// Individual metadata-token patterns used to find where the show name ends
|
||||||
// inside a folder name.
|
// inside a folder name.
|
||||||
private static readonly Regex[] MetadataPatterns =
|
private static readonly Regex[] MetadataPatterns =
|
||||||
@@ -104,8 +112,9 @@ public static class FileNameHelper
|
|||||||
/// stripped and promoted to a bracket prefix. Takes priority over
|
/// stripped and promoted to a bracket prefix. Takes priority over
|
||||||
/// any folder-derived tag.</item>
|
/// any folder-derived tag.</item>
|
||||||
/// <item>Show-name injection — if the (now tag-free) filename starts with
|
/// <item>Show-name injection — if the (now tag-free) filename starts with
|
||||||
/// an episode code (e.g. S01E01) the show name is derived from the
|
/// an episode code (e.g. S01E01), or with a bare episode number
|
||||||
/// parent folder and prepended.</item>
|
/// (e.g. "11 - Title") once a release tag has been resolved, the
|
||||||
|
/// show name is derived from the parent folder and prepended.</item>
|
||||||
/// <item>Release-tag prefix — a <c>[TAG]</c> bracket prefix, sourced from
|
/// <item>Release-tag prefix — a <c>[TAG]</c> bracket prefix, sourced from
|
||||||
/// the filename suffix, the folder suffix, or the folder prefix,
|
/// the filename suffix, the folder suffix, or the folder prefix,
|
||||||
/// in that priority order.</item>
|
/// in that priority order.</item>
|
||||||
@@ -211,6 +220,17 @@ public static class FileNameHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Pattern C: file has no tag of its own — the tag came only from
|
||||||
|
// the folder — but the filename still starts with a bare
|
||||||
|
// episode number, e.g. "11 - Title.mkv" in a
|
||||||
|
// "[DmonHiro] Show Name (BD, 1080p)" folder. Inject the show
|
||||||
|
// name here; the tag is prepended separately in step 4.
|
||||||
|
else if (BareLeadingEpisodeNumberRegex.IsMatch(stemNoExt))
|
||||||
|
{
|
||||||
|
string showName = ExtractShowName(folderName);
|
||||||
|
if (!string.IsNullOrEmpty(showName))
|
||||||
|
fileName = showName + " " + fileName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,6 +293,19 @@ public static class FileNameHelper
|
|||||||
name = FolderSuffixBracketTagRegex.Replace(name, "").Trim();
|
name = FolderSuffixBracketTagRegex.Replace(name, "").Trim();
|
||||||
name = PrefixTagRegex.Replace(name, "").Trim();
|
name = PrefixTagRegex.Replace(name, "").Trim();
|
||||||
|
|
||||||
|
// Strip a trailing parenthesised metadata block, e.g. "(BD, 1080p)",
|
||||||
|
// when every comma/space-separated word inside it is recognisable
|
||||||
|
// quality/source metadata — so a real release group or descriptive
|
||||||
|
// parenthetical left at the end of the name isn't mistakenly dropped.
|
||||||
|
var trailingParenMatch = TrailingParenGroupRegex.Match(name);
|
||||||
|
if (trailingParenMatch.Success)
|
||||||
|
{
|
||||||
|
var parenWords = trailingParenMatch.Groups[1].Value
|
||||||
|
.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (parenWords.Length > 0 && parenWords.All(IsMetadataToken))
|
||||||
|
name = name[..trailingParenMatch.Index].Trim();
|
||||||
|
}
|
||||||
|
|
||||||
// Nothing left, or what remains immediately starts with a bracket — no show name.
|
// Nothing left, or what remains immediately starts with a bracket — no show name.
|
||||||
if (string.IsNullOrEmpty(name) || name[0] == '[') return string.Empty;
|
if (string.IsNullOrEmpty(name) || name[0] == '[') return string.Empty;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user