diff --git a/MediaBrowser.Api/Playback/Dash/MpegDashService.cs b/MediaBrowser.Api/Playback/Dash/MpegDashService.cs index cbee821d2d..5a36b0aa25 100644 --- a/MediaBrowser.Api/Playback/Dash/MpegDashService.cs +++ b/MediaBrowser.Api/Playback/Dash/MpegDashService.cs @@ -322,7 +322,7 @@ namespace MediaBrowser.Api.Playback.Dash } } - private static List GetLastTranscodingFiles(string playlist, string segmentExtension, IFileSystem fileSystem, int count) + private static List GetLastTranscodingFiles(string playlist, string segmentExtension, IFileSystem fileSystem, int count) { var folder = Path.GetDirectoryName(playlist); @@ -336,7 +336,7 @@ namespace MediaBrowser.Api.Playback.Dash } catch (DirectoryNotFoundException) { - return new List(); + return new List(); } } diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index cb49e65c7e..39bdee6991 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -354,7 +354,7 @@ namespace MediaBrowser.Api.Playback.Hls } } - private void DeleteFile(FileInfo file, int retryCount) + private void DeleteFile(FileSystemMetadata file, int retryCount) { if (retryCount >= 5) { @@ -378,7 +378,7 @@ namespace MediaBrowser.Api.Playback.Hls } } - private static FileInfo GetLastTranscodingFile(string playlist, string segmentExtension, IFileSystem fileSystem) + private static FileSystemMetadata GetLastTranscodingFile(string playlist, string segmentExtension, IFileSystem fileSystem) { var folder = Path.GetDirectoryName(playlist); diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index 00935dd1e1..4ad8b3903a 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -118,7 +118,7 @@ namespace MediaBrowser.Api.System public object Get(GetServerLogs request) { - List files; + List files; try { @@ -128,7 +128,7 @@ namespace MediaBrowser.Api.System } catch (DirectoryNotFoundException) { - files = new List(); + files = new List(); } var result = files.Select(i => new LogFile diff --git a/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs b/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs index b899e88c23..f13b9b1a94 100644 --- a/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs +++ b/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs @@ -27,7 +27,7 @@ namespace MediaBrowser.Common.Implementations.IO SetInvalidFileNameChars(usePresetInvalidFileNameChars); } - private void SetInvalidFileNameChars(bool usePresetInvalidFileNameChars) + protected void SetInvalidFileNameChars(bool usePresetInvalidFileNameChars) { // GetInvalidFileNameChars is less restrictive in Linux/Mac than Windows, this mimic Windows behavior for mono under Linux/Mac. @@ -115,7 +115,7 @@ namespace MediaBrowser.Common.Implementations.IO /// /// The path. /// FileSystemInfo. - public FileSystemInfo GetFileSystemInfo(string path) + public FileSystemMetadata GetFileSystemInfo(string path) { if (string.IsNullOrEmpty(path)) { @@ -129,10 +129,10 @@ namespace MediaBrowser.Common.Implementations.IO if (fileInfo.Exists) { - return fileInfo; + return GetFileSystemMetadata(fileInfo); } - return new DirectoryInfo(path); + return GetFileSystemMetadata(new DirectoryInfo(path)); } else { @@ -140,13 +140,63 @@ namespace MediaBrowser.Common.Implementations.IO if (fileInfo.Exists) { - return fileInfo; + return GetFileSystemMetadata(fileInfo); } - return new FileInfo(path); + return GetFileSystemMetadata(new FileInfo(path)); } } + public FileSystemMetadata GetFileInfo(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + var fileInfo = new FileInfo(path); + + return GetFileSystemMetadata(fileInfo); + } + + public FileSystemMetadata GetDirectoryInfo(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + var fileInfo = new DirectoryInfo(path); + + return GetFileSystemMetadata(fileInfo); + } + + private FileSystemMetadata GetFileSystemMetadata(FileSystemInfo info) + { + var result = new FileSystemMetadata(); + + result.Attributes = info.Attributes; + result.Exists = info.Exists; + result.FullName = info.FullName; + result.Extension = info.Extension; + result.Name = info.Name; + + if (result.Exists) + { + var fileInfo = info as FileInfo; + if (fileInfo != null) + { + result.Length = fileInfo.Length; + result.DirectoryName = fileInfo.DirectoryName; + } + + result.CreationTimeUtc = GetCreationTimeUtc(info); + result.LastWriteTimeUtc = GetLastWriteTimeUtc(info); + } + + return result; + } + /// /// The space char /// @@ -194,6 +244,26 @@ namespace MediaBrowser.Common.Implementations.IO } } + /// + /// Gets the creation time UTC. + /// + /// The path. + /// DateTime. + public DateTime GetCreationTimeUtc(string path) + { + return GetCreationTimeUtc(GetFileSystemInfo(path)); + } + + public DateTime GetCreationTimeUtc(FileSystemMetadata info) + { + return info.CreationTimeUtc; + } + + public DateTime GetLastWriteTimeUtc(FileSystemMetadata info) + { + return info.LastWriteTimeUtc; + } + /// /// Gets the creation time UTC. /// @@ -346,41 +416,9 @@ namespace MediaBrowser.Common.Implementations.IO return path.TrimEnd(Path.DirectorySeparatorChar); } - public string SubstitutePath(string path, string from, string to) + public string GetFileNameWithoutExtension(FileSystemMetadata info) { - if (string.IsNullOrWhiteSpace(path)) - { - throw new ArgumentNullException("path"); - } - if (string.IsNullOrWhiteSpace(from)) - { - throw new ArgumentNullException("from"); - } - if (string.IsNullOrWhiteSpace(to)) - { - throw new ArgumentNullException("to"); - } - - var newPath = path.Replace(from, to, StringComparison.OrdinalIgnoreCase); - - if (!string.Equals(newPath, path)) - { - if (to.IndexOf('/') != -1) - { - newPath = newPath.Replace('\\', '/'); - } - else - { - newPath = newPath.Replace('/', '\\'); - } - } - - return newPath; - } - - public string GetFileNameWithoutExtension(FileSystemInfo info) - { - if (info is DirectoryInfo) + if (info.IsDirectory) { return info.Name; } @@ -426,28 +464,28 @@ namespace MediaBrowser.Common.Implementations.IO { Directory.CreateDirectory(path); } - - public IEnumerable GetDirectories(string path, bool recursive = false) + + public IEnumerable GetDirectories(string path, bool recursive = false) { var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - return new DirectoryInfo (path).EnumerateDirectories("*", searchOption); + return new DirectoryInfo(path).EnumerateDirectories("*", searchOption).Select(GetFileSystemMetadata); } - public IEnumerable GetFiles(string path, bool recursive = false) + public IEnumerable GetFiles(string path, bool recursive = false) { var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - return new DirectoryInfo (path).EnumerateFiles("*", searchOption); + return new DirectoryInfo (path).EnumerateFiles("*", searchOption).Select(GetFileSystemMetadata); } - public IEnumerable GetFileSystemEntries(string path, bool recursive = false) + public IEnumerable GetFileSystemEntries(string path, bool recursive = false) { var directoryInfo = new DirectoryInfo (path); var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - return directoryInfo.EnumerateDirectories("*", searchOption) - .Concat(directoryInfo.EnumerateFiles("*", searchOption)); + return directoryInfo.EnumerateDirectories("*", searchOption).Select(GetFileSystemMetadata) + .Concat(directoryInfo.EnumerateFiles("*", searchOption).Select(GetFileSystemMetadata)); } public Stream OpenRead(string path) diff --git a/MediaBrowser.Common/IO/FileSystemMetadata.cs b/MediaBrowser.Common/IO/FileSystemMetadata.cs new file mode 100644 index 0000000000..ba8a1b8b87 --- /dev/null +++ b/MediaBrowser.Common/IO/FileSystemMetadata.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Common.IO +{ + public class FileSystemMetadata + { + public FileAttributes Attributes { get; set; } + + public bool Exists { get; set; } + public string FullName { get; set; } + public string Name { get; set; } + public string Extension { get; set; } + public long Length { get; set; } + public string DirectoryName { get; set; } + + public DateTime LastWriteTimeUtc { get; set; } + public DateTime CreationTimeUtc { get; set; } + + public bool IsDirectory + { + get + { + return (Attributes & FileAttributes.Directory) == FileAttributes.Directory; + } + } + } +} diff --git a/MediaBrowser.Common/IO/IFileSystem.cs b/MediaBrowser.Common/IO/IFileSystem.cs index ce15ad999c..e084f94ed2 100644 --- a/MediaBrowser.Common/IO/IFileSystem.cs +++ b/MediaBrowser.Common/IO/IFileSystem.cs @@ -36,8 +36,22 @@ namespace MediaBrowser.Common.IO /// /// The path. /// FileSystemInfo. - FileSystemInfo GetFileSystemInfo(string path); + FileSystemMetadata GetFileSystemInfo(string path); + /// + /// Gets the file information. + /// + /// The path. + /// FileSystemMetadata. + FileSystemMetadata GetFileInfo(string path); + + /// + /// Gets the directory information. + /// + /// The path. + /// FileSystemMetadata. + FileSystemMetadata GetDirectoryInfo(string path); + /// /// Gets the valid filename. /// @@ -48,17 +62,24 @@ namespace MediaBrowser.Common.IO /// /// Gets the creation time UTC. /// - /// The info. + /// The information. + /// DateTime. + DateTime GetCreationTimeUtc(FileSystemMetadata info); + + /// + /// Gets the creation time UTC. + /// + /// The path. /// DateTime. - DateTime GetCreationTimeUtc(FileSystemInfo info); + DateTime GetCreationTimeUtc(string path); /// /// Gets the last write time UTC. /// /// The information. /// DateTime. - DateTime GetLastWriteTimeUtc(FileSystemInfo info); - + DateTime GetLastWriteTimeUtc(FileSystemMetadata info); + /// /// Gets the last write time UTC. /// @@ -77,6 +98,11 @@ namespace MediaBrowser.Common.IO /// FileStream. Stream GetFileStream(string path, FileMode mode, FileAccess access, FileShare share, bool isAsync = false); + /// + /// Opens the read. + /// + /// The path. + /// Stream. Stream OpenRead(String path); /// @@ -108,21 +134,12 @@ namespace MediaBrowser.Common.IO /// System.String. string NormalizePath(string path); - /// - /// Substitutes the path. - /// - /// The path. - /// From. - /// To. - /// System.String. - string SubstitutePath(string path, string from, string to); - /// /// Gets the file name without extension. /// /// The information. /// System.String. - string GetFileNameWithoutExtension(FileSystemInfo info); + string GetFileNameWithoutExtension(FileSystemMetadata info); /// /// Gets the file name without extension. @@ -150,37 +167,125 @@ namespace MediaBrowser.Common.IO /// The path. /// if set to true [recursive]. void DeleteDirectory(string path, bool recursive); - - IEnumerable GetDirectories(string path, bool recursive = false); - IEnumerable GetFiles(string path, bool recursive = false); + /// + /// Gets the directories. + /// + /// The path. + /// if set to true [recursive]. + /// IEnumerable<DirectoryInfo>. + IEnumerable GetDirectories(string path, bool recursive = false); - IEnumerable GetFileSystemEntries(string path, bool recursive = false); + /// + /// Gets the files. + /// + /// The path. + /// if set to true [recursive]. + /// IEnumerable<FileInfo>. + IEnumerable GetFiles(string path, bool recursive = false); + + /// + /// Gets the file system entries. + /// + /// The path. + /// if set to true [recursive]. + /// IEnumerable<FileSystemMetadata>. + IEnumerable GetFileSystemEntries(string path, bool recursive = false); + /// + /// Creates the directory. + /// + /// The path. void CreateDirectory(string path); + /// + /// Copies the file. + /// + /// The source. + /// The target. + /// if set to true [overwrite]. void CopyFile(string source, string target, bool overwrite); + /// + /// Moves the file. + /// + /// The source. + /// The target. void MoveFile(string source, string target); + /// + /// Moves the directory. + /// + /// The source. + /// The target. void MoveDirectory(string source, string target); + /// + /// Directories the exists. + /// + /// The path. + /// true if XXXX, false otherwise. bool DirectoryExists(string path); + /// + /// Files the exists. + /// + /// The path. + /// true if XXXX, false otherwise. bool FileExists(string path); + /// + /// Reads all text. + /// + /// The path. + /// System.String. string ReadAllText(string path); + /// + /// Writes all text. + /// + /// The path. + /// The text. void WriteAllText(string path, string text); - + + /// + /// Writes all text. + /// + /// The path. + /// The text. + /// The encoding. void WriteAllText(string path, string text, Encoding encoding); + /// + /// Reads all text. + /// + /// The path. + /// The encoding. + /// System.String. string ReadAllText(string path, Encoding encoding); + /// + /// Gets the directory paths. + /// + /// The path. + /// if set to true [recursive]. + /// IEnumerable<System.String>. IEnumerable GetDirectoryPaths(string path, bool recursive = false); + /// + /// Gets the file paths. + /// + /// The path. + /// if set to true [recursive]. + /// IEnumerable<System.String>. IEnumerable GetFilePaths(string path, bool recursive = false); + /// + /// Gets the file system entry paths. + /// + /// The path. + /// if set to true [recursive]. + /// IEnumerable<System.String>. IEnumerable GetFileSystemEntryPaths(string path, bool recursive = false); } } diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index ad0c0cecdb..0476f3f602 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -60,6 +60,7 @@ + diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 66a0d551b2..5af02e9bb6 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Providers; namespace MediaBrowser.Controller.Entities @@ -62,7 +63,7 @@ namespace MediaBrowser.Controller.Entities public List PhysicalLocationsList { get; set; } - protected override IEnumerable GetFileSystemChildren(IDirectoryService directoryService) + protected override IEnumerable GetFileSystemChildren(IDirectoryService directoryService) { return CreateResolveArgs(directoryService).FileSystemChildren; } @@ -73,7 +74,7 @@ namespace MediaBrowser.Controller.Entities var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths , directoryService) { - FileInfo = new DirectoryInfo(path), + FileInfo = FileSystem.GetDirectoryInfo(path), Path = path, Parent = Parent }; @@ -94,7 +95,7 @@ namespace MediaBrowser.Controller.Entities { var paths = LibraryManager.NormalizeRootPathList(fileSystemDictionary.Keys); - fileSystemDictionary = paths.Select(i => (FileSystemInfo)new DirectoryInfo(i)).ToDictionary(i => i.FullName); + fileSystemDictionary = paths.Select(FileSystem.GetDirectoryInfo).ToDictionary(i => i.FullName); } args.FileSystemDictionary = fileSystemDictionary; diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 5403c16ddf..963f4725ad 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -676,7 +676,7 @@ namespace MediaBrowser.Controller.Entities /// Loads the theme songs. /// /// List{Audio.Audio}. - private IEnumerable LoadThemeSongs(List fileSystemChildren, IDirectoryService directoryService) + private IEnumerable LoadThemeSongs(List fileSystemChildren, IDirectoryService directoryService) { var files = fileSystemChildren.OfType() .Where(i => string.Equals(i.Name, ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase)) @@ -684,8 +684,8 @@ namespace MediaBrowser.Controller.Entities .ToList(); // Support plex/xbmc convention - files.AddRange(fileSystemChildren.OfType() - .Where(i => string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase)) + files.AddRange(fileSystemChildren + .Where(i => !i.IsDirectory && string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase)) ); return LibraryManager.ResolvePaths(files, directoryService, null) @@ -712,7 +712,7 @@ namespace MediaBrowser.Controller.Entities /// Loads the video backdrops. /// /// List{Video}. - private IEnumerable