Compare commits

12 Commits

Author SHA1 Message Date
e6df9ae54e disk-info-helper
selenium-helper (Not fully tested)

sync-helper (Not fully tested)
2025-05-19 09:59:09 -07:00
e50a90f0fc decryptedPassword 2025-04-29 14:33:00 -07:00
31b5a4925b deterministic-hash-code-helper 2025-04-06 13:22:44 -07:00
4e6504af7e Switch multilevel app settings
Removed gpcl6win64 and LincPDFC just from proj file

Removed package.json to clean out publish directory
2025-03-05 16:50:02 -07:00
84d1b07301 HelperCamstarOracle 2024-10-22 09:48:28 -07:00
5cd2500983 Bump 2024-10-11 10:53:43 -07:00
9fff0541ae Moved HelperInfinityQS.DisableMaxDuplicates to EAF 2024-10-10 10:30:46 -07:00
61008fd9cf Ready to test HelperInfinityQS Select 2024-09-25 14:04:15 -07:00
4219a9f3a4 Removed HelperEAFProgramData-MoveFiles 2024-08-21 09:30:38 -07:00
db19697d73 Removed HelperEAFProgramData-MoveFiles 2024-08-21 09:30:05 -07:00
c831ad2ab9 Added ISO 2024-08-19 16:30:53 -07:00
38340090be More logging 2024-07-30 14:06:02 -07:00
44 changed files with 2105 additions and 552 deletions

4
.gitignore vendored
View File

@ -331,4 +331,6 @@ ASALocalRun/
*.all
*.pcl
*.pdf
*.raw
*.raw
.vscode/.UserSecrets/secrets.json

View File

@ -1,142 +0,0 @@
{
"CompassConfiguration": {
"Destination": "\\\\10.95.1.211\\Share\\RawData\\TRENDLOG",
"HoursBack": 4,
"MonthPattern": "MMM",
"Pattern": "*.csv",
"Source": "C:/Alerton/Compass/1.0/CLIMATEC/archive/trendlog",
"TriggerAppendage": ".trg",
"YearPattern": "yyyy"
},
"DriveConfiguration": {
"Letter": "s",
"Password": "zjtaxxwdEnJ/9tfXQFdj6TKiKBAmpCHWjdi6XYrflw4=",
"Share": "\\\\10.95.1.211\\Share",
"Use": true,
"User": "infineon\\ECMESEAF"
},
"EAFLogConfiguration": {
"SearchPattern": "*.log*"
},
"EAFProgramDataConfiguration": {
"Destination": "\\\\messa08ec.infineon.com\\d$\\ProgramData\\EC_Characterization_Si\\RawData",
"Source": "D:/ProgramData/EC_Characterization_Si/RawData"
},
"EDADatabaseConfiguration": {
"CSharpDateTimeFormat": "yyyy-MM-dd_hh:mm:ss tt",
"FileShare": "\\\\mesfs.infineon.com\\EC_EDA",
"Name": "Staging",
"OracleDateTimeFormat": "yyyy-MM-dd_hh:mi:ss AM",
"Password": "8vIs2nEZPkcdBUfXX0hHlA==",
"TNS": "(description=(address_list=(address=(protocol=tcp)(host=fimess-db.mes.infineon.com)(port=7001)))(connect_data=(sid=fimess)))",
"TNSX": "(description=(address_list=(address=(protocol=tcp)(host=fimesp-db.mes.infineon.com)(port=7002)))(connect_data=(sid=fimesp)))",
"UserName": "edastag"
},
"MetrologyConfiguration": {
"DeleteOlderThanWeeks": 16,
"DirectoriesBack": 2,
"HardcodedValues": [
"BIORAD2",
"BIORAD3",
"BIORAD4",
"BIORAD5",
"CDE2",
"CDE3",
"CDE4",
"CDE5",
"CDE6",
"HGCV1",
"HGCV2",
"HGCV3",
"TENCOR1",
"TENCOR2",
"TENCOR3",
"SP101",
"SPV01",
"SRP",
"WC6Inch",
"WC8Inch",
"Bio-Rad"
],
"SourceDirectories": [
"\\\\messa01ec.infineon.com\\apps\\Metrology\\Run Data Repository\\MET08ANLYSDIFAAST230\\Source\\MET08ANLYSDIFAAST230",
"\\\\messa01ec.infineon.com\\apps\\Metrology\\Run Data Repository\\MET08DDUPSFS6420\\Source\\MET08DDUPSFS6420",
"\\\\messa01ec.infineon.com\\apps\\Metrology\\Run Data Repository\\MET08DDUPSP1TBI\\Source\\MET08DDUPSP1TBI",
"\\\\messa01ec.infineon.com\\apps\\Metrology\\Run Data Repository\\MET08RESIHGCV\\Source\\MET08RESIHGCV",
"\\\\messa01ec.infineon.com\\apps\\Metrology\\Run Data Repository\\MET08RESIMAPCDE\\Source\\MET08RESIMAPCDE",
"\\\\messa01ec.infineon.com\\apps\\Metrology\\Run Data Repository\\MET08RESISRP2100\\Source\\MET08RESISRP2100",
"\\\\messa01ec.infineon.com\\apps\\Metrology\\Run Data Repository\\MET08THFTIRQS408M\\Source\\MET08THFTIRQS408M",
"\\\\messa01ec.infineon.com\\apps\\Metrology\\Run Data Repository\\MET08THFTIRSTRATUS\\Source\\MET08THFTIRSTRATUS"
]
},
"NugetConfiguration": {
"Destination": "L:/File-Watcher/Helper/Nuget/Packages",
"KeyFileExtension": ".nuspec",
"KeyFileExtensionB": "icon",
"KeyFileExtensionC": "readme",
"RenameToLower": true,
"SearchPattern": "*.nupkg",
"Source": "C:/Users/phares/.nuget/packages"
},
"SerialConfiguration": {
"Destination": "L:/DevOps/MESA_FI/File-Watcher/.vscode",
"GhostPCLFileName": "gpcl6win64.exe",
"LincPDFCFileName": "LincPDFC.exe",
"PortName": "COM37"
},
"StratusConfiguration": {
"Days": 4,
"Destination": "D:/Tmp",
"DestinationX": "\\\\10.95.1.211\\Share\\RawData\\BIORAD4",
"FileDelimiterPattern": "Mean [0-9.]*, STDD [0-9.]*",
"WatchFile": "DataBiorad.txt"
},
"TransmissionControlProtocolConfiguration": {
"Destination": "L:/DevOps/MESA_FI/File-Watcher/.vscode",
"GhostPCLFileName": "gpcl6win64.exe",
"IPAddress": "COM37",
"IPAddresses": {
"10.95.154.19": [
"EPP-WEST",
"6INCH",
"WC6INCH3"
],
"10.95.154.43": [
"FQA",
"6INCH",
"WC6INCH1"
],
"10.95.154.44": [
"MU",
"6INCH",
"WC6INCH2"
],
"10.95.154.46": [
"EPP-EAST",
"6INCH",
"WC6INCH4"
],
"10.95.154.47": [
"FQA",
"8INCH",
"WC8INCH1"
],
"10.95.154.48": [
"MU",
"8INCH",
"WC8INCH2"
],
"10.95.154.49": [
"EPP-WEST",
"8INCH",
"WC8INCH3"
]
},
"Port": 950,
"Server": false
},
"WaferCounterConfiguration": {
"Destination": "\\\\mestsa01ec.infineon.com\\apps\\WaferCounter\\V203",
"MatchPath": false
}
}

View File

@ -1,51 +0,0 @@
{
"_Application": "File-Watcher",
"_UserSecretsId": "6062c774-99a9-4f4a-b42d-a9cb7fcbd8be",
"BuildNumber": "1234",
"ConfigurationDirectoryNames": [
"Microsoft",
"UserSecrets",
"6062c774-99a9-4f4a-b42d-a9cb7fcbd8be"
],
"ConfigurationSpecialFolder": 26,
"ConfigurationFileName": "file-watcher.json",
"Company": "Infineon Technologies Americas Corp.",
"GitCommitSeven": "asdf",
"HelperX": "HelperTCP",
"HelperXX": "HelperNuget",
"HelperXXX": "HelperEAFLog",
"HelperXXXX": "HelperSerial",
"HelperXXXXX": "HelperCompass",
"Helper": "HelperStratus",
"HelperXXXXXXX": "HelperEventLog",
"HelperXXXXXXXX": "HelperInfinityQS",
"HelperXXXXXXXXX": "HelperWaferCounter",
"HelperXXXXXXXXXX": "HelperEAFProgramData",
"HelperXXXXXXXXXXX": "HelperMetrologyFiles",
"Logging:Console:FormatterName": "simple",
"Logging:Console:FormatterOptions:IncludeScopes": "True",
"Logging:Console:FormatterOptions:SingleLine": "True",
"Logging:Console:FormatterOptions:TimestampFormat": "HH:mm:ss ",
"Logging:Console:FormatterOptions:UseUtcTimestamp": "True",
"Logging:Console:LogLevel:Default": "Information",
"Logging:Console:LogLevel:Microsoft": "Warning",
"Logging:Console:LogLevel:Microsoft.Hosting.Lifetime": "Information",
"Logging:Debug:FormatterName": "simple",
"Logging:Debug:FormatterOptions:IncludeScopes": "True",
"Logging:Debug:FormatterOptions:SingleLine": "True",
"Logging:Debug:FormatterOptions:TimestampFormat": "HH:mm:ss ",
"Logging:Debug:FormatterOptions:UseUtcTimestamp": "True",
"Logging:Debug:LogLevel:Default": "Warning",
"Logging:Debug:LogLevel:Microsoft": "Information",
"Logging:Debug:LogLevel:Microsoft.Hosting.Lifetime": "Debug",
"Logging:EventLog:LogLevel:Default": "Warning",
"Logging:EventSource:LogLevel:Default": "Warning",
"Logging:LogLevel:Default": "Debug",
"Logging:LogLevel:Microsoft": "Information",
"Logging:LogLevel:Microsoft.Hosting.Lifetime": "Debug",
"MillisecondsDelay": 54000,
"URLs": "http://localhost:5003;",
"WatchDirectory": "D:/Tmp/Phares/Event-Log",
"WatchDirectoryXX": "D:/EAF/EAF Instances",
"WatchDirectoryXXX": "C:/software/WaferCounter/V203"
}

