|
|
|
@ -1,5 +1,3 @@
|
|
|
|
|
#pragma warning disable CS1591
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Globalization;
|
|
|
|
@ -23,6 +21,11 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
private readonly string _tempPath;
|
|
|
|
|
private static readonly bool _isEnvironmentCaseInsensitive = OperatingSystem.IsWindows();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="ManagedFileSystem"/> class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="logger">The <see cref="ILogger"/> instance to use.</param>
|
|
|
|
|
/// <param name="applicationPaths">The <see cref="IApplicationPaths"/> instance to use.</param>
|
|
|
|
|
public ManagedFileSystem(
|
|
|
|
|
ILogger<ManagedFileSystem> logger,
|
|
|
|
|
IApplicationPaths applicationPaths)
|
|
|
|
@ -31,6 +34,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
_tempPath = applicationPaths.TempDirectory;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual void AddShortcutHandler(IShortcutHandler handler)
|
|
|
|
|
{
|
|
|
|
|
_shortcutHandlers.Add(handler);
|
|
|
|
@ -72,6 +76,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
return handler?.Resolve(filename);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual string MakeAbsolutePath(string folderPath, string filePath)
|
|
|
|
|
{
|
|
|
|
|
// path is actually a stream
|
|
|
|
@ -358,11 +363,13 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
return GetCreationTimeUtc(GetFileSystemInfo(path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual DateTime GetCreationTimeUtc(FileSystemMetadata info)
|
|
|
|
|
{
|
|
|
|
|
return info.CreationTimeUtc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual DateTime GetLastWriteTimeUtc(FileSystemMetadata info)
|
|
|
|
|
{
|
|
|
|
|
return info.LastWriteTimeUtc;
|
|
|
|
@ -397,6 +404,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
return GetLastWriteTimeUtc(GetFileSystemInfo(path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual void SetHidden(string path, bool isHidden)
|
|
|
|
|
{
|
|
|
|
|
if (!OperatingSystem.IsWindows())
|
|
|
|
@ -421,6 +429,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual void SetAttributes(string path, bool isHidden, bool readOnly)
|
|
|
|
|
{
|
|
|
|
|
if (!OperatingSystem.IsWindows())
|
|
|
|
@ -444,7 +453,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
|
|
|
|
|
if (readOnly)
|
|
|
|
|
{
|
|
|
|
|
attributes = attributes | FileAttributes.ReadOnly;
|
|
|
|
|
attributes |= FileAttributes.ReadOnly;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -453,7 +462,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
|
|
|
|
|
if (isHidden)
|
|
|
|
|
{
|
|
|
|
|
attributes = attributes | FileAttributes.Hidden;
|
|
|
|
|
attributes |= FileAttributes.Hidden;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -498,6 +507,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
File.Copy(temp1, file2, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual bool ContainsSubPath(string parentPath, string path)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(parentPath))
|
|
|
|
@ -515,6 +525,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
_isEnvironmentCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual string NormalizePath(string path)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(path))
|
|
|
|
@ -530,6 +541,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
return Path.TrimEndingDirectorySeparator(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual bool AreEqual(string path1, string path2)
|
|
|
|
|
{
|
|
|
|
|
if (path1 == null && path2 == null)
|
|
|
|
@ -548,6 +560,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
_isEnvironmentCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual string GetFileNameWithoutExtension(FileSystemMetadata info)
|
|
|
|
|
{
|
|
|
|
|
if (info.IsDirectory)
|
|
|
|
@ -558,11 +571,11 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
return Path.GetFileNameWithoutExtension(info.FullName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual bool IsPathFile(string path)
|
|
|
|
|
{
|
|
|
|
|
// Cannot use Path.IsPathRooted because it returns false under mono when using windows-based paths, e.g. C:\\
|
|
|
|
|
if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) != -1 &&
|
|
|
|
|
!path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
if (path.Contains("://", StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
&& !path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@ -570,12 +583,14 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual void DeleteFile(string path)
|
|
|
|
|
{
|
|
|
|
|
SetAttributes(path, false, false);
|
|
|
|
|
File.Delete(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual List<FileSystemMetadata> GetDrives()
|
|
|
|
|
{
|
|
|
|
|
// check for ready state to avoid waiting for drives to timeout
|
|
|
|
@ -593,16 +608,19 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
}).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual IEnumerable<FileSystemMetadata> GetDirectories(string path, bool recursive = false)
|
|
|
|
|
{
|
|
|
|
|
return ToMetadata(new DirectoryInfo(path).EnumerateDirectories("*", GetEnumerationOptions(recursive)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual IEnumerable<FileSystemMetadata> GetFiles(string path, bool recursive = false)
|
|
|
|
|
{
|
|
|
|
|
return GetFiles(path, null, false, recursive);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual IEnumerable<FileSystemMetadata> GetFiles(string path, IReadOnlyList<string>? extensions, bool enableCaseSensitiveExtensions, bool recursive = false)
|
|
|
|
|
{
|
|
|
|
|
var enumerationOptions = GetEnumerationOptions(recursive);
|
|
|
|
@ -633,6 +651,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
return ToMetadata(files);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual IEnumerable<FileSystemMetadata> GetFileSystemEntries(string path, bool recursive = false)
|
|
|
|
|
{
|
|
|
|
|
var directoryInfo = new DirectoryInfo(path);
|
|
|
|
@ -646,16 +665,19 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
return infos.Select(GetFileSystemMetadata);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual IEnumerable<string> GetDirectoryPaths(string path, bool recursive = false)
|
|
|
|
|
{
|
|
|
|
|
return Directory.EnumerateDirectories(path, "*", GetEnumerationOptions(recursive));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual IEnumerable<string> GetFilePaths(string path, bool recursive = false)
|
|
|
|
|
{
|
|
|
|
|
return GetFilePaths(path, null, false, recursive);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual IEnumerable<string> GetFilePaths(string path, string[]? extensions, bool enableCaseSensitiveExtensions, bool recursive = false)
|
|
|
|
|
{
|
|
|
|
|
var enumerationOptions = GetEnumerationOptions(recursive);
|
|
|
|
@ -686,6 +708,7 @@ namespace Emby.Server.Implementations.IO
|
|
|
|
|
return files;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public virtual IEnumerable<string> GetFileSystemEntryPaths(string path, bool recursive = false)
|
|
|
|
|
{
|
|
|
|
|
return Directory.EnumerateFileSystemEntries(path, "*", GetEnumerationOptions(recursive));
|
|
|
|
|