Files
DearFTP/DearFTP/Utils/NavigablePath.cs
Eveldee 5face5379c Fix NavigablePath
Copy was in reverse order
2019-07-17 23:53:49 +02:00

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());
}
}
}