23
.vscode/.http vendored Normal file
View File

@ -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/

12
.vscode/settings.json vendored
View File

@ -12,21 +12,33 @@
"cSpell.words": [
"ASPNETCORE",
"BIRT",
"Camstar",
"CHIL",
"DEAT",
"DEVICEHEIGHTPOINTS",
"DEVICEWIDTHPOINTS",
"endianness",
"Exif",
"FAMC",
"FAMS",
"FIXEDMEDIA",
"GIVN",
"gpcl",
"Hmmssfff",
"HUSB",
"INDI",
"Infineon",
"Kanban",
"kanbn",
"Kofax",
"linc",
"Linc",
"NOPAUSE",
"NSFX",
"OBJE",
"onenote",
"PDFC",
"pdfwrite",
"PDSF",
"pged",
"Phares",

17
.vscode/tasks.json vendored
View File

@ -54,6 +54,16 @@
],
"problemMatcher": "$msCompile"
},
{
"label": "Format-Whitespaces",
"command": "dotnet",
"type": "process",
"args": [
"format",
"whitespace"
],
"problemMatcher": "$msCompile"
},
{
"label": "Publish AOT",
"command": "dotnet",
@ -72,13 +82,16 @@
"problemMatcher": "$msCompile"
},
{
"label": "File-Folder-Helper AOT s X Sort",
"label": "File-Folder-Helper AOT s X Day-Helper-2025-03-20",
"type": "shell",
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe",
"args": [
"s",
"X",
"L:/DevOps/Mesa_FI/File-Watcher' Day-Helper-2024-01-08 'L:/DevOps/Mesa_FI/File-Watcher/Helpers"
"L:/DevOps/Mesa_FI/File-Watcher",
"Day-Helper-2025-03-20",
"false",
"4"
],
"problemMatcher": []
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
@ -10,34 +10,28 @@
<UserSecretsId>6062c774-99a9-4f4a-b42d-a9cb7fcbd8be</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.5.0" />
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.7" />
<PackageReference Include="CliWrap" Version="3.8.2" />
<PackageReference Include="DiscUtils.Iso9660" Version="0.16.13" />
<PackageReference Include="Nancy.Owin" Version="2.0.0" />
<PackageReference Include="Microsoft.Owin" Version="4.2.2" />
<PackageReference Include="Microsoft.Owin.Cors" Version="4.2.2" />
<PackageReference Include="Microsoft.Owin.Hosting" Version="4.2.2" />
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="4.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.16" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="8.0.1" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.7.0" />
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.16" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="System.Drawing.Common" Version="8.0.16" />
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>
<ItemGroup>
<None Condition="'$(Configuration)' == 'Debug'" Include="\\mestsa003.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\GhostPCL\gpcl6win64\gpcl6dll64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Condition="'$(Configuration)' == 'Debug'" Include="\\mestsa003.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\GhostPCL\gpcl6win64\gpcl6win64.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Condition="'$(Configuration)' == 'Debug'" Include="\\mestsa003.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\LincPDFC\v2.6.6.21\LincPDFC.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Condition="'$(Configuration)' == 'Release'" Include="\\mesfs.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\GhostPCL\gpcl6win64\gpcl6dll64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Condition="'$(Configuration)' == 'Release'" Include="\\mesfs.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\GhostPCL\gpcl6win64\gpcl6win64.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Condition="'$(Configuration)' == 'Release'" Include="\\mesfs.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\LincPDFC\v2.6.6.21\LincPDFC.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<PackageReference Include="System.Text.Json" Version="9.0.5" />
<PackageReference Include="Phares.AA.Shared" Version="8.0.114.12235" />
<PackageReference Include="Phares.AA.Metadata" Version="8.0.114.12235" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,363 @@
using CliWrap;
using File_Watcher.Models;
using ShellProgressBar;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Text.Json;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Metadata.Models.Stateless;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless;
namespace File_Watcher.Helpers;
internal static partial class DeterministicHashCodeHelper
{
private class Windows : IWindows, IDisposable
{
private ProgressBar? _ProgressBar;
private readonly ProgressBarOptions _ProgressBarOptions;
public int CurrentTick { get; internal set; }
public Windows() =>
_ProgressBarOptions = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
DeterministicHashCode IWindows.GetDeterministicHashCode(HttpClient httpClient, Uri uri) =>
GetDeterministicHashCode(httpClient, uri);
DeterministicHashCode IWindows.GetDeterministicHashCode(HttpClient? httpClient, FilePath filePath)
{
DeterministicHashCode result;
if (httpClient is not null)
result = GetDeterministicHashCode(httpClient, new Uri(filePath.FullName));
else
{
Stream stream = File.OpenRead(filePath.FullName);
result = GetDeterministicHashCode(stream);
stream.Dispose();
}
return result;
}
private static DeterministicHashCode GetDeterministicHashCode(HttpClient httpClient, Uri uri)
{
DeterministicHashCode result;
Stream stream = GetStream(httpClient, uri);
result = GetDeterministicHashCode(stream);
stream.Dispose();
return result;
}
private static Stream GetStream(HttpClient httpClient, Uri uri)
{
Stream result;
Task<Stream> task = httpClient.GetStreamAsync(uri);
task.Wait();
result = task.Result;
return result;
}
private static DeterministicHashCode GetDeterministicHashCode(Stream stream)
{
DeterministicHashCode result;
int? id;
int? width;
int? height;
try
{
#pragma warning disable CA1416
using Image image = Image.FromStream(stream);
width = image.Width;
height = image.Height;
using Bitmap bitmap = new(image);
Rectangle rectangle = new(0, 0, image.Width, image.Height);
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
IntPtr intPtr = bitmapData.Scan0;
int length = bitmapData.Stride * bitmap.Height;
byte[] bytes = new byte[length];
Marshal.Copy(intPtr, bytes, 0, length);
bitmap.UnlockBits(bitmapData);
#pragma warning restore CA1416
id = IId.GetDeterministicHashCode(bytes);
}
catch (Exception)
{
id = null;
width = null;
height = null;
}
result = new(height, id, width);
return result;
}
void IWindows.Tick() =>
_ProgressBar?.Tick();
void IDisposable.Dispose()
{
_ProgressBar?.Dispose();
GC.SuppressFinalize(this);
}
void IWindows.ConstructProgressBar(int maxTicks, string message)
{
_ProgressBar?.Dispose();
_ProgressBar = new(maxTicks, message, _ProgressBarOptions);
}
ReadOnlyCollection<string> IWindows.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(ResultSettings resultSettings, HttpClient? httpClient, FilePath filePath)
{
List<string> results = [];
bool isValidVideoFormatExtensions = resultSettings.ValidVideoFormatExtensions.Contains(filePath.ExtensionLowered);
if (isValidVideoFormatExtensions)
{
bool check;
if (httpClient is not null)
DownloadFile(httpClient, filePath);
try
{
CommandTask<CommandResult> commandTask = Cli.Wrap("L:/Git/ffmpeg-2024-10-02-git-358fdf3083-full_build/bin/ffmpeg.exe")
.WithArguments(["-i", filePath.FullName, "-vf", "select=eq(n\\,0)", "-q:v", "1", $"{filePath.Name}-%4d.jpg"])
.WithWorkingDirectory(filePath.DirectoryFullPath)
.ExecuteAsync();
commandTask.Task.Wait();
check = true;
}
catch (Exception)
{
check = false;
}
if (check)
{
results.AddRange(Directory.GetFiles(filePath.DirectoryFullPath, $"{filePath.Name}-*.jpg", SearchOption.TopDirectoryOnly));
if (results.Count == 0)
throw new Exception();
File.SetCreationTime(results[0], new(filePath.CreationTicks));
File.SetLastWriteTime(results[0], new(filePath.LastWriteTicks));
Thread.Sleep(100);
}
}
return results.AsReadOnly();
}
private static void DownloadFile(HttpClient httpClient, FilePath filePath)
{
FileStream fileStream = new(filePath.FullName, FileMode.Truncate);
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(filePath.FullName);
httpResponseMessage.Wait();
Task task = httpResponseMessage.Result.Content.CopyToAsync(fileStream);
task.Wait();
}
}
internal static bool WindowsWork(AppSettings appSettings, ILogger<Worker>? logger)
{
string json;
string jsonFile;
string sourceDirectory;
List<string> check = [];
string archiveEntryFile;
long ticks = DateTime.Now.Ticks;
ReadOnlyCollection<FirstPass> collection;
string rootDirectory = Path.GetFullPath(appSettings.ResultSettings.RootDirectory);
if (!Directory.Exists(rootDirectory))
_ = Directory.CreateDirectory(rootDirectory);
string[] zipFiles = Directory.GetFiles(rootDirectory, "*.zip", SearchOption.TopDirectoryOnly);
if (zipFiles.Length > 0)
_ = IPath.DeleteEmptyDirectories(rootDirectory);
foreach (string zipFile in zipFiles)
{
check.Clear();
sourceDirectory = zipFile[..^4];
jsonFile = $"{sourceDirectory}.json";
if (Directory.Exists(sourceDirectory) || File.Exists(jsonFile))
continue;
_ = Directory.CreateDirectory(sourceDirectory);
using ZipArchive zip = ZipFile.Open(zipFile, ZipArchiveMode.Read);
foreach (ZipArchiveEntry zipArchiveEntry in zip.Entries)
{
check.Add(zipArchiveEntry.Name);
archiveEntryFile = Path.Combine(sourceDirectory, zipArchiveEntry.Name);
zipArchiveEntry.ExtractToFile(archiveEntryFile);
}
collection = WindowsWork(logger, appSettings, ticks, sourceDirectory);
if (check.Count == collection.Count)
{
json = JsonSerializer.Serialize(collection.ToList(), FirstPassCollectionSourceGenerationContext.Default.ListFirstPass);
File.WriteAllText(jsonFile, json);
}
Directory.Delete(sourceDirectory, recursive: true);
}
return true;
}
private static ReadOnlyCollection<FirstPass> WindowsWork(ILogger<Worker>? logger, AppSettings appSettings, long ticks, string sourceDirectory)
{
ReadOnlyCollection<FirstPass> results;
Windows windows = new();
IWindows windowsInterface = windows;
logger?.LogInformation("{Ticks} {RootDirectory}", ticks, sourceDirectory);
A_Metadata metadata = new(appSettings.ResultSettings, appSettings.MetadataSettings);
int appSettingsMaxDegreeOfParallelism = appSettings.DeterministicHashCodeConfiguration.MaxDegreeOfParallelism;
ReadOnlyCollection<string> files = Directory.GetFiles(sourceDirectory, "*", SearchOption.AllDirectories).AsReadOnly();
if (files.Count > 0)
_ = IPath.DeleteEmptyDirectories(sourceDirectory);
int filesCount = appSettingsMaxDegreeOfParallelism == 1 ? files.Count : 123000;
windowsInterface.ConstructProgressBar(filesCount, "EnumerateFiles load");
if (appSettingsMaxDegreeOfParallelism == 1)
results = WindowsSynchronousWork(logger, appSettings, windowsInterface, files, metadata);
else
results = WindowsAsynchronousWork(appSettings, windows, files, metadata, appSettingsMaxDegreeOfParallelism);
return results;
}
private static ReadOnlyCollection<FirstPass> WindowsSynchronousWork(ILogger<Worker>? logger, AppSettings appSettings, IWindows windows, IEnumerable<string> files, A_Metadata metadata)
{
List<FirstPass> results = [];
int index = -1;
ReadOnlyDictionary<string, List<FileHolder>> keyValuePairs = IMetadata.GetKeyValuePairs(files);
foreach (KeyValuePair<string, List<FileHolder>> keyValuePair in keyValuePairs)
{
if (keyValuePair.Value.Count > 2)
throw new NotSupportedException("Too many sidecar files!");
index = WindowsSynchronousWork(logger, appSettings, windows, metadata, results, index, keyValuePair);
}
return results.AsReadOnly();
}
private static int WindowsSynchronousWork(ILogger<Worker>? logger, AppSettings appSettings, IWindows windows, A_Metadata metadata, List<FirstPass> results, int index, KeyValuePair<string, List<FileHolder>> keyValuePair)
{
int result = index + 1;
windows.Tick();
FilePath filePath;
FirstPass firstPass;
string directoryName;
ExifDirectory exifDirectory;
HttpClient? httpClient = null;
List<FileHolder> sidecarFiles;
DeterministicHashCode deterministicHashCode;
bool fastForwardMovingPictureExpertsGroupUsed;
MinimumYearAndPathCombined minimumYearAndPathCombined;
FilePath? fastForwardMovingPictureExpertsGroupFilePath;
ReadOnlyCollection<string>? fastForwardMovingPictureExpertsGroupFiles;
foreach (FileHolder fileHolder in keyValuePair.Value)
{
if (appSettings.DeterministicHashCodeConfiguration.SidecarExtensions.Contains(fileHolder.ExtensionLowered))
continue;
if (appSettings.ResultSettings.IgnoreExtensions.Contains(fileHolder.ExtensionLowered))
continue;
filePath = FilePath.Get(appSettings.ResultSettings, appSettings.MetadataSettings, fileHolder, result);
if (filePath.Id is not null && (filePath.IsIntelligentIdFormat || filePath.SortOrder is not null))
continue;
if (filePath.Id is not null)
{
fastForwardMovingPictureExpertsGroupFiles = null;
deterministicHashCode = new(null, filePath.Id, null);
directoryName = Path.GetFileName(filePath.DirectoryFullPath);
if (directoryName.EndsWith(filePath.Id.Value.ToString()))
continue;
}
else
{
fastForwardMovingPictureExpertsGroupFiles = windows.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(appSettings.ResultSettings, httpClient, filePath);
fastForwardMovingPictureExpertsGroupFilePath = fastForwardMovingPictureExpertsGroupFiles.Count == 0 ? null : FilePath.Get(appSettings.ResultSettings, appSettings.MetadataSettings, FileHolder.Get(fastForwardMovingPictureExpertsGroupFiles[0]), result);
deterministicHashCode = fastForwardMovingPictureExpertsGroupFilePath is null ? windows.GetDeterministicHashCode(httpClient, filePath) : windows.GetDeterministicHashCode(httpClient, fastForwardMovingPictureExpertsGroupFilePath);
}
sidecarFiles = [];
filePath = FilePath.Get(filePath, deterministicHashCode);
for (int i = 0; i < keyValuePair.Value.Count; i++)
{
if (keyValuePair.Value[i].ExtensionLowered == fileHolder.ExtensionLowered)
continue;
sidecarFiles.Add(keyValuePair.Value[i]);
}
try
{ (minimumYearAndPathCombined, exifDirectory) = metadata.GetMetadataCollection(appSettings.ResultSettings, appSettings.MetadataSettings, httpClient, filePath); }
catch (Exception)
{
logger?.LogWarning("<{filePath}>", filePath.FullName);
continue;
}
fastForwardMovingPictureExpertsGroupUsed = fastForwardMovingPictureExpertsGroupFiles is not null && fastForwardMovingPictureExpertsGroupFiles.Count > 0;
if (fastForwardMovingPictureExpertsGroupUsed && fastForwardMovingPictureExpertsGroupFiles is not null)
{
foreach (string fastForwardMovingPictureExpertsGroupFile in fastForwardMovingPictureExpertsGroupFiles)
File.Delete(fastForwardMovingPictureExpertsGroupFile);
}
if (!fastForwardMovingPictureExpertsGroupUsed && appSettings.ResultSettings.ValidVideoFormatExtensions.Contains(filePath.ExtensionLowered))
fastForwardMovingPictureExpertsGroupUsed = true;
firstPass = new(exifDirectory, fastForwardMovingPictureExpertsGroupUsed, minimumYearAndPathCombined, sidecarFiles.ToArray());
results.Add(firstPass);
}
return result;
}
private static ReadOnlyCollection<FirstPass> WindowsAsynchronousWork(AppSettings appSettings, Windows windows, ReadOnlyCollection<string> files, A_Metadata metadata, int appSettingsMaxDegreeOfParallelism)
{
List<FirstPass> results = [];
FirstPass firstPass;
List<string> distinct = [];
List<MetadataGroup> metadataGroups = [];
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = appSettingsMaxDegreeOfParallelism };
files.AsParallel().ForAll(IMetadata.SetExifDirectoryCollection(windows, appSettings.ResultSettings, appSettings.MetadataSettings, metadata, distinct, metadataGroups));
if (windows?.CurrentTick != results.Count)
throw new NotSupportedException();
foreach (MetadataGroup metadataGroup in metadataGroups)
{
if (metadataGroup.FastForwardMovingPictureExpertsGroupUsed || !appSettings.ResultSettings.ValidVideoFormatExtensions.Contains(metadataGroup.FilePath.ExtensionLowered))
firstPass = new(metadataGroup.ExifDirectory, metadataGroup.FastForwardMovingPictureExpertsGroupUsed, metadataGroup.MinimumYearAndPathCombined, metadataGroup.SidecarFiles.ToArray());
else
firstPass = new(metadataGroup.ExifDirectory, FastForwardMovingPictureExpertsGroupUsed: true, metadataGroup.MinimumYearAndPathCombined, metadataGroup.SidecarFiles.ToArray());
results.Add(firstPass);
}
return results.AsReadOnly();
}
private static ReadOnlyCollection<NginxFileSystem>? GetRecursiveCollection(HttpClient httpClient, string host, string page)
{
List<NginxFileSystem>? results;
Uri uri = new($"http://{host}/{page}");
string format = NginxFileSystem.GetFormat();
TimeZoneInfo timeZoneInfo = TimeZoneInfo.Local;
Task<HttpResponseMessage> taskHttpResponseMessage = httpClient.GetAsync(uri);
taskHttpResponseMessage.Wait();
if (!taskHttpResponseMessage.Result.IsSuccessStatusCode)
results = null;
else
{
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
taskString.Wait();
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
if (nginxFileSystems is null)
results = null;
else
{
results = [];
NginxFileSystem nginxFileSystem;
ReadOnlyCollection<NginxFileSystem>? directory;
for (int i = 0; i < nginxFileSystems.Length; i++)
{
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
if (nginxFileSystem.Type == "file")
results.Add(nginxFileSystem);
else
{
directory = GetRecursiveCollection(httpClient, host, $"{page}/{nginxFileSystem.Name}");
if (directory is null)
continue;
results.AddRange(directory);
}
}
}
}
return results?.AsReadOnly();
}
}

