using System; using System.Collections.Generic; using System.Linq; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.IO; 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; public IDirectoryService DirectoryService { get; private set; } /// /// Initializes a new instance of the class. /// /// The app paths. /// The directory service. public ItemResolveArgs(IServerApplicationPaths appPaths, IDirectoryService directoryService) { _appPaths = appPaths; DirectoryService = directoryService; } /// /// Gets the file system children. /// /// The file system children. public FileSystemMetadata[] FileSystemChildren { get; set; } public LibraryOptions LibraryOptions { get; set; } public LibraryOptions GetLibraryOptions() { return LibraryOptions ?? (LibraryOptions = Parent == null ? new LibraryOptions() : BaseItem.LibraryManager.GetLibraryOptions(Parent)); } /// /// Gets or sets the parent. /// /// The parent. public Folder Parent { get; set; } /// /// Gets or sets the file info. /// /// The file info. public FileSystemMetadata 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 => FileInfo.IsDirectory; /// /// 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 => IsDirectory && BaseItem.FileSystem.AreEqual(Path, _appPaths.RootFolderPath); /// /// Gets or sets the additional locations. /// /// The additional locations. private List AdditionalLocations { get; set; } public bool HasParent() where T : Folder { var parent = Parent; if (parent != null) { var item = parent as T; // Just in case the user decided to nest episodes. // Not officially supported but in some cases we can handle it. if (item == null) { var parents = parent.GetParents(); foreach (var currentParent in parents) { if (currentParent is T) { return true; } } } return item != null; } return false; } /// /// Adds the additional location. /// /// The path. /// public void AddAdditionalLocation(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentException("The path was empty or null.", nameof(path)); } if (AdditionalLocations == null) { AdditionalLocations = new List(); } AdditionalLocations.Add(path); } // REVIEW: @bond /// /// Gets the physical locations. /// /// The physical locations. public string[] PhysicalLocations { get { var paths = string.IsNullOrEmpty(Path) ? Array.Empty() : new[] { Path }; return AdditionalLocations == null ? paths : paths.Concat(AdditionalLocations).ToArray(); } } /// /// Gets the name of the file system entry by. /// /// The name. /// FileSystemInfo. /// public FileSystemMetadata GetFileSystemEntryByName(string name) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException("The name was empty or null.", nameof(name)); } return GetFileSystemEntryByPath(System.IO.Path.Combine(Path, name)); } /// /// Gets the file system entry by path. /// /// The path. /// FileSystemInfo. /// public FileSystemMetadata GetFileSystemEntryByPath(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentException("The path was empty or null.", nameof(path)); } foreach (var file in FileSystemChildren) { if (string.Equals(file.FullName, path, StringComparison.Ordinal)) { return file; } } return 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 CollectionType; } public string CollectionType { get; set; } /// /// 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(); } /// /// Equals 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 && BaseItem.FileSystem.AreEqual(args.Path, Path); } return false; } } }