using FileFlows.Plugin;
using FileFlows.Plugin.Models;
using FileFlows.Plugin.Services;
using System.IO;
using FileHelper = FileFlows.Plugin.Helpers.FileHelper;
namespace PluginTestLibrary;
///
/// Local file service
///
public class LocalFileService : IFileService
{
///
/// Gets or sets the path separator for the file system
///
public char PathSeparator { get; init; } = Path.DirectorySeparatorChar;
public ReplaceVariablesDelegate? ReplaceVariables { get; set; }
///
/// Gets or sets the allowed paths the file service can access
///
public string[] AllowedPaths { get; init; } = null!;
///
/// Gets or sets the permissions to use for files
///
public int? Permissions { get; set; }
///
/// Gets or sets the owner:group to use for files
///
public string OwnerGroup { get; set; } = null!;
///
/// Gets or sets the logger used for logging
///
public ILogger? Logger { get; set; }
public Result GetFiles(string path, string searchPattern = "", bool recursive = false)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
return Directory.GetFiles(path, searchPattern ?? string.Empty,
recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
}
catch (Exception)
{
return new string[] { };
}
}
public Result GetDirectories(string path)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
return Directory.GetDirectories(path);
}
catch (Exception)
{
return new string[] { };
}
}
public Result DirectoryExists(string path)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
return Directory.Exists(path);
}
catch (Exception)
{
return false;
}
}
public Result DirectoryDelete(string path, bool recursive = false)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
Directory.Delete(path, recursive);
return true;
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
public Result DirectoryMove(string path, string destination)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
if (IsProtectedPath(ref destination))
return Result.Fail("Cannot access protected path: " + destination);
try
{
Directory.Move(path, destination);
SetPermissions(destination);
return true;
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
public Result DirectoryCreate(string path)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
var dirInfo = new DirectoryInfo(path);
if (dirInfo.Exists == false)
dirInfo.Create();
SetPermissions(path);
return true;
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
public Result DirectoryCreationTimeUtc(string path)
{
throw new NotImplementedException();
}
public Result DirectoryLastWriteTimeUtc(string path)
{
throw new NotImplementedException();
}
public Result FileExists(string path)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
return System.IO.File.Exists(path);
}
catch (Exception)
{
return false;
}
}
public Result FileInfo(string path)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
FileInfo fileInfo = new FileInfo(path);
return new FileInformation
{
CreationTime = fileInfo.CreationTime,
CreationTimeUtc = fileInfo.CreationTimeUtc,
LastWriteTime = fileInfo.LastWriteTime,
LastWriteTimeUtc = fileInfo.LastWriteTimeUtc,
Extension = fileInfo.Extension.TrimStart('.'),
Name = fileInfo.Name,
FullName = fileInfo.FullName,
Length = fileInfo.Length,
Directory = fileInfo.DirectoryName!
};
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
public Result FileDelete(string path)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
var fileInfo = new FileInfo(path);
if(fileInfo.Exists)
fileInfo.Delete();
return true;
}
catch (Exception)
{
return false;
}
}
public Result FileSize(string path)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
var fileInfo = new FileInfo(path);
if (fileInfo.Exists == false)
return Result.Fail("File does not exist");
return fileInfo.Length;
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
public Result FileCreationTimeUtc(string path)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
var fileInfo = new FileInfo(path);
if (fileInfo.Exists == false)
return Result.Fail("File does not exist");
return fileInfo.CreationTimeUtc;
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
public Result FileLastWriteTimeUtc(string path)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
var fileInfo = new FileInfo(path);
if (fileInfo.Exists == false)
return Result.Fail("File does not exist");
return fileInfo.LastWriteTimeUtc;
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
public Result FileMove(string path, string destination, bool overwrite = true)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
if (IsProtectedPath(ref destination))
return Result.Fail("Cannot access protected path: " + destination);
try
{
var fileInfo = new FileInfo(path);
if (fileInfo.Exists == false)
return Result.Fail("File does not exist");
var destDir = new FileInfo(destination).Directory!;
if (destDir.Exists == false)
{
destDir.Create();
SetPermissions(destDir.FullName);
}
fileInfo.MoveTo(destination, overwrite);
SetPermissions(destination);
return true;
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
public Result FileCopy(string path, string destination, bool overwrite = true)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
if (IsProtectedPath(ref destination))
return Result.Fail("Cannot access protected path: " + destination);
try
{
var fileInfo = new FileInfo(path);
if (fileInfo.Exists == false)
return Result.Fail("File does not exist");
var destDir = new FileInfo(destination).Directory!;
if (destDir.Exists == false)
{
destDir.Create();
SetPermissions(destDir.FullName);
}
fileInfo.CopyTo(destination, overwrite);
SetPermissions(destination);
return true;
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
public Result FileAppendAllText(string path, string text)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
System.IO.File.AppendAllText(path, text);
SetPermissions(path);
return true;
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
public bool FileIsLocal(string path) => true;
///
/// Gets the local path
///
/// the path
/// the local path to the file
public Result GetLocalPath(string path)
=> Result.Success(path);
public Result Touch(string path)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
if (DirectoryExists(path).Is(true))
{
try
{
Directory.SetLastWriteTimeUtc(path, DateTime.UtcNow);
return true;
}
catch (Exception ex)
{
return Result.Fail("Failed to touch directory: " + ex.Message);
}
}
try
{
if (System.IO.File.Exists(path))
System.IO.File.SetLastWriteTimeUtc(path, DateTime.UtcNow);
else
{
System.IO.File.Create(path);
SetPermissions(path);
}
return true;
}
catch (Exception ex)
{
return Result.Fail($"Failed to touch file: '{path}' => {ex.Message}");
}
}
public Result DirectorySize(string path)
{
if (string.IsNullOrWhiteSpace(path))
return 0;
if (System.IO.File.Exists(path))
path = new FileInfo(path).Directory?.FullName ?? string.Empty;
if (string.IsNullOrWhiteSpace(path))
return 0;
if (Directory.Exists(path) == false)
return 0;
try
{
DirectoryInfo dir = new DirectoryInfo(path);
return dir.EnumerateFiles("*.*", SearchOption.AllDirectories).Sum(x => x.Length);
}
catch (Exception)
{
return 0;
}
}
public Result SetCreationTimeUtc(string path, DateTime date)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
if (!System.IO.File.Exists(path))
return Result.Fail("File not found.");
System.IO.File.SetCreationTimeUtc(path, date);
return Result.Success(true);
}
catch (Exception ex)
{
return Result.Fail($"Error setting creation time: {ex.Message}");
}
}
public Result SetLastWriteTimeUtc(string path, DateTime date)
{
if (IsProtectedPath(ref path))
return Result.Fail("Cannot access protected path: " + path);
try
{
if (!System.IO.File.Exists(path))
return Result.Fail("File not found.");
System.IO.File.SetLastWriteTimeUtc(path, date);
return Result.Success(true);
}
catch (Exception ex)
{
return Result.Fail($"Error setting last write time: {ex.Message}");
}
}
///
/// Checks if a path is accessible by the file server
///
/// the path to check
/// true if accessible, otherwise false
private bool IsProtectedPath(ref string path)
{
if (OperatingSystem.IsWindows())
path = path.Replace("/", "\\");
else
path = path.Replace("\\", "/");
if(ReplaceVariables != null)
path = ReplaceVariables(path, true);
if (FileHelper.IsSystemDirectory(path))
return true; // a system directory, no access
if (AllowedPaths?.Any() != true)
return false; // no allowed paths configured, allow all
if (OperatingSystem.IsWindows())
path = path.ToLowerInvariant();
for(int i=0;i? logMethod = null)
{
logMethod ??= (string message) => Logger?.ILog(message);
permissions = permissions != null && permissions > 0 ? permissions : Permissions;
if (permissions == null || permissions < 1)
permissions = 777;
if ((System.IO.File.Exists(path) == false && Directory.Exists(path) == false))
{
logMethod("SetPermissions: File doesnt existing, skipping");
return;
}
//StringLogger stringLogger = new StringLogger();
var logger = new TestLogger();
bool isFile = new FileInfo(path).Exists;
FileHelper.SetPermissions(logger, path, file: isFile, permissions: permissions);
FileHelper.ChangeOwner(logger, path, file: isFile, ownerGroup: OwnerGroup);
logMethod(logger.ToString());
}
}