using System; using System.Diagnostics.CodeAnalysis; using System.IO; using Emby.Naming.Common; using MediaBrowser.Common.Extensions; namespace Emby.Naming.Video { /// /// Resolves from file path. /// public class VideoResolver { private readonly NamingOptions _options; /// /// Initializes a new instance of the class. /// /// object containing VideoFileExtensions, StubFileExtensions, CleanStringRegexes and CleanDateTimeRegexes /// and passes options in , , and . public VideoResolver(NamingOptions options) { _options = options; } /// /// Resolves the directory. /// /// The path. /// VideoFileInfo. public VideoFileInfo? ResolveDirectory(string? path) { return Resolve(path, true); } /// /// Resolves the file. /// /// The path. /// VideoFileInfo. public VideoFileInfo? ResolveFile(string? path) { return Resolve(path, false); } /// /// Resolves the specified path. /// /// The path. /// if set to true [is folder]. /// Whether or not the name should be parsed for info. /// VideoFileInfo. /// path is null. public VideoFileInfo? Resolve(string? path, bool isDirectory, bool parseName = true) { if (string.IsNullOrEmpty(path)) { return null; } bool isStub = false; ReadOnlySpan container = ReadOnlySpan.Empty; string? stubType = null; if (!isDirectory) { var extension = Path.GetExtension(path.AsSpan()); // Check supported extensions if (!_options.VideoFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)) { // It's not supported. Check stub extensions if (!StubResolver.TryResolveFile(path, _options, out stubType)) { return null; } isStub = true; } container = extension.TrimStart('.'); } var flags = new FlagParser(_options).GetFlags(path); var format3DResult = new Format3DParser(_options).Parse(flags); var extraResult = new ExtraResolver(_options).GetExtraInfo(path); var name = Path.GetFileNameWithoutExtension(path); int? year = null; if (parseName) { var cleanDateTimeResult = CleanDateTime(name); name = cleanDateTimeResult.Name; year = cleanDateTimeResult.Year; if (extraResult.ExtraType == null && TryCleanString(name, out ReadOnlySpan newName)) { name = newName.ToString(); } } return new VideoFileInfo( path: path, container: container.IsEmpty ? null : container.ToString(), isStub: isStub, name: name, year: year, stubType: stubType, is3D: format3DResult.Is3D, format3D: format3DResult.Format3D, extraType: extraResult.ExtraType, isDirectory: isDirectory, extraRule: extraResult.Rule); } /// /// Determines if path is video file based on extension. /// /// Path to file. /// True if is video file. public bool IsVideoFile(string path) { var extension = Path.GetExtension(path.AsSpan()); return _options.VideoFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase); } /// /// Determines if path is video file stub based on extension. /// /// Path to file. /// True if is video file stub. public bool IsStubFile(string path) { var extension = Path.GetExtension(path.AsSpan()); return _options.StubFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase); } /// /// Tries to clean name of clutter. /// /// Raw name. /// Clean name. /// True if cleaning of name was successful. public bool TryCleanString([NotNullWhen(true)] string? name, out ReadOnlySpan newName) { return CleanStringParser.TryClean(name, _options.CleanStringRegexes, out newName); } /// /// Tries to get name and year from raw name. /// /// Raw name. /// Returns with name and optional year. public CleanDateTimeResult CleanDateTime(string name) { return CleanDateTimeParser.Clean(name, _options.CleanDateTimeRegexes); } } }