.editorconfig

2023-12-12 SplitJsonFile
2023-11-28 Migrated to File-Watcher
2023-12-05 SplitMarkdownFile
2023-11-30 RenameReactorProcessDataStandardFormatFiles
2023-11-22 ProcessDataStandardFormat
This commit is contained in:
Mike Phares 2023-12-13 13:19:37 -07:00
parent 5fe51ef645
commit 1f5743cf74
7 changed files with 880 additions and 5 deletions

View File

@ -108,6 +108,7 @@ dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be removed
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
dotnet_diagnostic.IDE0060.severity = warning # IDE0060: Remove unused parameter
dotnet_diagnostic.IDE0270.severity = warning # IDE0270: Null check can be simplified
dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]csharp(IDE0290)
dotnet_diagnostic.IDE0300.severity = error # IDE0300: Collection initialization can be simplified
dotnet_diagnostic.IDE0301.severity = error #IDE0301: Collection initialization can be simplified

193
Day/Helper-2023-11-22.cs Normal file
View File

@ -0,0 +1,193 @@
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 = [];
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;
results.Add(new(file, fileName, equipment, timestamp));
}
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);
}
}
}

126
Day/Helper-2023-11-30.cs Normal file
View File

@ -0,0 +1,126 @@
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 ReadOnlyCollection<Record> GetRecords(string sourceDirectory, string timestampFormat)
{
List<Record> results = [];
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;
results.Add(new(file, fileName, equipment, timestamp));
}
return new(results.OrderBy(l => l.TimeStamp).ToArray());
}
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);
}
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);
}
}

99
Day/Helper-2023-12-05.cs Normal file
View File

@ -0,0 +1,99 @@
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.Day;
internal static partial class Helper20231205
{
[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;
}
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;
}
internal static void SplitMarkdownFile(ILogger<Worker> logger, List<string> args)
{
string[] lines;
string? fileName;
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)
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();
}
}
}
}

435
Day/Helper-2023-12-12.cs Normal file
View File

@ -0,0 +1,435 @@
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.Day;
internal static partial class Helper20231212
{
[GeneratedRegex(@"[\\,\/,\:,\*,\?,\"",\<,\>,\|]")]
private static partial Regex WindowsSafe();
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 HostNames(
[property: JsonPropertyName("HostName")] object 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? GetStrippedIPV4(string value)
{
string? result;
string[] subSegments = value.Split('.');
if (subSegments.Length != 4)
result = null;
else
{
if (!subSegments.All(l => int.TryParse(l, out _)))
result = null;
else
result = value.Replace(".", string.Empty);
}
return result;
}
private static string? GetStrippedMacAddress(string value)
{
string? result;
if (value.Length != 17)
result = null;
else
{
if (value[2] is not ':' or '-' || value[5] is not ':' or '-' || value[8] is not ':' or '-' || value[11] is not ':' or '-' || value[14] is not ':' or '-')
result = null;
else
result = $"{value[0]}{value[1]}{value[3]}{value[4]}{value[6]}{value[7]}{value[9]}{value[10]}{value[12]}{value[13]}{value[15]}{value[16]}".ToLower();
}
return result;
}
internal static void SplitJsonFile(ILogger<Worker> logger, List<string> args)
{
string json;
Record? record;
string fileName;
string checkFileName;
string? strippedIpV4;
List<string> lines = [];
List<string> links = [];
string? strippedMacAddress;
string fileNameWithoutExtension;
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)
{
links.Clear();
json = File.ReadAllText(file);
record = JsonSerializer.Deserialize(json, RecordSourceGenerationContext.Default.Record);
if (record is null)
continue;
foreach (Host host in record.Hosts)
{
lines.Clear();
strippedIpV4 = null;
strippedMacAddress = null;
foreach (HostAddress hostAddress in host.HostAddresses)
{
if (hostAddress.AddressType == "ipv4")
strippedIpV4 = GetStrippedIPV4(hostAddress.Address);
else if (hostAddress.AddressType == "mac")
strippedMacAddress = GetStrippedMacAddress(hostAddress.Address);
else
continue;
}
if (strippedMacAddress is null && strippedIpV4 is null)
continue;
json = JsonSerializer.Serialize(host, HostSourceGenerationContext.Default.Host);
fileNameWithoutExtension = strippedMacAddress is null ? $"ipv4-{strippedIpV4}" : $"mac-{strippedMacAddress}";
fileName = $"{fileNameWithoutExtension}.md";
links.Add($"- [{string.Join(" - ", host.HostAddresses.Select(l => l.Address))}]({fileName})");
lines.Add($"# {fileNameWithoutExtension}");
lines.Add(string.Empty);
lines.Add("```json");
lines.Add(json);
lines.Add("```");
lines.Add(string.Empty);
logger.LogInformation("{fileName} created", fileName);
checkFileName = Path.Combine(outputDirectory, fileName);
if (File.Exists(checkFileName))
File.Delete(checkFileName);
File.WriteAllLines(checkFileName, lines);
}
lines.Clear();
record.Hosts.Clear();
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
json = JsonSerializer.Serialize(record, RecordSourceGenerationContext.Default.Record);
lines.Add($"# {fileNameWithoutExtension}");
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, $"{fileNameWithoutExtension}-links.md");
if (File.Exists(checkFileName))
File.Delete(checkFileName);
File.WriteAllLines(checkFileName, lines);
}
}
}

