SortCodeMethods

DirectoryToISO
TextToJson
This commit is contained in:
2024-01-08 10:02:30 -07:00
parent ccea8de8cf
commit 84ad97ac6e
22 changed files with 465 additions and 281 deletions

View File

@ -0,0 +1,31 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.Day;
internal static class Helper20231010
{
internal static void HgCV(ILogger<Worker> logger, string argsZero)
{
long ticks;
DateTime dateTime;
TimeSpan timeSpan;
string[] segments;
DirectoryInfo argsZeroDirectoryInfo = new(argsZero);
int padLength = "64-612464-4626_2023-10-10_06;37_AM_2529222011".Length;
ReadOnlyCollection<DirectoryInfo> directoryInfoCollection = new(argsZeroDirectoryInfo.GetDirectories().OrderBy(l => l.LastWriteTime).ToArray());
foreach (DirectoryInfo directoryInfo in directoryInfoCollection)
{
segments = directoryInfo.Name.Split('_');
if (!long.TryParse(segments[^1], out ticks))
continue;
dateTime = new(ticks);
timeSpan = new(ticks);
dateTime = new(ticks);
logger.LogInformation("{directory.Name} at {LastWriteTime} took {TotalMinutes} minutes(s)", directoryInfo.Name.PadRight(padLength, ' '), directoryInfo.LastWriteTime, Math.Round(timeSpan.TotalMinutes, 3));
}
}
}

View File

@ -0,0 +1,37 @@
using Microsoft.Extensions.Logging;
using System.Globalization;
namespace File_Folder_Helper.Day;
internal static class Helper20231016
{
internal static void MoveDirectory(ILogger<Worker> logger, string argsZero)
{
string weekOfYear;
string checkDirectory;
long ticks = DateTime.Now.AddHours(-84).Ticks;
DirectoryInfo argsZeroDirectoryInfo = new(argsZero);
Calendar calendar = new CultureInfo("en-US").Calendar;
DirectoryInfo[] directoryInfoCollection = argsZeroDirectoryInfo.GetDirectories();
string fileShareDirectory = Path.GetDirectoryName(argsZero) ?? throw new Exception();
string archiveDirectory = Path.Combine(fileShareDirectory, "Archive");
if (!Directory.Exists(archiveDirectory))
throw new NotSupportedException();
foreach (DirectoryInfo directoryInfo in directoryInfoCollection)
{
foreach (DirectoryInfo directory in directoryInfo.GetDirectories())
{
if (directory.CreationTime.Ticks > ticks)
continue;
weekOfYear = calendar.GetWeekOfYear(directory.CreationTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
checkDirectory = Path.Combine(archiveDirectory, directoryInfo.Name, $"{directory.CreationTime.Year}_Week_{weekOfYear}", directory.CreationTime.ToString("yyyy-MM-dd"));
if (!Directory.Exists(checkDirectory))
continue;
Directory.Move(directory.FullName, Path.Combine(checkDirectory, directory.Name));
logger.LogInformation("{directory.CreationTime} - {directory.Name}", directory.CreationTime, directory.Name);
}
}
}
}

View File

@ -0,0 +1,125 @@
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day;
internal record Drive(string Share,
bool Use,
string User);
internal static class Helper20231024
{
internal static void NetUse(ILogger<Worker> logger, string argsZero)
{
Process? process;
string arguments;
string[] segments;
string standardError;
string standardOutput;
string fileName = "net";
StringBuilder stringBuilder = new();
string json = File.ReadAllText(Path.Combine(argsZero, ".json"));
string decrypted = File.ReadAllText(Path.Combine(argsZero, ".password"));
List<Drive> drives = JsonSerializer.Deserialize(json, DrivesSourceGenerationContext.Default.ListDrive) ?? throw new NullReferenceException();
foreach (Drive drive in drives)
{
if (!drive.Use)
continue;
arguments = $"use * \"{drive.Share}\" /p:yes /user:{drive.User} {decrypted}";
_ = stringBuilder.Clear();
segments = arguments.Split(' ');
for (int j = 0; j < segments.Length - 1; j++)
_ = stringBuilder.Append(segments[j]).Append(' ');
logger.LogInformation("// {stringBuilder}", stringBuilder);
ProcessStartInfo processStartInfo = new(fileName, arguments)
{
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false
};
try
{
process = Process.Start(processStartInfo);
if (process is null)
continue;
for (int j = 1; j < 45; j++)
{
_ = process.WaitForExit(1000);
if (process.HasExited)
break;
}
if (!process.HasExited)
logger.LogError("// Never exited!");
else
{
standardError = process.StandardError.ReadToEnd();
standardOutput = process.StandardOutput.ReadToEnd();
logger.LogInformation("// {standardError}{Environment.NewLine}{Environment.NewLine}// {standardOutput}", standardError, Environment.NewLine, Environment.NewLine, standardOutput);
try
{
_ = Directory.CreateDirectory($"{drive.Share}\\Tmp\\Phares");
string reg = """
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\ODBC\ODBC.INI\SPCEPIWORLD]
"Driver"="C:\\WINDOWS\\system32\\SQLSRV32.dll"
"Description"="InfinityQS SPC (Si)"
"Server"="messqlec1.infineon.com\\PROD1,53959"
"Database"="SPCEPIWORLD"
"LastUser"=""
"Trusted_Connection"="Yes"
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\ODBC\ODBC.INI\ODBC Data Sources]
"SPCEPIWORLD"="SQL Server"
""";
string bat = """
@ECHO OFF
NET USE G: /delete
NET USE H: /delete
NET USE M: /delete
NET USE P: /delete
NET USE R: /delete
NET USE T: /delete
NET USE V: /delete
NET USE Y: /delete
NET USE G: \\mesfs.infineon.com\EC_Engineering /PERSISTENT:YES
NET USE H: \\mesfs.infineon.com\EC_TempHumidity_Controls /PERSISTENT:YES
NET USE M: \\mesfs.infineon.com\EC_Maintenance /PERSISTENT:YES
NET USE P: \\mesfs.infineon.com\EC_Production /PERSISTENT:YES
NET USE R: \\mesfs.infineon.com\EC_Customer_Service /PERSISTENT:YES
NET USE T: \\mesfs.infineon.com\EC_Materials /PERSISTENT:YES
NET USE V: \\mesfs.infineon.com\EC_Engineering /PERSISTENT:YES
NET USE Y: \\mesfs.infineon.com\EC_EpiReactorRecipes /PERSISTENT:YES
""";
File.WriteAllText($"{drive.Share}\\Tmp\\Phares\\SPCEPIWORLD_hklm.reg", reg);
File.WriteAllText($"{drive.Share}\\Tmp\\Phares\\MESA-Users-Drives.bat", bat);
File.WriteAllText($"{drive.Share}\\Tmp\\Phares\\lnk.txt", """"\\messa04ec.infineon.com\EC_SPC_Si\SPC\Projects\Active\ir epi services database.ipj"""");
}
catch (Exception)
{ }
}
}
catch (Exception ex)
{
logger.LogError(ex, "Error:");
}
}
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Drive))]
internal partial class DriveSourceGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(List<Drive>))]
internal partial class DrivesSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,35 @@
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.Day;
internal static class Helper20231102
{
internal static void NuSpec(ILogger<Worker> logger, string argsZero)
{
string[] lines;
string? idLine;
string? versionLine;
string[] files = Directory.GetFiles(argsZero);
logger.LogInformation("{fileCount}", files.Length.ToString());
foreach (string file in files)
{
idLine = null;
versionLine = null;
lines = File.ReadAllLines(file);
foreach (string line in lines)
{
if (!line.EndsWith("</id>") && !line.EndsWith("</version>"))
continue;
if (line.EndsWith("</id>"))
idLine = line.TrimEnd();
if (line.EndsWith("</version>"))
versionLine = line.TrimEnd();
if (idLine is not null && versionLine is not null)
break;
}
File.AppendAllText(".txt", $"{idLine}{versionLine}{Environment.NewLine}");
}
}
}

