489 lines
20 KiB
C#
489 lines
20 KiB
C#
using System.Collections.ObjectModel;
|
|
|
|
namespace View_by_Distance.Shared.Models.Stateless;
|
|
|
|
internal abstract class XPath
|
|
{
|
|
|
|
private static ReadOnlyDictionary<byte, ReadOnlyCollection<string>> Convert(List<CombinedEnumAndIndex> collection)
|
|
{
|
|
Dictionary<byte, List<string>> results = [];
|
|
List<string>? c;
|
|
foreach (CombinedEnumAndIndex cei in collection)
|
|
{
|
|
if (!results.TryGetValue(cei.Enum, out c))
|
|
{
|
|
results.Add(cei.Enum, []);
|
|
if (!results.TryGetValue(cei.Enum, out c))
|
|
throw new Exception();
|
|
}
|
|
c.Add(cei.Combined);
|
|
}
|
|
return Convert(results);
|
|
}
|
|
|
|
private static ReadOnlyDictionary<int, ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>>> Convert(Dictionary<int, Dictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>>> keyValuePairs)
|
|
{
|
|
Dictionary<int, ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>>> results = [];
|
|
foreach (KeyValuePair<int, Dictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>>> keyValuePair in keyValuePairs)
|
|
results.Add(keyValuePair.Key, new(keyValuePair.Value));
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
internal static void DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories)
|
|
{
|
|
if (Directory.Exists(rootDirectory))
|
|
{
|
|
string[] files;
|
|
string[] directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
if (directories.Length > 0)
|
|
files = [];
|
|
else
|
|
files = Directory.GetFiles(rootDirectory, "*", SearchOption.AllDirectories);
|
|
if (directories.Length == 0 && files.Length == 0)
|
|
{
|
|
deletedDirectories.Add(rootDirectory);
|
|
try
|
|
{ Directory.Delete(rootDirectory); }
|
|
catch (UnauthorizedAccessException)
|
|
{
|
|
new DirectoryInfo(rootDirectory).Attributes = FileAttributes.Normal;
|
|
Directory.Delete(rootDirectory);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
List<string> check = [];
|
|
foreach (string directory in directories)
|
|
{
|
|
DeleteEmptyDirectories(directory, check);
|
|
deletedDirectories.AddRange(check);
|
|
if (check.Count > 0)
|
|
DeleteEmptyDirectories(directory, deletedDirectories);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static byte GetEnum(FilePath filePath) =>
|
|
GetEnum(filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal);
|
|
|
|
private static byte GetEnum(bool? ik, bool? dto)
|
|
{
|
|
byte result;
|
|
if (ik is not null && ik.Value && dto is not null && dto.Value)
|
|
result = 11;
|
|
else if (ik is not null && ik.Value && dto is not null && !dto.Value)
|
|
result = 15;
|
|
else if (ik is not null && ik.Value && dto is null)
|
|
result = 19;
|
|
else if (ik is not null && !ik.Value && dto is not null && dto.Value)
|
|
result = 51;
|
|
else if (ik is not null && !ik.Value && dto is not null && !dto.Value)
|
|
result = 55;
|
|
else if (ik is not null && !ik.Value && dto is null)
|
|
result = 59;
|
|
else if (ik is null && dto is not null && dto.Value)
|
|
result = 91;
|
|
else if (ik is null && dto is not null && !dto.Value)
|
|
result = 95;
|
|
else if (ik is null && dto is null)
|
|
result = 99;
|
|
else
|
|
throw new Exception();
|
|
return result;
|
|
}
|
|
|
|
internal static List<string> GetDirectories(string directory)
|
|
{
|
|
List<string> results = [];
|
|
string? checkDirectory = directory;
|
|
string? pathRoot = Path.GetPathRoot(directory);
|
|
if (string.IsNullOrEmpty(pathRoot))
|
|
throw new NullReferenceException(nameof(pathRoot));
|
|
if (Directory.Exists(directory))
|
|
results.Add(directory);
|
|
for (int i = 0; i < int.MaxValue; i++)
|
|
{
|
|
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
|
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
|
|
break;
|
|
results.Add(checkDirectory);
|
|
}
|
|
results.Add(pathRoot);
|
|
results.Reverse();
|
|
return results;
|
|
}
|
|
|
|
internal static List<string> GetDirectoryNames(string directory)
|
|
{
|
|
List<string> results = [];
|
|
string? fileName;
|
|
string? checkDirectory = directory;
|
|
string? pathRoot = Path.GetPathRoot(directory);
|
|
string extension = Path.GetExtension(directory);
|
|
if (string.IsNullOrEmpty(pathRoot))
|
|
throw new NullReferenceException(nameof(pathRoot));
|
|
if (Directory.Exists(directory))
|
|
{
|
|
fileName = Path.GetFileName(directory);
|
|
if (!string.IsNullOrEmpty(fileName))
|
|
results.Add(fileName);
|
|
}
|
|
else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory))
|
|
{
|
|
fileName = Path.GetFileName(directory);
|
|
if (!string.IsNullOrEmpty(fileName))
|
|
results.Add(fileName);
|
|
}
|
|
for (int i = 0; i < int.MaxValue; i++)
|
|
{
|
|
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
|
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
|
|
break;
|
|
fileName = Path.GetFileName(checkDirectory);
|
|
if (string.IsNullOrEmpty(fileName))
|
|
continue;
|
|
results.Add(fileName);
|
|
}
|
|
results.Add(pathRoot);
|
|
results.Reverse();
|
|
return results;
|
|
}
|
|
|
|
internal static bool DeleteEmptyDirectories(string rootDirectory)
|
|
{
|
|
bool result;
|
|
List<string> results = [];
|
|
DeleteEmptyDirectories(rootDirectory, results);
|
|
result = results.Count > 0;
|
|
return result;
|
|
}
|
|
|
|
internal static void MakeHiddenIfAllItemsAreHidden(string rootDirectory)
|
|
{
|
|
bool check;
|
|
FileInfo fileInfo;
|
|
IEnumerable<string> files;
|
|
DirectoryInfo directoryInfo;
|
|
IEnumerable<string> subDirectories;
|
|
string[] directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
|
|
foreach (string directory in directories)
|
|
{
|
|
directoryInfo = new(directory);
|
|
if (directoryInfo.Attributes.HasFlag(FileAttributes.Hidden))
|
|
continue;
|
|
check = true;
|
|
subDirectories = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly);
|
|
foreach (string subDirectory in subDirectories)
|
|
{
|
|
directoryInfo = new(subDirectory);
|
|
if (!directoryInfo.Attributes.HasFlag(FileAttributes.Hidden))
|
|
{
|
|
check = false;
|
|
break;
|
|
}
|
|
}
|
|
if (!check)
|
|
continue;
|
|
files = Directory.EnumerateFiles(directory, "*", SearchOption.TopDirectoryOnly);
|
|
foreach (string file in files)
|
|
{
|
|
fileInfo = new(file);
|
|
if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
|
|
{
|
|
check = false;
|
|
break;
|
|
}
|
|
}
|
|
if (!check)
|
|
continue;
|
|
directoryInfo.Attributes |= FileAttributes.Hidden;
|
|
}
|
|
}
|
|
|
|
internal static void CreateDirectories(ReadOnlyCollection<string> directories)
|
|
{
|
|
string checkDirectory;
|
|
foreach (string directory in directories)
|
|
{
|
|
for (int i = 0; i < 101; i++)
|
|
{
|
|
checkDirectory = Path.Combine(directory, i.ToString("000"));
|
|
if (!Directory.Exists(checkDirectory))
|
|
_ = Directory.CreateDirectory(checkDirectory);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static void ChangeDateForEmptyDirectories(string rootDirectory, long ticks)
|
|
{
|
|
DateTime dateTime = new(ticks);
|
|
IEnumerable<string> fileSystemEntries;
|
|
string[] directories;
|
|
if (!Directory.Exists(rootDirectory))
|
|
directories = [];
|
|
else
|
|
directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
|
|
foreach (string directory in directories)
|
|
{
|
|
fileSystemEntries = Directory.EnumerateFileSystemEntries(directory, "*", SearchOption.TopDirectoryOnly);
|
|
if (fileSystemEntries.Any())
|
|
continue;
|
|
Directory.SetLastWriteTime(directory, dateTime);
|
|
}
|
|
}
|
|
|
|
internal static string GetRelativePath(string path, int length, bool forceExtensionToLower)
|
|
{
|
|
string result;
|
|
if (forceExtensionToLower)
|
|
{
|
|
string extension = Path.GetExtension(path);
|
|
string extensionLowered = Path.GetExtension(path).ToLower();
|
|
if (extension != extensionLowered)
|
|
{
|
|
string? directoryName = Path.GetDirectoryName(path);
|
|
if (string.IsNullOrEmpty(directoryName))
|
|
throw new NullReferenceException(directoryName);
|
|
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
|
|
if (string.IsNullOrEmpty(fileNameWithoutExtension))
|
|
throw new NullReferenceException(fileNameWithoutExtension);
|
|
path = Path.Combine(directoryName, $"{fileNameWithoutExtension}{extensionLowered}");
|
|
}
|
|
}
|
|
result = path[length..].Replace(@"\", "/");
|
|
return result;
|
|
}
|
|
|
|
internal static string GetDirectory(string sourceDirectory, int level, string directoryName)
|
|
{
|
|
string result;
|
|
string? checkDirectory;
|
|
checkDirectory = Path.GetDirectoryName(sourceDirectory);
|
|
for (int i = 0; i < level; i++)
|
|
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
|
if (string.IsNullOrEmpty(checkDirectory))
|
|
throw new Exception();
|
|
checkDirectory = Path.Combine(checkDirectory, directoryName);
|
|
if (!Directory.Exists(checkDirectory))
|
|
_ = Directory.CreateDirectory(checkDirectory);
|
|
result = checkDirectory;
|
|
return result;
|
|
}
|
|
|
|
internal static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory)
|
|
{
|
|
int result = 0;
|
|
string? directory;
|
|
string? checkDirectory;
|
|
List<string> results = [];
|
|
checkDirectory = sourceDirectory;
|
|
for (int i = 0; i < int.MaxValue; i++)
|
|
{
|
|
result += 1;
|
|
directory = Path.GetFileName(checkDirectory);
|
|
if (string.IsNullOrEmpty(directory))
|
|
break;
|
|
results.Add(directory);
|
|
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
|
if (checkDirectory == rootDirectory)
|
|
break;
|
|
}
|
|
results.Reverse();
|
|
return new(result, results);
|
|
}
|
|
|
|
internal static CombinedEnumAndIndex GetCombinedEnumAndIndex(ResultSettings resultSettings, FilePath filePath)
|
|
{
|
|
CombinedEnumAndIndex result;
|
|
if (filePath.Id is not null)
|
|
result = GetCombinedEnumAndIndex(resultSettings, filePath, filePath.Id.Value.ToString());
|
|
else
|
|
result = GetCombinedEnumAndIndex(resultSettings, filePath, filePath.NameWithoutExtension);
|
|
return result;
|
|
}
|
|
|
|
private static CombinedEnumAndIndex GetCombinedEnumAndIndex(ResultSettings resultSettings, FilePath filePath, string fileNameWithoutExtension)
|
|
{
|
|
CombinedEnumAndIndex result;
|
|
byte @enum;
|
|
int converted;
|
|
string combined;
|
|
byte missingDateTimeOriginal = IId.GetMissingDateTimeOriginal(resultSettings, filePath);
|
|
if (!filePath.IsIntelligentIdFormat)
|
|
@enum = missingDateTimeOriginal;
|
|
else
|
|
{
|
|
if (filePath.HasIgnoreKeyword is null || filePath.HasDateTimeOriginal is null)
|
|
throw new NotImplementedException("Chicken and Egg!");
|
|
if (filePath.HasIgnoreKeyword.Value)
|
|
@enum = IId.GetHasIgnoreKeyword(filePath);
|
|
else if (!filePath.HasDateTimeOriginal.Value)
|
|
@enum = missingDateTimeOriginal;
|
|
else
|
|
@enum = IId.GetHasDateTimeOriginal(resultSettings, filePath);
|
|
}
|
|
string fileNameBeforeFirst = fileNameWithoutExtension.Split('.')[0];
|
|
string check = fileNameBeforeFirst.Length < resultSettings.ResultAllInOneSubdirectoryLength ?
|
|
new('-', resultSettings.ResultAllInOneSubdirectoryLength) :
|
|
fileNameBeforeFirst[^resultSettings.ResultAllInOneSubdirectoryLength..];
|
|
if (check.Any(l => !char.IsNumber(l)))
|
|
{
|
|
combined = $"{@enum}{new('-', resultSettings.ResultAllInOneSubdirectoryLength)}";
|
|
converted = int.Parse($"1{new string('0', resultSettings.ResultAllInOneSubdirectoryLength)}");
|
|
}
|
|
else
|
|
{
|
|
combined = $"{@enum}{check}";
|
|
converted = int.Parse(check);
|
|
}
|
|
result = new(combined, @enum, converted);
|
|
return result;
|
|
}
|
|
|
|
internal static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches)
|
|
{
|
|
bool result;
|
|
string text;
|
|
if (!compareBeforeWrite)
|
|
result = true;
|
|
else
|
|
{
|
|
if (!File.Exists(path))
|
|
text = string.Empty;
|
|
else
|
|
text = File.ReadAllText(path);
|
|
result = text != contents;
|
|
if (!result && updateDateWhenMatches)
|
|
{
|
|
if (updateToWhenMatches is null)
|
|
File.SetLastWriteTime(path, DateTime.Now);
|
|
else
|
|
File.SetLastWriteTime(path, updateToWhenMatches.Value);
|
|
}
|
|
}
|
|
if (result)
|
|
{
|
|
if (path.Contains("()"))
|
|
File.WriteAllText(path, contents);
|
|
else if (path.Contains("{}") && !path.EndsWith(".json"))
|
|
File.WriteAllText(path, contents);
|
|
else if (path.Contains("[]") && !path.EndsWith(".json"))
|
|
File.WriteAllText(path, contents);
|
|
else if (path.Contains("{}") && path.EndsWith(".json") && contents[0] == '{')
|
|
File.WriteAllText(path, contents);
|
|
else if (path.Contains("[]") && path.EndsWith(".json") && contents[0] == '[')
|
|
File.WriteAllText(path, contents);
|
|
else
|
|
File.WriteAllText(path, contents);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal static ReadOnlyDictionary<int, ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>>> GetKeyValuePairs(ResultSettings resultSettings, string? resultsFullGroupDirectory, string[]? jsonGroups)
|
|
{
|
|
Dictionary<int, Dictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>>> results = [];
|
|
if (jsonGroups is not null)
|
|
{
|
|
DateTime dateTime = DateTime.Now;
|
|
ReadOnlyCollection<int> years = GetYears(resultSettings);
|
|
Dictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>>? k;
|
|
ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePairs = GetKeyValuePairs(resultSettings, resultsFullGroupDirectory, jsonGroups, dateTime);
|
|
foreach (int year in years)
|
|
{
|
|
results.Add(year, []);
|
|
if (!results.TryGetValue(year, out k))
|
|
throw new NullReferenceException(nameof(k));
|
|
foreach (KeyValuePair<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePair in keyValuePairs)
|
|
k.Add(keyValuePair.Key, keyValuePair.Value);
|
|
}
|
|
}
|
|
return Convert(results);
|
|
}
|
|
|
|
private static ReadOnlyCollection<int> GetYears(ResultSettings resultSettings)
|
|
{
|
|
List<int> results = [];
|
|
int currentYear = DateTime.Now.Year;
|
|
for (int i = resultSettings.EpicYear; i < currentYear + 1; i++)
|
|
results.Add(i);
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
private static ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> GetKeyValuePairs(ResultSettings resultSettings, string? resultsFullGroupDirectory, string[]? jsonGroups, DateTime dateTime)
|
|
{
|
|
Dictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> results = [];
|
|
int plusOne;
|
|
string directory;
|
|
string checkDirectory;
|
|
CombinedEnumAndIndex cei;
|
|
byte[] bytes = GetBytes();
|
|
List<CombinedEnumAndIndex> collection = [];
|
|
ReadOnlyDictionary<byte, ReadOnlyCollection<string>> keyValuePairs;
|
|
int converted = int.Parse($"1{new string('0', resultSettings.ResultAllInOneSubdirectoryLength)}");
|
|
if (jsonGroups is not null)
|
|
{
|
|
plusOne = converted + 1;
|
|
foreach (string jsonGroup in jsonGroups)
|
|
{
|
|
if (resultsFullGroupDirectory is null)
|
|
continue;
|
|
foreach (byte @enum in bytes)
|
|
{
|
|
for (int i = 0; i < plusOne; i++)
|
|
{
|
|
if (string.IsNullOrEmpty(jsonGroup))
|
|
{
|
|
if (i == converted)
|
|
checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, $"{@enum}{new('-', resultSettings.ResultAllInOneSubdirectoryLength)}"));
|
|
else
|
|
checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, $"{@enum}{i.ToString().PadLeft(resultSettings.ResultAllInOneSubdirectoryLength, '0')}"));
|
|
}
|
|
else
|
|
{
|
|
directory = Path.Combine(resultsFullGroupDirectory, jsonGroup);
|
|
if (i == converted)
|
|
checkDirectory = Path.GetFullPath(Path.Combine(directory, $"{@enum}{new('-', resultSettings.ResultAllInOneSubdirectoryLength)}"));
|
|
else
|
|
checkDirectory = Path.GetFullPath(Path.Combine(directory, $"{@enum}{i.ToString().PadLeft(resultSettings.ResultAllInOneSubdirectoryLength, '0')}"));
|
|
}
|
|
if (!Directory.Exists(checkDirectory))
|
|
_ = Directory.CreateDirectory(checkDirectory);
|
|
cei = new(Combined: checkDirectory, Enum: @enum, Index: -1);
|
|
collection.Add(cei);
|
|
}
|
|
}
|
|
keyValuePairs = Convert(collection);
|
|
if (!string.IsNullOrEmpty(jsonGroup))
|
|
results.Add(jsonGroup, keyValuePairs);
|
|
else
|
|
results.Add(dateTime.Ticks.ToString(), keyValuePairs);
|
|
}
|
|
}
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
private static byte[] GetBytes() =>
|
|
[
|
|
0,
|
|
1,
|
|
2,
|
|
3,
|
|
4,
|
|
5,
|
|
6,
|
|
7,
|
|
8,
|
|
9
|
|
];
|
|
|
|
private static ReadOnlyDictionary<byte, ReadOnlyCollection<string>> Convert(Dictionary<byte, List<string>> keyValuePairs)
|
|
{
|
|
Dictionary<byte, ReadOnlyCollection<string>> results = [];
|
|
foreach (KeyValuePair<byte, List<string>> keyValuePair in keyValuePairs)
|
|
results.Add(keyValuePair.Key, new(keyValuePair.Value));
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
} |