503
Helpers/DiskInfoHelper.cs Normal file
View File

@ -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<string, object>))]
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<DiskPartition> 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<Worker> logger)
{
string? json = WriteRecord();
ReadOnlyCollection<DiskDrive> devices = GetDrives(appSettings, logger);
string yaml = GetYetAnotherMarkupLanguage(devices);
ReadOnlyCollection<string> 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<Record> 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<DiskDrive> GetDrives(AppSettings appSettings, ILogger<Worker> logger)
{
#pragma warning disable CA1416
List<DiskDrive> 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<Worker> 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<string, object> DeserializeAndFlatten(string json, char? remove)
{
Dictionary<string, object> results = [];
JsonElement jsonElement = JsonSerializer.Deserialize(json, JsonElementSourceGenerationContext.Default.JsonElement);
FillDictionaryFromJToken(results, jsonElement, string.Empty, remove);
return results;
}
private static void FillDictionaryFromJToken(Dictionary<string, object> 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<DiskDrive> devices)
{
string result;
List<string> results = [];
string json = JsonSerializer.Serialize(devices.ToArray(), DiskDriveArraySourceGenerationContext.Default.DiskDriveArray);
Dictionary<string, object> 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<string> GetNormalized(AppSettings appSettings, ILogger<Worker> logger, ReadOnlyCollection<DiskDrive> drives)
{
List<string> 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();
}
}

View File

@ -0,0 +1,117 @@
using File_Watcher.Infineon.Monitoring.MonA;
using File_Watcher.Models;
using System.Diagnostics;
using System.Globalization;
namespace File_Watcher.Helpers;
internal static partial class HelperCamstarOracle
{
private static IMonIn? _MonIn;
private static int? _LastValue;
private static Calendar? _Calendar;
private static DateTime? _LastUpload;
internal static void Heartbeat(AppSettings appSettings, IHttpClientFactory httpClientFactory, ILogger<Worker> logger, State state, CancellationToken cancellationToken)
{
_MonIn ??= MonIn.GetInstance(httpClientFactory);
CamstarOracleConfiguration camstarOracleConfiguration = appSettings.CamstarOracleConfiguration;
Task<HttpResponseMessage> httpResponseMessage = _MonIn.SendStatus(camstarOracleConfiguration.MonitorApplicationSite, camstarOracleConfiguration.MonitorApplicationResource, "Heartbeat", state);
httpResponseMessage.Wait(cancellationToken);
if (httpResponseMessage.Result.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(httpResponseMessage.Result.StatusCode.ToString());
Task<string> body = httpResponseMessage.Result.Content.ReadAsStringAsync(cancellationToken);
body.Wait(cancellationToken);
logger.LogDebug(body.Result);
}
#pragma warning disable CA1416
private static List<EventLogEntry> GetOracleEventLogEntries(CamstarOracleConfiguration camstarOracleConfiguration, DateTime dateTime, CancellationToken cancellationToken)
{
List<EventLogEntry> results = [];
EventLog[] eventLogs = EventLog.GetEventLogs();
long ticks = dateTime.AddMinutes(-camstarOracleConfiguration.RollingMinutes).Ticks;
foreach (EventLog eventLog in eventLogs)
{
if (cancellationToken.IsCancellationRequested)
break;
if (!eventLog.Log.Contains(camstarOracleConfiguration.LogFilter))
continue;
foreach (object? item in eventLog.Entries)
{
if (cancellationToken.IsCancellationRequested)
break;
if (item is not EventLogEntry eventLogEntry)
continue;
if (eventLogEntry.TimeGenerated.Ticks < ticks)
continue;
if (!camstarOracleConfiguration.MessageFilters.Any(eventLogEntry.Message.Contains))
continue;
results.Add(eventLogEntry);
}
}
return results;
}
private static List<(DateTime, string)> GetOracleEventLogEntryMessages(CamstarOracleConfiguration camstarOracleConfiguration, DateTime dateTime, CancellationToken cancellationToken)
{
List<(DateTime, string)> results = [];
List<EventLogEntry> collection = GetOracleEventLogEntries(camstarOracleConfiguration, dateTime, cancellationToken);
foreach (EventLogEntry eventLogEntry in collection)
{
if (cancellationToken.IsCancellationRequested)
break;
results.Add(new(eventLogEntry.TimeGenerated, eventLogEntry.Message));
}
return results;
}
internal static bool Check(AppSettings appSettings, IHttpClientFactory httpClientFactory, ILogger<Worker> logger, CancellationToken cancellationToken)
{
if (_MonIn is null)
throw new NullReferenceException(nameof(_MonIn));
string directory;
DateTime dateTime;
string weekOfYear;
string weekDirectory;
string formattedDateTime;
List<string> lines = [];
_Calendar ??= new CultureInfo("en-US").Calendar;
CamstarOracleConfiguration camstarOracleConfiguration = appSettings.CamstarOracleConfiguration;
string performanceName = string.Concat(camstarOracleConfiguration.MonitorApplicationResource, "_Count");
lines.Clear();
dateTime = DateTime.Now;
weekOfYear = _Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
weekDirectory = $"{dateTime:yyyy}_Week_{weekOfYear}{@"\"}{dateTime:yyyy-MM-dd}";
directory = Path.Combine(camstarOracleConfiguration.Directory, weekDirectory);
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
List<(DateTime, string)> collection = GetOracleEventLogEntryMessages(camstarOracleConfiguration, dateTime, cancellationToken);
foreach ((DateTime timeGenerated, string message) in collection)
{
if (cancellationToken.IsCancellationRequested)
break;
formattedDateTime = timeGenerated.ToString(camstarOracleConfiguration.DateFormat);
lines.Add($"{formattedDateTime}\t{message}");
}
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> 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)
throw new Exception(httpResponseMessage.Result.StatusCode.ToString());
Task<string> body = httpResponseMessage.Result.Content.ReadAsStringAsync(cancellationToken);
body.Wait(cancellationToken);
logger.LogDebug(body.Result);
_LastUpload = DateTime.Now;
_LastValue = lines.Count;
}
return true;
}
}

View File

@ -29,7 +29,7 @@ internal class HelperCompass
if (string.IsNullOrEmpty(appSettings.DriveConfiguration.Password))
decrypted = string.Empty;
else
decrypted = RijndaelEncryption.Decrypt(appSettings.DriveConfiguration.Password, appSettings.Company);
decrypted = RijndaelEncryption.Decrypt(appSettings.DriveConfiguration.Password, appSettings.FileWatcherConfiguration.Company);
arguments = $"use {appSettings.DriveConfiguration.Letter}: \"{appSettings.DriveConfiguration.Share}\" /p:yes /user:{appSettings.DriveConfiguration.User} {decrypted}";
_ = stringBuilder.Clear();
segments = arguments.Split(' ');

View File

@ -7,8 +7,8 @@ internal static partial class HelperEAFLog
internal static bool DeleteFiles(AppSettings appSettings, ILogger<Worker> logger)
{
string[] files = Directory.GetFiles(appSettings.WatchDirectory, appSettings.EAFLogConfiguration.SearchPattern, SearchOption.AllDirectories);
logger.LogInformation("After {MillisecondsDelay} with search pattern '{SearchPattern}' found {files}", appSettings.MillisecondsDelay, appSettings.EAFLogConfiguration.SearchPattern, files.Length);
string[] files = Directory.GetFiles(appSettings.FileWatcherConfiguration.WatchDirectory, appSettings.EAFLogConfiguration.SearchPattern, SearchOption.AllDirectories);
logger.LogInformation("After {MillisecondsDelay} with search pattern '{SearchPattern}' found {files}", appSettings.FileWatcherConfiguration.MillisecondsDelay, appSettings.EAFLogConfiguration.SearchPattern, files.Length);
foreach (string file in files)
{
if (file.EndsWith(".dll"))

View File

@ -1,37 +0,0 @@
using File_Watcher.Models;
namespace File_Watcher.Helpers;
internal static partial class HelperEAFProgramData
{
internal static bool MoveFiles(AppSettings appSettings, ILogger<Worker> logger)
{
string checkFile;
string checkDirectory;
string source = Path.GetFullPath(appSettings.EAFProgramDataConfiguration.Source);
string[] files = Directory.GetFiles(source, "*", SearchOption.AllDirectories);
logger.LogInformation("After {MillisecondsDelay} with search pattern '{SearchPattern}' found {files}", appSettings.MillisecondsDelay, appSettings.EAFLogConfiguration.SearchPattern, files.Length);
foreach (string file in files)
{
Thread.Sleep(500);
checkFile = file.Replace(source, appSettings.EAFProgramDataConfiguration.Destination);
if (checkFile == file)
throw new NotSupportedException("Replace failed!");
checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new NotSupportedException();
try
{
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
Thread.Sleep(500);
}
catch (Exception ex)
{ logger.LogInformation(ex, "Inner loop error!"); }
}
return true;
}
}

View File

@ -1,9 +1,7 @@
using File_Watcher.Helpers.EDA;
using File_Watcher.Models;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Serialization;
@ -12,12 +10,8 @@ namespace File_Watcher.Helpers;
internal static partial class HelperEDADatabase
{
private static Calendar? _Calendar;
private static string? _EDADataCollectionPlansLastRun;
[GeneratedRegex("[a-zA-Z0-9]{1,}")]
private static partial Regex RegexAZ09();
private static Stream ToStream(string @this)
{
MemoryStream? stream = new();
@ -207,7 +201,7 @@ internal static partial class HelperEDADatabase
}
}
private static void DataCollectionPlans(AppSettings appSettings, ILogger<Worker> logger, Calendar calendar, CancellationToken cancellationToken)
private static void DataCollectionPlans(AppSettings appSettings, ILogger<Worker> logger, CancellationToken cancellationToken)
{
int fieldCount;
object @object;
@ -219,7 +213,7 @@ internal static partial class HelperEDADatabase
Array objectTypes = Enum.GetValues(typeof(ModuleInstanceTypeName));
#pragma warning restore IL3050
Dictionary<string, Dictionary<ModuleInstanceTypeName, List<List<object>>>> rows = [];
string decrypted = RijndaelEncryption.Decrypt(appSettings.EDADatabaseConfiguration.Password, appSettings.Company);
string decrypted = RijndaelEncryption.Decrypt(appSettings.EDADatabaseConfiguration.Password, appSettings.FileWatcherConfiguration.Company);
string connectionString = $"Data Source={appSettings.EDADatabaseConfiguration.TNS}; User Id={appSettings.EDADatabaseConfiguration.UserName}; Password={decrypted};";
rows.Add(appSettings.EDADatabaseConfiguration.Name, []);
foreach (ModuleInstanceTypeName objectType in objectTypes)
@ -278,8 +272,7 @@ internal static partial class HelperEDADatabase
internal static bool SaveDataCollectionPlans(AppSettings appSettings, ILogger<Worker> logger, CancellationToken cancellationToken)
{
_Calendar ??= new CultureInfo("en-US").Calendar;
DataCollectionPlans(appSettings, logger, _Calendar, cancellationToken);
DataCollectionPlans(appSettings, logger, cancellationToken);
return true;
}

View File

@ -8,7 +8,7 @@ internal static partial class HelperEventLog
internal static bool ClearEventLogs(AppSettings appSettings, ILogger<Worker> logger)
{
if (Directory.Exists(appSettings.WatchDirectory))
if (Directory.Exists(appSettings.FileWatcherConfiguration.WatchDirectory))
{
#pragma warning disable CA1416
using (EventLog eventLog = new("Security", Environment.MachineName))
@ -26,7 +26,7 @@ internal static partial class HelperEventLog
{ logger.LogInformation("Error: {logName} - {message}.", eventLog.LogDisplayName, ex.Message); }
}
#pragma warning restore CA1416
logger.LogCritical("{Company}", appSettings.Company);
logger.LogCritical("{Company}", appSettings.FileWatcherConfiguration.Company);
}
return true;
}

40
Helpers/HelperISO.cs Normal file
View File

@ -0,0 +1,40 @@
using DiscUtils.Iso9660;
using File_Watcher.Models;
namespace File_Watcher.Helpers;
internal static partial class HelperISO
{
private static void DirectoryToISO(ILogger<Worker> logger, string destinationDirectory, bool mapOnly, string directory)
{
byte[] bytes = [];
string relativePath;
string directoryName = Path.GetFileName(directory);
CDBuilder builder = new() { UseJoliet = true, VolumeIdentifier = directoryName.Length < 25 ? directoryName : directoryName[..25] };
IEnumerable<string> files = Directory.EnumerateFiles(directory, "*", new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true });
foreach (string file in files)
{
relativePath = Path.GetRelativePath(directory, file).Replace(';', '_');
if (!mapOnly)
_ = builder.AddFile(relativePath, file);
else
_ = builder.AddFile(relativePath, bytes);
}
logger.LogInformation(destinationDirectory);
builder.Build(Path.Combine(destinationDirectory, $"{directoryName}.iso"));
logger.LogInformation(directoryName);
}
internal static bool DirectoryToISO(AppSettings appSettings, ILogger<Worker> logger)
{
IsoConfiguration isoConfiguration = appSettings.IsoConfiguration;
logger.LogInformation(isoConfiguration.SourceDirectory);
bool mapOnly = isoConfiguration.SourceDirectory.Length == 2;
if (!Directory.Exists(isoConfiguration.DestinationDirectory))
_ = Directory.CreateDirectory(isoConfiguration.DestinationDirectory);
DirectoryToISO(logger, isoConfiguration.DestinationDirectory, mapOnly, isoConfiguration.SourceDirectory);
return true;
}
}

View File

@ -6,22 +6,41 @@ namespace File_Watcher.Helpers;
internal static partial class HelperInfinityQS
{
internal static bool RunMI(AppSettings appSettings, ILogger<Worker> logger)
private static void KillExisting(string processName)
{
Process[] processes = Process.GetProcessesByName(processName);
foreach (Process process in processes)
{
try
{ process.Kill(); }
catch (Exception) { }
}
}
private static void RunMI(string decryptedPassword)
{
#pragma warning disable CA1416
logger.LogInformation(appSettings.Company);
ProcessStartInfo processStartInfo = new("iispcmi.exe")
string processName = "iispcmi.exe";
KillExisting(processName);
ProcessStartInfo processStartInfo = new(processName)
{
Domain = "Infineon",
UseShellExecute = false,
UserName = "ecfisysadmin",
PasswordInClearText = "j(1(P%xB=g}3w9db",
PasswordInClearText = decryptedPassword,
WorkingDirectory = "C:/Program Files (x86)/InfinityQS International/ProFicient/Applications"
};
TimeSpan timeSpan = new(DateTime.Now.AddDays(7).Ticks - DateTime.Now.Ticks);
Process process = Process.Start(processStartInfo) ?? throw new NullReferenceException(nameof(Process));
process.WaitForExit();
_ = process.WaitForExit((int)timeSpan.TotalMilliseconds);
#pragma warning restore CA1416
return true;
}
internal static bool ProcessStart(AppSettings appSettings, ILogger<Worker> logger)
{
logger.LogInformation(appSettings.FileWatcherConfiguration.Company);
string decrypted = RijndaelEncryption.Decrypt(appSettings.InfinityQSConfiguration.EncryptedPassword, appSettings.FileWatcherConfiguration.Company);
RunMI(decrypted);
return true;
}
}

View File

@ -29,7 +29,7 @@ internal static partial class HelperStratus
continue;
if (!Regex.Match(line, appSettings.StratusConfiguration.FileDelimiterPattern).Success)
continue;
weekYearDirectory = Path.Combine(appSettings.WatchDirectory, $"{fileInfo.CreationTime.Year}_Week_{weekOfYear}");
weekYearDirectory = Path.Combine(appSettings.FileWatcherConfiguration.WatchDirectory, $"{fileInfo.CreationTime.Year}_Week_{weekOfYear}");
checkDirectory = Path.Combine(weekYearDirectory, fileInfo.CreationTime.ToString("yyyy-MM-dd"));
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
@ -81,19 +81,19 @@ internal static partial class HelperStratus
internal static bool MoveFile(AppSettings appSettings, ILogger<Worker> logger)
{
// http://10.95.154.10:8081/2023_Week_45/2023-11-08/a.txt
string checkFile = Path.Combine(appSettings.WatchDirectory, appSettings.StratusConfiguration.WatchFile);
string checkFile = Path.Combine(appSettings.FileWatcherConfiguration.WatchDirectory, appSettings.StratusConfiguration.WatchFile);
try
{ TryMoveFile(appSettings, checkFile); }
catch (Exception ex)
{
logger.LogError(ex, "Inner loop error!");
Thread.Sleep(appSettings.MillisecondsDelay * 5);
Thread.Sleep(appSettings.FileWatcherConfiguration.MillisecondsDelay * 5);
}
Console.WriteLine("Hello");
int days = appSettings.StratusConfiguration.Days;
string sourceDirectory = appSettings.WatchDirectory;
int millisecondsDelay = appSettings.MillisecondsDelay;
string pattern = appSettings.StratusConfiguration.FileDelimiterPattern;
string sourceDirectory = appSettings.FileWatcherConfiguration.WatchDirectory;
int millisecondsDelay = appSettings.FileWatcherConfiguration.MillisecondsDelay;
string archiveDirectory = Path.GetFullPath(appSettings.StratusConfiguration.Destination);
try
{ TryArchiveFilesFramework(sourceDirectory, pattern, archiveDirectory, days); }

View File

@ -99,7 +99,7 @@ internal static partial class HelperTCP
{
List<byte> results = [];
byte[] bytes = new byte[1024];
string directory = Path.Combine(transmissionControlProtocolConfiguration.Destination, transmissionControlProtocolConfiguration.IPAddress);
string directory = Path.GetFullPath(Path.Combine(transmissionControlProtocolConfiguration.Destination, transmissionControlProtocolConfiguration.IPAddress));
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
do
@ -110,7 +110,7 @@ internal static partial class HelperTCP
}
while (networkStream.DataAvailable);
if (results.Count > 0)
File.WriteAllBytes(string.Concat(directory, $"-{DateTime.Now.Ticks}{directory[^1]}.raw"), results.ToArray());
File.WriteAllBytes(Path.Combine(directory, $"{DateTime.Now.Ticks}{directory[^1]}.raw"), results.ToArray());
}
internal static bool ReadWrite(AppSettings appSettings, ILogger<Worker> logger)

View File

@ -11,7 +11,7 @@ internal static partial class HelperWaferCounter
string checkFile;
FileInfo fileInfo;
string checkDirectory;
string[] directories = Directory.GetDirectories(appSettings.WatchDirectory, "*", SearchOption.TopDirectoryOnly);
string[] directories = Directory.GetDirectories(appSettings.FileWatcherConfiguration.WatchDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
checkDirectory = !appSettings.WaferCounterConfiguration.MatchPath ? appSettings.WaferCounterConfiguration.Destination : Path.Combine(appSettings.WaferCounterConfiguration.Destination, Path.GetFileName(directory));
@ -23,7 +23,7 @@ internal static partial class HelperWaferCounter
foreach (string file in files)
{
fileInfo = new(file);
if (new TimeSpan(DateTime.Now.Ticks - fileInfo.LastWriteTime.Ticks).TotalMilliseconds < appSettings.MillisecondsDelay)
if (new TimeSpan(DateTime.Now.Ticks - fileInfo.LastWriteTime.Ticks).TotalMilliseconds < appSettings.FileWatcherConfiguration.MillisecondsDelay)
continue;
checkFile = Path.Combine(checkDirectory, Path.GetFileName(file));
if (File.Exists(checkFile))

45
Helpers/SeleniumHelper.cs Normal file
View File

@ -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
{
// <PackageReference Include="Selenium.WebDriver" Version="4.31.0" />
// <PackageReference Include="Selenium.WebDriver.MSEdgeDriver" Version="135.0.3179.85" />
internal static bool HyperTextMarkupLanguageToPortableNetworkGraphics(AppSettings appSettings, ILogger<Worker> 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;
}
}

51
Helpers/SyncHelper.cs Normal file
View File

@ -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<string, object>))]
private partial class DictionaryStringObjectBSourceGenerationContext : JsonSerializerContext
{
}
internal static bool Check(AppSettings _, ILogger<Worker> __) =>
true;
internal static string GetReply(string body, Dictionary<string, object> 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}";
}
}

