diff options
| author | cvium <clausvium@gmail.com> | 2021-12-10 14:23:31 +0100 |
|---|---|---|
| committer | cvium <clausvium@gmail.com> | 2021-12-10 14:23:31 +0100 |
| commit | 220443eca1dfef08a2a0e000ac5963e18af073fc (patch) | |
| tree | bcaef09e4fdb8b8a0c19850f366096a16c07fabd /Emby.Naming/Video/StackResolver.cs | |
| parent | 6030946d78cb52395a55a288ecdfb41890700cc7 (diff) | |
Simplify StackResolver
Diffstat (limited to 'Emby.Naming/Video/StackResolver.cs')
| -rw-r--r-- | Emby.Naming/Video/StackResolver.cs | 198 |
1 files changed, 56 insertions, 142 deletions
diff --git a/Emby.Naming/Video/StackResolver.cs b/Emby.Naming/Video/StackResolver.cs index be73f69db..7900e09c2 100644 --- a/Emby.Naming/Video/StackResolver.cs +++ b/Emby.Naming/Video/StackResolver.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text.RegularExpressions; using Emby.Naming.AudioBook; using Emby.Naming.Common; using MediaBrowser.Model.IO; @@ -51,19 +50,13 @@ namespace Emby.Naming.Video { foreach (var file in directory) { - var stack = new FileStack { Name = Path.GetFileNameWithoutExtension(file.Path), IsDirectoryStack = false }; - stack.Files.Add(file.Path); + var stack = new FileStack(Path.GetFileNameWithoutExtension(file.Path), false, new[] { file.Path }); yield return stack; } } else { - var stack = new FileStack { Name = Path.GetFileName(directory.Key), IsDirectoryStack = false }; - foreach (var file in directory) - { - stack.Files.Add(file.Path); - } - + var stack = new FileStack(Path.GetFileName(directory.Key), false, directory.Select(f => f.Path).ToArray()); yield return stack; } } @@ -77,166 +70,87 @@ namespace Emby.Naming.Video /// <returns>Enumerable <see cref="FileStack"/> of videos.</returns> public static IEnumerable<FileStack> Resolve(IEnumerable<FileSystemMetadata> files, NamingOptions namingOptions) { - var list = files + var potentialFiles = files .Where(i => i.IsDirectory || VideoResolver.IsVideoFile(i.FullName, namingOptions) || VideoResolver.IsStubFile(i.FullName, namingOptions)) - .OrderBy(i => i.FullName) - .Select(f => (f.IsDirectory, FileName: GetFileNameWithExtension(f), f.FullName)) - .ToList(); + .OrderBy(i => i.FullName); - // TODO is there a "nicer" way? - var cache = new Dictionary<(string, Regex, int), Match>(); - - var expressions = namingOptions.VideoFileStackingRegexes; - - for (var i = 0; i < list.Count; i++) + var potentialStacks = new Dictionary<string, StackMetadata>(); + foreach (var file in potentialFiles) { - var offset = 0; - - var file1 = list[i]; - - var expressionIndex = 0; - while (expressionIndex < expressions.Length) + for (var i = 0; i < namingOptions.VideoFileStackingRules.Length; i++) { - var exp = expressions[expressionIndex]; - FileStack? stack = null; + var name = file.Name; + if (string.IsNullOrEmpty(name)) + { + name = Path.GetFileName(file.FullName); + } + + var rule = namingOptions.VideoFileStackingRules[i]; + if (!rule.Match(name, out var stackParsingResult)) + { + continue; + } - // (Title)(Volume)(Ignore)(Extension) - var match1 = FindMatch(file1.FileName, exp, offset, cache); + var stackName = stackParsingResult.Value.StackName; + var partNumber = stackParsingResult.Value.PartNumber; + var partType = stackParsingResult.Value.PartType; - if (match1.Success) + if (!potentialStacks.TryGetValue(stackName, out var stackResult)) { - var title1 = match1.Groups[1].Value; - var volume1 = match1.Groups[2].Value; - var ignore1 = match1.Groups[3].Value; - var extension1 = match1.Groups[4].Value; + stackResult = new StackMetadata(file.IsDirectory, rule.IsNumerical, partType); + potentialStacks[stackName] = stackResult; + } - var j = i + 1; - while (j < list.Count) + if (stackResult.Parts.Count > 0) + { + if (stackResult.IsDirectory != file.IsDirectory + || !string.Equals(partType, stackResult.PartType, StringComparison.OrdinalIgnoreCase) + || stackResult.ContainsPart(partNumber)) { - var file2 = list[j]; - - if (file1.IsDirectory != file2.IsDirectory) - { - j++; - continue; - } - - // (Title)(Volume)(Ignore)(Extension) - var match2 = FindMatch(file2.FileName, exp, offset, cache); - - if (match2.Success) - { - var title2 = match2.Groups[1].Value; - var volume2 = match2.Groups[2].Value; - var ignore2 = match2.Groups[3].Value; - var extension2 = match2.Groups[4].Value; - - if (string.Equals(title1, title2, StringComparison.OrdinalIgnoreCase)) - { - if (!string.Equals(volume1, volume2, StringComparison.OrdinalIgnoreCase)) - { - if (string.Equals(ignore1, ignore2, StringComparison.OrdinalIgnoreCase) - && string.Equals(extension1, extension2, StringComparison.OrdinalIgnoreCase)) - { - stack ??= new FileStack(); - if (stack.Files.Count == 0) - { - stack.Name = title1 + ignore1; - stack.IsDirectoryStack = file1.IsDirectory; - stack.Files.Add(file1.FullName); - } - - stack.Files.Add(file2.FullName); - } - else - { - // Sequel - offset = 0; - expressionIndex++; - break; - } - } - else if (!string.Equals(ignore1, ignore2, StringComparison.OrdinalIgnoreCase)) - { - // False positive, try again with offset - offset = match1.Groups[3].Index; - break; - } - else - { - // Extension mismatch - offset = 0; - expressionIndex++; - break; - } - } - else - { - // Title mismatch - offset = 0; - expressionIndex++; - break; - } - } - else - { - // No match 2, next expression - offset = 0; - expressionIndex++; - break; - } - - j++; + continue; } - if (j == list.Count) + if (rule.IsNumerical != stackResult.IsNumerical) { - expressionIndex = expressions.Length; + break; } } - else - { - // No match 1 - offset = 0; - expressionIndex++; - } - if (stack?.Files.Count > 1) - { - yield return stack; - i += stack.Files.Count - 1; - break; - } + stackResult.Parts.Add(partNumber, file); + break; } } - } - private static string GetFileNameWithExtension(FileSystemMetadata file) - { - // For directories, dummy up an extension otherwise the expressions will fail - var input = file.FullName; - if (file.IsDirectory) + foreach (var (fileName, stack) in potentialStacks) { - input = Path.ChangeExtension(input, "mkv"); - } + if (stack.Parts.Count < 2) + { + continue; + } - return Path.GetFileName(input); + yield return new FileStack(fileName, stack.IsDirectory, stack.Parts.Select(kv => kv.Value.FullName).ToArray()); + } } - private static Match FindMatch(string input, Regex regex, int offset, Dictionary<(string, Regex, int), Match> cache) + private class StackMetadata { - if (offset < 0 || offset >= input.Length) + public StackMetadata(bool isDirectory, bool isNumerical, string partType) { - return Match.Empty; + Parts = new Dictionary<string, FileSystemMetadata>(StringComparer.OrdinalIgnoreCase); + IsDirectory = isDirectory; + IsNumerical = isNumerical; + PartType = partType; } - if (!cache.TryGetValue((input, regex, offset), out var result)) - { - result = regex.Match(input, offset, input.Length - offset); - cache.Add((input, regex, offset), result); - } + public Dictionary<string, FileSystemMetadata> Parts { get; } + + public bool IsDirectory { get; } + + public bool IsNumerical { get; } + + public string PartType { get; } - return result; + public bool ContainsPart(string partNumber) => Parts.ContainsKey(partNumber); } } } |
