using MediaBrowser.Controller.Entities; using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace MediaBrowser.Controller.Library { /// /// These are arguments relating to the file system that are collected once and then referred to /// whenever needed. Primarily for entity resolution. /// public class ItemResolveArgs : EventArgs { /// /// The _app paths /// private readonly IServerApplicationPaths _appPaths; private readonly ILibraryManager _libraryManager; /// /// Initializes a new instance of the class. /// /// The app paths. /// The library manager. public ItemResolveArgs(IServerApplicationPaths appPaths, ILibraryManager libraryManager) { _appPaths = appPaths; _libraryManager = libraryManager; } /// /// Gets the file system children. /// /// The file system children. public IEnumerable FileSystemChildren { get { return FileSystemDictionary.Values; } } /// /// Gets or sets the file system dictionary. /// /// The file system dictionary. public Dictionary FileSystemDictionary { get; set; } /// /// Gets or sets the parent. /// /// The parent. public Folder Parent { get; set; } /// /// Gets or sets the file info. /// /// The file info. public FileSystemInfo FileInfo { get; set; } /// /// Gets or sets the path. /// /// The path. public string Path { get; set; } /// /// Gets a value indicating whether this instance is directory. /// /// true if this instance is directory; otherwise, false. public bool IsDirectory { get { return (FileInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory; } } /// /// Gets a value indicating whether this instance is hidden. /// /// true if this instance is hidden; otherwise, false. public bool IsHidden { get { return (FileInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden; } } /// /// Gets a value indicating whether this instance is system file. /// /// true if this instance is system file; otherwise, false. public bool IsSystemFile { get { return (FileInfo.Attributes & FileAttributes.System) == FileAttributes.System; } } /// /// Gets a value indicating whether this instance is vf. /// /// true if this instance is vf; otherwise, false. public bool IsVf { // we should be considered a virtual folder if we are a child of one of the children of the system root folder. // this is a bit of a trick to determine that... the directory name of a sub-child of the root will start with // the root but not be equal to it get { if (!IsDirectory) { return false; } var parentDir = System.IO.Path.GetDirectoryName(Path) ?? string.Empty; return (parentDir.Length > _appPaths.RootFolderPath.Length && parentDir.StartsWith(_appPaths.RootFolderPath, StringComparison.OrdinalIgnoreCase)); } } /// /// Gets a value indicating whether this instance is physical root. /// /// true if this instance is physical root; otherwise, false. public bool IsPhysicalRoot { get { return IsDirectory && Path.Equals(_appPaths.RootFolderPath, StringComparison.OrdinalIgnoreCase); } } /// /// Gets a value indicating whether this instance is root. /// /// true if this instance is root; otherwise, false. public bool IsRoot { get { return Parent == null; } } /// /// Gets or sets the additional locations. /// /// The additional locations. private List AdditionalLocations { get; set; } /// /// Adds the additional location. /// /// The path. /// public void AddAdditionalLocation(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(); } if (AdditionalLocations == null) { AdditionalLocations = new List(); } AdditionalLocations.Add(path); } /// /// Gets the physical locations. /// /// The physical locations. public IEnumerable PhysicalLocations { get { var paths = string.IsNullOrWhiteSpace(Path) ? new string[] {} : new[] {Path}; return AdditionalLocations == null ? paths : paths.Concat(AdditionalLocations); } } /// /// Store these to reduce disk access in Resolvers /// /// The metadata file dictionary. private Dictionary MetadataFileDictionary { get; set; } /// /// Gets the metadata files. /// /// The metadata files. public IEnumerable MetadataFiles { get { if (MetadataFileDictionary != null) { return MetadataFileDictionary.Values; } return new FileSystemInfo[] { }; } } /// /// Adds the metadata file. /// /// The path. /// public void AddMetadataFile(string path) { var file = new FileInfo(path); if (!file.Exists) { throw new FileNotFoundException(path); } AddMetadataFile(file); } /// /// Adds the metadata file. /// /// The file info. public void AddMetadataFile(FileSystemInfo fileInfo) { AddMetadataFiles(new[] { fileInfo }); } /// /// Adds the metadata files. /// /// The files. /// public void AddMetadataFiles(IEnumerable files) { if (files == null) { throw new ArgumentNullException(); } if (MetadataFileDictionary == null) { MetadataFileDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); } foreach (var file in files) { MetadataFileDictionary[file.Name] = file; } } /// /// Gets the name of the file system entry by. /// /// The name. /// FileSystemInfo. /// public FileSystemInfo GetFileSystemEntryByName(string name) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException(); } return GetFileSystemEntryByPath(System.IO.Path.Combine(Path, name)); } /// /// Gets the file system entry by path. /// /// The path. /// FileSystemInfo. /// public FileSystemInfo GetFileSystemEntryByPath(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(); } if (FileSystemDictionary != null) { FileSystemInfo entry; if (FileSystemDictionary.TryGetValue(path, out entry)) { return entry; } } return null; } /// /// Gets the meta file by path. /// /// The path. /// FileSystemInfo. /// public FileSystemInfo GetMetaFileByPath(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(); } if (MetadataFileDictionary != null) { FileSystemInfo entry; if (MetadataFileDictionary.TryGetValue(System.IO.Path.GetFileName(path), out entry)) { return entry; } } return GetFileSystemEntryByPath(path); } /// /// Gets the name of the meta file by. /// /// The name. /// FileSystemInfo. /// public FileSystemInfo GetMetaFileByName(string name) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException(); } if (MetadataFileDictionary != null) { FileSystemInfo entry; if (MetadataFileDictionary.TryGetValue(name, out entry)) { return entry; } } return GetFileSystemEntryByName(name); } /// /// Determines whether [contains meta file by name] [the specified name]. /// /// The name. /// true if [contains meta file by name] [the specified name]; otherwise, false. public bool ContainsMetaFileByName(string name) { return GetMetaFileByName(name) != null; } /// /// Determines whether [contains file system entry by name] [the specified name]. /// /// The name. /// true if [contains file system entry by name] [the specified name]; otherwise, false. public bool ContainsFileSystemEntryByName(string name) { return GetFileSystemEntryByName(name) != null; } public string GetCollectionType() { return Parent == null ? null : _libraryManager.FindCollectionType(Parent); } #region Equality Overrides /// /// Determines whether the specified is equal to this instance. /// /// The object to compare with the current object. /// true if the specified is equal to this instance; otherwise, false. public override bool Equals(object obj) { return (Equals(obj as ItemResolveArgs)); } /// /// Returns a hash code for this instance. /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. public override int GetHashCode() { return Path.GetHashCode(); } /// /// Equalses the specified args. /// /// The args. /// true if XXXX, false otherwise protected bool Equals(ItemResolveArgs args) { if (args != null) { if (args.Path == null && Path == null) return true; return args.Path != null && args.Path.Equals(Path, StringComparison.OrdinalIgnoreCase); } return false; } #endregion } }