View File

@ -0,0 +1,145 @@
namespace File_Watcher.Infineon.Monitoring.MonA;
public interface IMonIn
{
Task<HttpResponseMessage> SendStatus(string site, string resource, string stateName, State state);
Task<HttpResponseMessage> SendStatus(string site,
DateTime timeStamp,
string resource,
string stateName,
State state);
Task<HttpResponseMessage> SendStatus(string site,
string resource,
string stateName,
State state,
string description);
Task<HttpResponseMessage> SendStatus(string site,
DateTime timeStamp,
string resource,
string stateName,
State state,
string description);
Task<HttpResponseMessage> SendStatus(string site,
string resource,
string subResource,
string stateName,
State state);
Task<HttpResponseMessage> SendStatus(string site,
DateTime timeStamp,
string resource,
string subResource,
string stateName,
State state);
Task<HttpResponseMessage> SendStatus(string site,
string resource,
string subResource,
string stateName,
State state,
string description);
Task<HttpResponseMessage> SendStatus(string site,
DateTime? timeStamp,
string resource,
string subResource,
string stateName,
State state,
string description);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
string resource,
string performanceName,
double value);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string performanceName,
double value);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
string resource,
string performanceName,
double value,
string description);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string performanceName,
double value,
string description);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string performanceName,
double value,
int? interval);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
string resource,
DateTime? timeStamp,
string performanceName,
double value,
string unit);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string performanceName,
double value,
string unit,
int? interval);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
string resource,
string subResource,
string performanceName,
double value);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string subResource,
string performanceName,
double value);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
string resource,
string subResource,
string performanceName,
double value,
string description);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string subResource,
string performanceName,
double value,
int? interval);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string subResource,
string performanceName,
double value,
string unit);
Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string subResource,
string performanceName,
double value,
string description,
string unit,
int? interval);
}

