From 733b891f529c2458d65560f556edf68052be2846 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 1 Apr 2017 20:36:06 -0400 Subject: stub out cifs support --- .../IO/SharpCifsFileSystem.cs | 542 +++++++++++++++++++++ 1 file changed, 542 insertions(+) create mode 100644 Emby.Common.Implementations/IO/SharpCifsFileSystem.cs (limited to 'Emby.Common.Implementations/IO/SharpCifsFileSystem.cs') diff --git a/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs b/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs new file mode 100644 index 000000000..fb32669f1 --- /dev/null +++ b/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs @@ -0,0 +1,542 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SharpCifs.Smb; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.System; + +namespace Emby.Common.Implementations.IO +{ + public class SharpCifsFileSystem + { + private readonly MediaBrowser.Model.System.OperatingSystem _operatingSystem; + + public SharpCifsFileSystem(MediaBrowser.Model.System.OperatingSystem operatingSystem) + { + _operatingSystem = operatingSystem; + } + + public bool IsEnabledForPath(string path) + { + if (_operatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows) + { + return false; + } + + return path.StartsWith("smb://", StringComparison.OrdinalIgnoreCase) || IsUncPath(path); + } + + public FileSystemMetadata GetFileSystemInfo(string path) + { + var file = CreateSmbFile(path); + return ToMetadata(file); + } + + public FileSystemMetadata GetFileInfo(string path) + { + var file = CreateSmbFile(path); + return ToMetadata(file, false); + } + + public FileSystemMetadata GetDirectoryInfo(string path) + { + var file = CreateSmbFile(path); + return ToMetadata(file, true); + } + + private bool IsUncPath(string path) + { + return path.StartsWith("\\\\", StringComparison.OrdinalIgnoreCase); + } + + private string GetReturnPath(SmbFile file) + { + return file.GetCanonicalPath(); + //return file.GetPath(); + } + + private string ConvertUncToSmb(string path) + { + if (IsUncPath(path)) + { + path = path.Replace('\\', '/'); + path = "smb:" + path; + } + return path; + } + + private string AddAuthentication(string path) + { + return path; + } + + private SmbFile CreateSmbFile(string path) + { + path = ConvertUncToSmb(path); + path = AddAuthentication(path); + + return new SmbFile(path); + } + + DateTime baseDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + private FileSystemMetadata ToMetadata(SmbFile info, bool? isDirectory = null) + { + var result = new FileSystemMetadata(); + + result.Exists = info.Exists(); + result.FullName = GetReturnPath(info); + result.Extension = Path.GetExtension(result.FullName); + result.Name = info.GetName(); + + if (result.Exists) + { + result.IsDirectory = info.IsDirectory(); + result.IsHidden = info.IsHidden(); + + result.IsReadOnly = !info.CanWrite(); + + if (info.IsFile()) + { + result.Length = info.Length(); + result.DirectoryName = info.GetParent(); + } + + result.CreationTimeUtc = baseDate.AddMilliseconds(info.CreateTime()); + result.LastWriteTimeUtc = baseDate.AddMilliseconds(info.GetLastModified()); + } + else + { + if (isDirectory.HasValue) + { + result.IsDirectory = isDirectory.Value; + } + } + + return result; + } + + public void SetHidden(string path, bool isHidden) + { + var file = CreateSmbFile(path); + + var isCurrentlyHidden = file.IsHidden(); + + if (isCurrentlyHidden && !isHidden) + { + file.SetAttributes(file.GetAttributes() & ~SmbFile.AttrReadonly); + } + else if (!isCurrentlyHidden && isHidden) + { + file.SetAttributes(file.GetAttributes() | SmbFile.AttrReadonly); + } + } + + public void SetReadOnly(string path, bool isReadOnly) + { + var file = CreateSmbFile(path); + + var isCurrentlyReadOnly = !file.CanWrite(); + + if (isCurrentlyReadOnly && !isReadOnly) + { + file.SetReadWrite(); + } + else if (!isCurrentlyReadOnly && isReadOnly) + { + file.SetReadOnly(); + } + } + + public void DeleteFile(string path) + { + var file = CreateSmbFile(path); + + AssertFileExists(file, path); + + file.Delete(); + } + + public void DeleteDirectory(string path, bool recursive) + { + var file = CreateSmbFile(path); + + AssertDirectoryExists(file, path); + + file.Delete(); + } + + public void CreateDirectory(string path) + { + } + + public string[] ReadAllLines(string path) + { + var lines = new List(); + + using (var stream = OpenRead(path)) + { + using (var reader = new StreamReader(stream)) + { + while (!reader.EndOfStream) + { + lines.Add(reader.ReadLine()); + } + } + } + + return lines.ToArray(); + } + + public void WriteAllLines(string path, IEnumerable lines) + { + using (var stream = GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + using (var writer = new StreamWriter(stream)) + { + foreach (var line in lines) + { + writer.WriteLine(line); + } + } + } + } + + private void AssertFileExists(SmbFile file, string path) + { + if (!file.Exists()) + { + throw new FileNotFoundException("File not found.", path); + } + } + + private void AssertDirectoryExists(SmbFile file, string path) + { + if (!file.Exists()) + { + throw new FileNotFoundException("File not found.", path); + } + } + + public Stream OpenRead(string path) + { + var file = CreateSmbFile(path); + + AssertFileExists(file, path); + + return file.GetInputStream(); + } + + private Stream OpenWrite(string path) + { + var file = CreateSmbFile(path); + + AssertFileExists(file, path); + + return file.GetInputStream(); + } + + public void CopyFile(string source, string target, bool overwrite) + { + if (string.Equals(source, target, StringComparison.Ordinal)) + { + throw new ArgumentException("Cannot CopyFile when source and target are the same"); + } + + using (var input = OpenRead(source)) + { + using (var output = GetFileStream(target, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + input.CopyTo(output); + } + } + } + + public void MoveFile(string source, string target) + { + if (string.Equals(source, target, StringComparison.Ordinal)) + { + throw new ArgumentException("Cannot MoveFile when source and target are the same"); + } + + using (var input = OpenRead(source)) + { + using (var output = GetFileStream(target, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + input.CopyTo(output); + } + } + + DeleteFile(source); + } + + public void MoveDirectory(string source, string target) + { + throw new NotImplementedException(); + } + + public bool DirectoryExists(string path) + { + var dir = CreateSmbFile(path); + + return dir.Exists() && dir.IsDirectory(); + } + + public bool FileExists(string path) + { + var file = CreateSmbFile(path); + return file.Exists(); + } + + public string ReadAllText(string path, Encoding encoding) + { + using (var stream = OpenRead(path)) + { + using (var reader = new StreamReader(stream, encoding)) + { + return reader.ReadToEnd(); + } + } + } + + public Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share) + { + if (mode == FileOpenMode.OpenOrCreate) + { + var file = CreateSmbFile(path); + if (!file.Exists()) + { + file.CreateNewFile(); + } + + mode = FileOpenMode.Open; + } + + if (mode == FileOpenMode.CreateNew) + { + var file = CreateSmbFile(path); + if (file.Exists()) + { + throw new IOException("File already exists"); + } + + file.CreateNewFile(); + + mode = FileOpenMode.Open; + } + + if (mode == FileOpenMode.Create) + { + var file = CreateSmbFile(path); + if (file.Exists()) + { + if (file.IsHidden()) + { + throw new UnauthorizedAccessException(string.Format("File {0} already exists and is hidden", path)); + } + + file.Delete(); + file.CreateNewFile(); + } + else + { + file.CreateNewFile(); + } + + mode = FileOpenMode.Open; + } + + if (mode == FileOpenMode.Open) + { + if (access == FileAccessMode.Read) + { + return OpenRead(path); + } + if (access == FileAccessMode.Write) + { + return OpenWrite(path); + } + throw new NotImplementedException(); + } + throw new NotImplementedException(); + } + + public void WriteAllBytes(string path, byte[] bytes) + { + using (var stream = GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + stream.Write(bytes, 0, bytes.Length); + } + } + + public void WriteAllText(string path, string text) + { + using (var stream = GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + using (var writer = new StreamWriter(stream)) + { + writer.Write(text); + } + } + } + + public void WriteAllText(string path, string text, Encoding encoding) + { + using (var stream = GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + using (var writer = new StreamWriter(stream, encoding)) + { + writer.Write(text); + } + } + } + + public string ReadAllText(string path) + { + using (var stream = OpenRead(path)) + { + using (var reader = new StreamReader(stream)) + { + return reader.ReadToEnd(); + } + } + } + + public byte[] ReadAllBytes(string path) + { + using (var stream = OpenRead(path)) + { + using (var ms = new MemoryStream()) + { + stream.CopyTo(ms); + ms.Position = 0; + return ms.ToArray(); + } + } + } + + public IEnumerable GetDirectories(string path, bool recursive = false) + { + var dir = CreateSmbFile(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + if (file.IsDirectory()) + { + yield return ToMetadata(file); + } + } + } + + public IEnumerable GetFiles(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) + { + var dir = CreateSmbFile(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + if (file.IsFile()) + { + var filePath = GetReturnPath(file); + var extension = Path.GetExtension(filePath); + + if (extensions == null || extensions.Length == 0 || extensions.Contains(extension ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + yield return ToMetadata(file); + } + } + } + } + + public IEnumerable GetFileSystemEntries(string path, bool recursive = false) + { + var dir = CreateSmbFile(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + yield return ToMetadata(file); + } + } + + public IEnumerable GetFileSystemEntryPaths(string path, bool recursive = false) + { + var dir = CreateSmbFile(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + yield return GetReturnPath(file); + } + } + + public IEnumerable GetFilePaths(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) + { + var dir = CreateSmbFile(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + if (file.IsFile()) + { + var filePath = GetReturnPath(file); + var extension = Path.GetExtension(filePath); + + if (extensions == null || extensions.Length == 0 || extensions.Contains(extension ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + yield return filePath; + } + } + } + } + + public IEnumerable GetDirectoryPaths(string path, bool recursive = false) + { + var dir = CreateSmbFile(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + if (file.IsDirectory()) + { + yield return GetReturnPath(file); + } + } + } + + private IEnumerable ListFiles(SmbFile dir, bool recursive) + { + var list = dir.ListFiles(); + + foreach (var file in list) + { + yield return file; + + if (recursive && file.IsDirectory()) + { + foreach (var subFile in ListFiles(file, recursive)) + { + yield return subFile; + } + } + } + } + } +} -- cgit v1.2.3 From 6e4d2342120c4bde4fdc99bc17dea0aec7b75ced Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 2 Apr 2017 00:08:07 -0400 Subject: update directory picker --- .../IO/ManagedFileSystem.cs | 28 ++++++++++++---------- .../IO/SharpCifsFileSystem.cs | 21 ++++++++++------ .../HttpServer/HttpListenerHost.cs | 13 ++++++++-- MediaBrowser.Model/IO/IFileSystem.cs | 1 - 4 files changed, 41 insertions(+), 22 deletions(-) (limited to 'Emby.Common.Implementations/IO/SharpCifsFileSystem.cs') diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs index f1f044bc5..d1903851f 100644 --- a/Emby.Common.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs @@ -69,14 +69,6 @@ namespace Emby.Common.Implementations.IO } } - public char PathSeparator - { - get - { - return Path.PathSeparator; - } - } - public string GetFullPath(string path) { return Path.GetFullPath(path); @@ -544,6 +536,16 @@ namespace Emby.Common.Implementations.IO CopyFile(temp1, file2, true); } + private char GetSeparatorChar(string path) + { + if (path.IndexOf('/') != -1) + { + return '/'; + } + + return '\\'; + } + public bool AreEqual(string path1, string path2) { if (path1 == null && path2 == null) @@ -556,8 +558,8 @@ namespace Emby.Common.Implementations.IO return false; } - path1 = path1.TrimEnd(DirectorySeparatorChar); - path2 = path2.TrimEnd(DirectorySeparatorChar); + path1 = path1.TrimEnd(GetSeparatorChar(path1)); + path2 = path2.TrimEnd(GetSeparatorChar(path2)); return string.Equals(path1, path2, StringComparison.OrdinalIgnoreCase); } @@ -574,7 +576,9 @@ namespace Emby.Common.Implementations.IO throw new ArgumentNullException("path"); } - return path.IndexOf(parentPath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) != -1; + var separatorChar = GetSeparatorChar(parentPath); + + return path.IndexOf(parentPath.TrimEnd(separatorChar) + separatorChar, StringComparison.OrdinalIgnoreCase) != -1; } public bool IsRootPath(string path) @@ -606,7 +610,7 @@ namespace Emby.Common.Implementations.IO return path; } - return path.TrimEnd(Path.DirectorySeparatorChar); + return path.TrimEnd(GetSeparatorChar(path)); } public string GetFileNameWithoutExtension(FileSystemMetadata info) diff --git a/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs b/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs index fb32669f1..f2157b7af 100644 --- a/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs +++ b/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs @@ -55,7 +55,7 @@ namespace Emby.Common.Implementations.IO private string GetReturnPath(SmbFile file) { - return file.GetCanonicalPath(); + return file.GetCanonicalPath().TrimEnd('/'); //return file.GetPath(); } @@ -419,9 +419,16 @@ namespace Emby.Common.Implementations.IO } } + private SmbFile CreateSmbDirectoryForListFiles(string path) + { + // In order to call ListFiles, it has to end with the separator + + return CreateSmbFile(path.TrimEnd('/') + '/'); + } + public IEnumerable GetDirectories(string path, bool recursive = false) { - var dir = CreateSmbFile(path); + var dir = CreateSmbDirectoryForListFiles(path); AssertDirectoryExists(dir, path); var list = ListFiles(dir, recursive); @@ -437,7 +444,7 @@ namespace Emby.Common.Implementations.IO public IEnumerable GetFiles(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) { - var dir = CreateSmbFile(path); + var dir = CreateSmbDirectoryForListFiles(path); AssertDirectoryExists(dir, path); var list = ListFiles(dir, recursive); @@ -459,7 +466,7 @@ namespace Emby.Common.Implementations.IO public IEnumerable GetFileSystemEntries(string path, bool recursive = false) { - var dir = CreateSmbFile(path); + var dir = CreateSmbDirectoryForListFiles(path); AssertDirectoryExists(dir, path); var list = ListFiles(dir, recursive); @@ -472,7 +479,7 @@ namespace Emby.Common.Implementations.IO public IEnumerable GetFileSystemEntryPaths(string path, bool recursive = false) { - var dir = CreateSmbFile(path); + var dir = CreateSmbDirectoryForListFiles(path); AssertDirectoryExists(dir, path); var list = ListFiles(dir, recursive); @@ -485,7 +492,7 @@ namespace Emby.Common.Implementations.IO public IEnumerable GetFilePaths(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) { - var dir = CreateSmbFile(path); + var dir = CreateSmbDirectoryForListFiles(path); AssertDirectoryExists(dir, path); var list = ListFiles(dir, recursive); @@ -507,7 +514,7 @@ namespace Emby.Common.Implementations.IO public IEnumerable GetDirectoryPaths(string path, bool recursive = false) { - var dir = CreateSmbFile(path); + var dir = CreateSmbDirectoryForListFiles(path); AssertDirectoryExists(dir, path); var list = ListFiles(dir, recursive); diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 6d15cc619..ee5245a69 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -273,10 +273,19 @@ namespace Emby.Server.Implementations.HttpServer return 400; } + var exceptionType = ex.GetType(); + int statusCode; - if (!_mapExceptionToStatusCode.TryGetValue(ex.GetType(), out statusCode)) + if (!_mapExceptionToStatusCode.TryGetValue(exceptionType, out statusCode)) { - statusCode = 500; + if (string.Equals(exceptionType.Name, "DirectoryNotFoundException", StringComparison.OrdinalIgnoreCase)) + { + statusCode = 404; + } + else + { + statusCode = 500; + } } return statusCode; diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs index 59e31debd..6773acbfa 100644 --- a/MediaBrowser.Model/IO/IFileSystem.cs +++ b/MediaBrowser.Model/IO/IFileSystem.cs @@ -312,7 +312,6 @@ namespace MediaBrowser.Model.IO void SetReadOnly(string path, bool isHidden); char DirectorySeparatorChar { get; } - char PathSeparator { get; } string GetFullPath(string path); -- cgit v1.2.3 From 4a8960fc866143e7107a5bc41527db6c5581974f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 2 Apr 2017 00:45:57 -0400 Subject: 3.2.10.4 --- Emby.Common.Implementations/IO/ManagedFileSystem.cs | 16 ++++++++-------- Emby.Common.Implementations/IO/SharpCifsFileSystem.cs | 10 ++++++++++ SharedVersion.cs | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'Emby.Common.Implementations/IO/SharpCifsFileSystem.cs') diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs index d1903851f..ba73c1ba2 100644 --- a/Emby.Common.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs @@ -536,14 +536,14 @@ namespace Emby.Common.Implementations.IO CopyFile(temp1, file2, true); } - private char GetSeparatorChar(string path) + private char GetDirectorySeparatorChar(string path) { - if (path.IndexOf('/') != -1) + if (_sharpCifsFileSystem.IsEnabledForPath(path)) { - return '/'; + return _sharpCifsFileSystem.GetDirectorySeparatorChar(path); } - return '\\'; + return Path.DirectorySeparatorChar; } public bool AreEqual(string path1, string path2) @@ -558,8 +558,8 @@ namespace Emby.Common.Implementations.IO return false; } - path1 = path1.TrimEnd(GetSeparatorChar(path1)); - path2 = path2.TrimEnd(GetSeparatorChar(path2)); + path1 = path1.TrimEnd(GetDirectorySeparatorChar(path1)); + path2 = path2.TrimEnd(GetDirectorySeparatorChar(path2)); return string.Equals(path1, path2, StringComparison.OrdinalIgnoreCase); } @@ -576,7 +576,7 @@ namespace Emby.Common.Implementations.IO throw new ArgumentNullException("path"); } - var separatorChar = GetSeparatorChar(parentPath); + var separatorChar = GetDirectorySeparatorChar(parentPath); return path.IndexOf(parentPath.TrimEnd(separatorChar) + separatorChar, StringComparison.OrdinalIgnoreCase) != -1; } @@ -610,7 +610,7 @@ namespace Emby.Common.Implementations.IO return path; } - return path.TrimEnd(GetSeparatorChar(path)); + return path.TrimEnd(GetDirectorySeparatorChar(path)); } public string GetFileNameWithoutExtension(FileSystemMetadata info) diff --git a/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs b/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs index f2157b7af..c1e429dc9 100644 --- a/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs +++ b/Emby.Common.Implementations/IO/SharpCifsFileSystem.cs @@ -30,6 +30,16 @@ namespace Emby.Common.Implementations.IO return path.StartsWith("smb://", StringComparison.OrdinalIgnoreCase) || IsUncPath(path); } + public char GetDirectorySeparatorChar(string path) + { + if (path.IndexOf('/') != -1) + { + return '/'; + } + + return '\\'; + } + public FileSystemMetadata GetFileSystemInfo(string path) { var file = CreateSmbFile(path); diff --git a/SharedVersion.cs b/SharedVersion.cs index 6f5bd9b1f..6f3c5261f 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.10.3")] +[assembly: AssemblyVersion("3.2.10.4")] -- cgit v1.2.3