diff --git a/.vscode/.http b/.vscode/.http
new file mode 100644
index 0000000..ab0a9a9
--- /dev/null
+++ b/.vscode/.http
@@ -0,0 +1,23 @@
+
+###
+
+GET https://eaf-dev.mes.infineon.com/bob/v1/sync/
+
+###
+
+POST https://eaf-dev.mes.infineon.com/bob/v1/sync/
+Accept: application/json
+
+{
+ "id": "110738",
+ "machineId": "30ef1b54e075c5370ce74eea2042cb750be659696b170f8758d219a8f9a88e10",
+ "page": "time",
+ "site": "MES",
+ "time": "1744339499677",
+ "username": "phares",
+ "value": "3"
+}
+
+###
+
+https://eaf-dev.mes.infineon.com/api/v1/ado/
\ No newline at end of file
diff --git a/File-Watcher.csproj b/File-Watcher.csproj
index 5a61b98..d2c0d57 100644
--- a/File-Watcher.csproj
+++ b/File-Watcher.csproj
@@ -12,7 +12,12 @@
-
+
+
+
+
+
+
@@ -20,12 +25,12 @@
-
+
-
+
-
+
diff --git a/Helpers/DiskInfoHelper.cs b/Helpers/DiskInfoHelper.cs
new file mode 100644
index 0000000..6268650
--- /dev/null
+++ b/Helpers/DiskInfoHelper.cs
@@ -0,0 +1,503 @@
+using File_Watcher.Models;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace File_Watcher.Helpers;
+
+internal static partial class DiskInfoHelper
+{
+
+ public record DiskDrive(string? Caption,
+ string? DeviceID,
+ string? FirmwareRevision,
+ uint? Index,
+ string? Model,
+ string? Name,
+ uint? Partitions,
+ DiskPartition[]? PartitionCollection,
+ string? SerialNumber,
+ ulong? Size,
+ string? Status,
+ string? SystemName,
+ ulong? TotalCylinders,
+ ulong? TotalHeads)
+ {
+
+ internal static DiskDrive Get(DiskDrive diskDrive, DiskPartition[] diskPartitions, LogicalDrive[] logicalDrives)
+ {
+ DiskDrive result;
+ DiskPartition[] collection = DiskPartition.Get((from l in diskPartitions where l.DiskIndex == diskDrive.Index select l).ToArray(), logicalDrives);
+ result = new(Caption: diskDrive.Caption,
+ DeviceID: diskDrive.DeviceID,
+ FirmwareRevision: diskDrive.FirmwareRevision,
+ Index: diskDrive.Index,
+ Model: diskDrive.Model,
+ Name: diskDrive.Name,
+ Partitions: diskDrive.Partitions,
+ PartitionCollection: collection,
+ SerialNumber: diskDrive.SerialNumber,
+ Size: diskDrive.Size,
+ Status: diskDrive.Status,
+ SystemName: diskDrive.SystemName,
+ TotalCylinders: diskDrive.TotalCylinders,
+ TotalHeads: diskDrive.TotalHeads);
+ return result;
+ }
+
+ }
+
+ [JsonSourceGenerationOptions(WriteIndented = true)]
+ [JsonSerializable(typeof(DiskDrive[]))]
+ private partial class DiskDriveArraySourceGenerationContext : JsonSerializerContext
+ {
+ }
+
+ [JsonSourceGenerationOptions(WriteIndented = true)]
+ [JsonSerializable(typeof(Dictionary))]
+ private partial class DictionaryStringObjectSourceGenerationContext : JsonSerializerContext
+ {
+ }
+
+ [JsonSourceGenerationOptions(WriteIndented = true)]
+ [JsonSerializable(typeof(JsonElement))]
+ private partial class JsonElementSourceGenerationContext : JsonSerializerContext
+ {
+ }
+
+ public record DiskPartition(bool? BootPartition,
+ string? Caption,
+ string? Description,
+ string? DeviceID,
+ uint? DiskIndex,
+ uint? Index,
+ LogicalDrive[]? LogicalDrives,
+ ulong? Size,
+ ulong? StartingOffset,
+ string? SystemName,
+ string? Type)
+ {
+
+ internal static DiskPartition[] Get(DiskPartition[] diskPartitions, LogicalDrive[] logicalDrives)
+ {
+ List results = [];
+ ulong lowerMatch;
+ ulong upperMatch;
+ LogicalDrive[] collection;
+ DiskPartition diskPartition;
+ foreach (DiskPartition p in diskPartitions)
+ {
+ if (p.Size is null)
+ continue;
+ lowerMatch = p.Size.Value - 10240;
+ upperMatch = p.Size.Value + 10240;
+ collection = (from l in logicalDrives where l.DriveType != 4 && l.Size > lowerMatch && l.Size < upperMatch select l).ToArray();
+ diskPartition = new(BootPartition: p.BootPartition,
+ Caption: p.Caption,
+ Description: p.Description,
+ DeviceID: p.DeviceID,
+ DiskIndex: p.DiskIndex,
+ Index: p.Index,
+ LogicalDrives: collection,
+ Size: p.Size,
+ StartingOffset: p.StartingOffset,
+ SystemName: p.SystemName,
+ Type: p.Type);
+ results.Add(diskPartition);
+ }
+ return results.ToArray();
+ }
+
+ }
+
+ [JsonSourceGenerationOptions(WriteIndented = true)]
+ [JsonSerializable(typeof(DiskPartition[]))]
+ private partial class DiskPartitionSourceGenerationContext : JsonSerializerContext
+ {
+ }
+
+ public record LogicalDrive(string? Caption,
+ string? DeviceID,
+ uint? DriveType,
+ string? FileSystem,
+ ulong? FreeSpace,
+ string? Name,
+ ulong? PercentageFree,
+ ulong? PercentageUsed,
+ string? ProviderName,
+ ulong? Size,
+ string? SystemName,
+ string? VolumeName,
+ string? VolumeSerialNumber);
+
+ [JsonSourceGenerationOptions(WriteIndented = true)]
+ [JsonSerializable(typeof(LogicalDrive[]))]
+ private partial class LogicalDriveSourceGenerationContext : JsonSerializerContext
+ {
+ }
+
+ public record Record(long AvailableFreeSpace,
+ string DriveFormat,
+ string DriveType,
+ bool IsReady,
+ char Name,
+ ulong PercentageFree,
+ ulong PercentageUsed,
+ long TotalFreeSpace,
+ long TotalSize,
+ string VolumeLabel)
+ {
+
+ public static Record Get(DriveInfo driveInfo) =>
+ new(AvailableFreeSpace: driveInfo.AvailableFreeSpace,
+ DriveFormat: driveInfo.DriveFormat,
+ DriveType: driveInfo.DriveType.ToString(),
+ IsReady: driveInfo.IsReady,
+ Name: driveInfo.Name.ToUpper()[0],
+ PercentageUsed: (ulong)(Math.Round(driveInfo.AvailableFreeSpace / (double)driveInfo.TotalSize, 2) * 100),
+ PercentageFree: (ulong)(Math.Round((driveInfo.TotalSize - driveInfo.AvailableFreeSpace) / (double)driveInfo.TotalSize, 2) * 100),
+ TotalFreeSpace: driveInfo.TotalFreeSpace,
+ TotalSize: driveInfo.TotalSize,
+ VolumeLabel: driveInfo.VolumeLabel);
+ }
+
+ [JsonSourceGenerationOptions(WriteIndented = true)]
+ [JsonSerializable(typeof(Record[]))]
+ private partial class RecordSourceGenerationContext : JsonSerializerContext
+ {
+ }
+
+ private record Win32(string? DiskDrive,
+ string? Processor,
+ string? LogicalDisk,
+ string? DiskPartition,
+ string? NetworkAdapter);
+
+ internal static bool WriteDiskInfo(AppSettings appSettings, ILogger logger)
+ {
+ string? json = WriteRecord();
+ ReadOnlyCollection devices = GetDrives(appSettings, logger);
+ string yaml = GetYetAnotherMarkupLanguage(devices);
+ ReadOnlyCollection normalized = GetNormalized(appSettings, logger, devices);
+ string text = string.Join(Environment.NewLine, normalized);
+ string markdown = string.Concat("# ",
+ Environment.MachineName.ToUpper(),
+ Environment.NewLine,
+ Environment.NewLine,
+ "## Normalized",
+ Environment.NewLine,
+ Environment.NewLine,
+ "```log",
+ Environment.NewLine,
+ text,
+ Environment.NewLine,
+ "```",
+ Environment.NewLine,
+ Environment.NewLine,
+ "## json",
+ Environment.NewLine,
+ Environment.NewLine,
+ "```json",
+ Environment.NewLine,
+ json,
+ Environment.NewLine,
+ "```",
+ Environment.NewLine,
+ Environment.NewLine,
+ "## yaml",
+ Environment.NewLine,
+ Environment.NewLine,
+ "```yaml",
+ Environment.NewLine,
+ yaml,
+ Environment.NewLine,
+ "```",
+ Environment.NewLine);
+ WriteAllText(Path.Combine(appSettings.DiskInfoConfiguration.Destination, $"{Environment.MachineName.ToUpper()}.md"), markdown);
+ return true;
+ }
+
+ private static string WriteRecord()
+ {
+ string result;
+ Record record;
+ List records = [];
+ DriveInfo[] drives = DriveInfo.GetDrives();
+ foreach (DriveInfo driveInfo in drives)
+ {
+ record = Record.Get(driveInfo);
+ records.Add(record);
+ }
+ result = JsonSerializer.Serialize(records.ToArray(), RecordSourceGenerationContext.Default.RecordArray);
+ return result;
+ }
+
+ private static ReadOnlyCollection GetDrives(AppSettings appSettings, ILogger logger)
+ {
+#pragma warning disable CA1416
+ List results = [];
+ Win32 win32 = GetWin32(appSettings, logger);
+ if (win32.DiskDrive is not null && win32.DiskPartition is not null && win32.LogicalDisk is not null)
+ {
+ DiskDrive diskDrive;
+ string diskDriveJson = win32.DiskDrive[0] == '[' ? win32.DiskDrive : $"[{win32.DiskDrive}]";
+ string logicalDiskJson = win32.LogicalDisk[0] == '[' ? win32.LogicalDisk : $"[{win32.LogicalDisk}]";
+ string diskPartitionJson = win32.DiskPartition[0] == '[' ? win32.DiskPartition : $"[{win32.DiskPartition}]";
+ DiskDrive[] diskDrives = JsonSerializer.Deserialize(diskDriveJson, DiskDriveArraySourceGenerationContext.Default.DiskDriveArray) ??
+ throw new NullReferenceException(nameof(DiskDrive));
+ LogicalDrive[] logicalDrives = JsonSerializer.Deserialize(logicalDiskJson, LogicalDriveSourceGenerationContext.Default.LogicalDriveArray) ??
+ throw new NullReferenceException(nameof(LogicalDrive));
+ DiskPartition[] diskPartitions = JsonSerializer.Deserialize(diskPartitionJson, DiskPartitionSourceGenerationContext.Default.DiskPartitionArray) ??
+ throw new NullReferenceException(nameof(DiskPartition));
+ foreach (DiskDrive d in diskDrives)
+ {
+ diskDrive = DiskDrive.Get(d, diskPartitions, logicalDrives);
+ results.Add(diskDrive);
+ }
+ }
+ return results.AsReadOnly();
+#pragma warning restore
+ }
+
+ private static Win32 GetWin32(AppSettings appSettings, ILogger logger)
+ {
+ Win32 win32;
+ Process? process;
+ string[] segments;
+ string standardError;
+ string standardOutput;
+ string? diskDrive = null;
+ string? processor = null;
+ string? logicalDisk = null;
+ string? diskPartition = null;
+ string? networkAdapter = null;
+ ProcessStartInfo processStartInfo;
+ string fileName = "powershell.exe";
+ string date = DateTime.Now.ToString("yyyy-MM-dd");
+ foreach (string className in appSettings.DiskInfoConfiguration.Classes)
+ {
+ segments = className.Split(' ');
+ if (segments[0].Length < 3)
+ continue;
+ processStartInfo = new(fileName, $"-NoProfile -ExecutionPolicy ByPass Get-WmiObject {className} | ConvertTo-JSON")
+ {
+ RedirectStandardError = true,
+ RedirectStandardOutput = true,
+ UseShellExecute = false
+ };
+ try
+ {
+ process = Process.Start(processStartInfo);
+ if (process is not null)
+ {
+ for (int j = 1; j < 45; j++)
+ {
+ _ = process.WaitForExit(1000);
+ if (process.HasExited)
+ break;
+ }
+ if (!process.HasExited)
+ {
+ logger.LogWarning($"// {segments[0]} Never exited!");
+ if (segments[0] is "Win32_DiskDrive" or "Win32_DiskPartition" or "Win32_LogicalDisk")
+ break;
+ }
+ else
+ {
+ standardError = process.StandardError.ReadToEnd();
+ standardOutput = process.StandardOutput.ReadToEnd();
+ logger.LogInformation("// {className}{line}{error}{line}{line}// {output}", segments[0], Environment.NewLine, standardError, Environment.NewLine, Environment.NewLine, standardOutput);
+ if (string.IsNullOrEmpty(standardError))
+ {
+ if (segments[0] == "Win32_DiskDrive")
+ diskDrive = standardOutput;
+ else if (segments[0] == "Win32_DiskPartition")
+ diskPartition = standardOutput;
+ else if (segments[0] == "Win32_LogicalDisk")
+ logicalDisk = standardOutput;
+ else if (segments[0] == "Win32_NetworkAdapter")
+ networkAdapter = standardOutput;
+ else if (segments[0] == "Win32_Processor")
+ processor = standardOutput;
+ WriteAllText(Path.Combine(appSettings.DiskInfoConfiguration.Destination, $"{Environment.MachineName.ToUpper()}-{segments[0]}-{date}.json"), standardOutput);
+ }
+ }
+ }
+ process?.Dispose();
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "Error:");
+ }
+ }
+ win32 = new(DiskDrive: diskDrive,
+ Processor: processor,
+ LogicalDisk: logicalDisk,
+ DiskPartition: diskPartition,
+ NetworkAdapter: networkAdapter);
+ return win32;
+ }
+
+ public static Dictionary DeserializeAndFlatten(string json, char? remove)
+ {
+ Dictionary results = [];
+ JsonElement jsonElement = JsonSerializer.Deserialize(json, JsonElementSourceGenerationContext.Default.JsonElement);
+ FillDictionaryFromJToken(results, jsonElement, string.Empty, remove);
+ return results;
+ }
+
+ private static void FillDictionaryFromJToken(Dictionary results, JsonElement jsonElement, string prefix, char? remove)
+ {
+ switch (jsonElement.ValueKind)
+ {
+ case JsonValueKind.Object:
+ foreach (JsonProperty jsonProperty in jsonElement.EnumerateObject())
+ {
+ FillDictionaryFromJToken(results, jsonProperty.Value, Join(prefix, jsonProperty.Name), remove);
+ }
+ break;
+
+ case JsonValueKind.Array:
+ int index = 0;
+ foreach (JsonElement value in jsonElement.EnumerateArray())
+ {
+ FillDictionaryFromJToken(results, value, Join(prefix, index.ToString()), remove);
+ index++;
+ }
+ break;
+
+ case JsonValueKind.String:
+ if (remove is null)
+ {
+ results.Add(prefix, jsonElement.ToString());
+ }
+ else
+ {
+ results.Add(prefix, jsonElement.ToString().Replace(remove.Value, '_'));
+ }
+ break;
+
+ case JsonValueKind.True:
+ case JsonValueKind.False:
+ case JsonValueKind.Number:
+ results.Add(prefix, jsonElement.ToString());
+ break;
+ }
+ }
+
+ private static string Join(string prefix, string name) =>
+ string.IsNullOrEmpty(prefix) ? name : prefix + "." + name;
+
+ private static string GetYetAnotherMarkupLanguage(ReadOnlyCollection devices)
+ {
+ string result;
+ List results = [];
+ string json = JsonSerializer.Serialize(devices.ToArray(), DiskDriveArraySourceGenerationContext.Default.DiskDriveArray);
+ Dictionary keyValuePairs = DeserializeAndFlatten(json, ':');
+ string[] lines = JsonSerializer.Serialize(keyValuePairs, DictionaryStringObjectSourceGenerationContext.Default.DictionaryStringObject).Split(Environment.NewLine);
+ for (int i = 1; i < lines.Length - 1; i++)
+ {
+ results.Add(lines[i].Trim()
+ .Trim(',')
+ .Trim('"')
+ .Replace("\": \"", ": ")
+ .Replace("\": ", ": "));
+ }
+ result = string.Join(Environment.NewLine, results);
+ return result;
+ }
+
+ private static string GetSizeWithSuffix(ulong value)
+ {
+ string result;
+ int i = 0;
+ double displayValue = value * 1f;
+ string[] SizeSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
+ while (Math.Round(displayValue / 1024f) >= 1)
+ {
+ displayValue /= 1024;
+ i++;
+ }
+ result = string.Format("{0:n1} {1}", displayValue, SizeSuffixes[i]);
+ return result;
+ }
+
+ private static void WriteAllText(string path, string text)
+ {
+ string check = !File.Exists(path) ? string.Empty : File.ReadAllText(path);
+ if (check != text)
+ File.WriteAllText(path, text);
+ }
+
+ private static ReadOnlyCollection GetNormalized(AppSettings appSettings, ILogger logger, ReadOnlyCollection drives)
+ {
+ List results = [];
+ decimal free;
+ decimal used;
+ string display;
+ int deviceCount;
+ int offsetCount;
+ string deviceSize;
+ int partitionCount;
+ results.Add("Max");
+ string offsetDisplay;
+ string partitionSize;
+ decimal devicePercent;
+ string logicalDriveUsed;
+ string logicalDriveSize;
+ decimal partitionPercent;
+ int logicalDriveFreeCount;
+ int logicalDriveUsedCount;
+ decimal partitionDecimalSize;
+ string logicalDriveFreeSpace;
+ decimal logicalDriveDecimalFreeSpace;
+ DiskInfoConfiguration diskInfoConfiguration = appSettings.DiskInfoConfiguration;
+ results.Add($"{new string('-', diskInfoConfiguration.Bars)} Value of Max Argument");
+ foreach (DiskDrive drive in drives.OrderBy(l => l.Index))
+ {
+ if (drive.Size is null || drive.PartitionCollection is null)
+ continue;
+ devicePercent = drive.Size.Value / diskInfoConfiguration.Max;
+ deviceSize = GetSizeWithSuffix(drive.Size.Value);
+ results.Add($"{drive.DeviceID} - Cylinders: {drive.TotalCylinders} - {drive.Model}");
+ deviceCount = (int)Math.Round(devicePercent * diskInfoConfiguration.Bars);
+ results.Add($"{new string('-', deviceCount)} {Math.Round(devicePercent, 2) * 100:000}% of Max Argument {deviceSize}");
+ foreach (DiskPartition partition in drive.PartitionCollection.OrderBy(l => l.Index))
+ {
+ if (partition.Size is null || partition.StartingOffset is null || partition.LogicalDrives is null)
+ continue;
+ partitionPercent = partition.Size.Value / diskInfoConfiguration.Max;
+ partitionSize = GetSizeWithSuffix(partition.Size.Value);
+ partitionCount = (int)Math.Round(partitionPercent * diskInfoConfiguration.Bars);
+ offsetCount = (int)Math.Round(partition.StartingOffset.Value / diskInfoConfiguration.Max * diskInfoConfiguration.Bars);
+ offsetDisplay = new string('_', offsetCount);
+ results.Add($"{partition.DeviceID} - {string.Join(", ", partition.LogicalDrives.Select(l => l.DeviceID))}");
+ results.Add($"{offsetDisplay}{new string('-', partitionCount)}{new string('_', diskInfoConfiguration.Bars - offsetCount - partitionCount)} {Math.Round(partitionPercent, 2) * 100:000}% of Disk {partitionSize}");
+ foreach (LogicalDrive logicalDrive in partition.LogicalDrives)
+ {
+ if (logicalDrive.Size is null || logicalDrive.FreeSpace is null)
+ continue;
+ if ((int)Math.Round(logicalDrive.Size.Value / diskInfoConfiguration.Max * diskInfoConfiguration.Bars) != (int)Math.Round(partition.Size.Value / diskInfoConfiguration.Max * diskInfoConfiguration.Bars))
+ {
+ logger.LogWarning("logicalDrive.Size !~ partition.Size");
+ break;
+ }
+ partitionDecimalSize = partition.Size.Value;
+ logicalDriveDecimalFreeSpace = logicalDrive.FreeSpace.Value;
+ logicalDriveSize = GetSizeWithSuffix(logicalDrive.Size.Value);
+ logicalDriveFreeSpace = GetSizeWithSuffix(logicalDrive.FreeSpace.Value);
+ logicalDriveUsed = GetSizeWithSuffix(logicalDrive.Size.Value - logicalDrive.FreeSpace.Value);
+ logicalDriveFreeCount = (int)Math.Round(logicalDriveDecimalFreeSpace / diskInfoConfiguration.Max * diskInfoConfiguration.Bars);
+ display = string.IsNullOrEmpty(logicalDrive.DeviceID) ? "Partition" : logicalDrive.DeviceID;
+ logicalDriveUsedCount = (int)Math.Round((partitionDecimalSize - logicalDriveDecimalFreeSpace) / diskInfoConfiguration.Max * diskInfoConfiguration.Bars);
+ free = (int)(Math.Round(logicalDriveDecimalFreeSpace / partitionDecimalSize, 2) * 100);
+ used = (int)(Math.Round((partitionDecimalSize - logicalDriveDecimalFreeSpace) / partitionDecimalSize, 2) * 100);
+ results.Add($"{offsetDisplay}{new string('-', logicalDriveUsedCount)}{new string('*', logicalDriveFreeCount)}{new string('_', diskInfoConfiguration.Bars - offsetCount - logicalDriveUsedCount - logicalDriveFreeCount)} {used:000}% of [{display}] {logicalDriveUsed} ({free:000}% {logicalDriveFreeSpace} free)");
+ }
+ }
+ }
+ return results.AsReadOnly();
+ }
+
+}
\ No newline at end of file
diff --git a/Helpers/HelperCamstarOracle.cs b/Helpers/HelperCamstarOracle.cs
index a33e0a2..b2f53a1 100644
--- a/Helpers/HelperCamstarOracle.cs
+++ b/Helpers/HelperCamstarOracle.cs
@@ -68,7 +68,7 @@ internal static partial class HelperCamstarOracle
return results;
}
- internal static bool Check(AppSettings appSettings, ILogger logger, CancellationToken cancellationToken)
+ internal static bool Check(AppSettings appSettings, IHttpClientFactory httpClientFactory, ILogger logger, CancellationToken cancellationToken)
{
if (_MonIn is null)
throw new NullReferenceException(nameof(_MonIn));
@@ -100,6 +100,7 @@ internal static partial class HelperCamstarOracle
File.WriteAllLines(Path.Combine(directory, $"{dateTime.Ticks}.tsv"), lines);
if (_LastValue is null || _LastUpload is null || _LastValue.Value != lines.Count || new TimeSpan(dateTime.Ticks - _LastUpload.Value.Ticks).TotalMinutes > 5)
{
+ Heartbeat(appSettings, httpClientFactory, logger, State.Up, cancellationToken);
Task httpResponseMessage = _MonIn.SendPerformanceMessage(camstarOracleConfiguration.MonitorApplicationSite, camstarOracleConfiguration.MonitorApplicationResource, performanceName, value: lines.Count, description: string.Empty);
httpResponseMessage.Wait(cancellationToken);
if (httpResponseMessage.Result.StatusCode != System.Net.HttpStatusCode.OK)
diff --git a/Helpers/SeleniumHelper.cs b/Helpers/SeleniumHelper.cs
new file mode 100644
index 0000000..424702b
--- /dev/null
+++ b/Helpers/SeleniumHelper.cs
@@ -0,0 +1,45 @@
+using File_Watcher.Models;
+#if Selenium
+using OpenQA.Selenium;
+using OpenQA.Selenium.Edge;
+#endif
+
+namespace File_Watcher.Helpers;
+
+internal static partial class SeleniumHelper
+{
+
+ //
+ //
+
+ internal static bool HyperTextMarkupLanguageToPortableNetworkGraphics(AppSettings appSettings, ILogger logger)
+ {
+ if (!string.IsNullOrEmpty(appSettings.SeleniumConfiguration.UniformResourceLocator))
+ logger.LogInformation("This helper is disabled!");
+#if Selenium
+ EdgeOptions edgeOptions = new();
+ foreach (string edgeOption in appSettings.SeleniumConfiguration.EdgeOptions)
+ edgeOptions.AddArgument(edgeOption);
+ EdgeDriver edgeDriver = new(edgeOptions);
+ string outputFile = Path.Combine(appSettings.SeleniumConfiguration.DestinationDirectory, $"{DateTime.Now:yyyy-MM-dd;HH-mi-ss-fff}.png");
+ try
+ {
+ edgeDriver.Navigate().GoToUrl(appSettings.SeleniumConfiguration.UniformResourceLocator);
+#pragma warning disable CS8602, CS8604
+ int fullWidth = int.Parse(edgeDriver.ExecuteScript("return document.body.parentNode.scrollWidth").ToString());
+ int fullHeight = int.Parse(edgeDriver.ExecuteScript("return document.body.parentNode.scrollHeight").ToString());
+#pragma warning restore CS8602, CS8604
+ edgeDriver.Manage().Window.Size = new(fullWidth, fullHeight);
+ Screenshot screenshot = edgeDriver.GetScreenshot();
+ screenshot.SaveAsFile(outputFile);
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, ex.Message);
+ }
+ edgeDriver.Close();
+#endif
+ return true;
+ }
+
+}
diff --git a/Helpers/SyncHelper.cs b/Helpers/SyncHelper.cs
new file mode 100644
index 0000000..c7431f6
--- /dev/null
+++ b/Helpers/SyncHelper.cs
@@ -0,0 +1,51 @@
+using File_Watcher.Models;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace File_Watcher.Helpers;
+
+internal static partial class SyncHelper
+{
+
+ private record Record(string RelativePath,
+ long Size,
+ long Ticks);
+
+ private record RelativePath(string Path,
+ Record[] Records);
+
+ [JsonSourceGenerationOptions(WriteIndented = true)]
+ [JsonSerializable(typeof(RelativePath))]
+ private partial class RelativePathSourceGenerationContext : JsonSerializerContext
+ {
+ }
+
+ [JsonSourceGenerationOptions(WriteIndented = true)]
+ [JsonSerializable(typeof(Dictionary))]
+ private partial class DictionaryStringObjectBSourceGenerationContext : JsonSerializerContext
+ {
+ }
+
+ internal static bool Check(AppSettings _, ILogger __) =>
+ true;
+
+ internal static string GetReply(string body, Dictionary keyValuePairs)
+ {
+ string? json;
+ RelativePath? relativePath;
+ if (!string.IsNullOrEmpty(body) && body[0] == '{')
+ {
+ File.WriteAllText(".json", body);
+ relativePath = JsonSerializer.Deserialize(body, RelativePathSourceGenerationContext.Default.RelativePath) ?? throw new NullReferenceException();
+ }
+ else
+ {
+ json = JsonSerializer.Serialize(keyValuePairs, DictionaryStringObjectBSourceGenerationContext.Default.DictionaryStringObject);
+ File.WriteAllText(".json", json);
+ relativePath = JsonSerializer.Deserialize(json, RelativePathSourceGenerationContext.Default.RelativePath) ?? throw new NullReferenceException();
+ }
+ if (relativePath is null)
+ { }
+ return $"wait-{relativePath?.Records.Length}";
+ }
+}
\ No newline at end of file
diff --git a/Models/AppSettings.cs b/Models/AppSettings.cs
index 781e502..c08c6eb 100644
--- a/Models/AppSettings.cs
+++ b/Models/AppSettings.cs
@@ -7,6 +7,7 @@ namespace File_Watcher.Models;
public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
CompassConfiguration CompassConfiguration,
DeterministicHashCodeConfiguration DeterministicHashCodeConfiguration,
+ DiskInfoConfiguration DiskInfoConfiguration,
DriveConfiguration DriveConfiguration,
EAFLogConfiguration EAFLogConfiguration,
EDADatabaseConfiguration EDADatabaseConfiguration,
@@ -17,8 +18,10 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
MetrologyConfiguration MetrologyConfiguration,
NugetConfiguration NugetConfiguration,
ResultSettings ResultSettings,
+ SeleniumConfiguration SeleniumConfiguration,
SerialConfiguration SerialConfiguration,
StratusConfiguration StratusConfiguration,
+ SyncConfiguration SyncConfiguration,
TransmissionControlProtocolConfiguration TransmissionControlProtocolConfiguration,
WaferCounterConfiguration WaferCounterConfiguration)
{
@@ -29,6 +32,7 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
#pragma warning disable IL3050, IL2026
CamstarOracleConfiguration? camstarOracleConfiguration = configurationRoot.GetSection(nameof(CamstarOracleConfiguration)).Get();
CompassConfiguration? compassConfiguration = configurationRoot.GetSection(nameof(CompassConfiguration)).Get();
+ DiskInfoConfiguration? diskInfoConfiguration = configurationRoot.GetSection(nameof(DiskInfoConfiguration)).Get();
DeterministicHashCodeConfiguration? deterministicHashCodeConfiguration = configurationRoot.GetSection(nameof(DeterministicHashCodeConfiguration)).Get();
DriveConfiguration? driveConfiguration = configurationRoot.GetSection(nameof(DriveConfiguration)).Get();
EAFLogConfiguration? eafLogConfiguration = configurationRoot.GetSection(nameof(EAFLogConfiguration)).Get();
@@ -40,14 +44,17 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
MetrologyConfiguration? metrologyConfiguration = configurationRoot.GetSection(nameof(MetrologyConfiguration)).Get();
NugetConfiguration? nugetConfiguration = configurationRoot.GetSection(nameof(NugetConfiguration)).Get();
ResultSettings? resultSettings = configurationRoot.GetSection(nameof(ResultSettings)).Get();
+ SeleniumConfiguration? seleniumConfiguration = configurationRoot.GetSection(nameof(SeleniumConfiguration)).Get();
SerialConfiguration? serialConfiguration = configurationRoot.GetSection(nameof(SerialConfiguration)).Get();
StratusConfiguration? stratusConfiguration = configurationRoot.GetSection(nameof(StratusConfiguration)).Get();
+ SyncConfiguration? syncConfiguration = configurationRoot.GetSection(nameof(SyncConfiguration)).Get();
TransmissionControlProtocolConfiguration? transmissionControlProtocolConfiguration = configurationRoot.GetSection(nameof(TransmissionControlProtocolConfiguration)).Get();
WaferCounterConfiguration? waferCounterConfiguration = configurationRoot.GetSection(nameof(WaferCounterConfiguration)).Get();
#pragma warning restore IL3050, IL2026
if (camstarOracleConfiguration is null
|| compassConfiguration is null
|| deterministicHashCodeConfiguration is null
+ || diskInfoConfiguration is null
|| driveConfiguration is null
|| eafLogConfiguration is null
|| edaDatabaseConfiguration is null
@@ -58,8 +65,10 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
|| metrologyConfiguration is null
|| nugetConfiguration is null
|| resultSettings is null
+ || seleniumConfiguration is null
|| serialConfiguration is null
|| stratusConfiguration is null
+ || syncConfiguration is null
|| transmissionControlProtocolConfiguration is null
|| waferCounterConfiguration is null
|| fileWatcherConfiguration?.Company is null)
@@ -78,6 +87,7 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
result = new(camstarOracleConfiguration,
compassConfiguration,
deterministicHashCodeConfiguration,
+ diskInfoConfiguration,
driveConfiguration,
eafLogConfiguration,
edaDatabaseConfiguration,
@@ -88,8 +98,10 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
metrologyConfiguration,
nugetConfiguration,
resultSettings,
+ seleniumConfiguration,
serialConfiguration,
stratusConfiguration,
+ syncConfiguration,
transmissionControlProtocolConfiguration,
waferCounterConfiguration);
Verify(result);
diff --git a/Models/DiskInfoConfiguration.cs b/Models/DiskInfoConfiguration.cs
new file mode 100644
index 0000000..d9bf5b1
--- /dev/null
+++ b/Models/DiskInfoConfiguration.cs
@@ -0,0 +1,24 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace File_Watcher.Models;
+
+public record DiskInfoConfiguration(int Bars,
+ string[] Classes,
+ string Destination,
+ decimal Max)
+{
+
+ public override string ToString()
+ {
+ string result = JsonSerializer.Serialize(this, DiskInfoConfigurationSourceGenerationContext.Default.DiskInfoConfiguration);
+ return result;
+ }
+
+}
+
+[JsonSourceGenerationOptions(WriteIndented = true)]
+[JsonSerializable(typeof(DiskInfoConfiguration))]
+internal partial class DiskInfoConfigurationSourceGenerationContext : JsonSerializerContext
+{
+}
\ No newline at end of file
diff --git a/Models/InfinityQSConfiguration.cs b/Models/InfinityQSConfiguration.cs
index 4e2ec5b..7b856ec 100644
--- a/Models/InfinityQSConfiguration.cs
+++ b/Models/InfinityQSConfiguration.cs
@@ -3,15 +3,6 @@ using System.Text.Json.Serialization;
namespace File_Watcher.Models;
-public record Test(string Name,
- long Value);
-
-[JsonSourceGenerationOptions(WriteIndented = true)]
-[JsonSerializable(typeof(Test[]))]
-internal partial class TestCollectionSourceGenerationContext : JsonSerializerContext
-{
-}
-
public record InfinityQSConfiguration(string ConnectionString,
string DestinationDirectory,
string EncryptedPassword,
diff --git a/Models/SeleniumConfiguration.cs b/Models/SeleniumConfiguration.cs
new file mode 100644
index 0000000..94f0b1f
--- /dev/null
+++ b/Models/SeleniumConfiguration.cs
@@ -0,0 +1,23 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace File_Watcher.Models;
+
+public record SeleniumConfiguration(string DestinationDirectory,
+ string[] EdgeOptions,
+ string UniformResourceLocator)
+{
+
+ public override string ToString()
+ {
+ string result = JsonSerializer.Serialize(this, SeleniumConfigurationSourceGenerationContext.Default.SeleniumConfiguration);
+ return result;
+ }
+
+}
+
+[JsonSourceGenerationOptions(WriteIndented = true)]
+[JsonSerializable(typeof(SeleniumConfiguration))]
+internal partial class SeleniumConfigurationSourceGenerationContext : JsonSerializerContext
+{
+}
\ No newline at end of file
diff --git a/Models/SyncConfiguration.cs b/Models/SyncConfiguration.cs
new file mode 100644
index 0000000..b078bc1
--- /dev/null
+++ b/Models/SyncConfiguration.cs
@@ -0,0 +1,21 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace File_Watcher.Models;
+
+public record SyncConfiguration(string UniformResourceLocator)
+{
+
+ public override string ToString()
+ {
+ string result = JsonSerializer.Serialize(this, SyncConfigurationSourceGenerationContext.Default.SyncConfiguration);
+ return result;
+ }
+
+}
+
+[JsonSourceGenerationOptions(WriteIndented = true)]
+[JsonSerializable(typeof(SyncConfiguration))]
+internal partial class SyncConfigurationSourceGenerationContext : JsonSerializerContext
+{
+}
\ No newline at end of file
diff --git a/Models/Test.cs b/Models/Test.cs
new file mode 100644
index 0000000..370c85c
--- /dev/null
+++ b/Models/Test.cs
@@ -0,0 +1,12 @@
+using System.Text.Json.Serialization;
+
+namespace File_Watcher.Models;
+
+public record Test(string Name,
+ long Value);
+
+[JsonSourceGenerationOptions(WriteIndented = true)]
+[JsonSerializable(typeof(Test[]))]
+internal partial class TestCollectionSourceGenerationContext : JsonSerializerContext
+{
+}
diff --git a/NancyModules/SyncModule.cs b/NancyModules/SyncModule.cs
new file mode 100644
index 0000000..6ecffa3
--- /dev/null
+++ b/NancyModules/SyncModule.cs
@@ -0,0 +1,51 @@
+using Nancy;
+using Nancy.Extensions;
+
+namespace File_Watcher.NancyModules;
+
+public class SyncModule : NancyModule
+{
+
+ public SyncModule()
+ {
+ Get("/bob/v1/sync/", _ =>
+ {
+ string? result;
+ try
+ {
+ string query = Request.Url.Query;
+ IDictionary> collection = Nancy.Helpers.HttpUtility.ParseQueryString(query).ToDictionary();
+ result = collection is null ? "null" : collection.ToString();
+ }
+ catch (Exception ex)
+ {
+ result = ex.Message;
+ }
+ return result;
+ });
+ Post("/bob/v1/sync/", _ =>
+ {
+ string result;
+ // Notification notification;
+ // ILog log = LogManager.GetLogger(typeof(SyncModule));
+ // log.Info($"Enter-{nameof(Post)}");
+ try
+ {
+ string body = Request.Body.AsString();
+ DynamicDictionary form = Request.Form;
+ Dictionary keyValuePairs = form.ToDictionary();
+ string reply = Helpers.SyncHelper.GetReply(body, keyValuePairs);
+ result = reply;
+ }
+ catch (Exception ex)
+ {
+ // log.Fatal($"Exception-{nameof(Post)}{Environment.NewLine}{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}");
+ result = ex.Message;
+ throw;
+ }
+ // log.Info($"Return-{nameof(Post)}");
+ return result;
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/Startup.cs b/Startup.cs
new file mode 100644
index 0000000..0d81aff
--- /dev/null
+++ b/Startup.cs
@@ -0,0 +1,19 @@
+using Microsoft.Owin.Cors;
+using Nancy.Owin;
+using Owin;
+
+namespace File_Watcher;
+
+public class Startup
+{
+
+ public Startup()
+ { }
+
+ public void Configuration(IAppBuilder app)
+ {
+ _ = app.UseCors(CorsOptions.AllowAll);
+ _ = app.UseNancy();
+ }
+
+}
\ No newline at end of file
diff --git a/Worker.cs b/Worker.cs
index d01bb42..0c2e1b2 100644
--- a/Worker.cs
+++ b/Worker.cs
@@ -7,7 +7,6 @@ namespace File_Watcher;
public partial class Worker : BackgroundService
{
- private int _First;
private readonly bool _IsWindowsService;
private readonly ILogger _Logger;
private readonly AppSettings _AppSettings;
@@ -23,6 +22,11 @@ public partial class Worker : BackgroundService
{ logger.LogInformation("<{folder}>", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)); }
catch (Exception) { }
_IsWindowsService = collection.Contains(nameof(WindowsServiceLifetime));
+ if (appSettings.FileWatcherConfiguration.Helper == nameof(Helpers.SyncHelper))
+ {
+ _ = Microsoft.Owin.Hosting.WebApp.Start(appSettings.SyncConfiguration.UniformResourceLocator);
+ logger.LogInformation("Server running on {url}", appSettings.SyncConfiguration.UniformResourceLocator);
+ }
}
public override Task StopAsync(CancellationToken cancellationToken)
@@ -64,32 +68,31 @@ public partial class Worker : BackgroundService
private void BodyInner(CancellationToken cancellationToken)
{
_Logger.LogInformation("A) Next execute will be at {date}", DateTime.Now.AddMilliseconds(_AppSettings.FileWatcherConfiguration.MillisecondsDelay).ToString("yyyy-MM-dd hh:mm:ss.fff tt"));
- if (_First < 9)
- {
- _First += 1;
- if (_AppSettings.FileWatcherConfiguration.Helper == nameof(Helpers.HelperCamstarOracle))
- Helpers.HelperCamstarOracle.Heartbeat(_AppSettings, _HttpClientFactory, _Logger, Infineon.Monitoring.MonA.State.Up, cancellationToken);
- }
if (!Directory.Exists(_AppSettings.FileWatcherConfiguration.WatchDirectory))
_ = Directory.CreateDirectory(_AppSettings.FileWatcherConfiguration.WatchDirectory);
else
{
_ = _AppSettings.FileWatcherConfiguration.Helper switch
{
+ nameof(Helpers.SyncHelper) => Helpers.SyncHelper.Check(_AppSettings, _Logger),
nameof(Helpers.HelperNuget) => Helpers.HelperNuget.Sync(_AppSettings, _Logger),
nameof(Helpers.HelperTCP) => Helpers.HelperTCP.ReadWrite(_AppSettings, _Logger),
nameof(Helpers.HelperISO) => Helpers.HelperISO.DirectoryToISO(_AppSettings, _Logger),
nameof(Helpers.HelperCompass) => Helpers.HelperCompass.CopyFile(_AppSettings, _Logger),
nameof(Helpers.HelperStratus) => Helpers.HelperStratus.MoveFile(_AppSettings, _Logger),
nameof(Helpers.HelperEAFLog) => Helpers.HelperEAFLog.DeleteFiles(_AppSettings, _Logger),
- nameof(Helpers.HelperInfinityQS) => Helpers.HelperInfinityQS.ProcessStart(_AppSettings, _Logger),
+ nameof(Helpers.DiskInfoHelper) => Helpers.DiskInfoHelper.WriteDiskInfo(_AppSettings, _Logger),
nameof(Helpers.HelperEventLog) => Helpers.HelperEventLog.ClearEventLogs(_AppSettings, _Logger),
+ nameof(Helpers.HelperInfinityQS) => Helpers.HelperInfinityQS.ProcessStart(_AppSettings, _Logger),
nameof(Helpers.HelperWaferCounter) => Helpers.HelperWaferCounter.MoveFile(_AppSettings, _Logger),
nameof(Helpers.HelperSerial) => Helpers.HelperSerial.ReadWrite(_AppSettings, _Logger, cancellationToken),
nameof(Helpers.HelperMetrologyFiles) => Helpers.HelperMetrologyFiles.SortAndDelete(_AppSettings, _Logger),
- nameof(Helpers.HelperCamstarOracle) => Helpers.HelperCamstarOracle.Check(_AppSettings, _Logger, cancellationToken),
nameof(Helpers.DeterministicHashCodeHelper) => Helpers.DeterministicHashCodeHelper.WindowsWork(_AppSettings, _Logger),
+#if Selenium
+ nameof(Helpers.SeleniumHelper) => Helpers.SeleniumHelper.HyperTextMarkupLanguageToPortableNetworkGraphics(_AppSettings, _Logger),
+#endif
nameof(Helpers.HelperEDADatabase) => Helpers.HelperEDADatabase.SaveDataCollectionPlans(_AppSettings, _Logger, cancellationToken),
+ nameof(Helpers.HelperCamstarOracle) => Helpers.HelperCamstarOracle.Check(_AppSettings, _HttpClientFactory, _Logger, cancellationToken),
_ => throw new NotSupportedException()
};
}