View File

@ -0,0 +1,266 @@
using System.Globalization;
using System.Text;
namespace File_Watcher.Infineon.Monitoring.MonA;
public class MonIn : IMonIn
{
private readonly string _MonInUrl;
private readonly HttpClient _HttpClient;
private static CultureInfo? _CultureInfo;
private static readonly Dictionary<string, MonIn> _Instances = [];
public const string MonInUrl = "http://moninhttp.{0}.infineon.com/input/text";
private static readonly DateTime _Utc1970DateTime = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static MonIn GetInstance(IHttpClientFactory httpClientFactory, string url = MonInUrl)
{
MonIn instance;
if (_Instances.ContainsKey(url))
{
instance = _Instances[url];
}
else
{
lock (_Instances)
{
if (!_Instances.ContainsKey(url))
{
instance = new MonIn(httpClientFactory, url);
_Instances.Add(url, instance);
}
else
instance = _Instances[url];
}
}
return instance;
}
private MonIn(IHttpClientFactory httpClientFactory, string url)
{
_MonInUrl = url;
_CultureInfo = new CultureInfo("en-US");
_HttpClient = httpClientFactory.CreateClient();
}
public Task<HttpResponseMessage> SendStatus(string site, string resource, string stateName, State state) =>
SendStatus(site, new DateTime?(), resource, string.Empty, stateName, state, string.Empty);
public Task<HttpResponseMessage> SendStatus(string site,
DateTime timeStamp,
string resource,
string stateName,
State state) =>
SendStatus(site, new DateTime?(timeStamp), resource, string.Empty, stateName, state, string.Empty);
public Task<HttpResponseMessage> SendStatus(string site,
string resource,
string stateName,
State state,
string description) =>
SendStatus(site, new DateTime?(), resource, string.Empty, stateName, state, description);
public Task<HttpResponseMessage> SendStatus(string site,
DateTime timeStamp,
string resource,
string stateName,
State state,
string description) =>
SendStatus(site, new DateTime?(timeStamp), resource, string.Empty, stateName, state, description);
public Task<HttpResponseMessage> SendStatus(string site,
string resource,
string subResource,
string stateName,
State state) =>
SendStatus(site, new DateTime?(), resource, subResource, stateName, state, string.Empty);
public Task<HttpResponseMessage> SendStatus(string site,
DateTime timeStamp,
string resource,
string subResource,
string stateName,
State state) =>
SendStatus(site, new DateTime?(timeStamp), resource, subResource, stateName, state, string.Empty);
public Task<HttpResponseMessage> SendStatus(string site,
string resource,
string subResource,
string stateName,
State state,
string description) =>
SendStatus(site, new DateTime?(), resource, subResource, stateName, state, description);
public Task<HttpResponseMessage> SendStatus(
string site,
DateTime? timeStamp,
string resource,
string subResource,
string stateName,
State state,
string description)
{
string statusMessage = CreateStatusMessage(site, timeStamp, resource, subResource, stateName, state.ToString(), description);
StringContent stringContent = new(statusMessage, Encoding.UTF8, "application/text");
lock (_HttpClient)
return _HttpClient.PostAsync(string.Format(_MonInUrl, site), stringContent);
}
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
string resource,
string performanceName,
double value) =>
SendPerformanceMessage(site, new DateTime?(), resource, string.Empty, performanceName, value, string.Empty, string.Empty, new int?());
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string performanceName,
double value) =>
SendPerformanceMessage(site, timeStamp, resource, string.Empty, performanceName, value, string.Empty, string.Empty, new int?());
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
string resource,
string performanceName,
double value,
string description) =>
SendPerformanceMessage(site, new DateTime?(), resource, string.Empty, performanceName, value, description, string.Empty, new int?());
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string performanceName,
double value,
string description) =>
SendPerformanceMessage(site, timeStamp, resource, string.Empty, performanceName, value, description, string.Empty, new int?());
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string performanceName,
double value,
int? interval) =>
SendPerformanceMessage(site, timeStamp, resource, string.Empty, performanceName, value, string.Empty, string.Empty, interval);
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
string resource,
DateTime? timeStamp,
string performanceName,
double value,
string unit) =>
SendPerformanceMessage(site, timeStamp, resource, string.Empty, performanceName, value, string.Empty, unit, new int?());
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string performanceName,
double value,
string unit,
int? interval) =>
SendPerformanceMessage(site, timeStamp, resource, string.Empty, performanceName, value, string.Empty, unit, interval);
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
string resource,
string subResource,
string performanceName,
double value) =>
SendPerformanceMessage(site, new DateTime?(), resource, subResource, performanceName, value, string.Empty, string.Empty, new int?());
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string subResource,
string performanceName,
double value) =>
SendPerformanceMessage(site, timeStamp, resource, subResource, performanceName, value, string.Empty, string.Empty, new int?());
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
string resource,
string subResource,
string performanceName,
double value,
string description) =>
SendPerformanceMessage(site, new DateTime?(), resource, subResource, performanceName, value, description, string.Empty, new int?());
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string subResource,
string performanceName,
double value,
int? interval) =>
SendPerformanceMessage(site, timeStamp, resource, subResource, performanceName, value, string.Empty, string.Empty, interval);
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string subResource,
string performanceName,
double value,
string unit) =>
SendPerformanceMessage(site, timeStamp, resource, subResource, performanceName, value, string.Empty, unit, new int?());
public Task<HttpResponseMessage> SendPerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string subResource,
string performanceName,
double value,
string description,
string unit,
int? interval)
{
string performanceMessage = CreatePerformanceMessage(site, timeStamp, resource, subResource, performanceName, value, description, unit, interval);
StringContent stringContent = new(performanceMessage, Encoding.UTF8, "application/text");
lock (_HttpClient)
return _HttpClient.PostAsync(string.Format(_MonInUrl, site), stringContent);
}
private static string CreateStatusMessage(string site,
DateTime? timeStamp,
string resource,
string subResource,
string stateName,
string state,
string description)
{
StringBuilder stringBuilder = new();
if (string.IsNullOrEmpty(subResource))
_ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} \n{5}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), stateName.Trim(), state.Trim(), description.Trim());
else
_ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} \n{6}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), subResource.Trim(), stateName.Trim(), state.Trim(), description.Trim());
return stringBuilder.ToString();
}
private static string CreatePerformanceMessage(string site,
DateTime? timeStamp,
string resource,
string subResource,
string performanceName,
double value,
string description,
string unit,
int? interval)
{
StringBuilder stringBuilder = new();
if (string.IsNullOrEmpty(subResource))
{
if (unit.Equals(string.Empty) && !interval.HasValue)
_ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} \n{5}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), performanceName.Trim(), value, description.Trim());
else
_ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} {5} {{interval={6}, unit={7}}}\n", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), performanceName.Trim(), value, description.Trim(), interval.HasValue ? interval.Value.ToString() : (object)string.Empty, unit.Trim());
}
else if (unit.Equals(string.Empty) && !interval.HasValue)
_ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} \n{6}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), subResource.Trim(), performanceName.Trim(), value, description.Trim());
else
_ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} {6} {{interval={7}, unit={8}}}\n", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), subResource.Trim(), performanceName.Trim(), value, description.Trim(), interval.HasValue ? interval.Value.ToString() : (object)string.Empty, unit.Trim());
return stringBuilder.ToString();
}
private static string GetDateTimeNowAsPosix(DateTime timeStamp)
{
if (timeStamp > DateTime.Now)
timeStamp = DateTime.Now;
return ((int)timeStamp.ToUniversalTime().Subtract(_Utc1970DateTime).TotalSeconds).ToString(CultureInfo.InvariantCulture);
}
}

