276 lines
7.2 KiB
C#
276 lines
7.2 KiB
C#
using DearFTP.Configurations;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace DearFTP.Utils
|
|
{
|
|
class NavigablePath
|
|
{
|
|
public Share[] Shares { get; }
|
|
public Share CurrentShare { get; set; }
|
|
public string CurrentDirectory { get; private set; }
|
|
|
|
private Stack<string> _path;
|
|
|
|
public NavigablePath(Share[] shares)
|
|
{
|
|
Shares = shares;
|
|
CurrentDirectory = "/";
|
|
|
|
_path = new Stack<string>();
|
|
}
|
|
public NavigablePath(NavigablePath navigablePath)
|
|
{
|
|
Shares = navigablePath.Shares;
|
|
CurrentShare = navigablePath.CurrentShare;
|
|
CurrentDirectory = navigablePath.CurrentDirectory;
|
|
|
|
_path = new Stack<string>(navigablePath._path.Reverse());
|
|
}
|
|
|
|
public string GetFilePath(string fileName)
|
|
{
|
|
string path = Path.Combine(GetRealPath(), fileName);
|
|
|
|
if (File.Exists(path))
|
|
{
|
|
return path;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
public string GetFilePath(string path, string fileName)
|
|
{
|
|
var tempNavigablePath = new NavigablePath(this);
|
|
|
|
if (tempNavigablePath.NavigateTo(path))
|
|
{
|
|
return tempNavigablePath.GetFilePath(fileName);
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public string GetDirectoryPath(string directoryName)
|
|
{
|
|
string path = Path.Combine(GetRealPath(), directoryName);
|
|
|
|
if (Directory.Exists(path))
|
|
{
|
|
return path;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
public string GetDirectoryPath(string path, string directoryName)
|
|
{
|
|
var tempNavigablePath = new NavigablePath(this);
|
|
|
|
if (tempNavigablePath.NavigateTo(path))
|
|
{
|
|
return tempNavigablePath.GetDirectoryPath(directoryName);
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public (NavigablePath navigablePath, string realPath, bool isDirectory) GetSystemFilePath(string path)
|
|
{
|
|
var tempNavigablePath = new NavigablePath(this);
|
|
|
|
var split = path.Split('/');
|
|
|
|
if (split.Length > 1)
|
|
{
|
|
string workingPath = string.Join('/', split.SkipLast(1));
|
|
|
|
tempNavigablePath.NavigateTo(workingPath);
|
|
}
|
|
|
|
string name = split.Last();
|
|
|
|
if (tempNavigablePath._path.Count < 1)
|
|
{
|
|
return (tempNavigablePath, null, false);
|
|
}
|
|
|
|
if (tempNavigablePath.GetDirectoryPath(name) is string directoryPath)
|
|
{
|
|
return (tempNavigablePath, directoryPath, true);
|
|
}
|
|
else if (tempNavigablePath.GetFilePath(name) is string filePath)
|
|
{
|
|
return (tempNavigablePath, filePath, false);
|
|
}
|
|
|
|
return (null, null, false);
|
|
}
|
|
|
|
public (NavigablePath navigablePath, string realPath) GetNewSystemFilePath(string path)
|
|
{
|
|
var tempNavigablePath = new NavigablePath(this);
|
|
|
|
var split = path.Split('/');
|
|
|
|
if (split.Length > 1)
|
|
{
|
|
string workingPath = string.Join('/', split.SkipLast(1));
|
|
|
|
if (!tempNavigablePath.NavigateTo(workingPath))
|
|
{
|
|
return (null, null);
|
|
}
|
|
}
|
|
|
|
if (tempNavigablePath._path.Count < 1)
|
|
{
|
|
return (tempNavigablePath, null);
|
|
}
|
|
|
|
return (tempNavigablePath, Path.Combine(GetRealPath(), split.Last()));
|
|
}
|
|
|
|
public IEnumerable<string> GetDirectories()
|
|
{
|
|
if (_path.Count < 1)
|
|
{
|
|
return Shares.Select(x => x.Path);
|
|
}
|
|
|
|
string path = GetRealPath();
|
|
|
|
return Directory.EnumerateDirectories(path);
|
|
}
|
|
public IEnumerable<string> GetDirectories(string path)
|
|
{
|
|
var tempNavigablePath = new NavigablePath(this);
|
|
|
|
if (tempNavigablePath.NavigateTo(path))
|
|
{
|
|
return tempNavigablePath.GetDirectories();
|
|
}
|
|
else
|
|
{
|
|
return Enumerable.Empty<string>();
|
|
}
|
|
}
|
|
|
|
public IEnumerable<string> GetFiles()
|
|
{
|
|
if (_path.Count < 1)
|
|
{
|
|
return Enumerable.Empty<string>();
|
|
}
|
|
|
|
string path = GetRealPath();
|
|
|
|
return Directory.EnumerateFiles(path);
|
|
}
|
|
public IEnumerable<string> GetFiles(string path)
|
|
{
|
|
var tempNavigablePath = new NavigablePath(this);
|
|
|
|
if (tempNavigablePath.NavigateTo(path))
|
|
{
|
|
return tempNavigablePath.GetFiles();
|
|
}
|
|
else
|
|
{
|
|
return Enumerable.Empty<string>();
|
|
}
|
|
}
|
|
|
|
public bool NavigateTo(string path)
|
|
{
|
|
var oldPath = new Stack<string>(_path.Reverse());
|
|
var queue = new Queue<string>(path.Split('/'));
|
|
|
|
// If absolute path
|
|
if (path.StartsWith('/'))
|
|
{
|
|
queue.Dequeue();
|
|
_path.Clear();
|
|
}
|
|
|
|
if (NavigateTo(queue))
|
|
{
|
|
CurrentDirectory = $"/{string.Join('/', _path.Reverse())}";
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
_path = oldPath;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
private bool NavigateTo(Queue<string> paths)
|
|
{
|
|
if (paths.TryDequeue(out string directory))
|
|
{
|
|
// Go to parent
|
|
if (directory == "..")
|
|
{
|
|
_path.TryPop(out _);
|
|
|
|
// Share changed
|
|
if (_path.Count == 0)
|
|
{
|
|
CurrentShare = null;
|
|
}
|
|
|
|
return NavigateTo(paths);
|
|
}
|
|
|
|
// Stay in same folder
|
|
if (directory == "." || directory == "")
|
|
{
|
|
return NavigateTo(paths);
|
|
}
|
|
|
|
// Go to child directory
|
|
if (GetDirectories().Select(x => Path.GetFileName(x)).Contains(directory))
|
|
{
|
|
// Share changed
|
|
if (_path.Count == 0)
|
|
{
|
|
CurrentShare = Shares.First(x => x.Name == directory);
|
|
}
|
|
|
|
_path.Push(directory);
|
|
|
|
return NavigateTo(paths);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private string GetRealPath()
|
|
{
|
|
if (_path.Count < 1)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return Path.Combine(_path.Reverse().Skip(1).Prepend(CurrentShare.Path).ToArray());
|
|
}
|
|
}
|
|
}
|