123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using Emby.Naming.AudioBook;
- using Emby.Naming.Common;
- using MediaBrowser.Model.IO;
- namespace Emby.Naming.Video
- {
- /// <summary>
- /// Resolve <see cref="FileStack"/> from list of paths.
- /// </summary>
- public static class StackResolver
- {
- /// <summary>
- /// Resolves only directories from paths.
- /// </summary>
- /// <param name="files">List of paths.</param>
- /// <param name="namingOptions">The naming options.</param>
- /// <returns>Enumerable <see cref="FileStack"/> of directories.</returns>
- public static IEnumerable<FileStack> ResolveDirectories(IEnumerable<string> files, NamingOptions namingOptions)
- {
- return Resolve(files.Select(i => new FileSystemMetadata { FullName = i, IsDirectory = true }), namingOptions);
- }
- /// <summary>
- /// Resolves only files from paths.
- /// </summary>
- /// <param name="files">List of paths.</param>
- /// <param name="namingOptions">The naming options.</param>
- /// <returns>Enumerable <see cref="FileStack"/> of files.</returns>
- public static IEnumerable<FileStack> ResolveFiles(IEnumerable<string> files, NamingOptions namingOptions)
- {
- return Resolve(files.Select(i => new FileSystemMetadata { FullName = i, IsDirectory = false }), namingOptions);
- }
- /// <summary>
- /// Resolves audiobooks from paths.
- /// </summary>
- /// <param name="files">List of paths.</param>
- /// <returns>Enumerable <see cref="FileStack"/> of directories.</returns>
- public static IEnumerable<FileStack> ResolveAudioBooks(IEnumerable<AudioBookFileInfo> files)
- {
- var groupedDirectoryFiles = files.GroupBy(file => Path.GetDirectoryName(file.Path));
- foreach (var directory in groupedDirectoryFiles)
- {
- if (string.IsNullOrEmpty(directory.Key))
- {
- foreach (var file in directory)
- {
- var stack = new FileStack(Path.GetFileNameWithoutExtension(file.Path), false, new[] { file.Path });
- yield return stack;
- }
- }
- else
- {
- var stack = new FileStack(Path.GetFileName(directory.Key), false, directory.Select(f => f.Path).ToArray());
- yield return stack;
- }
- }
- }
- /// <summary>
- /// Resolves videos from paths.
- /// </summary>
- /// <param name="files">List of paths.</param>
- /// <param name="namingOptions">The naming options.</param>
- /// <returns>Enumerable <see cref="FileStack"/> of videos.</returns>
- public static IEnumerable<FileStack> Resolve(IEnumerable<FileSystemMetadata> files, NamingOptions namingOptions)
- {
- var potentialFiles = files
- .Where(i => i.IsDirectory || VideoResolver.IsVideoFile(i.FullName, namingOptions) || VideoResolver.IsStubFile(i.FullName, namingOptions))
- .OrderBy(i => i.FullName);
- var potentialStacks = new Dictionary<string, StackMetadata>();
- foreach (var file in potentialFiles)
- {
- var name = file.Name;
- if (string.IsNullOrEmpty(name))
- {
- name = Path.GetFileName(file.FullName);
- }
- for (var i = 0; i < namingOptions.VideoFileStackingRules.Length; i++)
- {
- var rule = namingOptions.VideoFileStackingRules[i];
- if (!rule.Match(name, out var stackParsingResult))
- {
- continue;
- }
- var stackName = stackParsingResult.Value.StackName;
- var partNumber = stackParsingResult.Value.PartNumber;
- var partType = stackParsingResult.Value.PartType;
- if (!potentialStacks.TryGetValue(stackName, out var stackResult))
- {
- stackResult = new StackMetadata(file.IsDirectory, rule.IsNumerical, partType);
- potentialStacks[stackName] = stackResult;
- }
- if (stackResult.Parts.Count > 0)
- {
- if (stackResult.IsDirectory != file.IsDirectory
- || !string.Equals(partType, stackResult.PartType, StringComparison.OrdinalIgnoreCase)
- || stackResult.ContainsPart(partNumber))
- {
- continue;
- }
- if (rule.IsNumerical != stackResult.IsNumerical)
- {
- break;
- }
- }
- stackResult.Parts.Add(partNumber, file);
- break;
- }
- }
- foreach (var (fileName, stack) in potentialStacks)
- {
- if (stack.Parts.Count < 2)
- {
- continue;
- }
- yield return new FileStack(fileName, stack.IsDirectory, stack.Parts.Select(kv => kv.Value.FullName).ToArray());
- }
- }
- private class StackMetadata
- {
- public StackMetadata(bool isDirectory, bool isNumerical, string partType)
- {
- Parts = new Dictionary<string, FileSystemMetadata>(StringComparer.OrdinalIgnoreCase);
- IsDirectory = isDirectory;
- IsNumerical = isNumerical;
- PartType = partType;
- }
- public Dictionary<string, FileSystemMetadata> Parts { get; }
- public bool IsDirectory { get; }
- public bool IsNumerical { get; }
- public string PartType { get; }
- public bool ContainsPart(string partNumber) => Parts.ContainsKey(partNumber);
- }
- }
- }
|