View File

@ -0,0 +1,11 @@
namespace File_Watcher.Infineon.Monitoring.MonA;
public enum State
{
Up,
Ok,
Warning,
Critical,
Down,
Unknown,
}

View File

@ -1,27 +1,119 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using View_by_Distance.Shared.Models;
namespace File_Watcher.Models;
public record AppSettings(EAFLogConfiguration EAFLogConfiguration,
EAFProgramDataConfiguration EAFProgramDataConfiguration,
EDADatabaseConfiguration EDADatabaseConfiguration,
public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
CompassConfiguration CompassConfiguration,
DeterministicHashCodeConfiguration DeterministicHashCodeConfiguration,
DiskInfoConfiguration DiskInfoConfiguration,
DriveConfiguration DriveConfiguration,
NugetConfiguration NugetConfiguration,
EAFLogConfiguration EAFLogConfiguration,
EDADatabaseConfiguration EDADatabaseConfiguration,
FileWatcherConfiguration FileWatcherConfiguration,
InfinityQSConfiguration InfinityQSConfiguration,
IsoConfiguration IsoConfiguration,
MetadataSettings MetadataSettings,
MetrologyConfiguration MetrologyConfiguration,
NugetConfiguration NugetConfiguration,
ResultSettings ResultSettings,
SeleniumConfiguration SeleniumConfiguration,
SerialConfiguration SerialConfiguration,
StratusConfiguration StratusConfiguration,
SyncConfiguration SyncConfiguration,
TransmissionControlProtocolConfiguration TransmissionControlProtocolConfiguration,
WaferCounterConfiguration WaferCounterConfiguration,
string BuildNumber,
string Company,
string GitCommitSeven,
string Helper,
int MillisecondsDelay,
string WatchDirectory)
WaferCounterConfiguration WaferCounterConfiguration)
{
public static AppSettings Get(IConfigurationRoot configurationRoot)
{
AppSettings result;
#pragma warning disable IL3050, IL2026
CamstarOracleConfiguration? camstarOracleConfiguration = configurationRoot.GetSection(nameof(CamstarOracleConfiguration)).Get<CamstarOracleConfiguration>();
CompassConfiguration? compassConfiguration = configurationRoot.GetSection(nameof(CompassConfiguration)).Get<CompassConfiguration>();
DiskInfoConfiguration? diskInfoConfiguration = configurationRoot.GetSection(nameof(DiskInfoConfiguration)).Get<DiskInfoConfiguration>();
DeterministicHashCodeConfiguration? deterministicHashCodeConfiguration = configurationRoot.GetSection(nameof(DeterministicHashCodeConfiguration)).Get<DeterministicHashCodeConfiguration>();
DriveConfiguration? driveConfiguration = configurationRoot.GetSection(nameof(DriveConfiguration)).Get<DriveConfiguration>();
EAFLogConfiguration? eafLogConfiguration = configurationRoot.GetSection(nameof(EAFLogConfiguration)).Get<EAFLogConfiguration>();
EDADatabaseConfiguration? edaDatabaseConfiguration = configurationRoot.GetSection(nameof(EDADatabaseConfiguration)).Get<EDADatabaseConfiguration>();
FileWatcherConfiguration? fileWatcherConfiguration = configurationRoot.GetSection(nameof(FileWatcherConfiguration)).Get<FileWatcherConfiguration>();
InfinityQSConfiguration? infinityQSConfiguration = configurationRoot.GetSection(nameof(InfinityQSConfiguration)).Get<InfinityQSConfiguration>();
IsoConfiguration? isoConfiguration = configurationRoot.GetSection(nameof(IsoConfiguration)).Get<IsoConfiguration>();
MetadataSettings? metadataSettings = configurationRoot.GetSection(nameof(MetadataSettings)).Get<MetadataSettings>();
MetrologyConfiguration? metrologyConfiguration = configurationRoot.GetSection(nameof(MetrologyConfiguration)).Get<MetrologyConfiguration>();
NugetConfiguration? nugetConfiguration = configurationRoot.GetSection(nameof(NugetConfiguration)).Get<NugetConfiguration>();
ResultSettings? resultSettings = configurationRoot.GetSection(nameof(ResultSettings)).Get<ResultSettings>();
SeleniumConfiguration? seleniumConfiguration = configurationRoot.GetSection(nameof(SeleniumConfiguration)).Get<SeleniumConfiguration>();
SerialConfiguration? serialConfiguration = configurationRoot.GetSection(nameof(SerialConfiguration)).Get<SerialConfiguration>();
StratusConfiguration? stratusConfiguration = configurationRoot.GetSection(nameof(StratusConfiguration)).Get<StratusConfiguration>();
SyncConfiguration? syncConfiguration = configurationRoot.GetSection(nameof(SyncConfiguration)).Get<SyncConfiguration>();
TransmissionControlProtocolConfiguration? transmissionControlProtocolConfiguration = configurationRoot.GetSection(nameof(TransmissionControlProtocolConfiguration)).Get<TransmissionControlProtocolConfiguration>();
WaferCounterConfiguration? waferCounterConfiguration = configurationRoot.GetSection(nameof(WaferCounterConfiguration)).Get<WaferCounterConfiguration>();
#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
|| fileWatcherConfiguration is null
|| infinityQSConfiguration is null
|| isoConfiguration is null
|| metadataSettings is null
|| 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)
{
List<string> paths = [];
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
{
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
continue;
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
continue;
paths.Add(physicalFileProvider.Root);
}
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
}
result = new(camstarOracleConfiguration,
compassConfiguration,
deterministicHashCodeConfiguration,
diskInfoConfiguration,
driveConfiguration,
eafLogConfiguration,
edaDatabaseConfiguration,
fileWatcherConfiguration,
infinityQSConfiguration,
isoConfiguration,
metadataSettings,
metrologyConfiguration,
nugetConfiguration,
resultSettings,
seleniumConfiguration,
serialConfiguration,
stratusConfiguration,
syncConfiguration,
transmissionControlProtocolConfiguration,
waferCounterConfiguration);
Verify(result);
return result;
}
private static void Verify(AppSettings appSettings)
{
if (appSettings.DeterministicHashCodeConfiguration.MaxDegreeOfParallelism > Environment.ProcessorCount)
throw new Exception($"Environment.ProcessorCount must be larger or equal to {nameof(appSettings.DeterministicHashCodeConfiguration.MaxDegreeOfParallelism)}");
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings);