View File

@ -0,0 +1,37 @@
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.Day;
internal static class Helper20231108
{
internal static void MasterImage(ILogger<Worker> logger, List<string> args)
{
string fileName;
string checkFile;
string[] aSegments;
string[] bSegments;
if (!Directory.Exists(args[0]))
throw new Exception(args[0]);
if (!Directory.Exists(args[2]))
throw new Exception(args[2]);
string directoryName = Path.GetFileName(args[0]) ?? throw new Exception();
string[] files = Directory.GetFiles(args[0]);
logger.LogInformation("{fileCount}", files.Length.ToString());
foreach (string file in files)
{
aSegments = Path.GetFileNameWithoutExtension(file).Split('-');
if (aSegments.Length != 2)
continue;
bSegments = aSegments[1].Split('_');
if (bSegments.Length != 3)
continue;
fileName = $"{directoryName}-{bSegments[1]}-{bSegments[0]}{Path.GetExtension(file)}";
checkFile = Path.Combine(args[2], fileName);
if (File.Exists(checkFile))
continue;
File.Copy(file, checkFile);
}
}
}

View File

@ -0,0 +1,195 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO.Compression;
namespace File_Folder_Helper.Day;
internal static class Helper20231122
{
private record Record(string File, string FileName, string Equipment, string TimeStamp);
private static ReadOnlyCollection<Record> GetRecords(string sourceDirectory, string timestampFormat)
{
List<Record> results = [];
Record record;
string fileName;
string equipment;
string timestamp;
string[] segments;
string[] files = Directory.GetFiles(sourceDirectory, "*.pdsf", SearchOption.TopDirectoryOnly).ToArray();
foreach (string file in files)
{
fileName = Path.GetFileName(file);
segments = fileName.Split('_');
if (segments.Length != 2)
continue;
equipment = segments[0];
timestamp = segments[1].Split('.')[0];
if (timestamp.Length != timestampFormat.Length)
continue;
record = new(file, fileName, equipment, timestamp);
results.Add(record);
}
return new(results.OrderBy(l => l.TimeStamp).ToArray());
}
private static void WriteFile(string sourceDirectory, string[] columns, string equipment, List<List<string>> data, List<string> timestamps, string timestamp, DateTime dateTime)
{
List<string> lines = [];
string checkFile = Path.Combine(sourceDirectory, $"{equipment}-{timestamp}.tvs");
if (File.Exists(checkFile))
throw new NotSupportedException();
lines.Add($"timestamp\t{string.Join('\t', timestamps)}");
for (int i = 0; i < columns.Length; i++)
lines.Add($"{columns[i]}\t{string.Join('\t', data[i])}");
File.WriteAllLines(checkFile, lines);
File.SetLastWriteTime(checkFile, dateTime);
}
private static void ZipAndDeleteFiles(string sourceDirectory, string equipment, string timestamp, List<string> files, DateTime dateTime)
{
string checkFile = Path.Combine(sourceDirectory, $"{equipment}-{timestamp}.zip");
if (File.Exists(checkFile))
throw new NotSupportedException();
using ZipArchive zip = ZipFile.Open(checkFile, ZipArchiveMode.Create);
foreach (string file in files)
{
_ = zip.CreateEntryFromFile(file, Path.GetFileName(file));
File.Delete(file);
}
File.SetLastWriteTime(checkFile, dateTime);
}
private static void MoveFilesBack(string sourceDirectory, string parsedDirectory, List<string> parsedFiles)
{
foreach (string parsedFile in parsedFiles)
File.Move(parsedFile, Path.Combine(sourceDirectory, Path.GetFileName(parsedFile)));
if (parsedFiles.Count > 0)
Directory.Delete(parsedDirectory);
}
private static ReadOnlyDictionary<string, ReadOnlyCollection<Record>> GetEquipmentToRecords(string sourceDirectory, string timestampFormat)
{
Dictionary<string, ReadOnlyCollection<Record>> results = [];
List<Record>? collection;
Dictionary<string, List<Record>> keyValuePairs = [];
ReadOnlyCollection<Record> records = GetRecords(sourceDirectory, timestampFormat);
foreach (Record record in records)
{
if (!keyValuePairs.TryGetValue(record.Equipment, out collection))
{
keyValuePairs.Add(record.Equipment, []);
if (!keyValuePairs.TryGetValue(record.Equipment, out collection))
throw new NotSupportedException();
}
collection.Add(record);
}
foreach (KeyValuePair<string, List<Record>> keyValuePair in keyValuePairs)
results.Add(keyValuePair.Key, new(keyValuePair.Value));
return new(results);
}
private static void ParseProcessDataStandardFormatRecords(ILogger<Worker> logger, string sourceDirectory, string timestampFormat, string keyColumn, string missingKeyDirectory, string parsedDirectory, ReadOnlyCollection<Record> records)
{
string[] lines;
string[] values;
string[] columns;
DateTime dateTime;
string parsedFile;
int? keyColumnIndex;
string keyColumnValue;
string? lastColumn = null;
List<List<string>> data = [];
List<string> timestamps = [];
List<string> parsedFiles = [];
int? lastKeyColumnIndex = null;
string? lastKeyColumnValue = null;
foreach (Record record in records)
{
lines = File.ReadAllLines(record.File);
if (lines.Length != 15)
continue;
if (lines[6].Length < 1 || lines[6][0] != '"' || !lines[6].StartsWith("\"Time\""))
continue;
if (lines[8].Length < 1 || lines[8][0] != 'N' || lines[8] != "NUM_DATA_ROWS\t000000001")
continue;
keyColumnIndex = null;
columns = lines[6].Split('\t');
if (columns.Length < 3)
continue;
values = lines[7].Split('\t');
if (values.Length != columns.Length)
continue;
for (int i = 0; i < columns.Length; i++)
{
if (columns[i] != keyColumn)
continue;
keyColumnIndex = i;
break;
}
if (keyColumnIndex is null)
{
File.Move(record.File, Path.Combine(sourceDirectory, missingKeyDirectory, record.FileName));
continue;
}
keyColumnValue = values[keyColumnIndex.Value];
parsedFile = Path.Combine(parsedDirectory, record.FileName);
if ((lastColumn is not null && lines[6] != lastColumn) || (lastKeyColumnIndex is not null && keyColumnIndex.Value != lastKeyColumnIndex.Value) || (lastKeyColumnValue is not null && lastKeyColumnValue != keyColumnValue) || timestamps.Count > 12345)
{
if (!DateTime.TryParseExact(record.TimeStamp, timestampFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
throw new NotSupportedException();
WriteFile(sourceDirectory, columns, record.Equipment, data, timestamps, record.TimeStamp, dateTime);
ZipAndDeleteFiles(sourceDirectory, record.Equipment, record.TimeStamp, parsedFiles, dateTime);
Directory.Delete(parsedDirectory);
logger.LogInformation("{timestamp} triggered", record.TimeStamp);
parsedFiles.Clear();
break;
}
parsedFiles.Add(parsedFile);
File.Move(record.File, parsedFile);
timestamps.Add($"'{record.TimeStamp}");
for (int i = 0; i < columns.Length; i++)
data.Add([]);
for (int i = 0; i < columns.Length; i++)
data[i].Add(values[i]);
lastColumn = lines[6];
lastKeyColumnIndex = keyColumnIndex;
lastKeyColumnValue = keyColumnValue;
}
MoveFilesBack(sourceDirectory, parsedDirectory, parsedFiles);
}
private static void ParseProcessDataStandardFormatFiles(ILogger<Worker> logger, string sourceDirectory, string timestampFormat, string keyColumn, string missingKeyDirectory)
{
string parsedDirectory;
ReadOnlyDictionary<string, ReadOnlyCollection<Record>> equipmentToRecords = GetEquipmentToRecords(sourceDirectory, timestampFormat);
foreach (KeyValuePair<string, ReadOnlyCollection<Record>> keyValuePair in equipmentToRecords)
{
parsedDirectory = Path.Combine(sourceDirectory, DateTime.Now.Ticks.ToString());
if (!Directory.Exists(parsedDirectory))
_ = Directory.CreateDirectory(parsedDirectory);
ParseProcessDataStandardFormatRecords(logger, sourceDirectory, timestampFormat, keyColumn, missingKeyDirectory, parsedDirectory, keyValuePair.Value);
Thread.Sleep(100);
}
}
internal static void ProcessDataStandardFormat(ILogger<Worker> logger, List<string> args)
{
string keyColumn = args[3];
string sourceDirectory = args[0];
string timestampFormat = args[2];
if (!Directory.Exists(sourceDirectory))
throw new Exception(sourceDirectory);
string missingKeyDirectory = Path.Combine(sourceDirectory, "Missing-Key");
if (!Directory.Exists(missingKeyDirectory))
_ = Directory.CreateDirectory(missingKeyDirectory);
while (true)
{
ParseProcessDataStandardFormatFiles(logger, sourceDirectory, timestampFormat, keyColumn, missingKeyDirectory);
Thread.Sleep(5000);
}
}
}

View File

@ -0,0 +1,128 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Globalization;
namespace File_Folder_Helper.Day;
internal static class Helper20231130
{
private record Record(string File, string FileName, string Equipment, string TimeStamp);
private static ReadOnlyDictionary<string, string> GetSystemStates()
{
Dictionary<string, string> results = [];
results.Add("1", "cold-idle");
results.Add("2", "running");
results.Add("3", "run-wafer");
results.Add("4", "warm-idle");
results.Add("5", "pause");
results.Add("6", "suspend");
results.Add("7", "startup");
results.Add("8", "shutdown");
results.Add("9", "abort");
results.Add("10", "safety-1");
results.Add("11", "safety-2");
results.Add("12", "safety-3");
return new(results);
}
private static ReadOnlyCollection<Record> GetRecords(string sourceDirectory, string timestampFormat)
{
List<Record> results = [];
Record record;
string fileName;
string equipment;
string timestamp;
string[] segments;
string[] files = Directory.GetFiles(sourceDirectory, "*.pdsf", SearchOption.TopDirectoryOnly).ToArray();
foreach (string file in files)
{
fileName = Path.GetFileName(file);
segments = fileName.Split('_');
if (segments.Length != 2)
continue;
equipment = segments[0];
timestamp = segments[1].Split('.')[0];
if (timestamp.Length != timestampFormat.Length)
continue;
record = new(file, fileName, equipment, timestamp);
results.Add(record);
}
return new(results.OrderBy(l => l.TimeStamp).ToArray());
}
internal static void RenameReactorProcessDataStandardFormatFiles(ILogger<Worker> logger, List<string> args)
{
string line;
string[] lines;
string[] values;
string[] columns;
DateTime dateTime;
int? keyColumnIndex;
string? systemState;
string checkFileName;
string keyColumnValue;
string? lastColumn = null;
List<string> allLines = [];
string keyColumn = args[3];
string sourceDirectory = args[0];
string timestampFormat = args[2];
if (!Directory.Exists(sourceDirectory))
throw new Exception(sourceDirectory);
string missingKeyDirectory = Path.Combine(sourceDirectory, "Missing-Key");
if (!Directory.Exists(missingKeyDirectory))
_ = Directory.CreateDirectory(missingKeyDirectory);
ReadOnlyDictionary<string, string> systemStates = GetSystemStates();
ReadOnlyCollection<Record> records = GetRecords(sourceDirectory, timestampFormat);
foreach (Record record in records)
{
lines = File.ReadAllLines(record.File);
if (lines.Length < 8)
continue;
if (lines[6].Length < 1 || lines[6][0] != '"' || !lines[6].StartsWith("\"Time\""))
continue;
if (lastColumn is not null && lines[6] != lastColumn)
break;
keyColumnIndex = null;
lastColumn = lines[6];
if (allLines.Count == 0)
allLines.Add($"\"Timestamp\"\t{lastColumn}");
columns = lines[6].Split('\t');
if (columns.Length < 3)
continue;
values = lines[7].Split('\t');
if (values.Length != columns.Length)
continue;
for (int i = 0; i < columns.Length; i++)
{
if (columns[i] != keyColumn)
continue;
keyColumnIndex = i;
break;
}
if (keyColumnIndex is null)
{
File.Move(record.File, Path.Combine(sourceDirectory, missingKeyDirectory, record.FileName));
continue;
}
for (int i = 7; i < lines.Length; i++)
{
line = lines[i];
if (line.Length < 1 || line[0] == 'N' && line.StartsWith("NUM_DATA_ROWS\t"))
break;
allLines.Add($"'{record.TimeStamp}\t{line}");
}
keyColumnValue = values[keyColumnIndex.Value];
logger.LogInformation("{timestamp} triggered", record.TimeStamp);
if (!systemStates.TryGetValue(keyColumnValue, out systemState))
continue;
checkFileName = Path.Combine(Path.GetDirectoryName(record.File) ?? throw new Exception(), $"{record.Equipment}-{record.TimeStamp}-{systemState}.pdsf");
File.Move(record.File, checkFileName);
if (DateTime.TryParseExact(record.TimeStamp, timestampFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
File.SetLastWriteTime(checkFileName, dateTime);
}
File.WriteAllLines(Path.Combine(sourceDirectory, $"{DateTime.Now.Ticks}.tsv"), allLines);
}
}

View File

@ -0,0 +1,103 @@
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.Day;
internal static partial class Helper20231205
{
private static string? GetStrippedMacAddress(string[] segments)
{
string? result = null;
foreach (string segment in segments)
{
if (segment.Length != 17)
continue;
if (segment[2] is not ':' or '-' || segment[5] is not ':' or '-' || segment[8] is not ':' or '-' || segment[11] is not ':' or '-' || segment[14] is not ':' or '-')
continue;
result = $"{segment[0]}{segment[1]}{segment[3]}{segment[4]}{segment[6]}{segment[7]}{segment[9]}{segment[10]}{segment[12]}{segment[13]}{segment[15]}{segment[16]}".ToLower();
}
return result;
}
[GeneratedRegex(@"[\\,\/,\:,\*,\?,\"",\<,\>,\|]")]
private static partial Regex WindowsSafe();
private static string? GetStrippedIPV4(string[] segments)
{
string? result = null;
string[] subSegments;
foreach (string segment in segments)
{
subSegments = segment.Split('.');
if (subSegments.Length != 4)
continue;
if (!subSegments.All(l => int.TryParse(l, out _)))
continue;
result = segment.Replace(".", string.Empty);
}
return result;
}
internal static void SplitMarkdownFile(ILogger<Worker> logger, List<string> args)
{
string[] lines;
string? fileName;
Regex windowsSafe;
string[] segments;
string checkFileName;
string? strippedIpV4;
string? strippedMacAddress;
List<string> collection = [];
string sourceDirectory = args[0];
if (!Directory.Exists(sourceDirectory))
throw new Exception(sourceDirectory);
string outputDirectory = Path.Combine(sourceDirectory, Path.GetFileNameWithoutExtension(args[2]));
if (!Directory.Exists(outputDirectory))
_ = Directory.CreateDirectory(outputDirectory);
string[] files = Directory.GetFiles(args[0], args[2], SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
fileName = null;
collection.Clear();
lines = File.ReadAllLines(file);
foreach (string line in lines)
{
collection.Add(line);
if (line.Length > 0 && line[0] == '#' && line.StartsWith("## "))
{
segments = line.Split(' ');
strippedIpV4 = GetStrippedIPV4(segments);
strippedMacAddress = GetStrippedMacAddress(segments);
if (strippedMacAddress is null && strippedIpV4 is null)
{
windowsSafe = WindowsSafe();
fileName = $"{windowsSafe.Replace(line[3..], "-").Trim().ToLower()}.md";
}
else if (strippedMacAddress is null)
{
fileName = $"ipv4-{strippedIpV4}.md";
collection.Insert(0, string.Empty);
collection.Insert(0, $"# {fileName}");
}
else
{
fileName = $"mac-{strippedMacAddress}.md";
collection.Insert(0, string.Empty);
collection.Insert(0, $"# {fileName}");
}
}
if (fileName is null || line != "----")
continue;
collection.RemoveAt(collection.Count - 1);
logger.LogInformation("{fileName} created", fileName);
checkFileName = Path.Combine(outputDirectory, fileName);
if (File.Exists(checkFileName))
File.Delete(checkFileName);
File.WriteAllLines(checkFileName, collection);
collection.Clear();
}
}
}
}

View File

@ -0,0 +1,538 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day;
internal static partial class Helper20231212
{
private record Debugging(
[property: JsonPropertyName("Level")] int Level
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Debugging))]
private partial class DebuggingSourceGenerationContext : JsonSerializerContext
{
}
private record Distance(
[property: JsonPropertyName("Value")] int Value
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Distance))]
private partial class DistanceSourceGenerationContext : JsonSerializerContext
{
}
private record Finished(
[property: JsonPropertyName("Elapsed")] double Elapsed,
[property: JsonPropertyName("Exit")] string Exit,
[property: JsonPropertyName("Summary")] string Summary,
[property: JsonPropertyName("Time")] int Time,
[property: JsonPropertyName("TimeStr")] string TimeStr
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Finished))]
private partial class FinishedSourceGenerationContext : JsonSerializerContext
{
}
private record Hop(
[property: JsonPropertyName("Host")] string Host,
[property: JsonPropertyName("IPAddr")] string IPAddr,
[property: JsonPropertyName("RTT")] double RTT,
[property: JsonPropertyName("TTL")] int TTL
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Hop))]
private partial class HopSourceGenerationContext : JsonSerializerContext
{
}
private record Host(
[property: JsonPropertyName("Distance")] Distance Distance,
[property: JsonPropertyName("EndTime")] int EndTime,
[property: JsonPropertyName("HostAddress")] IReadOnlyList<HostAddress> HostAddresses,
[property: JsonPropertyName("HostNames")] HostNames HostNames,
[property: JsonPropertyName("IPIDSequence")] IPIDSequence IPIDSequence,
[property: JsonPropertyName("OS")] OS OS,
[property: JsonPropertyName("Port")] IReadOnlyList<Port> Ports,
[property: JsonPropertyName("StartTime")] int StartTime,
[property: JsonPropertyName("Status")] Status Status,
[property: JsonPropertyName("TCPSequence")] TCPSequence TCPSequence,
[property: JsonPropertyName("TCPTSSequence")] TCPTSSequence TCPTSSequence,
[property: JsonPropertyName("Trace")] Trace Trace,
[property: JsonPropertyName("Uptime")] Uptime Uptime
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Host))]
private partial class HostSourceGenerationContext : JsonSerializerContext
{
}
private record HostAddress(
[property: JsonPropertyName("Address")] string Address,
[property: JsonPropertyName("AddressType")] string AddressType,
[property: JsonPropertyName("Vendor")] string Vendor
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(HostAddress))]
private partial class HostAddressSourceGenerationContext : JsonSerializerContext
{
}
private record HostName(
[property: JsonPropertyName("Name")] string Name,
[property: JsonPropertyName("Type")] string Type
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(HostName))]
private partial class HostNameSourceGenerationContext : JsonSerializerContext
{
}
private record HostNames(
[property: JsonPropertyName("HostName")] IReadOnlyList<HostName> HostName
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(HostNames))]
private partial class HostNamesSourceGenerationContext : JsonSerializerContext
{
}
private record Hosts(
[property: JsonPropertyName("Down")] int Down,
[property: JsonPropertyName("Total")] int Total,
[property: JsonPropertyName("Up")] int Up
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Hosts))]
private partial class HostsSourceGenerationContext : JsonSerializerContext
{
}
private record IPIDSequence(
[property: JsonPropertyName("Class")] string Class,
[property: JsonPropertyName("Values")] string Values
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(IPIDSequence))]
private partial class IPIDSequenceSourceGenerationContext : JsonSerializerContext
{
}
private record OS(
[property: JsonPropertyName("OSClass")] object OSClass,
[property: JsonPropertyName("OSMatch")] IReadOnlyList<OSMatch> OSMatches,
[property: JsonPropertyName("OSPortUsed")] IReadOnlyList<OSPortUsed> OSPortsUsed
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(OS))]
private partial class OSSourceGenerationContext : JsonSerializerContext
{
}
private record OSMatch(
[property: JsonPropertyName("Accuracy")] string Accuracy,
[property: JsonPropertyName("Line")] string Line,
[property: JsonPropertyName("Name")] string Name
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(OSMatch))]
private partial class OSMatchSourceGenerationContext : JsonSerializerContext
{
}
private record OSPortUsed(
[property: JsonPropertyName("PortID")] int PortID,
[property: JsonPropertyName("Protocol")] string Protocol,
[property: JsonPropertyName("State")] string State
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(OSPortUsed))]
private partial class OSPortUsedSourceGenerationContext : JsonSerializerContext
{
}
private record Port(
[property: JsonPropertyName("PortID")] int PortID,
[property: JsonPropertyName("Protocol")] string Protocol,
[property: JsonPropertyName("Script")] IReadOnlyList<Script> Scripts,
[property: JsonPropertyName("Service")] Service Service,
[property: JsonPropertyName("State")] State State
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Port))]
private partial class PortSourceGenerationContext : JsonSerializerContext
{
}
private record Record(
[property: JsonPropertyName("Args")] string Args,
[property: JsonPropertyName("Debugging")] Debugging Debugging,
[property: JsonPropertyName("Host")] List<Host> Hosts,
[property: JsonPropertyName("RunStats")] RunStats RunStats,
[property: JsonPropertyName("ScanInfo")] ScanInfo ScanInfo,
[property: JsonPropertyName("Scanner")] string Scanner,
[property: JsonPropertyName("Start")] int Start,
[property: JsonPropertyName("StartStr")] string StartStr,
[property: JsonPropertyName("Verbose")] Verbose Verbose,
[property: JsonPropertyName("Version")] string Version
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Record))]
private partial class RecordSourceGenerationContext : JsonSerializerContext
{
}
private record RunStats(
[property: JsonPropertyName("Finished")] Finished Finished,
[property: JsonPropertyName("Hosts")] Hosts Hosts
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(RunStats))]
private partial class RunStatsSourceGenerationContext : JsonSerializerContext
{
}
private record ScanInfo(
[property: JsonPropertyName("NumServices")] int NumServices,
[property: JsonPropertyName("Protocol")] string Protocol,
[property: JsonPropertyName("Services")] string Services,
[property: JsonPropertyName("Type")] string Type
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(ScanInfo))]
private partial class ScanInfoSourceGenerationContext : JsonSerializerContext
{
}
private record Script(
[property: JsonPropertyName("ID")] string ID,
[property: JsonPropertyName("Output")] string Output
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Script))]
private partial class ScriptSourceGenerationContext : JsonSerializerContext
{
}
private record Service(
[property: JsonPropertyName("Conf")] string Conf,
[property: JsonPropertyName("CPE")] IReadOnlyList<string> CPEs,
[property: JsonPropertyName("ExtraInfo")] string ExtraInfo,
[property: JsonPropertyName("Method")] string Method,
[property: JsonPropertyName("Name")] string Name,
[property: JsonPropertyName("Product")] string Product,
[property: JsonPropertyName("Version")] string Version
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Service))]
private partial class ServiceSourceGenerationContext : JsonSerializerContext
{
}
private record State(
[property: JsonPropertyName("Reason")] string Reason,
[property: JsonPropertyName("ReasonTTL")] string ReasonTTL,
[property: JsonPropertyName("State")] string Value
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(State))]
private partial class StateSourceGenerationContext : JsonSerializerContext
{
}
private record Status(
[property: JsonPropertyName("Reason")] string Reason,
[property: JsonPropertyName("State")] string State
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Status))]
private partial class StatusSourceGenerationContext : JsonSerializerContext
{
}
private record TCPSequence(
[property: JsonPropertyName("Difficulty")] string Difficulty,
[property: JsonPropertyName("Index")] string Index,
[property: JsonPropertyName("Values")] string Values
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(TCPSequence))]
private partial class TCPSequenceSourceGenerationContext : JsonSerializerContext
{
}
private record TCPTSSequence(
[property: JsonPropertyName("Class")] string Class,
[property: JsonPropertyName("Values")] string Values
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(TCPTSSequence))]
private partial class TCPTSSequenceSourceGenerationContext : JsonSerializerContext
{
}
private record Trace(
[property: JsonPropertyName("Hops")] IReadOnlyList<Hop> Hops,
[property: JsonPropertyName("Port")] int Port,
[property: JsonPropertyName("Protocol")] string Protocol
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Trace))]
private partial class TraceSourceGenerationContext : JsonSerializerContext
{
}
private record Uptime(
[property: JsonPropertyName("LastBoot")] string LastBoot,
[property: JsonPropertyName("Seconds")] int Seconds
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Uptime))]
private partial class UptimeSourceGenerationContext : JsonSerializerContext
{
}
private record Verbose(
[property: JsonPropertyName("Level")] int Level
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Verbose))]
private partial class VerboseSourceGenerationContext : JsonSerializerContext
{
}
private static string[] GetIPV4Segments(string value)
{
string[] result;
string[] subSegments = value.Split('.');
if (subSegments.Length != 4)
result = [];
else
{
if (!subSegments.All(l => int.TryParse(l, out _)))
result = [];
else
result = value.Split('.');
}
return result;
}
private static ReadOnlyCollection<ReadOnlyCollection<string>> GetHostLinesSpaceSegments()
{
List<ReadOnlyCollection<string>> results = [];
string hostFile = "C:/Windows/System32/drivers/etc/hosts";
string[] lines = !File.Exists(hostFile) ? [] : File.ReadAllLines(hostFile);
foreach (string line in lines)
results.Add(new(line.Split(' ')));
return new(results);
}
private static string[] GetMacAddressSegments(string value)
{
string[] result;
if (value.Length != 17)
result = [];
else
{
string v = value.ToLower();
if (v[2] is not ':' or '-' || v[5] is not ':' or '-' || v[8] is not ':' or '-' || v[11] is not ':' or '-' || v[14] is not ':' or '-')
result = [];
else
{
result = [$"{v[0]}{v[1]}", $"{v[3]}{v[4]}", $"{v[6]}{v[7]}", $"{v[9]}{v[10]}", $"{v[12]}{v[13]}", $"{v[15]}{v[16]}"];
}
}
return result;
}
internal static void SplitJsonFile(ILogger<Worker> logger, List<string> args)
{
string json;
string title;
Record? record;
string fileName;
FileInfo fileInfo;
string checkFileName;
string sourceFileName;
string[] ipV4Segments;
string outputDirectory;
List<string> lines = [];
List<string> links = [];
List<string> allLines = [];
string[] macAddressSegments;
string macAddressWithHyphens;
string ipV4SegmentsWithPeriods;
List<string> titleSegments = [];
string fileNameWithoutExtension;
const int ipV4SegmentsLength = 4;
string sourceDirectory = args[0];
const int macAddressSegmentsLength = 6;
string[] fileNameWithoutExtensionSegments;
string fileNameWithoutExtensionFirstThreeSegments;
if (!Directory.Exists(sourceDirectory))
throw new Exception(sourceDirectory);
List<ReadOnlyCollection<string>> hostLineMatchSpaceSegments;
ReadOnlyCollection<ReadOnlyCollection<string>> hostLinesSpaceSegments = GetHostLinesSpaceSegments();
string[] files = Directory.GetFiles(sourceDirectory, args[2], SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
links.Clear();
fileInfo = new(file);
json = File.ReadAllText(file);
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
outputDirectory = Path.Combine(sourceDirectory, fileNameWithoutExtension);
fileNameWithoutExtensionSegments = GetIPV4Segments(fileNameWithoutExtension);
if (fileNameWithoutExtensionSegments.Length != ipV4SegmentsLength)
continue;
fileNameWithoutExtensionFirstThreeSegments = $"{fileNameWithoutExtensionSegments[0]}.{fileNameWithoutExtensionSegments[1]}.{fileNameWithoutExtensionSegments[2]}.";
if (!Directory.Exists(outputDirectory))
_ = Directory.CreateDirectory(outputDirectory);
record = JsonSerializer.Deserialize(json, RecordSourceGenerationContext.Default.Record);
if (record is null)
continue;
foreach (Host host in record.Hosts)
{
lines.Clear();
ipV4Segments = [];
titleSegments.Clear();
macAddressSegments = [];
foreach (HostAddress hostAddress in host.HostAddresses)
{
if (hostAddress.AddressType == "ipv4")
ipV4Segments = GetIPV4Segments(hostAddress.Address);
else if (hostAddress.AddressType == "mac")
macAddressSegments = GetMacAddressSegments(hostAddress.Address);
else
continue;
}
if (ipV4Segments.Length != ipV4SegmentsLength)
continue;
ipV4SegmentsWithPeriods = string.Join('.', ipV4Segments);
macAddressWithHyphens = string.Join('-', macAddressSegments);
if (macAddressSegments.Length != macAddressSegmentsLength)
hostLineMatchSpaceSegments = (from l in hostLinesSpaceSegments where l.Count > 0 && l.Contains(ipV4SegmentsWithPeriods) select l).ToList();
else
{
hostLineMatchSpaceSegments = (from l in hostLinesSpaceSegments where l.Count > 0 && l.Contains(macAddressWithHyphens) select l).ToList();
if (hostLineMatchSpaceSegments.Count == 1)
title = string.Join(' ', hostLineMatchSpaceSegments[0]);
else
hostLineMatchSpaceSegments = (from l in hostLineMatchSpaceSegments where l.Count > 0 && l[0].StartsWith(fileNameWithoutExtensionFirstThreeSegments) select l).ToList();
}
if (ipV4Segments.Length == ipV4SegmentsLength)
titleSegments.Add(ipV4SegmentsWithPeriods);
if (hostLineMatchSpaceSegments.Count == 1)
title = $"{ipV4SegmentsWithPeriods} {string.Join(' ', hostLineMatchSpaceSegments[0].Skip(1))}";
else
{
if (host.HostNames.HostName is null)
titleSegments.Add("unknown #");
else
titleSegments.Add($"{string.Join("_", host.HostNames.HostName.Select(l => l.Name.Replace(' ', '-')))} #");
if (macAddressSegments.Length == macAddressSegmentsLength)
titleSegments.Add(macAddressWithHyphens);
title = string.Join(" ", titleSegments);
logger.LogInformation("{title} Type DeviceInfo ~ needs to be added to host file!", title);
}
json = JsonSerializer.Serialize(host, HostSourceGenerationContext.Default.Host);
fileNameWithoutExtension = macAddressSegments.Length != macAddressSegmentsLength ? $"ipv4-{string.Join(string.Empty, ipV4Segments)}" : $"mac-{string.Join(string.Empty, macAddressSegments)}";
fileName = $"{fileNameWithoutExtension}.md";
links.Add($"- [{title}]({fileName})");
lines.Add("---");
allLines.Add(title);
lines.Add(string.Empty);
lines.Add($"# {title}");
lines.Add(string.Empty);
lines.Add($"## {fileNameWithoutExtension}");
if (host.Ports is not null)
{
lines.Add(string.Empty);
lines.Add("## Port(s)");
lines.Add(string.Empty);
lines.Add("| Id | Protocol | State | Service |");
lines.Add("| - | - | - | - |");
foreach (Port port in host.Ports)
lines.Add($"| {port.PortID} | {port.Protocol} | {port.State.Value} | {port.Service.Name} |");
}
lines.Add(string.Empty);
lines.Add("```json");
lines.Add(json);
lines.Add("```");
checkFileName = Path.Combine(outputDirectory, fileName);
if (File.Exists(checkFileName))
File.Delete(checkFileName);
File.WriteAllLines(checkFileName, lines);
File.SetCreationTime(checkFileName, fileInfo.CreationTime);
File.SetLastWriteTime(checkFileName, fileInfo.LastWriteTime);
logger.LogInformation("{title} created", title);
}
lines.Clear();
record.Hosts.Clear();
title = Path.GetFileNameWithoutExtension(file);
json = JsonSerializer.Serialize(record, RecordSourceGenerationContext.Default.Record);
lines.Add("---");
lines.Add(string.Empty);
lines.Add($"# {title}");
lines.Add(string.Empty);
lines.Add($"## {title}");
lines.Add(string.Empty);
lines.Add("## Hosts");
lines.Add(string.Empty);
lines.AddRange(links);
lines.Add(string.Empty);
lines.Add("```json");
lines.Add(json);
lines.Add("```");
checkFileName = Path.Combine(outputDirectory, $"{title}.md");
if (File.Exists(checkFileName))
File.Delete(checkFileName);
File.WriteAllLines(checkFileName, lines);
File.SetCreationTime(checkFileName, fileInfo.CreationTime);
File.SetLastWriteTime(checkFileName, fileInfo.LastWriteTime);
logger.LogInformation("{title} created", title);
checkFileName = Path.Combine(outputDirectory, Path.GetFileName(file));
if (File.Exists(checkFileName))
File.Delete(checkFileName);
File.Move(file, checkFileName);
checkFileName = Path.Combine(outputDirectory, $"{Path.GetFileNameWithoutExtension(file)}.xml");
if (File.Exists(checkFileName))
File.Delete(checkFileName);
sourceFileName = Path.ChangeExtension(file, ".xml");
if (File.Exists(sourceFileName))
File.Move(sourceFileName, checkFileName);
}
File.WriteAllLines(Path.Combine(sourceDirectory, $"{DateTime.Now.Ticks}.ssv"), allLines);
}
}