View File

@ -20,6 +20,16 @@ internal static class HelperDay
Day.Helper20231102.NuSpec(logger, args[0]);
else if (args[1] == "Day-Helper-2023-11-08")
Day.Helper20231108.MasterImage(logger, args);
else if (args[1] == "Day-Helper-2023-11-22")
Day.Helper20231122.ProcessDataStandardFormat(logger, args);
else if (args[1] == "Day-Helper-2023-11-28")
logger.LogError("{arg} - has been migrated to File-Watcher", args[1]);
else if (args[1] == "Day-Helper-2023-11-30")
Day.Helper20231130.RenameReactorProcessDataStandardFormatFiles(logger, args);
else if (args[1] == "Day-Helper-2023-12-05")
Day.Helper20231205.SplitMarkdownFile(logger, args);
else if (args[1] == "Day-Helper-2023-12-12")
Day.Helper20231212.SplitJsonFile(logger, args);
else
throw new Exception(appSettings.Company);
}

View File

@ -31,11 +31,12 @@ internal static partial class HelperZipFilesBy
return dateTimeOffset;
}
private static bool ExtractKeyFileAndSetDateFromZipEntry(ILogger<Worker> logger, string[] zipFiles, string keyFileExtension, string keyFileExtensionB, string keyFileExtensionC)
private static bool ExtractKeyFileAndSetDateFromZipEntry(ILogger<Worker> logger, string[] zipFiles, string keyFileExtension, string keyFileExtensionB, string keyFileExtensionC, bool renameToLower)
{
bool result = false;
string[] files;
string checkFile;
string? lowerName;
FileInfo fileInfo;
FileInfo extractKeyFileInfo;
DateTimeOffset? dateTimeOffset;
@ -44,6 +45,16 @@ internal static partial class HelperZipFilesBy
fileInfo = new(zipFile);
if (fileInfo.DirectoryName is null)
throw new NullReferenceException(nameof(fileInfo.DirectoryName));
lowerName = !renameToLower ? null : Path.Combine(fileInfo.DirectoryName, fileInfo.Name.ToLower());
if (renameToLower && lowerName is not null && lowerName != fileInfo.FullName)
{
files = Directory.GetFiles(fileInfo.DirectoryName, $"{Path.GetFileNameWithoutExtension(fileInfo.Name)}*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
File.Move(file, Path.Combine(fileInfo.DirectoryName, Path.GetFileName(file).ToLower()));
fileInfo = new(lowerName);
if (fileInfo.DirectoryName is null)
throw new NullReferenceException(nameof(fileInfo.DirectoryName));
}
extractKeyFileInfo = new(Path.Combine(fileInfo.DirectoryName, $"{Path.GetFileNameWithoutExtension(fileInfo.Name)}{keyFileExtension}"));
if (extractKeyFileInfo.Exists)
{
@ -250,10 +261,10 @@ internal static partial class HelperZipFilesBy
return result;
}
internal static bool ExportNuspecAndSetDateFromZipEntry(ILogger<Worker> logger, string[] files) =>
ExtractKeyFileAndSetDateFromZipEntry(logger, files, ".nuspec", "icon", "readme");
internal static bool ExportNuspecAndSetDateFromZipEntry(ILogger<Worker> logger, string[] files, bool renameToLower) =>
ExtractKeyFileAndSetDateFromZipEntry(logger, files, ".nuspec", "icon", "readme", renameToLower);
internal static bool ExtractKeyFileAndSetDateFromZipEntry(ILogger<Worker> logger, string sourceDirectory, SearchOption searchOption = SearchOption.AllDirectories)
internal static bool ExtractKeyFileAndSetDateFromZipEntry(ILogger<Worker> logger, string sourceDirectory, SearchOption searchOption = SearchOption.AllDirectories, bool renameToLower = false)
{
bool result = false;
bool loop;
@ -273,7 +284,7 @@ internal static partial class HelperZipFilesBy
_ => throw new NotSupportedException()
};
zipFiles = Directory.GetFiles(sourceDirectory, searchPattern, searchOption);
loop = ExtractKeyFileAndSetDateFromZipEntry(logger, zipFiles, keyFileExtension, keyFileExtensionB, keyFileExtensionC);
loop = ExtractKeyFileAndSetDateFromZipEntry(logger, zipFiles, keyFileExtension, keyFileExtensionB, keyFileExtensionC, renameToLower);
if (loop && !result)
result = true;
}