View File

@ -1,2 +0,0 @@
[*.cs]
csharp_preserve_single_line_statements = true

View File

@ -1,144 +0,0 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Watcher.Models.Binder;
public class AppSettings
{
public string? BuildNumber { get; set; }
public string[]? ConfigurationDirectoryNames { get; set; }
public int? ConfigurationSpecialFolder { get; set; }
public string? ConfigurationFileName { get; set; }
public string? Company { get; set; }
public string? GitCommitSeven { get; set; }
public string? Helper { get; set; }
public int? MillisecondsDelay { get; set; }
public string? WatchDirectory { get; set; }
public override string ToString()
{
string result = JsonSerializer.Serialize(this, BinderAppSettingsSourceGenerationContext.Default.AppSettings);
return result;
}
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
{
if (appSettings?.BuildNumber is null)
{
List<string> paths = [];
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
{
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
continue;
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
continue;
paths.Add(physicalFileProvider.Root);
}
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
}
}
private static void Verify(AppSettings _)
{
}
private static Models.AppSettings Get(AppSettings? appSettings,
DriveConfiguration driveConfiguration,
CompassConfiguration compassConfiguration,
EAFLogConfiguration eafLogConfiguration,
EAFProgramDataConfiguration eafProgramDataConfiguration,
EDADatabaseConfiguration edaDatabaseConfiguration,
NugetConfiguration nugetConfiguration,
MetrologyConfiguration metrologyConfiguration,
SerialConfiguration serialConfiguration,
StratusConfiguration stratusConfiguration,
TransmissionControlProtocolConfiguration transmissionControlProtocolConfiguration,
WaferCounterConfiguration waferCounterConfiguration)
{
Models.AppSettings result;
if (appSettings is null) throw new NullReferenceException(nameof(appSettings));
if (appSettings.BuildNumber is null) throw new NullReferenceException(nameof(BuildNumber));
if (appSettings.Company is null) throw new NullReferenceException(nameof(Company));
if (appSettings.GitCommitSeven is null) throw new NullReferenceException(nameof(GitCommitSeven));
if (appSettings.Helper is null) throw new NullReferenceException(nameof(Helper));
if (appSettings.MillisecondsDelay is null) throw new NullReferenceException(nameof(MillisecondsDelay));
if (appSettings.WatchDirectory is null) throw new NullReferenceException(nameof(WatchDirectory));
Verify(appSettings);
result = new(eafLogConfiguration,
eafProgramDataConfiguration,
edaDatabaseConfiguration,
compassConfiguration,
driveConfiguration,
nugetConfiguration,
metrologyConfiguration,
serialConfiguration,
stratusConfiguration,
transmissionControlProtocolConfiguration,
waferCounterConfiguration,
appSettings.BuildNumber,
appSettings.Company,
appSettings.GitCommitSeven,
appSettings.Helper,
appSettings.MillisecondsDelay.Value,
appSettings.WatchDirectory);
return result;
}
private static Models.AppSettings Get(AppSettings? appSettings)
{
Models.AppSettings? results;
string? json;
if (appSettings is null || appSettings.ConfigurationFileName is null)
throw new NotSupportedException($"{nameof(appSettings.ConfigurationFileName)} must be set!");
string jsonFile = Path.Combine(AppContext.BaseDirectory, appSettings.ConfigurationFileName);
if (File.Exists(jsonFile))
json = File.ReadAllText(jsonFile);
else
{
json = null;
string applicationData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
List<string> collection = [applicationData];
if (appSettings?.ConfigurationDirectoryNames is not null)
collection.AddRange(appSettings.ConfigurationDirectoryNames);
if (appSettings?.ConfigurationFileName is not null)
collection.Add(appSettings.ConfigurationFileName);
jsonFile = Path.Combine(collection.ToArray());
}
if (string.IsNullOrEmpty(json) && File.Exists(jsonFile))
json = File.ReadAllText(jsonFile);
results = (string.IsNullOrEmpty(json) ? null : results = JsonSerializer.Deserialize(json, AppSettingsSourceGenerationContext.Default.AppSettings)) ??
throw new NullReferenceException(nameof(Models.AppSettings));
results = Get(appSettings,
results.DriveConfiguration,
results.CompassConfiguration,
results.EAFLogConfiguration,
results.EAFProgramDataConfiguration,
results.EDADatabaseConfiguration,
results.NugetConfiguration,
results.MetrologyConfiguration,
results.SerialConfiguration,
results.StratusConfiguration,
results.TransmissionControlProtocolConfiguration,
results.WaferCounterConfiguration);
return results;
}
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
{
Models.AppSettings result;
#pragma warning disable IL3050, IL2026
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
#pragma warning restore IL3050, IL2026
PreVerify(configurationRoot, appSettings);
result = Get(appSettings);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(AppSettings))]
internal partial class BinderAppSettingsSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,28 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Watcher.Models;
public record CamstarOracleConfiguration(string DateFormat,
string Directory,
string LogFilter,
string[] MessageFilters,
string MonitorApplicationResource,
string MonitorApplicationSite,
int MillisecondsDelay,
int RollingMinutes)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, CamstarOracleConfigurationSourceGenerationContext.Default.CamstarOracleConfiguration);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(CamstarOracleConfiguration))]
internal partial class CamstarOracleConfigurationSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,22 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Watcher.Models;
public record DeterministicHashCodeConfiguration(int MaxDegreeOfParallelism,
string[] SidecarExtensions)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, DeterministicHashCodeConfigurationSourceGenerationContext.Default.DeterministicHashCodeConfiguration);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(DeterministicHashCodeConfiguration))]
internal partial class DeterministicHashCodeConfigurationSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -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
{
}