View File

@ -0,0 +1,231 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text;
namespace File_Folder_Helper.Day;
internal static partial class Helper20231222
{
private record Record(string File,
string DestinationDirectory,
string DestinationFile);
private record IntelligentIdRecord(int Key,
ReadOnlyCollection<char> ResultAllInOneSubdirectoryChars,
string Reverse);
private record FilePath(long CreationTicks,
string DirectoryName,
string ExtensionLowered,
string FileNameFirstSegment,
string FullName,
int? Id,
bool IsIntelligentIdFormat,
long LastWriteTicks,
long Length,
string Name,
string NameWithoutExtension,
int? SortOrder);
public record MetadataConfiguration(int ResultAllInOneSubdirectoryLength, int Offset, int IntMinValueLength);
private static short GetSortOrderOnlyLengthIndex(MetadataConfiguration metadataConfiguration) =>
(short)metadataConfiguration.Offset.ToString().Length;
private static bool NameWithoutExtensionIsIntelligentIdFormat(MetadataConfiguration metadataConfiguration, string fileNameFirstSegment) =>
fileNameFirstSegment.Length - 1 == metadataConfiguration.IntMinValueLength && fileNameFirstSegment[^1] is '1' or '2' or '8' or '9' && fileNameFirstSegment.All(char.IsNumber);
private static bool NameWithoutExtensionIsPaddedIntelligentIdFormat(MetadataConfiguration metadataConfiguration, short sortOrderOnlyLengthIndex, string fileNameFirstSegment) =>
fileNameFirstSegment.Length == metadataConfiguration.IntMinValueLength + sortOrderOnlyLengthIndex + 1
&& fileNameFirstSegment[^1] is '1' or '2' or '8' or '9'
&& fileNameFirstSegment.All(char.IsNumber);
private static bool NameWithoutExtensionIsIdFormat(MetadataConfiguration metadataConfiguration, string fileNameFirstSegment)
{
bool result;
if (fileNameFirstSegment.Length < 5 || fileNameFirstSegment.Length > metadataConfiguration.IntMinValueLength)
result = false;
else
{
bool skipOneAllAreNumbers = fileNameFirstSegment[1..].All(char.IsNumber);
result = (skipOneAllAreNumbers && fileNameFirstSegment[0] == '-') || (skipOneAllAreNumbers && char.IsNumber(fileNameFirstSegment[0]));
}
return result;
}
private static FilePath GetFilePath(MetadataConfiguration metadataConfiguration, FileInfo fileInfo, int? index)
{
FilePath result;
int? id;
int? sortOder;
string fileNameFirstSegment = fileInfo.Name.Split('.')[0];
short sortOrderOnlyLengthIndex = GetSortOrderOnlyLengthIndex(metadataConfiguration);
string fileDirectoryName = fileInfo.DirectoryName ?? throw new NullReferenceException();
bool fileNameFirstSegmentIsIntelligentIdFormat = NameWithoutExtensionIsIntelligentIdFormat(metadataConfiguration, fileNameFirstSegment);
bool fileNameFirstSegmentIsPaddedIntelligentIdFormat = NameWithoutExtensionIsPaddedIntelligentIdFormat(metadataConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment);
bool fileNameFirstSegmentIsIdFormat = !fileNameFirstSegmentIsPaddedIntelligentIdFormat && !fileNameFirstSegmentIsIntelligentIdFormat && NameWithoutExtensionIsIdFormat(metadataConfiguration, fileNameFirstSegment);
if (fileNameFirstSegmentIsIdFormat)
{
if (index is null)
throw new NullReferenceException(nameof(index));
if (!int.TryParse(fileNameFirstSegment, out int valueOfFileNameFirstSegment))
throw new NotSupportedException();
(id, sortOder) = (valueOfFileNameFirstSegment, metadataConfiguration.Offset + index);
}
else if (!fileNameFirstSegmentIsIntelligentIdFormat && !fileNameFirstSegmentIsPaddedIntelligentIdFormat)
(id, sortOder) = (null, null);
else if (fileNameFirstSegmentIsIntelligentIdFormat)
(id, sortOder) = (GetId(metadataConfiguration, fileNameFirstSegment), null);
else if (fileNameFirstSegmentIsPaddedIntelligentIdFormat)
{
if (!int.TryParse(fileNameFirstSegment[..sortOrderOnlyLengthIndex], out int absoluteValueOfSortOrder))
(id, sortOder) = (null, null);
else
(id, sortOder) = (GetId(metadataConfiguration, fileNameFirstSegment[sortOrderOnlyLengthIndex..]), absoluteValueOfSortOrder);
}
else
throw new NotSupportedException();
result = new(fileInfo.CreationTime.Ticks,
fileDirectoryName,
fileInfo.Extension.ToLower(),
fileNameFirstSegment,
fileInfo.FullName,
id,
fileNameFirstSegmentIsIntelligentIdFormat,
fileInfo.LastWriteTime.Ticks,
fileInfo.Length,
fileInfo.Name,
Path.GetFileNameWithoutExtension(fileInfo.Name),
sortOder);
return result;
}
private static IntelligentIdRecord GetIntelligentIdRecord(MetadataConfiguration metadataConfiguration, long id, bool ignore)
{
IntelligentIdRecord result;
StringBuilder stringBuilder = new();
if (metadataConfiguration.IntMinValueLength < (metadataConfiguration.ResultAllInOneSubdirectoryLength + 2))
throw new NotSupportedException();
int key;
string value;
List<char> chars = [];
if (id > -1)
{
key = ignore ? 8 : 9;
value = id.ToString().PadLeft(metadataConfiguration.IntMinValueLength, '0');
}
else
{
key = ignore ? 2 : 1;
value = id.ToString()[1..].PadLeft(metadataConfiguration.IntMinValueLength, '0');
}
for (int i = value.Length - metadataConfiguration.ResultAllInOneSubdirectoryLength - 1; i > -1; i--)
_ = stringBuilder.Append(value[i]);
for (int i = value.Length - metadataConfiguration.ResultAllInOneSubdirectoryLength; i < value.Length; i++)
chars.Add(value[i]);
result = new(key, new(chars), stringBuilder.ToString());
return result;
}
private static string GetIntelligentId(IntelligentIdRecord intelligentId) =>
$"{intelligentId.Reverse}{string.Join(string.Empty, intelligentId.ResultAllInOneSubdirectoryChars)}{intelligentId.Key}";
private static int GetId(MetadataConfiguration metadataConfiguration, string intelligentId)
{
int result;
StringBuilder results = new();
if (metadataConfiguration.IntMinValueLength < (metadataConfiguration.ResultAllInOneSubdirectoryLength + 2))
throw new NotSupportedException();
for (int i = intelligentId.Length - (metadataConfiguration.ResultAllInOneSubdirectoryLength + 2); i > -1; i--)
_ = results.Append(intelligentId[i]);
_ = results.Append(intelligentId[^3]).Append(intelligentId[^2]);
result = int.Parse(results.ToString());
if (intelligentId[^1] is '1' or '2')
result *= -1;
else if (intelligentId[^1] is not '9' and not '8')
throw new NotSupportedException();
return result;
}
private static ReadOnlyCollection<Record> GetRecords(MetadataConfiguration metadataConfiguration, string sourceDirectory, string searchPattern)
{
List<Record> results = [];
int check;
int index = -1;
FileInfo fileInfo;
FilePath filePath;
string? directory;
string[] segments;
bool ignore = false;
string directoryName;
string intelligentId;
string? parentDirectory;
IntelligentIdRecord intelligentIdRecord;
string sourceParentDirectory = Path.GetDirectoryName(sourceDirectory) ?? throw new NotSupportedException();
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
foreach (string file in files)
{
index += 1;
directory = Path.GetDirectoryName(file);
if (directory is null)
continue;
parentDirectory = Path.GetDirectoryName(directory);
if (parentDirectory is null)
continue;
fileInfo = new(file);
directoryName = Path.GetFileName(directory);
filePath = GetFilePath(metadataConfiguration, fileInfo, index);
if (filePath.Id is null)
continue;
intelligentIdRecord = GetIntelligentIdRecord(metadataConfiguration, filePath.Id.Value, ignore);
intelligentId = GetIntelligentId(intelligentIdRecord);
check = GetId(metadataConfiguration, intelligentId);
if (check != filePath.Id.Value)
throw new NotSupportedException();
segments = Path.GetFileName(file).Split('.');
if (segments.Length == 2)
{
if (filePath.SortOrder is not null)
results.Add(new(file, directory, $"{filePath.SortOrder.Value}{intelligentId}.{segments[1]}"));
else
results.Add(new(file, Path.Combine(sourceParentDirectory, intelligentIdRecord.Key.ToString(), string.Join(string.Empty, intelligentIdRecord.ResultAllInOneSubdirectoryChars)), $"{intelligentId}.{segments[1]}"));
}
else if (segments.Length == 3)
results.Add(new(file, Path.Combine(sourceParentDirectory, intelligentIdRecord.Key.ToString(), string.Join(string.Empty, intelligentIdRecord.ResultAllInOneSubdirectoryChars)), $"{intelligentId}.{segments[1]}.{segments[2]}"));
else if (segments.Length == 4)
{
if (directoryName != segments[0])
results.Add(new(file, directory, $"{intelligentId}.{segments[1]}.{segments[2]}.{segments[3]}"));
else
results.Add(new(file, Path.Combine(sourceParentDirectory, intelligentIdRecord.Key.ToString(), string.Join(string.Empty, intelligentIdRecord.ResultAllInOneSubdirectoryChars), intelligentId), $"{intelligentId}.{segments[1]}.{segments[2]}.{segments[3]}"));
}
else if (segments.Length == 5)
results.Add(new(file, directory, $"{intelligentId}.{segments[1]}.{segments[2]}.{segments[3]}.{segments[4]}"));
else
continue;
}
return new(results);
}
internal static void ConvertId(ILogger<Worker> logger, List<string> args)
{
List<string> distinct = [];
string searchPattern = args[2];
string sourceDirectory = args[0];
logger.LogInformation("{sourceDirectory}", sourceDirectory);
MetadataConfiguration metadataConfiguration = new(2, 1000000, int.MinValue.ToString().Length);
ReadOnlyCollection<Record> records = GetRecords(metadataConfiguration, sourceDirectory, searchPattern);
foreach (Record record in records)
{
if (distinct.Contains(record.DestinationDirectory))
continue;
distinct.Add(record.DestinationDirectory);
if (!Directory.Exists(record.DestinationDirectory))
_ = Directory.CreateDirectory(record.DestinationDirectory);
}
foreach (Record record in records)
File.Move(record.File, Path.Combine(record.DestinationDirectory, record.DestinationFile));
}
}