using System; using System.Collections.Generic; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; namespace MediaBrowser.Controller.IO { /// /// Provides low level File access that is much faster than the File/Directory api's. /// public static class FileData { /// /// Gets the filtered file system entries. /// /// The directory service. /// The path. /// The file system. /// The application host. /// The logger. /// The args. /// The flatten folder depth. /// if set to true [resolve shortcuts]. /// Dictionary{System.StringFileSystemInfo}. /// path public static FileSystemMetadata[] GetFilteredFileSystemEntries( IDirectoryService directoryService, string path, IFileSystem fileSystem, IServerApplicationHost appHost, ILogger logger, ItemResolveArgs args, int flattenFolderDepth = 0, bool resolveShortcuts = true) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } if (args == null) { throw new ArgumentNullException(nameof(args)); } var entries = directoryService.GetFileSystemEntries(path); if (!resolveShortcuts && flattenFolderDepth == 0) { return entries; } var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var entry in entries) { var isDirectory = entry.IsDirectory; var fullName = entry.FullName; if (resolveShortcuts && fileSystem.IsShortcut(fullName)) { try { var newPath = appHost.ExpandVirtualPath(fileSystem.ResolveShortcut(fullName)); if (string.IsNullOrEmpty(newPath)) { // invalid shortcut - could be old or target could just be unavailable logger.LogWarning("Encountered invalid shortcut: " + fullName); continue; } // Don't check if it exists here because that could return false for network shares. var data = fileSystem.GetDirectoryInfo(newPath); // add to our physical locations args.AddAdditionalLocation(newPath); dict[newPath] = data; } catch (Exception ex) { logger.LogError(ex, "Error resolving shortcut from {path}", fullName); } } else if (flattenFolderDepth > 0 && isDirectory) { foreach (var child in GetFilteredFileSystemEntries(directoryService, fullName, fileSystem, appHost, logger, args, flattenFolderDepth: flattenFolderDepth - 1, resolveShortcuts: resolveShortcuts)) { dict[child.FullName] = child; } } else { dict[fullName] = entry; } } var returnResult = new FileSystemMetadata[dict.Count]; var index = 0; var values = dict.Values; foreach (var value in values) { returnResult[index] = value; index++; } return returnResult; } } }