View File

@ -1,21 +0,0 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Watcher.Models;
public record EAFProgramDataConfiguration(string Destination, string Source)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, EAFProgramDataConfigurationSourceGenerationContext.Default.EAFProgramDataConfiguration);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(EAFProgramDataConfiguration))]
internal partial class EAFProgramDataConfigurationSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,24 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Watcher.Models;
public record FileWatcherConfiguration(string Company,
string Helper,
int MillisecondsDelay,
string WatchDirectory)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, FileWatcherConfigurationSourceGenerationContext.Default.FileWatcherConfiguration);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FileWatcherConfiguration))]
internal partial class FileWatcherConfigurationSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,26 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Watcher.Models;
public record InfinityQSConfiguration(string ConnectionString,
string DestinationDirectory,
string EncryptedPassword,
long SubGroupTime,
string TestsFile,
Test[] Tests)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, InfinityQSConfigurationSourceGenerationContext.Default.InfinityQSConfiguration);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(InfinityQSConfiguration))]
internal partial class InfinityQSConfigurationSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,22 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Watcher.Models;
public record IsoConfiguration(string DestinationDirectory,
string SourceDirectory)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, IsoConfigurationSourceGenerationContext.Default.IsoConfiguration);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(IsoConfiguration))]
internal partial class IsoConfigurationSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -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
{
}

View File

@ -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
{
}

12
Models/Test.cs Normal file
View File

@ -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
{
}

View File

@ -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<string, IEnumerable<string>> 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<string, object> 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;
});
}
}

View File

@ -14,12 +14,17 @@ public class Program
WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args);
#pragma warning restore IL3050
_ = webApplicationBuilder.Configuration.AddUserSecrets<Program>();
AppSettings appSettings = Models.Binder.AppSettings.Get(webApplicationBuilder.Configuration);
if (string.IsNullOrEmpty(appSettings.Company))
AppSettings appSettings = AppSettings.Get(webApplicationBuilder.Configuration);
if (string.IsNullOrEmpty(appSettings.FileWatcherConfiguration.Company))
throw new Exception("Company name must have a value!");
try
{
List<string> collection = [];
List<string> collection =
[
$"BuildNumber:{webApplicationBuilder.Configuration.GetValue<string>("BuildNumber")};",
$"GitCommitSeven:{webApplicationBuilder.Configuration.GetValue<string>("GitCommitSeven")};"
];
_ = webApplicationBuilder.Services.AddHttpClient();
_ = webApplicationBuilder.Services.AddHostedService<Worker>();
_ = webApplicationBuilder.Services.AddSingleton(collection);
_ = webApplicationBuilder.Services.AddSingleton(appSettings);
@ -37,13 +42,13 @@ public class Program
}
using WebApplication webApplication = webApplicationBuilder.Build();
logger = webApplication.Services.GetRequiredService<ILogger<Program>>();
if (string.IsNullOrEmpty(appSettings.Company))
if (string.IsNullOrEmpty(appSettings.FileWatcherConfiguration.Company))
{
Environment.ExitCode = -1;
_ = webApplication.StopAsync();
}
logger.LogInformation("Starting Web Application");
logger.LogCritical("{Company}", appSettings.Company);
logger.LogCritical("{Company}", appSettings.FileWatcherConfiguration.Company);
await webApplication.RunAsync();
}
catch (Exception ex)

19
Startup.cs Normal file
View File

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

View File

@ -10,64 +10,93 @@ public partial class Worker : BackgroundService
private readonly bool _IsWindowsService;
private readonly ILogger<Worker> _Logger;
private readonly AppSettings _AppSettings;
private readonly IHttpClientFactory _HttpClientFactory;
public Worker(IServiceProvider serviceProvider, ILogger<Worker> logger, AppSettings appSettings, List<string> collection)
public Worker(IHttpClientFactory httpClientFactory, ILogger<Worker> logger, IServiceProvider serviceProvider, AppSettings appSettings, List<string> collection)
{
_Logger = logger;
_AppSettings = appSettings;
logger.LogInformation("{buildNumber}-{gitCommitSeven}", _AppSettings.BuildNumber, _AppSettings.GitCommitSeven);
_HttpClientFactory = httpClientFactory;
logger.LogInformation(string.Join(Environment.NewLine, collection));
try
{ 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<Startup>(appSettings.SyncConfiguration.UniformResourceLocator);
logger.LogInformation("Server running on {url}", appSettings.SyncConfiguration.UniformResourceLocator);
}
}
private void BodyInner(CancellationToken cancellationToken)
public override Task StopAsync(CancellationToken cancellationToken)
{
_Logger.LogInformation("A) Next execute will be at {date}", DateTime.Now.AddMilliseconds(_AppSettings.MillisecondsDelay).ToString("yyyy-MM-dd hh:mm:ss.fff tt"));
if (!Directory.Exists(_AppSettings.WatchDirectory))
_ = Directory.CreateDirectory(_AppSettings.WatchDirectory);
else
{
_ = _AppSettings.Helper switch
{
nameof(Helpers.HelperNuget) => Helpers.HelperNuget.Sync(_AppSettings, _Logger),
nameof(Helpers.HelperTCP) => Helpers.HelperTCP.ReadWrite(_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.RunMI(_AppSettings, _Logger),
nameof(Helpers.HelperEventLog) => Helpers.HelperEventLog.ClearEventLogs(_AppSettings, _Logger),
nameof(Helpers.HelperWaferCounter) => Helpers.HelperWaferCounter.MoveFile(_AppSettings, _Logger),
nameof(Helpers.HelperEAFProgramData) => Helpers.HelperEAFProgramData.MoveFiles(_AppSettings, _Logger),
nameof(Helpers.HelperSerial) => Helpers.HelperSerial.ReadWrite(_AppSettings, _Logger, cancellationToken),
nameof(Helpers.HelperMetrologyFiles) => Helpers.HelperMetrologyFiles.SortAndDelete(_AppSettings, _Logger),
nameof(Helpers.HelperEDADatabase) => Helpers.HelperEDADatabase.SaveDataCollectionPlans(_AppSettings, _Logger, cancellationToken),
_ => throw new NotSupportedException()
};
}
_Logger.LogInformation("B) Next execute will be at {date}", DateTime.Now.AddMilliseconds(_AppSettings.MillisecondsDelay).ToString("yyyy-MM-dd hh:mm:ss.fff tt"));
if (_AppSettings.FileWatcherConfiguration.Helper == nameof(Helpers.HelperCamstarOracle))
Helpers.HelperCamstarOracle.Heartbeat(_AppSettings, _HttpClientFactory, _Logger, Infineon.Monitoring.MonA.State.Down, cancellationToken);
return base.StopAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken) =>
await Body(cancellationToken);
private async Task Body(CancellationToken cancellationToken)
{
if (!_IsWindowsService)
throw new EvaluateException($"Set break point and skip to run {_AppSettings.Helper}!");
{
_Logger.LogInformation("Set break point and skip to run {_AppSettings.FileWatcherConfiguration.Helper}!", _AppSettings.FileWatcherConfiguration.Helper);
throw new EvaluateException($"Set break point and skip to run {_AppSettings.FileWatcherConfiguration.Helper}!");
}
if (!_IsWindowsService)
{
for (int i = 0; i < int.MaxValue; i++)
{
BodyInner(cancellationToken);
Thread.Sleep(500);
Thread.Sleep(_AppSettings.FileWatcherConfiguration.MillisecondsDelay);
}
}
while (_IsWindowsService && !cancellationToken.IsCancellationRequested)
{
BodyInner(cancellationToken);
await Task.Delay(_AppSettings.MillisecondsDelay, cancellationToken);
try
{
BodyInner(cancellationToken);
await Task.Delay(_AppSettings.FileWatcherConfiguration.MillisecondsDelay, cancellationToken);
}
catch (Exception ex) { _Logger.LogError(ex, "Unexpected Error!"); }
}
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken) =>
await Body(cancellationToken);
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 (!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.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.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()
};
}
_Logger.LogInformation("B) Next execute will be at {date}", DateTime.Now.AddMilliseconds(_AppSettings.FileWatcherConfiguration.MillisecondsDelay).ToString("yyyy-MM-dd hh:mm:ss.fff tt"));
}
}

35
package-lock.json generated
View File

@ -1,35 +0,0 @@
{
"name": "File-Watcher",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"devDependencies": {
"prettier": "3.0.0"
}
},
"node_modules/prettier": {
"version": "3.0.0",
"resolved": "http://localhost:4873/prettier/-/prettier-3.0.0.tgz",
"integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
}
},
"dependencies": {
"prettier": {
"version": "3.0.0",
"resolved": "http://localhost:4873/prettier/-/prettier-3.0.0.tgz",
"integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==",
"dev": true
}
}
}

View File

@ -1,10 +0,0 @@
{
"scripts": {
"prettier.check": "prettier . --check",
"prettier.write": "prettier . --write",
"garbage-collect": "git gc"
},
"devDependencies": {
"prettier": "3.0.0"
}
}