using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Text.RegularExpressions; namespace MediaBrowser.Controller.Resolvers { /// /// Class EntityResolutionHelper /// public static class EntityResolutionHelper { /// /// Any folder named in this list will be ignored - can be added to at runtime for extensibility /// public static readonly List IgnoreFolders = new List { "metadata", "ps3_update", "ps3_vprm", "extrafanart", "extrathumbs", ".actors", ".wd_tv" }; private static readonly Regex MultiFileRegex = new Regex( @"(.*?)([ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck]|d)[ _.-]*[0-9]+)(.*?)(\.[^.]+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex MultiFolderRegex = new Regex( @"(.*?)([ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck]|d)[ _.-]*[0-9]+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); /// /// Determines whether [is multi part file] [the specified path]. /// /// The path. /// true if [is multi part file] [the specified path]; otherwise, false. public static bool IsMultiPartFile(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } path = Path.GetFileName(path); return MultiFileRegex.Match(path).Success; } public static bool IsMultiPartFolder(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } path = Path.GetFileName(path); return MultiFolderRegex.Match(path).Success; } /// /// The audio file extensions /// public static readonly string[] AudioFileExtensions = { ".mp3", ".flac", ".wma", ".aac", ".acc", ".m4a", ".m4b", ".wav", ".ape", ".ogg", ".oga" //".asf", //".mp4" }; private static readonly Dictionary AudioFileExtensionsDictionary = AudioFileExtensions.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); /// /// Determines whether [is audio file] [the specified args]. /// /// The path. /// true if [is audio file] [the specified args]; otherwise, false. public static bool IsAudioFile(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } var extension = Path.GetExtension(path); if (string.IsNullOrEmpty(extension)) { return false; } return AudioFileExtensionsDictionary.ContainsKey(extension); } /// /// Determines whether [is video file] [the specified path]. /// /// The path. /// true if [is video file] [the specified path]; otherwise, false. public static bool IsVideoFile(string path) { return MimeTypes.IsVideoFile(path); } /// /// Determines whether [is place holder] [the specified path]. /// /// The path. /// true if [is place holder] [the specified path]; otherwise, false. /// path public static bool IsVideoPlaceHolder(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } var extension = Path.GetExtension(path); return string.Equals(extension, ".disc", StringComparison.OrdinalIgnoreCase); } /// /// Determines whether [is multi disc album folder] [the specified path]. /// /// The path. /// true if [is multi disc album folder] [the specified path]; otherwise, false. public static bool IsMultiDiscAlbumFolder(string path) { var filename = Path.GetFileName(path); if (string.IsNullOrWhiteSpace(filename)) { return false; } // Normalize // Remove whitespace filename = filename.Replace("-", string.Empty); filename = filename.Replace(".", string.Empty); filename = Regex.Replace(filename, @"\s+", ""); var prefixes = new[] { "disc", "cd", "disk", "vol", "volume" }; foreach (var prefix in prefixes) { if (filename.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) == 0) { var tmp = filename.Substring(prefix.Length); int val; if (int.TryParse(tmp, NumberStyles.Any, CultureInfo.InvariantCulture, out val)) { return true; } } } return false; } /// /// Ensures DateCreated and DateModified have values /// /// The file system. /// The item. /// The args. /// if set to true [include creation time]. public static void EnsureDates(IFileSystem fileSystem, BaseItem item, ItemResolveArgs args, bool includeCreationTime) { if (fileSystem == null) { throw new ArgumentNullException("fileSystem"); } if (item == null) { throw new ArgumentNullException("item"); } if (args == null) { throw new ArgumentNullException("args"); } // See if a different path came out of the resolver than what went in if (!string.Equals(args.Path, item.Path, StringComparison.OrdinalIgnoreCase)) { var childData = args.IsDirectory ? args.GetFileSystemEntryByPath(item.Path) : null; if (childData != null) { if (includeCreationTime) { SetDateCreated(item, fileSystem, childData); } item.DateModified = fileSystem.GetLastWriteTimeUtc(childData); } else { var fileData = fileSystem.GetFileSystemInfo(item.Path); if (fileData.Exists) { if (includeCreationTime) { SetDateCreated(item, fileSystem, fileData); } item.DateModified = fileSystem.GetLastWriteTimeUtc(fileData); } } } else { if (includeCreationTime) { SetDateCreated(item, fileSystem, args.FileInfo); } item.DateModified = fileSystem.GetLastWriteTimeUtc(args.FileInfo); } } private static void SetDateCreated(BaseItem item, IFileSystem fileSystem, FileSystemInfo info) { var config = BaseItem.ConfigurationManager.GetMetadataConfiguration(); if (config.UseFileCreationTimeForDateAdded) { item.DateModified = fileSystem.GetCreationTimeUtc(info); } else { item.DateCreated = DateTime.UtcNow; } } } }