Compare commits
12 Commits
846908d3f4
...
master
Author | SHA1 | Date | |
---|---|---|---|
89bb87bd14 | |||
e7c1fd2221 | |||
fc4449f515 | |||
6ce6c28db1 | |||
2e4aa313fa | |||
116d5e9734 | |||
5ca22b3792 | |||
b98d1e480b | |||
404ffe18f5 | |||
5becc546b2 | |||
0f9d004122 | |||
dd5baba9bc |
1
.gitignore
vendored
1
.gitignore
vendored
@ -336,3 +336,4 @@ ASALocalRun/
|
||||
.extensions-vscode-oss
|
||||
.extensions-vscode-insiders
|
||||
.vscode/.UserSecrets/secrets.json
|
||||
.vscode/.helper
|
||||
|
4
.vscode/equipment-automation-framework-cell-instance-status.http
vendored
Normal file
4
.vscode/equipment-automation-framework-cell-instance-status.http
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
@host = eaf-prod.mes.infineon.com:9003
|
||||
|
||||
POST {{host}}/StatusQuery
|
||||
Accept: application/json
|
102
.vscode/launch.json
vendored
102
.vscode/launch.json
vendored
@ -11,6 +11,74 @@
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/File-Folder-Helper.dll",
|
||||
"args": [
|
||||
"s",
|
||||
"X",
|
||||
"V:/Tmp/Phares/Pictures/2023 TI2023.6 Fall Samsung",
|
||||
"Day-Helper-2025-07-05",
|
||||
"x-653889110721.jpg~401223300869.jpg",
|
||||
"3648,2736,1~3024,4032,6",
|
||||
"0.341694,0.599963,0.1642,0.279605~0.552357,0.65095,0.195175,0.32383~0.31002,0.42328,0.0379464,0.0459656",
|
||||
"0.259594,0.460161,0.1642,0.279605~0.45477,0.489035,0.195175,0.32383~0.328993,0.446263,0.0379464,0.0459656",
|
||||
"9",
|
||||
"x-825511723~x-444522128~831410304",
|
||||
"s",
|
||||
"X",
|
||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\PollPath",
|
||||
"Day-Helper-2025-07-01",
|
||||
"*.pdsf",
|
||||
"654321",
|
||||
"Time",
|
||||
"id12~CenterTemp,id13~CenterSetpt,id15~FrontTemp,id153~PPSTEPNAME,id154~SystemState,id16~FrontSetpt,id172~LVC1Ratio,id173~LVC1Carrier,id176~TotalWaferCount,i-d-1-7-8~TIME,id18~SideTemp,id183~SCRDrive4,id19~SideSetpt,id193~SCRLOAD4,id21~RearTemp,id22~RearSetpt,id221~LeftDefaultRecipe,id222~RightDefaultRecipe,id223~RecipeCompleteMsg,id25~N2H2Setpt,id26~N2H2Flow,id27~HCLSetpt,id28~HCLFlow,id29~HCLHISetpt,id30~HCLHIFlow,id37~NSRCSetpt,id38~NSRCFlow,id39~NDILSetpt,id40~NDILFlow,id41~NINJSetpt,id42~NINJFlow,id57~LVC1Setpt,id58~LVC1Flow,id61~ROTSetpt,id62~ROTSpeed,id78~LL1State,id79~LL1Init,id80~LL1Lotid,id81~LL1WafersIn,id82~LL1WfrCnt,id83~LL2State,id84~LL2Init,id85~LL2Lotid,id86~LL2WafersIn,id87~LL2WfrCnt,id93~ProcessState",
|
||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\Markdown",
|
||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\KeyValuePairs",
|
||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\JavaScriptObjectNotation",
|
||||
"s",
|
||||
"X",
|
||||
"F:/0-ISO-A",
|
||||
"Day-Helper-2025-06-28",
|
||||
"*.iso",
|
||||
"F",
|
||||
"s",
|
||||
"X",
|
||||
"D:/5-Other-Small",
|
||||
"Day-Helper-2024-12-17",
|
||||
".job.json",
|
||||
"thumbs.db~sync.ffs_db~verify.json~.html",
|
||||
"D:/0-ISO-A",
|
||||
"D:/5-Other-Small/Proxmox/Snap2HTML/Snap2HTML.exe",
|
||||
"s",
|
||||
"M",
|
||||
"D:/5-Other-Small/Notes/EC-Documentation",
|
||||
"-d",
|
||||
"D:/5-Other-Small/Notes/EC-Documentation/.vscode/helper",
|
||||
"s",
|
||||
"X",
|
||||
"D:/5-Other-Small/Proxmox/DiskInfo",
|
||||
"Day-Helper-2025-06-18",
|
||||
"*.json",
|
||||
"D:/5-Other-Small/Proxmox/Disk-Info-Old",
|
||||
"-2025-",
|
||||
"1",
|
||||
"s",
|
||||
"X",
|
||||
"D:/Tmp",
|
||||
"Day-Helper-2025-06-02",
|
||||
"infineon\\MESPhares",
|
||||
"BACKLOG~BIORAD2~BIORAD3~BIORAD4~BIORAD5~CDE4~CDE5~CDE6~DEP08CEPIEPSILON~DEP08SIASM~DEP08SIHTRPLC~EC~HGCV1~HGCV2~HGCV3~MESAFIBACKLOG~MET06AWCT~MET08ANLYSDIFAAST230~MET08AWCT~MET08DDUPSFS6420~MET08DDUPSP1TBI~MET08RESIHGCV~MET08RESIMAPCDE~MET08RESISRP2100~MET08THFTIRQS408M~MET08THFTIRSTRATUS~METCLIMATEC~R29~R32~R36~R47~R55~R57~R61~R62~R65~R70~R72~R73~R74~R75~R77~SP101~SPV01~SRP~TENCOR1~TENCOR2~TENCOR3~TRENDLOG~WC6INCH1~WC6INCH2~WC6INCH3~WC6INCH4~WC8INCH1~WC8INCH2~WC8INCH3",
|
||||
"s",
|
||||
"X",
|
||||
"D:/5-Other-Small/Proxmox/ffnm",
|
||||
"Day-Helper-2025-05-21",
|
||||
"*.pdf",
|
||||
"*.md",
|
||||
"2",
|
||||
"MM-dd-yy",
|
||||
"Trans Date~Effective Date~Description~Withdrawal Deposit~Balance",
|
||||
"s",
|
||||
"X",
|
||||
"D:/Tmp/phares/VisualStudioCode",
|
||||
"Day-Helper-2025-05-19",
|
||||
"D:/Tmp/phares/VisualStudioCode/.vscode/input.json",
|
||||
"s",
|
||||
"X",
|
||||
"D:/Tmp/phares/VisualStudioCode",
|
||||
@ -22,14 +90,14 @@
|
||||
"/api/SyncV1/?",
|
||||
",L",
|
||||
".G",
|
||||
"+|G||L|+|Custom-Default",
|
||||
"+~G~~L~+~Custom-Default",
|
||||
"",
|
||||
"+|G||G|-|Mirror",
|
||||
"+|G||||Update",
|
||||
"+|G||L|+|Custom-Default",
|
||||
"-|G||G|+|Custom-A",
|
||||
"-|L||L|+|Custom-B",
|
||||
"+|L||L|-|Custom-C",
|
||||
"+~G~~G~-~Mirror",
|
||||
"+~G~~~~Update",
|
||||
"+~G~~L~+~Custom-Default",
|
||||
"-~G~~G~+~Custom-A",
|
||||
"-~L~~L~+~Custom-B",
|
||||
"+~L~~L~-~Custom-C",
|
||||
"s",
|
||||
"X",
|
||||
"\\\\mesfs.infineon.com\\EC_Characterization_Si\\Archive\\BIORAD4\\2025_Week_16\\2025-04-17",
|
||||
@ -95,6 +163,26 @@
|
||||
"request": "launch",
|
||||
"name": "node Launch Current Opened File",
|
||||
"program": "${file}"
|
||||
},
|
||||
{
|
||||
"type": "bun",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"request": "launch",
|
||||
"name": "Debug File",
|
||||
"program": "${file}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopOnEntry": false,
|
||||
"watchMode": false
|
||||
},
|
||||
{
|
||||
"type": "bun",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"request": "launch",
|
||||
"name": "Run File",
|
||||
"program": "${file}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"noDebug": true,
|
||||
"watchMode": false
|
||||
}
|
||||
]
|
||||
}
|
34
.vscode/mklink.md
vendored
34
.vscode/mklink.md
vendored
@ -14,18 +14,28 @@ mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.kanbn" "D:\5-Other-Small\Kanban
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.kanbn" "D:\5-Other-Small\Kanban\File-Folder-Helper"
|
||||
```
|
||||
|
||||
```bash
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode"
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-oss"
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-insiders"
|
||||
mkdir "C:\Users\phares\.vscode\extensions\ifx.type-script-helper-1.111.0\net8.0\win-x64\publish"
|
||||
mkdir "C:\Users\phares\.vscode-oss\extensions\ifx.type-script-helper-1.111.0\net8.0\win-x64\publish"
|
||||
mkdir "C:\Users\phares\.vscode-insiders\extensions\ifx.type-script-helper-1.111.0\net8.0\win-x64\publish"
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode" "C:\Users\phares\.vscode\extensions\ifx.type-script-helper-1.111.0"
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-oss" "C:\Users\phares\.vscode-oss\extensions\ifx.type-script-helper-1.111.0"
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-insiders" "C:\Users\phares\.vscode-insiders\extensions\ifx.type-script-helper-1.111.0"
|
||||
```
|
||||
|
||||
```bash Thu Jul 18 2024 13:47:40 GMT-0700 (Mountain Standard Time)
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.vscode\.UserSecrets" "C:\Users\phares\AppData\Roaming\Microsoft\UserSecrets\8da397d4-13ec-4576-9722-3c79cad25563"
|
||||
```
|
||||
|
||||
```bash 1749414316830 = 638850111168300000 = 2025-2.Spring = Sun Jun 08 2025 13:25:16 GMT-0700 (Mountain Standard Time)
|
||||
C:\Users\PHARES\.vscode\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode"
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-oss"
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-insiders"
|
||||
mkdir "C:\Users\phares\.vscode\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64"
|
||||
mkdir "C:\Users\phares\.vscode-oss\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64"
|
||||
mkdir "C:\Users\phares\.vscode-insiders\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64"
|
||||
mklink /J "C:\Users\phares\.vscode\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64\publish" "L:\DevOps\Mesa_FI\File-Folder-Helper\bin\Release\net8.0\win-x64\publish"
|
||||
mklink /J "C:\Users\phares\.vscode-oss\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64\publish" "L:\DevOps\Mesa_FI\File-Folder-Helper\bin\Release\net8.0\win-x64\publish"
|
||||
mklink /J "C:\Users\phares\.vscode-insiders\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64\publish" "L:\DevOps\Mesa_FI\File-Folder-Helper\bin\Release\net8.0\win-x64\publish"
|
||||
```
|
||||
|
||||
```bash 1749957317559 = 638855541175590000 = 2025-2.Spring = Sat Jun 14 2025 20:15:17 GMT-0700 (Mountain Standard Time)
|
||||
mkdir "L:\DevOps\MESA_FI\file-folder-helper\bin\Release\net8.0\win-x64"
|
||||
mklink /J "L:\DevOps\MESA_FI\file-folder-helper\bin\Release\net8.0\win-x64\publish" "D:\5-Other-Small\Proxmox\publish"
|
||||
```
|
||||
|
||||
```bash 1750459968132 = 638860567681320000 = 2025-3.Summer = Fri Jun 20 2025 15:52:47 GMT-0700 (Mountain Standard Time)
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.vscode\.helper" "D:\5-Other-Small\Notes\Infineon\.vscode\helper"
|
||||
```
|
||||
|
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -10,6 +10,8 @@
|
||||
"**/node_modules": true
|
||||
},
|
||||
"cSpell.words": [
|
||||
"abcdefghiklmnopqrstuvwxyz",
|
||||
"Acks",
|
||||
"ASPNETCORE",
|
||||
"BIORAD",
|
||||
"BIRT",
|
||||
@ -21,6 +23,7 @@
|
||||
"FAMS",
|
||||
"Gatus",
|
||||
"GIVN",
|
||||
"HGCV",
|
||||
"HUSB",
|
||||
"Immich",
|
||||
"INDI",
|
||||
@ -31,6 +34,7 @@
|
||||
"Linc",
|
||||
"mesfs",
|
||||
"mestsa",
|
||||
"netrm",
|
||||
"NpgSql",
|
||||
"NSFX",
|
||||
"OBJE",
|
||||
@ -44,9 +48,11 @@
|
||||
"Reparse",
|
||||
"Rijndael",
|
||||
"Serilog",
|
||||
"startable",
|
||||
"SUBM",
|
||||
"SURN",
|
||||
"SYSLIB",
|
||||
"TENCOR",
|
||||
"VSTS",
|
||||
"WIQL",
|
||||
"WSJF"
|
||||
|
@ -24,9 +24,12 @@ internal static partial class Helper20241217
|
||||
long Length,
|
||||
string RelativePath);
|
||||
|
||||
private record Record(string Directory,
|
||||
private record Record(string DestinationDirectory,
|
||||
string DirectoryName,
|
||||
Job Job,
|
||||
string Path);
|
||||
string Path,
|
||||
string Snap2HyperTextMarkupLanguage,
|
||||
string SourceDirectory);
|
||||
|
||||
private record Job(string? AlternatePath,
|
||||
string Directory,
|
||||
@ -49,27 +52,52 @@ internal static partial class Helper20241217
|
||||
{
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<File> GetFiles(string searchPattern, string[] ignoreFileNames, Record record) =>
|
||||
GetFiles(record.SourceDirectory, searchPattern, ignoreFileNames);
|
||||
|
||||
internal static void Backup(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
Job jobNew;
|
||||
string path;
|
||||
string? json;
|
||||
string fileName;
|
||||
bool areTheyTheSame;
|
||||
string directoryName;
|
||||
IEnumerable<Record> records;
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
logger.LogInformation(args[3]);
|
||||
logger.LogInformation(args[4]);
|
||||
ReadOnlyCollection<File> files;
|
||||
string searchPattern = args[2];
|
||||
IEnumerable<string> searchPatternFiles;
|
||||
string[] ignoreFileNames = args[3].Split('~');
|
||||
string destination = Path.GetFullPath(args[4]);
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
char destinationDriveLetter = args[4].Split(':')[0][0];
|
||||
string? snap2HyperTextMarkupLanguage = args.Count < 6 ? null : Path.GetFullPath(args[5]);
|
||||
logger.LogInformation("Searching <{sourceDirectory}> with search pattern {searchPattern}", args[0], searchPattern);
|
||||
if (Debugger.IsAttached)
|
||||
Verify(searchPattern, ignoreFileNames);
|
||||
IEnumerable<Record> records = GetRecords(sourceDirectory, searchPattern);
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
searchPatternFiles = Directory.EnumerateFiles(sourceDirectory, searchPattern, new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true });
|
||||
}
|
||||
else if (i == 2)
|
||||
{
|
||||
searchPatternFiles = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
records = GetRecords(sourceDirectory, destination, searchPatternFiles);
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (record.Job is null || string.IsNullOrEmpty(record.Job.Extension))
|
||||
continue;
|
||||
logger.LogInformation("Searching <{directory}>", record.Directory);
|
||||
logger.LogInformation("Searching <{directory}>", record.SourceDirectory);
|
||||
if (snap2HyperTextMarkupLanguage is not null && System.IO.File.Exists(snap2HyperTextMarkupLanguage))
|
||||
WriteSnap2HyperTextMarkupLanguage(logger, snap2HyperTextMarkupLanguage, record);
|
||||
files = GetFiles(searchPattern, ignoreFileNames, record);
|
||||
jobNew = GetJob(searchPattern, ignoreFileNames, record, files);
|
||||
json = JsonSerializer.Serialize(jobNew, JobSourceGenerationContext.Default.Job);
|
||||
@ -79,17 +107,14 @@ internal static partial class Helper20241217
|
||||
WriteAllText(record.Path, json);
|
||||
continue;
|
||||
}
|
||||
directoryName = Path.GetFileName(record.Directory);
|
||||
path = Path.Combine(record.Directory, $"{directoryName}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss-fff}{record.Job.Extension}");
|
||||
logger.LogInformation("Writing <{directory}> extension", record.Directory);
|
||||
WritePassedExtension(destinationDriveLetter, record, files, path);
|
||||
WriteAllText(record.Path, json);
|
||||
fileName = $"{record.DirectoryName}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss-fff}{record.Job.Extension}";
|
||||
path = Path.Combine(record.DestinationDirectory, fileName);
|
||||
logger.LogInformation("Writing <{path}> extension", path);
|
||||
WritePassedExtension(record, files, record.DirectoryName, path);
|
||||
logger.LogInformation("Wrote <{path}> extension", path);
|
||||
logger.LogInformation("Moved <{path}> extension", path);
|
||||
WriteAllText(record, json, path);
|
||||
}
|
||||
if (Debugger.IsAttached && records.Count() == 0)
|
||||
{
|
||||
files = GetFiles(sourceDirectory, searchPattern, ignoreFileNames);
|
||||
json = JsonSerializer.Serialize(files.ToArray(), FilesSourceGenerationContext.Default.FileArray);
|
||||
WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", ".json"), json);
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,24 +163,28 @@ internal static partial class Helper20241217
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static IEnumerable<Record> GetRecords(string directory, string searchPattern)
|
||||
private static IEnumerable<Record> GetRecords(string directory, string destination, IEnumerable<string> files)
|
||||
{
|
||||
Job? job;
|
||||
string json;
|
||||
Record record;
|
||||
string fileName;
|
||||
string directoryName;
|
||||
IEnumerable<string> files = Directory.EnumerateFiles(directory, searchPattern, new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true });
|
||||
string sourceDirectory;
|
||||
string destinationDirectory;
|
||||
string snap2HyperTextMarkupLanguage;
|
||||
foreach (string file in files)
|
||||
{
|
||||
fileName = Path.GetFileName(file);
|
||||
directoryName = Path.GetDirectoryName(file) ?? throw new Exception();
|
||||
sourceDirectory = Path.GetDirectoryName(file) ?? throw new Exception();
|
||||
directoryName = Path.GetFileName(sourceDirectory);
|
||||
if (!fileName.StartsWith('.'))
|
||||
{
|
||||
System.IO.File.Move(file, Path.Combine(directoryName, $".{fileName}"));
|
||||
System.IO.File.Move(file, Path.Combine(sourceDirectory, $".{fileName}"));
|
||||
continue;
|
||||
}
|
||||
json = System.IO.File.ReadAllText(file);
|
||||
snap2HyperTextMarkupLanguage = Path.Combine(sourceDirectory, ".html");
|
||||
if (string.IsNullOrEmpty(json) || json is "{}" or "[]")
|
||||
job = null;
|
||||
else
|
||||
@ -168,11 +197,36 @@ internal static partial class Helper20241217
|
||||
FilesTotalLength: 0,
|
||||
Keep: 3,
|
||||
Targets: []);
|
||||
record = new(Directory: directoryName, Job: job, Path: file);
|
||||
destinationDirectory = $"{destination}{sourceDirectory[2..]}";
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
_ = Directory.CreateDirectory(destinationDirectory);
|
||||
record = new(DestinationDirectory: destinationDirectory,
|
||||
DirectoryName: directoryName,
|
||||
Job: job,
|
||||
Path: file,
|
||||
Snap2HyperTextMarkupLanguage: snap2HyperTextMarkupLanguage,
|
||||
SourceDirectory: sourceDirectory);
|
||||
yield return record;
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteSnap2HyperTextMarkupLanguage(ILogger<Worker> logger, string snap2HyperTextMarkupLanguage, Record record)
|
||||
{
|
||||
string title = Path.GetFileName(record.SourceDirectory);
|
||||
ProcessStartInfo processStartInfo = new()
|
||||
{
|
||||
Arguments = $"-path:\"{record.SourceDirectory}\" -outfile:\"{record.Snap2HyperTextMarkupLanguage}\" -title:\"{title}\" -hidden -silent",
|
||||
FileName = snap2HyperTextMarkupLanguage,
|
||||
RedirectStandardError = true,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
WorkingDirectory = record.SourceDirectory
|
||||
};
|
||||
Process? process = Process.Start(processStartInfo) ?? throw new Exception("Process should not be null.");
|
||||
process.WaitForExit();
|
||||
logger.LogInformation($"Snap2HyperTextMarkupLanguage: {process.StandardOutput.ReadToEnd()}{Environment.NewLine}{process.StandardError.ReadToEnd()}{Environment.NewLine}{process.ExitCode}");
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<File> GetFiles(string directory, string searchPattern, string[] ignoreFileNames)
|
||||
{
|
||||
List<File> results = [];
|
||||
@ -197,16 +251,13 @@ internal static partial class Helper20241217
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<File> GetFiles(string searchPattern, string[] ignoreFileNames, Record record) =>
|
||||
GetFiles(record.Directory, searchPattern, ignoreFileNames);
|
||||
|
||||
private static Job GetJob(string searchPattern, string[] ignoreFileNames, Record record, ReadOnlyCollection<File> files)
|
||||
{
|
||||
Job result;
|
||||
ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, files);
|
||||
double filesTotalLengthNew = collection.Select(l => l.Length).Sum();
|
||||
result = new(AlternatePath: record.Job.AlternatePath,
|
||||
Directory: record.Directory,
|
||||
Directory: record.SourceDirectory,
|
||||
Extension: record.Job.Extension,
|
||||
Files: collection.ToArray(),
|
||||
FilesCount: collection.Count,
|
||||
@ -225,7 +276,7 @@ internal static partial class Helper20241217
|
||||
if (filesCountNew != filesCountOld)
|
||||
{
|
||||
result = false;
|
||||
logger.LogInformation("<{directory}> file count has changed {filesCountNew} != {filesCountOld}", record.Directory, filesCountNew, filesCountOld);
|
||||
logger.LogInformation("<{directory}> file count has changed {filesCountNew} != {filesCountOld}", record.SourceDirectory, filesCountNew, filesCountOld);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -234,7 +285,7 @@ internal static partial class Helper20241217
|
||||
if (filesTotalLengthNew != filesTotalLengthOld)
|
||||
{
|
||||
result = false;
|
||||
logger.LogInformation("<{directory}> file length has changed {filesTotalLengthNew} != {filesTotalLengthOld}", record.Directory, filesTotalLengthNew, filesTotalLengthOld);
|
||||
logger.LogInformation("<{directory}> file length has changed {filesTotalLengthNew} != {filesTotalLengthOld}", record.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -245,9 +296,12 @@ internal static partial class Helper20241217
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", "old.json"), jsonOld);
|
||||
WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", "new.json"), jsonNew);
|
||||
logger.LogInformation("<{directory}> file serialized are different {filesTotalLengthNew} != {filesTotalLengthOld}", record.Directory, filesTotalLengthNew, filesTotalLengthOld);
|
||||
}
|
||||
logger.LogInformation("<{directory}> file serialized are different {filesTotalLengthNew} != {filesTotalLengthOld}", record.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -261,36 +315,27 @@ internal static partial class Helper20241217
|
||||
System.IO.File.WriteAllText(path, text);
|
||||
}
|
||||
|
||||
private static void WritePassedExtension(char destinationDriveLetter, Record record, ReadOnlyCollection<File> files, string path)
|
||||
private static void WritePassedExtension(Record record, ReadOnlyCollection<File> files, string directoryName, string path)
|
||||
{
|
||||
string directoryName = Path.GetFileName(record.Directory);
|
||||
if (record.Job.Extension.Equals(".iso", StringComparison.OrdinalIgnoreCase))
|
||||
WriteISO(destinationDriveLetter, record, files, path, directoryName);
|
||||
WriteISO(record, files, path, directoryName);
|
||||
else if (record.Job.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase))
|
||||
WriteZIP(destinationDriveLetter, record, files, path);
|
||||
WriteZIP(record, files, path);
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static void WriteISO(char destinationDriveLetter, Record record, ReadOnlyCollection<File> files, string path, string directoryName)
|
||||
private static void WriteISO(Record record, ReadOnlyCollection<File> files, string path, string directoryName)
|
||||
{
|
||||
string checkFile = $"{destinationDriveLetter}{path[1..]}";
|
||||
string checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new Exception();
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
CDBuilder builder = new() { UseJoliet = true, VolumeIdentifier = directoryName.Length < 25 ? directoryName : directoryName[..25] };
|
||||
foreach (File file in files)
|
||||
_ = builder.AddFile(file.RelativePath, Path.Combine(record.Directory, file.RelativePath));
|
||||
builder.Build(checkFile);
|
||||
_ = builder.AddFile(file.RelativePath, Path.Combine(record.SourceDirectory, file.RelativePath));
|
||||
builder.Build(path);
|
||||
}
|
||||
|
||||
private static void WriteZIP(char destinationDriveLetter, Record record, ReadOnlyCollection<File> files, string path)
|
||||
private static void WriteZIP(Record record, ReadOnlyCollection<File> files, string path)
|
||||
{
|
||||
string checkFile = $"{destinationDriveLetter}{path[1..]}";
|
||||
string checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new Exception();
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
using ZipArchive zip = ZipFile.Open(checkFile, ZipArchiveMode.Create);
|
||||
using ZipArchive zip = ZipFile.Open(path, ZipArchiveMode.Create);
|
||||
string directoryEntry;
|
||||
List<string> directoryEntries = [];
|
||||
foreach (File file in files)
|
||||
@ -302,7 +347,16 @@ internal static partial class Helper20241217
|
||||
_ = zip.CreateEntry(file.RelativePath);
|
||||
}
|
||||
foreach (File file in files)
|
||||
_ = zip.CreateEntryFromFile(Path.Combine(record.Directory, file.RelativePath), file.RelativePath);
|
||||
_ = zip.CreateEntryFromFile(Path.Combine(record.SourceDirectory, file.RelativePath), file.RelativePath);
|
||||
}
|
||||
|
||||
private static void WriteAllText(Record record, string text, string path)
|
||||
{
|
||||
WriteAllText(record.Path, text);
|
||||
System.IO.File.Copy(record.Path, $"{path}.json");
|
||||
string checkFile = Path.Combine(record.SourceDirectory, ".html");
|
||||
if (System.IO.File.Exists(checkFile))
|
||||
System.IO.File.Copy(checkFile, $"{path}.html");
|
||||
}
|
||||
|
||||
}
|
@ -277,12 +277,12 @@ internal static partial class Helper20250219 {
|
||||
}
|
||||
if (!lookForNumbers) {
|
||||
for (int c = 0; c < segments.Length; c++) {
|
||||
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
|
||||
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\",");
|
||||
}
|
||||
} else {
|
||||
for (int c = 0; c < segments.Length; c++) {
|
||||
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
|
||||
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
if (string.IsNullOrEmpty(value))
|
||||
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,");
|
||||
else if (value.All(char.IsDigit))
|
||||
|
@ -71,7 +71,7 @@ internal static partial class Helper20250306 {
|
||||
if (segments.Length != columnsLength)
|
||||
continue;
|
||||
for (int c = 1; c < segments.Length; c++) {
|
||||
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
|
||||
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
line += '"' + columns[c].Trim('"') + '"' + ':' + '"' + value + '"' + ',';
|
||||
}
|
||||
line = line.Substring(0, line.Length - 1) + '}' + ',' + '\n';
|
||||
|
277
ADO2025/PI6/Envelope.cs
Normal file
277
ADO2025/PI6/Envelope.cs
Normal file
@ -0,0 +1,277 @@
|
||||
#nullable disable
|
||||
#pragma warning disable CS8603
|
||||
#pragma warning disable CS8632
|
||||
#pragma warning disable IDE1006
|
||||
|
||||
namespace IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
|
||||
|
||||
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
|
||||
[System.Xml.Serialization.XmlRoot(Namespace = "http://www.w3.org/2003/05/soap-envelope", IsNullable = false)]
|
||||
public partial class Envelope
|
||||
{
|
||||
|
||||
private EnvelopeHeader? headerField;
|
||||
|
||||
private EnvelopeBody? bodyField;
|
||||
|
||||
/// <remarks/>
|
||||
public EnvelopeHeader Header
|
||||
{
|
||||
get => this.headerField;
|
||||
set => this.headerField = value;
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public EnvelopeBody Body
|
||||
{
|
||||
get => this.bodyField;
|
||||
set => this.bodyField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
|
||||
public partial class EnvelopeHeader
|
||||
{
|
||||
|
||||
private Sequence? sequenceField;
|
||||
private SequenceAcknowledgement? sequenceAcknowledgementField;
|
||||
private Action? actionField;
|
||||
|
||||
private string? relatesToField;
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public Sequence Sequence
|
||||
{
|
||||
get => this.sequenceField;
|
||||
set => this.sequenceField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public SequenceAcknowledgement SequenceAcknowledgement
|
||||
{
|
||||
get => this.sequenceAcknowledgementField;
|
||||
set => this.sequenceAcknowledgementField = value;
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")]
|
||||
public Action Action
|
||||
{
|
||||
get => this.actionField;
|
||||
set => this.actionField = value;
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")]
|
||||
public string RelatesTo
|
||||
{
|
||||
get => this.relatesToField;
|
||||
set => this.relatesToField = value;
|
||||
}
|
||||
}
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
[System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)]
|
||||
public partial class Sequence
|
||||
{
|
||||
private string? identifierField;
|
||||
private byte messageNumberField;
|
||||
private object? lastMessageField;
|
||||
private byte mustUnderstandField;
|
||||
/// <remarks/>
|
||||
public string Identifier
|
||||
{
|
||||
get => this.identifierField;
|
||||
set => this.identifierField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
public byte MessageNumber
|
||||
{
|
||||
get => this.messageNumberField;
|
||||
set => this.messageNumberField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
public object LastMessage
|
||||
{
|
||||
get => this.lastMessageField;
|
||||
set => this.lastMessageField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
|
||||
public byte mustUnderstand
|
||||
{
|
||||
get => this.mustUnderstandField;
|
||||
set => this.mustUnderstandField = value;
|
||||
}
|
||||
}
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
[System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)]
|
||||
public partial class SequenceAcknowledgement
|
||||
{
|
||||
private string? identifierField;
|
||||
private SequenceAcknowledgementAcknowledgementRange? acknowledgementRangeField;
|
||||
private byte bufferRemainingField;
|
||||
/// <remarks/>
|
||||
public string Identifier
|
||||
{
|
||||
get => this.identifierField;
|
||||
set => this.identifierField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
public SequenceAcknowledgementAcknowledgementRange AcknowledgementRange
|
||||
{
|
||||
get => this.acknowledgementRangeField;
|
||||
set => this.acknowledgementRangeField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.microsoft.com/ws/2006/05/rm")]
|
||||
public byte BufferRemaining
|
||||
{
|
||||
get => this.bufferRemainingField;
|
||||
set => this.bufferRemainingField = value;
|
||||
}
|
||||
}
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public partial class SequenceAcknowledgementAcknowledgementRange
|
||||
{
|
||||
private byte lowerField;
|
||||
private byte upperField;
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttribute()]
|
||||
public byte Lower
|
||||
{
|
||||
get => this.lowerField;
|
||||
set => this.lowerField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttribute()]
|
||||
public byte Upper
|
||||
{
|
||||
get => this.upperField;
|
||||
set => this.upperField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2005/08/addressing")]
|
||||
[System.Xml.Serialization.XmlRoot(Namespace = "http://www.w3.org/2005/08/addressing", IsNullable = false)]
|
||||
public partial class Action
|
||||
{
|
||||
|
||||
private byte mustUnderstandField;
|
||||
|
||||
private string? valueField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
|
||||
public byte mustUnderstand
|
||||
{
|
||||
get => this.mustUnderstandField;
|
||||
set => this.mustUnderstandField = value;
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlText()]
|
||||
public string Value
|
||||
{
|
||||
get => this.valueField;
|
||||
set => this.valueField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
|
||||
public partial class EnvelopeBody
|
||||
{
|
||||
|
||||
private CreateSequenceResponse? createSequenceResponseField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public CreateSequenceResponse CreateSequenceResponse
|
||||
{
|
||||
get => this.createSequenceResponseField;
|
||||
set => this.createSequenceResponseField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
[System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)]
|
||||
public partial class CreateSequenceResponse
|
||||
{
|
||||
|
||||
private string? identifierField;
|
||||
|
||||
private CreateSequenceResponseAccept? acceptField;
|
||||
|
||||
/// <remarks/>
|
||||
public string Identifier
|
||||
{
|
||||
get => this.identifierField;
|
||||
set => this.identifierField = value;
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public CreateSequenceResponseAccept Accept
|
||||
{
|
||||
get => this.acceptField;
|
||||
set => this.acceptField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public partial class CreateSequenceResponseAccept
|
||||
{
|
||||
|
||||
private CreateSequenceResponseAcceptAcksTo? acksToField;
|
||||
|
||||
/// <remarks/>
|
||||
public CreateSequenceResponseAcceptAcksTo AcksTo
|
||||
{
|
||||
get => this.acksToField;
|
||||
set => this.acksToField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public partial class CreateSequenceResponseAcceptAcksTo
|
||||
{
|
||||
|
||||
private string? addressField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")]
|
||||
public string Address
|
||||
{
|
||||
get => this.addressField;
|
||||
set => this.addressField = value;
|
||||
}
|
||||
}
|
@ -13,11 +13,18 @@ internal static partial class Helper20250519 {
|
||||
|
||||
private record RelativePath(string LeftDirectory,
|
||||
string? RightDirectory,
|
||||
Record[] Records);
|
||||
Record[] Records) {
|
||||
|
||||
public override string ToString() {
|
||||
string result = JsonSerializer.Serialize(this, Helper20250519RelativePath.Default.RelativePath);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(RelativePath))]
|
||||
private partial class RelativePathSourceGenerationContext : JsonSerializerContext {
|
||||
private partial class Helper20250519RelativePath : JsonSerializerContext {
|
||||
}
|
||||
|
||||
private record Review(Segment[]? AreEqual,
|
||||
@ -26,11 +33,18 @@ internal static partial class Helper20250519 {
|
||||
Segment[]? NotEqualBut,
|
||||
Record[]? Records,
|
||||
Segment[]? RightSideIsNewer,
|
||||
Segment[]? RightSideOnly);
|
||||
Segment[]? RightSideOnly) {
|
||||
|
||||
public override string ToString() {
|
||||
string result = JsonSerializer.Serialize(this, Helper20250519Review.Default.Review);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Review))]
|
||||
private partial class ReviewSourceGenerationContext : JsonSerializerContext {
|
||||
private partial class Helper20250519Review : JsonSerializerContext {
|
||||
}
|
||||
|
||||
private record Record(string RelativePath,
|
||||
@ -49,6 +63,38 @@ internal static partial class Helper20250519 {
|
||||
long Ticks,
|
||||
string UrlEncodedFile);
|
||||
|
||||
private record Input(string RightDirectory,
|
||||
string LeftDirectory,
|
||||
string IncludePatternsFile,
|
||||
string ExcludePatternsFile,
|
||||
string[] BaseAddresses,
|
||||
string Page,
|
||||
string[] Segments) {
|
||||
|
||||
private static string GetDirectory(List<string> args) =>
|
||||
Path.GetFullPath(args[0].Split('~')[0]);
|
||||
|
||||
internal static Input Get(List<string> args) =>
|
||||
new(RightDirectory: GetDirectory(args),
|
||||
LeftDirectory: Path.GetFullPath(args[2].Split('~')[0]),
|
||||
IncludePatternsFile: Path.Combine(GetDirectory(args), ".vscode", args[3]),
|
||||
ExcludePatternsFile: Path.Combine(GetDirectory(args), ".vscode", args[4]),
|
||||
BaseAddresses: args.Count < 5 ? [] : args[5].Split('~'),
|
||||
Page: args[6],
|
||||
Segments: args[9].Split('~'));
|
||||
|
||||
public override string ToString() {
|
||||
string result = JsonSerializer.Serialize(this, Helper20250519Input.Default.Input);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Input))]
|
||||
private partial class Helper20250519Input : JsonSerializerContext {
|
||||
}
|
||||
|
||||
private record Logic(string Comment,
|
||||
char GreaterThan,
|
||||
bool? LeftSideIsNewer,
|
||||
@ -85,53 +131,53 @@ internal static partial class Helper20250519 {
|
||||
const int leftSideIsNewerIndex = 1;
|
||||
const int rightSideIsNewerIndex = 3;
|
||||
string comment = segments[commentIndex];
|
||||
if (string.IsNullOrEmpty(segments[leftSideOnlyIndex]))
|
||||
if (string.IsNullOrEmpty(segments[leftSideOnlyIndex])) {
|
||||
leftSideOnly = null;
|
||||
else if (segments[leftSideOnlyIndex][0] == plus)
|
||||
} else if (segments[leftSideOnlyIndex][0] == plus) {
|
||||
leftSideOnly = true;
|
||||
else if (segments[leftSideOnlyIndex][0] == minus)
|
||||
} else if (segments[leftSideOnlyIndex][0] == minus) {
|
||||
leftSideOnly = false;
|
||||
else {
|
||||
} else {
|
||||
check = false;
|
||||
leftSideOnly = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[leftSideIsNewerIndex]))
|
||||
if (string.IsNullOrEmpty(segments[leftSideIsNewerIndex])) {
|
||||
leftSideIsNewer = null;
|
||||
else if (segments[leftSideIsNewerIndex][0] == greaterThan)
|
||||
} else if (segments[leftSideIsNewerIndex][0] == greaterThan) {
|
||||
leftSideIsNewer = true;
|
||||
else if (segments[leftSideIsNewerIndex][0] == lessThan)
|
||||
} else if (segments[leftSideIsNewerIndex][0] == lessThan) {
|
||||
leftSideIsNewer = false;
|
||||
else {
|
||||
} else {
|
||||
check = false;
|
||||
leftSideIsNewer = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[notEqualButIndex]))
|
||||
if (string.IsNullOrEmpty(segments[notEqualButIndex])) {
|
||||
notEqualBut = null;
|
||||
else if (segments[notEqualButIndex][0] == greaterThan)
|
||||
} else if (segments[notEqualButIndex][0] == greaterThan) {
|
||||
notEqualBut = true;
|
||||
else if (segments[notEqualButIndex][0] == lessThan)
|
||||
} else if (segments[notEqualButIndex][0] == lessThan) {
|
||||
notEqualBut = false;
|
||||
else {
|
||||
} else {
|
||||
check = false;
|
||||
notEqualBut = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[rightSideIsNewerIndex]))
|
||||
if (string.IsNullOrEmpty(segments[rightSideIsNewerIndex])) {
|
||||
rightSideIsNewer = null;
|
||||
else if (segments[rightSideIsNewerIndex][0] == greaterThan)
|
||||
} else if (segments[rightSideIsNewerIndex][0] == greaterThan) {
|
||||
rightSideIsNewer = true;
|
||||
else if (segments[rightSideIsNewerIndex][0] == lessThan)
|
||||
} else if (segments[rightSideIsNewerIndex][0] == lessThan) {
|
||||
rightSideIsNewer = false;
|
||||
else {
|
||||
} else {
|
||||
check = false;
|
||||
rightSideIsNewer = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[rightSideOnlyIndex]))
|
||||
if (string.IsNullOrEmpty(segments[rightSideOnlyIndex])) {
|
||||
rightSideOnly = null;
|
||||
else if (segments[rightSideOnlyIndex][0] == plus)
|
||||
} else if (segments[rightSideOnlyIndex][0] == plus) {
|
||||
rightSideOnly = true;
|
||||
else if (segments[rightSideOnlyIndex][0] == minus)
|
||||
} else if (segments[rightSideOnlyIndex][0] == minus) {
|
||||
rightSideOnly = false;
|
||||
else {
|
||||
} else {
|
||||
check = false;
|
||||
rightSideOnly = null;
|
||||
}
|
||||
@ -154,27 +200,46 @@ internal static partial class Helper20250519 {
|
||||
return result;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
string result = JsonSerializer.Serialize(this, Helper20250519Logic.Default.Logic);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Logic))]
|
||||
private partial class Helper20250519Logic : JsonSerializerContext {
|
||||
}
|
||||
|
||||
internal static void LiveSync(ILogger<Worker> logger, List<string> args) {
|
||||
string[] segments = args[9].Split('~');
|
||||
Logic? logic = segments.Length != 6 ? null : Logic.Get(segments);
|
||||
string[] baseAddresses = args.Count < 5 ? [] : args[5].Split('~');
|
||||
if (logic is null || baseAddresses.Length == 0)
|
||||
logger.LogInformation("Invalid input!");
|
||||
else {
|
||||
string rightDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
string excludePatternsFile = Path.Combine(rightDirectory, args[4]);
|
||||
string includePatternsFile = Path.Combine(rightDirectory, args[3]);
|
||||
Matcher matcher = GetMatcher(excludePatternsFile, includePatternsFile);
|
||||
ReadOnlyCollection<Record> records = GetRecords(rightDirectory, matcher);
|
||||
if (records.Count == 0)
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
if (args[2].EndsWith("input.json") && !File.Exists(args[2])) {
|
||||
File.WriteAllText(args[2], "{}");
|
||||
}
|
||||
string? json = !args[2].EndsWith("input.json") ? null : File.ReadAllText(args[2]);
|
||||
Input input = string.IsNullOrEmpty(json)
|
||||
? Input.Get(args)
|
||||
: JsonSerializer.Deserialize(json, Helper20250519Input.Default.Input)
|
||||
?? throw new Exception();
|
||||
Logic? logic = input.Segments.Length != 6 ? null : Logic.Get(input.Segments);
|
||||
if (logic is null || input.BaseAddresses.Length == 0) {
|
||||
logger.LogInformation($"Invalid input!{Environment.NewLine}{input}");
|
||||
} else {
|
||||
Matcher matcher = GetMatcher(input.ExcludePatternsFile, input.IncludePatternsFile);
|
||||
ReadOnlyCollection<Record> records = GetRecords(input.RightDirectory, matcher);
|
||||
if (records.Count == 0) {
|
||||
logger.LogInformation("No source records");
|
||||
else {
|
||||
string page = args[6];
|
||||
string leftDirectory = Path.GetFullPath(args[2].Split('~')[0]);
|
||||
RelativePath relativePath = new(LeftDirectory: leftDirectory, RightDirectory: rightDirectory, Records: records.ToArray());
|
||||
LiveSync180(logger, logic, baseAddresses, page, relativePath);
|
||||
} else {
|
||||
RelativePath relativePath = new(LeftDirectory: input.LeftDirectory, RightDirectory: input.RightDirectory, Records: records.ToArray());
|
||||
json = JsonSerializer.Serialize(relativePath, Helper20250519RelativePath.Default.RelativePath);
|
||||
if (string.IsNullOrEmpty(json)) {
|
||||
LiveSync180(logger, logic, input.BaseAddresses, input.Page, relativePath);
|
||||
} else {
|
||||
File.WriteAllText(Path.Combine(input.RightDirectory, ".vscode", $"{nameof(RelativePath)}.json"), json);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -197,11 +262,13 @@ internal static partial class Helper20250519 {
|
||||
ReadOnlyCollection<ReadOnlyCollection<string>> collection = Helpers.HelperDirectory.GetFilesCollection(directory, "*", "*");
|
||||
foreach (ReadOnlyCollection<string> c in collection) {
|
||||
foreach (string f in c) {
|
||||
if (!matcher.Match(directory, f).HasMatches)
|
||||
if (!matcher.Match(directory, f).HasMatches) {
|
||||
continue;
|
||||
}
|
||||
fileInfo = new(f);
|
||||
if (fileInfo.Length == 0)
|
||||
if (fileInfo.Length == 0) {
|
||||
continue;
|
||||
}
|
||||
relativePath = Path.GetRelativePath(directory, fileInfo.FullName);
|
||||
record = new(RelativePath: relativePath,
|
||||
Size: fileInfo.Length,
|
||||
@ -216,13 +283,14 @@ internal static partial class Helper20250519 {
|
||||
Review? review;
|
||||
Task<string> response;
|
||||
Task<HttpResponseMessage> httpResponseMessage;
|
||||
StringContent stringContent = new(JsonSerializer.Serialize(relativePath, RelativePathSourceGenerationContext.Default.RelativePath), Encoding.UTF8, "application/json");
|
||||
string json = JsonSerializer.Serialize(relativePath, Helper20250519RelativePath.Default.RelativePath);
|
||||
foreach (string baseAddress in baseAddresses) {
|
||||
if (!baseAddress.StartsWith("http:")) {
|
||||
logger.LogInformation("Not supported URL <{url}>", baseAddress);
|
||||
} else {
|
||||
HttpClient httpClient = new();
|
||||
httpClient.BaseAddress = new(baseAddress);
|
||||
StringContent stringContent = new(json, Encoding.UTF8, "application/json");
|
||||
httpResponseMessage = httpClient.PostAsync(page, stringContent);
|
||||
httpResponseMessage.Wait();
|
||||
if (!httpResponseMessage.Result.IsSuccessStatusCode) {
|
||||
@ -230,7 +298,7 @@ internal static partial class Helper20250519 {
|
||||
} else {
|
||||
response = httpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
response.Wait();
|
||||
review = JsonSerializer.Deserialize(response.Result, ReviewSourceGenerationContext.Default.Review);
|
||||
review = JsonSerializer.Deserialize(response.Result, Helper20250519Review.Default.Review);
|
||||
if (review is null) {
|
||||
logger.LogInformation("Failed to download: <{uniformResourceLocator}>;", httpClient.BaseAddress);
|
||||
continue;
|
||||
@ -242,27 +310,37 @@ internal static partial class Helper20250519 {
|
||||
}
|
||||
|
||||
private static void LiveSync(ILogger<Worker> logger, Logic l, string page, RelativePath relativePath, HttpClient httpClient, Review review) {
|
||||
if (review.NotEqualBut.Length > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Minus && !l.NotEqualBut.Value)
|
||||
if (review.NotEqualBut?.Length > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Minus && !l.NotEqualBut.Value) {
|
||||
logger.LogDebug("Doing nothing with {name}", nameof(Logic.NotEqualBut));
|
||||
if (review.LeftSideOnly.Length > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Minus && !l.LeftSideOnly.Value)
|
||||
}
|
||||
if (review.LeftSideOnly?.Length > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Minus && !l.LeftSideOnly.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.LeftDirectory, (from x in review.LeftSideOnly select x.Left).ToArray().AsReadOnly(), HttpMethod.Delete, delete: false);
|
||||
if (review.LeftSideIsNewer.Length > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.LessThan && !l.LeftSideIsNewer.Value)
|
||||
}
|
||||
if (review.LeftSideIsNewer?.Length > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.LessThan && !l.LeftSideIsNewer.Value) {
|
||||
throw new Exception(); // LiveSync(logger, page, relativePath, httpClient, relativePath.LeftDirectory, (from x in review.LeftSideIsNewer select x.Left).ToArray().AsReadOnly(), HttpMethod.Patch, delete: true);
|
||||
if (review.RightSideIsNewer.Length > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.LessThan && !l.RightSideIsNewer.Value)
|
||||
}
|
||||
if (review.RightSideIsNewer?.Length > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.LessThan && !l.RightSideIsNewer.Value) {
|
||||
throw new Exception(); // LiveSync(logger, page, relativePath, httpClient, relativePath.RightDirectory, (from x in review.RightSideIsNewer select x.Right).ToArray().AsReadOnly(), HttpMethod.Patch, delete: true);
|
||||
if (review.RightSideOnly.Length > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Plus && l.RightSideOnly.Value)
|
||||
}
|
||||
if (review.RightSideOnly?.Length > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Plus && l.RightSideOnly.Value) {
|
||||
throw new Exception(); // LiveSync(logger, page, relativePath, httpClient, relativePath.RightDirectory, (from x in review.RightSideOnly select x.Right).ToArray().AsReadOnly(), HttpMethod.Put, delete: false);
|
||||
if (review.RightSideOnly.Length > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Minus && !l.RightSideOnly.Value)
|
||||
}
|
||||
if (review.RightSideOnly?.Length > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Minus && !l.RightSideOnly.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.RightDirectory, (from x in review.RightSideOnly select x.Right).ToArray().AsReadOnly(), httpMethod: null, delete: true);
|
||||
if (review.LeftSideOnly.Length > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Plus && l.LeftSideOnly.Value)
|
||||
}
|
||||
if (review.LeftSideOnly?.Length > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Plus && l.LeftSideOnly.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.LeftDirectory, (from x in review.LeftSideOnly select x.Left).ToArray().AsReadOnly(), HttpMethod.Get, delete: false);
|
||||
if (review.LeftSideIsNewer.Length > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.GreaterThan && l.LeftSideIsNewer.Value)
|
||||
}
|
||||
if (review.LeftSideIsNewer?.Length > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.GreaterThan && l.LeftSideIsNewer.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.LeftDirectory, (from x in review.LeftSideIsNewer select x.Left).ToArray().AsReadOnly(), HttpMethod.Get, delete: true);
|
||||
if (review.NotEqualBut.Length > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Plus && l.NotEqualBut.Value)
|
||||
}
|
||||
if (review.NotEqualBut?.Length > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Plus && l.NotEqualBut.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.LeftDirectory, (from x in review.NotEqualBut select x.Left).ToArray().AsReadOnly(), HttpMethod.Get, delete: true);
|
||||
if (review.RightSideIsNewer.Length > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.GreaterThan && l.RightSideIsNewer.Value)
|
||||
}
|
||||
if (review.RightSideIsNewer?.Length > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.GreaterThan && l.RightSideIsNewer.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.RightDirectory, (from x in review.RightSideIsNewer select x.Right).ToArray().AsReadOnly(), HttpMethod.Get, delete: true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void LiveSync(ILogger<Worker> logger, string page, RelativePath relativePath, HttpClient httpClient, string directory, ReadOnlyCollection<Record> records, HttpMethod? httpMethod, bool delete) {
|
||||
long sum;
|
||||
@ -308,8 +386,9 @@ internal static partial class Helper20250519 {
|
||||
progressBar.Tick();
|
||||
#endif
|
||||
record = records[i];
|
||||
if (record is null)
|
||||
if (record is null) {
|
||||
continue;
|
||||
}
|
||||
size = GetSizeWithSuffix(record.Size);
|
||||
try {
|
||||
File.Delete(Path.Combine(directory, record.RelativePath));
|
||||
@ -359,9 +438,9 @@ internal static partial class Helper20250519 {
|
||||
throw new NotImplementedException();
|
||||
httpResponseMessage = httpClient.SendAsync(httpRequestMessage);
|
||||
httpResponseMessage.Wait(-1);
|
||||
if (!httpResponseMessage.Result.IsSuccessStatusCode)
|
||||
if (!httpResponseMessage.Result.IsSuccessStatusCode) {
|
||||
logger.LogInformation("Failed to {httpMethod}: <{display}> - {size};", httpMethod, verb.Display, size);
|
||||
else {
|
||||
} else {
|
||||
try {
|
||||
if (httpMethod != HttpMethod.Get) {
|
||||
duration = GetDurationWithSuffix(ticks);
|
||||
@ -401,12 +480,15 @@ internal static partial class Helper20250519 {
|
||||
checkFile = Path.Combine(directory, record.RelativePath);
|
||||
checkFileName = Path.GetFileName(checkFile);
|
||||
checkDirectory = Path.GetDirectoryName(checkFile);
|
||||
if (string.IsNullOrEmpty(checkDirectory))
|
||||
if (string.IsNullOrEmpty(checkDirectory)) {
|
||||
continue;
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
}
|
||||
if (!Directory.Exists(checkDirectory)) {
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
if (File.Exists(checkFile) && new FileInfo(checkFile).Length == 0)
|
||||
}
|
||||
if (File.Exists(checkFile) && new FileInfo(checkFile).Length == 0) {
|
||||
File.Delete(checkFile);
|
||||
}
|
||||
verb = new(Directory: checkDirectory,
|
||||
Display: $"{checkFileName}{Environment.NewLine}{checkDirectory}",
|
||||
File: checkFile,
|
||||
@ -419,26 +501,30 @@ internal static partial class Helper20250519 {
|
||||
}
|
||||
Verb[] sorted = (from l in collection orderby l.Size select l).ToArray();
|
||||
int stop = sorted.Length < 100 ? sorted.Length : 100;
|
||||
for (int i = 0; i < stop; i++)
|
||||
for (int i = 0; i < stop; i++) {
|
||||
results.Add(sorted[i]);
|
||||
for (int i = sorted.Length - 1; i > stop - 1; i--)
|
||||
}
|
||||
for (int i = sorted.Length - 1; i > stop - 1; i--) {
|
||||
results.Add(sorted[i]);
|
||||
if (collection.Count != results.Count)
|
||||
}
|
||||
if (collection.Count != results.Count) {
|
||||
throw new Exception();
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string GetDurationWithSuffix(long ticks) {
|
||||
string result;
|
||||
TimeSpan timeSpan = new(DateTime.Now.Ticks - ticks);
|
||||
if (timeSpan.TotalMilliseconds < 1000)
|
||||
if (timeSpan.TotalMilliseconds < 1000) {
|
||||
result = $"{timeSpan.Milliseconds} ms";
|
||||
else if (timeSpan.TotalMilliseconds < 60000)
|
||||
} else if (timeSpan.TotalMilliseconds < 60000) {
|
||||
result = $"{Math.Floor(timeSpan.TotalSeconds)} s";
|
||||
else if (timeSpan.TotalMilliseconds < 3600000)
|
||||
} else if (timeSpan.TotalMilliseconds < 3600000) {
|
||||
result = $"{Math.Floor(timeSpan.TotalMinutes)} m";
|
||||
else
|
||||
} else {
|
||||
result = $"{Math.Floor(timeSpan.TotalHours)} h";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
184
ADO2025/PI6/Helper-2025-05-21.cs
Normal file
184
ADO2025/PI6/Helper-2025-05-21.cs
Normal file
@ -0,0 +1,184 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250521 {
|
||||
|
||||
[GeneratedRegex(@"[~\-,.0-9]")]
|
||||
private static partial Regex Number();
|
||||
|
||||
[GeneratedRegex(@"[^\u0020-\u007E]")]
|
||||
private static partial Regex ASCII();
|
||||
|
||||
private record Record(string Directory, string FileNameWithoutExtension);
|
||||
|
||||
private record LineCheck(string[] Segments, DateTime TransactionDate, DateTime EffectiveDate) {
|
||||
|
||||
internal static LineCheck Get(int dateLineSegmentCount, string datePattern, string line) {
|
||||
LineCheck result;
|
||||
string[] segments = line.Split(' ');
|
||||
if (segments.Length >= dateLineSegmentCount
|
||||
&& segments[0].Length == datePattern.Length
|
||||
&& segments[1].Length == datePattern.Length
|
||||
&& DateTime.TryParseExact(segments[0], datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime transactionDate)
|
||||
&& DateTime.TryParseExact(segments[1], datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime effectiveDate)) {
|
||||
result = new(Segments: segments, TransactionDate: transactionDate, EffectiveDate: effectiveDate);
|
||||
} else {
|
||||
result = new(Segments: segments, TransactionDate: DateTime.MinValue, EffectiveDate: DateTime.MinValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private record RecordB(int I,
|
||||
DateTime TransactionDate,
|
||||
DateTime EffectiveDate,
|
||||
string Description,
|
||||
decimal WithdrawalOrDeposit,
|
||||
decimal Balance);
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(RecordB[]))]
|
||||
private partial class Helper20250521RecordB : JsonSerializerContext {
|
||||
}
|
||||
|
||||
internal static void MatchDirectory(ILogger<Worker> logger, List<string> args) {
|
||||
Record record;
|
||||
string datePattern = args[5];
|
||||
string searchPattern = args[2];
|
||||
string searchPatternB = args[3];
|
||||
string columns = args[6].Replace('~', ',');
|
||||
int dateLineSegmentCount = int.Parse(args[4]);
|
||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
ReadOnlyDictionary<string, string> keyValuePairs = GetKeyValuePairs(searchPattern, sourceDirectory);
|
||||
MoveMatchDirectory(searchPatternB, keyValuePairs, sourceDirectory);
|
||||
ReadOnlyCollection<RecordB> records = GetRecords(searchPatternB, sourceDirectory, dateLineSegmentCount, datePattern, columns);
|
||||
WriteRecords(sourceDirectory, records);
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, string> GetKeyValuePairs(string searchPattern, string sourceDirectory) {
|
||||
Dictionary<string, string> results = [];
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
foreach (string file in files) {
|
||||
results.Add(Path.GetFileNameWithoutExtension(file), Path.GetDirectoryName(file));
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void MoveMatchDirectory(string searchPatternB, ReadOnlyDictionary<string, string> keyValuePairs, string sourceDirectory) {
|
||||
string checkFile;
|
||||
string fileNameWithoutExtension;
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPatternB, SearchOption.AllDirectories);
|
||||
foreach (string file in files) {
|
||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
|
||||
if (!keyValuePairs.TryGetValue(fileNameWithoutExtension, out string? match))
|
||||
continue;
|
||||
checkFile = Path.Combine(match, Path.GetFileName(file));
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
File.Move(file, checkFile);
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<RecordB> GetRecords(string searchPatternB, string sourceDirectory, int dateLineSegmentCount, string datePattern, string columns) {
|
||||
List<RecordB> results = [];
|
||||
string line;
|
||||
string[] lines;
|
||||
RecordB? record;
|
||||
LineCheck lineCheck;
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPatternB, SearchOption.AllDirectories);
|
||||
foreach (string file in files) {
|
||||
lines = File.ReadAllLines(file);
|
||||
for (int i = 0; i < lines.Length; i++) {
|
||||
line = lines[i];
|
||||
if (string.IsNullOrEmpty(line)) {
|
||||
continue;
|
||||
}
|
||||
lineCheck = LineCheck.Get(dateLineSegmentCount, datePattern, line);
|
||||
if (lineCheck.EffectiveDate == DateTime.MinValue || lineCheck.TransactionDate == DateTime.MinValue) {
|
||||
continue;
|
||||
} else {
|
||||
record = GetRecord(dateLineSegmentCount, datePattern, lines, i, lineCheck.Segments, lineCheck.TransactionDate, lineCheck.EffectiveDate);
|
||||
if (record is not null) {
|
||||
i = record.I;
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static RecordB? GetRecord(int dateLineSegmentCount, string datePattern, string[] lines, int i, string[] segments, DateTime transactionDate, DateTime effectiveDate) {
|
||||
RecordB? result = null;
|
||||
string line;
|
||||
RecordB record;
|
||||
LineCheck lineCheck;
|
||||
List<string> collection = [];
|
||||
for (int j = i + 1; j < lines.Length; j++) {
|
||||
line = lines[j];
|
||||
if (string.IsNullOrEmpty(line)) {
|
||||
continue;
|
||||
}
|
||||
lineCheck = LineCheck.Get(dateLineSegmentCount, datePattern, line);
|
||||
if (lineCheck.EffectiveDate == DateTime.MinValue || lineCheck.TransactionDate == DateTime.MinValue) {
|
||||
collection.Add(line);
|
||||
} else {
|
||||
if (lineCheck.Segments.Length > dateLineSegmentCount) {
|
||||
collection.Insert(0, string.Join(' ', lineCheck.Segments.Skip(2)));
|
||||
}
|
||||
result = GetRecord(transactionDate, effectiveDate, collection.AsReadOnly(), j - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result is null && collection.Count > 0) {
|
||||
result = GetRecord(transactionDate, effectiveDate, collection.AsReadOnly(), lines.Length - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static RecordB GetRecord(DateTime transactionDate, DateTime effectiveDate, ReadOnlyCollection<string> collection, int i) {
|
||||
RecordB? result;
|
||||
List<string> verified = [];
|
||||
foreach (string check in collection) {
|
||||
if (Number().Replace(check, string.Empty).Length != 0) {
|
||||
verified.Clear();
|
||||
} else {
|
||||
verified.Add(check);
|
||||
}
|
||||
if (verified.Count == 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (verified.Count != 2) {
|
||||
result = null;
|
||||
} else {
|
||||
decimal balance = decimal.Parse(verified[^1]);
|
||||
decimal withdrawalOrDeposit = decimal.Parse(verified[^2]);
|
||||
string description = ASCII().Replace(string.Join(' ', collection.SkipLast(2)), string.Empty);
|
||||
result = new(I: i,
|
||||
TransactionDate: transactionDate,
|
||||
EffectiveDate: effectiveDate,
|
||||
Description: description,
|
||||
WithdrawalOrDeposit: withdrawalOrDeposit,
|
||||
Balance: balance);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void WriteRecords(string sourceDirectory, ReadOnlyCollection<RecordB> records) {
|
||||
string json = JsonSerializer.Serialize(records.ToArray(), Helper20250521RecordB.Default.RecordBArray);
|
||||
string sourceDirectoryVsCode = Path.Combine(sourceDirectory, ".vscode");
|
||||
if (!Directory.Exists(sourceDirectoryVsCode))
|
||||
_ = Directory.CreateDirectory(sourceDirectoryVsCode);
|
||||
File.WriteAllText(Path.Combine(sourceDirectoryVsCode, $"{DateTime.Now.Ticks}.json"), json);
|
||||
}
|
||||
|
||||
}
|
394
ADO2025/PI6/Helper-2025-06-01.cs
Normal file
394
ADO2025/PI6/Helper-2025-06-01.cs
Normal file
@ -0,0 +1,394 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
using IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250601 {
|
||||
|
||||
private static readonly bool _IsEnvironment_Development = false;
|
||||
|
||||
private record Record(string Text, string Host, int Port, string[] Segments, bool StateContainsDisabled);
|
||||
|
||||
private record Status(string CellInstanceName,
|
||||
string CommunicationState,
|
||||
string CurrentActiveVersion,
|
||||
string CurrentHost,
|
||||
string ErrorDescription,
|
||||
string Host,
|
||||
string IsReadyForRestart,
|
||||
string NPort,
|
||||
int Port,
|
||||
string StartTime,
|
||||
string Startable,
|
||||
string State,
|
||||
string StopTime,
|
||||
string Text);
|
||||
|
||||
internal static void EquipmentAutomationFrameworkStatus(ILogger<Worker> logger, List<string> args) {
|
||||
Status status;
|
||||
Record? record;
|
||||
List<string[]> messages;
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
string[] cellInstanceNames = args[2].Split('~');
|
||||
Dictionary<string, Record> records;
|
||||
if (_IsEnvironment_Development) {
|
||||
records = GetEquipmentAutomationFrameworkCellInstanceStatus(development: true, staging: false, production: false);
|
||||
} else {
|
||||
records = GetEquipmentAutomationFrameworkCellInstanceStatus(development: false, staging: true, production: true);
|
||||
}
|
||||
foreach (string cellInstanceName in cellInstanceNames) {
|
||||
if (!records.TryGetValue(cellInstanceName, out record)) {
|
||||
logger.LogWarning("{cellInstance} not found!", cellInstanceName);
|
||||
continue;
|
||||
}
|
||||
status = EquipmentAutomationFrameworkCellInstanceStatus(cellInstanceName, record);
|
||||
logger.LogInformation("{host}) {cellInstanceName} => {status}", record.Host, cellInstanceName, status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, Record> GetEquipmentAutomationFrameworkCellInstanceStatus(bool development, bool staging, bool production) {
|
||||
Dictionary<string, Record> results = [];
|
||||
string key;
|
||||
string host;
|
||||
string text;
|
||||
string state;
|
||||
string response;
|
||||
bool stop = false;
|
||||
string[] segments;
|
||||
string[] cellNames;
|
||||
byte[] responseBytes;
|
||||
string responseAfter;
|
||||
#pragma warning disable SYSLIB0014
|
||||
WebClient webClient = new();
|
||||
#pragma warning restore SYSLIB0014
|
||||
string disabled = "Disabled";
|
||||
UnicodeCategory unicodeCategory;
|
||||
StringBuilder stringBuilder = new();
|
||||
EquipmentAutomationFrameworkCellInstanceParseCheck();
|
||||
Dictionary<char, char> unicodeReplaces = GetUnicodeReplaces();
|
||||
List<UnicodeCategory> unicodeCategories = GetUnicodeCategory();
|
||||
ReadOnlyCollection<string> urls = GetUrls(development, staging, production);
|
||||
// Dictionary<UnicodeCategory, List<char>> unicodeCategoriesList = new Dictionary<UnicodeCategory, List<char>>();
|
||||
byte[] bodyBytes = [86, 2, 11, 1, 115, 4, 11, 1, 97, 6, 86, 8, 68, 10, 30, 0, 130, 153, 48, 104, 116, 116, 112, 58, 47, 47, 116, 101, 109, 112, 117, 114, 105, 46, 111, 114, 103, 47, 73, 83, 116, 97, 116, 117, 115, 81, 117, 101, 114, 121, 47, 71, 101, 116, 70, 97, 99, 116, 111, 114, 121, 83, 116, 97, 116, 117, 115, 68, 26, 173, 181, 241, 2, 149, 65, 209, 208, 66, 143, 234, 233, 157, 246, 118, 78, 238, 68, 44, 68, 42, 171, 20, 1, 68, 12, 30, 0, 130, 153, 49, 104, 116, 116, 112, 58, 47, 47, 101, 97, 102, 45, 112, 114, 111, 100, 46, 109, 101, 115, 46, 105, 110, 102, 105, 110, 101, 111, 110, 46, 99, 111, 109, 58, 57, 48, 48, 51, 47, 83, 116, 97, 116, 117, 115, 81, 117, 101, 114, 121, 1, 86, 14, 64, 16, 71, 101, 116, 70, 97, 99, 116, 111, 114, 121, 83, 116, 97, 116, 117, 115, 8, 19, 104, 116, 116, 112, 58, 47, 47, 116, 101, 109, 112, 117, 114, 105, 46, 111, 114, 103, 47, 64, 16, 105, 110, 99, 108, 117, 100, 101, 65, 103, 101, 110, 116, 76, 105, 115, 116, 135, 64, 17, 105, 110, 99, 108, 117, 100, 101, 83, 116, 97, 116, 117, 115, 76, 105, 115, 116, 135, 64, 23, 101, 120, 116, 101, 110, 100, 101, 100, 83, 116, 97, 116, 117, 115, 67, 101, 108, 108, 78, 97, 109, 101, 115, 9, 1, 98, 57, 104, 116, 116, 112, 58, 47, 47, 115, 99, 104, 101, 109, 97, 115, 46, 109, 105, 99, 114, 111, 115, 111, 102, 116, 46, 99, 111, 109, 47, 50, 48, 48, 51, 47, 49, 48, 47, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 47, 65, 114, 114, 97, 121, 115, 9, 1, 105, 41, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97, 45, 105, 110, 115, 116, 97, 110, 99, 101, 95, 6, 115, 116, 114, 105, 110, 103, 153, 20, 66, 73, 79, 82, 65, 68, 53, 95, 70, 105, 108, 101, 65, 114, 99, 104, 105, 118, 101, 114, 1, 1, 1, 1];
|
||||
foreach (string url in urls) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
segments = url.Split(':');
|
||||
host = segments[0];
|
||||
if (segments.Length == 0 || !int.TryParse(segments[1], out int port)) {
|
||||
port = 80;
|
||||
}
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+msbin1");
|
||||
responseBytes = webClient.UploadData($"http://{host}:{port}/StatusQuery", bodyBytes);
|
||||
// File.WriteAllText(@"L:\Tmp\a.txt", BitConverter.ToString(responseBytes));
|
||||
response = Encoding.UTF8.GetString(responseBytes);
|
||||
foreach (char c in response) {
|
||||
unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
|
||||
if (unicodeCategory == UnicodeCategory.Control && unicodeReplaces.ContainsKey(c)) {
|
||||
_ = stringBuilder.Append(unicodeReplaces[c]);
|
||||
} else if (unicodeCategories.Contains(unicodeCategory)) {
|
||||
_ = stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
responseAfter = stringBuilder.ToString();
|
||||
cellNames = responseAfter.Split(new string[] { "CellName" }, StringSplitOptions.None);
|
||||
foreach (string segment in cellNames) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
key = string.Empty;
|
||||
state = string.Empty;
|
||||
segments = segment.Split(new string[] { "WindowsName" }, StringSplitOptions.None);
|
||||
if (segments.Length != 2) {
|
||||
continue;
|
||||
}
|
||||
text = segments[0];
|
||||
segments = text.Replace('\r', ' ').Replace('\n', ' ').Split(' ');
|
||||
for (int i = 0; i < segments.Length - 3; i++) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(segments[i]) && string.IsNullOrEmpty(key)) {
|
||||
key = segments[i].Trim();
|
||||
} else if (segments[i].StartsWith("State")) {
|
||||
state = segments[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (key.EndsWith("a")) {
|
||||
key = key[..^1];
|
||||
}
|
||||
if (!results.ContainsKey(key)) {
|
||||
results.Add(key, new Record(Text: text, Host: host, Port: port, Segments: segments, StateContainsDisabled: state.Contains(disabled)));
|
||||
} else if (results[key].StateContainsDisabled) {
|
||||
results[key] = new Record(Text: text, Host: host, Port: port, Segments: segments, StateContainsDisabled: state.Contains(disabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<string> GetUrls(bool development, bool staging, bool production) {
|
||||
List<string> results = [];
|
||||
if (development) {
|
||||
results.Add("eaf-dev.mes.infineon.com:9003");
|
||||
}
|
||||
if (staging) {
|
||||
results.Add("eaf-staging.mes.infineon.com:9003");
|
||||
}
|
||||
if (production) {
|
||||
results.Add("eaf-prod.mes.infineon.com:9003");
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static List<UnicodeCategory> GetUnicodeCategory() {
|
||||
List<UnicodeCategory> unicodeCategories = [
|
||||
// UnicodeCategory.Control, // 33 - <20>
|
||||
UnicodeCategory.UppercaseLetter, // 25 - ABCDEFGHIJKLMNOPQRSTUVWXY
|
||||
UnicodeCategory.LowercaseLetter, // 25 - abcdefghiklmnopqrstuvwxyz
|
||||
UnicodeCategory.DecimalDigitNumber, // 10 - 0123456789
|
||||
UnicodeCategory.OtherPunctuation, // 10 - !"#%&,./:@
|
||||
UnicodeCategory.ClosePunctuation, // 2 - )]
|
||||
UnicodeCategory.MathSymbol, // 2 - |؈
|
||||
UnicodeCategory.OpenPunctuation, // 2 - ([
|
||||
// UnicodeCategory.OtherSymbol, // 1 - <20>
|
||||
UnicodeCategory.DashPunctuation, // 1 - -
|
||||
UnicodeCategory.ConnectorPunctuation, // 1 - _
|
||||
UnicodeCategory.ModifierSymbol, // 1 - `
|
||||
UnicodeCategory.NonSpacingMark, // 1 - ̵
|
||||
UnicodeCategory.SpaceSeparator, // 1 -
|
||||
UnicodeCategory.CurrencySymbol, // 1 - $
|
||||
];
|
||||
return unicodeCategories;
|
||||
}
|
||||
|
||||
private static void EquipmentAutomationFrameworkCellInstanceParseCheck() {
|
||||
Envelope? envelope;
|
||||
string xmlStart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:6eb7a538-0b2b-4d04-8f2a-ab50e1e5338a</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlStart891 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/StartAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:38977fa4-262a-42fb-8df7-d8d3074820b2</a:RelatesTo></s:Header><s:Body><StartAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlStart748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlStart707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string xmlStop621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:97f7aeb4-015f-440b-b0ff-a2a5aa4f4ab9</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlStop889 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/StopAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:04b8b0ea-8576-4756-b456-8a817cd10826</a:RelatesTo></s:Header><s:Body><StopAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlStop748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlStop707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string xmlRestart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:e228a621-e7ab-4ebf-97ba-5571cb5f4ad7</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlRestart895 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/RestartAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:efaeaf12-4aa0-4cd1-8296-05019e47261a</a:RelatesTo></s:Header><s:Body><RestartAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlRestart748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlRestart707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string[] xmlSets = [xmlStart621, xmlStart891, xmlStart748, xmlStart707, xmlStop621, xmlStop889, xmlStop748, xmlStop707, xmlRestart621, xmlRestart895, xmlRestart748, xmlRestart707];
|
||||
foreach (string xmlSet in xmlSets) {
|
||||
envelope = ParseXML<Envelope>(xmlSet, throwExceptions: true);
|
||||
}
|
||||
}
|
||||
|
||||
private static T? ParseXML<T>(string value, bool throwExceptions) where T : class {
|
||||
object? result = null;
|
||||
try {
|
||||
Stream stream = ToStream(value.Trim());
|
||||
XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
|
||||
#pragma warning disable IL2026, IL2090
|
||||
XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes());
|
||||
result = xmlSerializer.Deserialize(xmlReader);
|
||||
#pragma warning restore IL2026, IL2090
|
||||
stream.Dispose();
|
||||
} catch (Exception) {
|
||||
if (throwExceptions) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return result as T;
|
||||
}
|
||||
|
||||
private static Stream ToStream(string value) {
|
||||
MemoryStream memoryStream = new();
|
||||
StreamWriter streamWriter = new(memoryStream);
|
||||
streamWriter.Write(value);
|
||||
streamWriter.Flush();
|
||||
memoryStream.Position = 0;
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
private static Dictionary<char, char> GetUnicodeReplaces() {
|
||||
Dictionary<char, char> results = new() {
|
||||
{ '\u0000', ' ' },
|
||||
{ '\u0001', ' ' },
|
||||
{ '\u0002', ' ' },
|
||||
{ '\u0003', ' ' },
|
||||
{ '\u0004', ' ' },
|
||||
{ '\u0005', ' ' },
|
||||
{ '\u0006', ' ' },
|
||||
{ '\u0007', ' ' },
|
||||
{ '\u0008', ' ' },
|
||||
{ '\u0009', '\t' },
|
||||
{ '\u000A', '\r' },
|
||||
{ '\u000B', '\r' },
|
||||
{ '\u000C', '\t' },
|
||||
{ '\u000D', '\r' },
|
||||
{ '\u000E', ' ' },
|
||||
{ '\u000F', ' ' },
|
||||
{ '\u0010', ' ' },
|
||||
{ '\u0011', ' ' },
|
||||
{ '\u0012', ' ' },
|
||||
{ '\u0013', ' ' },
|
||||
{ '\u0014', ' ' },
|
||||
{ '\u0015', ' ' },
|
||||
{ '\u0016', ' ' },
|
||||
{ '\u0017', ' ' },
|
||||
{ '\u0018', ' ' },
|
||||
{ '\u0019', ' ' },
|
||||
{ '\u001A', ' ' },
|
||||
{ '\u001B', ' ' },
|
||||
{ '\u001C', '\r' },
|
||||
{ '\u001D', '\t' },
|
||||
{ '\u001E', '\t' },
|
||||
{ '\u001F', '\t' },
|
||||
{ '\u007F', ' ' },
|
||||
// C1
|
||||
{ '\u0080', '\t' },
|
||||
{ '\u0081', ' ' },
|
||||
{ '\u0082', ' ' },
|
||||
{ '\u0083', ' ' },
|
||||
{ '\u0084', ' ' },
|
||||
{ '\u0085', '\r' },
|
||||
{ '\u0086', ' ' },
|
||||
{ '\u0087', ' ' },
|
||||
{ '\u0088', '\t' },
|
||||
{ '\u0089', '\t' },
|
||||
{ '\u008A', '\t' },
|
||||
{ '\u008B', '\r' },
|
||||
{ '\u008C', ' ' },
|
||||
{ '\u008D', ' ' },
|
||||
{ '\u008E', ' ' },
|
||||
{ '\u008F', ' ' },
|
||||
{ '\u0090', ' ' },
|
||||
{ '\u0091', ' ' },
|
||||
{ '\u0092', ' ' },
|
||||
{ '\u0093', ' ' },
|
||||
{ '\u0094', ' ' },
|
||||
{ '\u0095', ' ' },
|
||||
{ '\u0096', ' ' },
|
||||
{ '\u0097', ' ' },
|
||||
{ '\u0098', ' ' },
|
||||
{ '\u0099', ' ' },
|
||||
{ '\u009A', ' ' },
|
||||
{ '\u009B', ' ' },
|
||||
{ '\u009C', ' ' },
|
||||
{ '\u009D', ' ' },
|
||||
{ '\u009E', ' ' },
|
||||
{ '\u009F', ' ' }
|
||||
};
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Status EquipmentAutomationFrameworkCellInstanceStatus(string cellInstanceName, Record record) {
|
||||
Status result;
|
||||
bool stop = false;
|
||||
string state = string.Empty;
|
||||
string stopTime = string.Empty;
|
||||
string startTime = string.Empty;
|
||||
string startable = string.Empty;
|
||||
string currentHost = string.Empty;
|
||||
string errorDescription = string.Empty;
|
||||
string isReadyForRestart = string.Empty;
|
||||
string communicationState = string.Empty;
|
||||
string currentActiveVersion = string.Empty;
|
||||
for (int i = 0; i < record.Segments.Length - 3; i++) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
if (string.IsNullOrEmpty(state) && record.Segments[i].StartsWith("State")) {
|
||||
state = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(startable) && record.Segments[i].Contains("Startable")) {
|
||||
startable = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(stopTime) && record.Segments[i].StartsWith("StopTime")) {
|
||||
stopTime = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(currentHost) && record.Segments[i].Contains("CurrentHost")) {
|
||||
currentHost = $"{record.Segments[i]} {record.Segments[i + 1]} {record.Segments[i + 2]}";
|
||||
} else if (string.IsNullOrEmpty(errorDescription) && record.Segments[i].StartsWith("ErrorDescription")) {
|
||||
errorDescription = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(communicationState) && record.Segments[i].StartsWith("CommunicationState")) {
|
||||
communicationState = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(isReadyForRestart) && record.Segments[i].StartsWith("IsReadyForRestart")) {
|
||||
isReadyForRestart = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(currentActiveVersion) && record.Segments[i].Contains("CurrentActiveVersion")) {
|
||||
currentActiveVersion = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(startTime) && record.Segments[i].Contains("StartTime")) {
|
||||
startTime = $"{record.Segments[i + 1]} {record.Segments[i + 2]} {record.Segments[i + 3]}".Split('\t')[0];
|
||||
}
|
||||
}
|
||||
if (errorDescription != "a") {
|
||||
string[] segments = record.Text.Split(new string[] { "ErrorDescription" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (segments.Length > 1) {
|
||||
segments = segments[1].Split(new string[] { "Info" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
errorDescription = segments[0].Trim();
|
||||
}
|
||||
}
|
||||
string nPort;
|
||||
Dictionary<string, string> nPorts = GetnPorts();
|
||||
if (!nPorts.ContainsKey(cellInstanceName)) {
|
||||
nPort = string.Empty;
|
||||
} else {
|
||||
nPort = nPorts[cellInstanceName];
|
||||
}
|
||||
if (state.EndsWith("a")) {
|
||||
state = state[0..^1];
|
||||
}
|
||||
if (state == "Running" && communicationState == "Not") {
|
||||
state = "Warning";
|
||||
}
|
||||
result = new(Host: record.Host,
|
||||
Port: record.Port,
|
||||
Text: record.Text,
|
||||
NPort: nPort,
|
||||
State: state,
|
||||
CellInstanceName: cellInstanceName,
|
||||
StopTime: stopTime,
|
||||
StartTime: startTime,
|
||||
Startable: startable,
|
||||
CurrentHost: currentHost,
|
||||
ErrorDescription: errorDescription,
|
||||
IsReadyForRestart: isReadyForRestart,
|
||||
CommunicationState: communicationState,
|
||||
CurrentActiveVersion: currentActiveVersion);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> GetnPorts() {
|
||||
Dictionary<string, string> results = new() {
|
||||
{ "TENCOR1", "10.95.192.31" },
|
||||
{ "TENCOR2", "10.95.192.32" },
|
||||
{ "TENCOR3", "10.95.192.33" },
|
||||
{ "HGCV1", "10.95.192.34" },
|
||||
{ "HGCV2", "10.95.154.17" },
|
||||
{ "HGCV3", "10.95.192.36" },
|
||||
{ "BIORAD2", "10.95.192.37" },
|
||||
{ "BIORAD3", "10.95.192.38" },
|
||||
{ "CDE2", "10.95.192.39" },
|
||||
{ "CDE3", "10.95.154.19" },
|
||||
{ "CDE5", "10.95.192.40" },
|
||||
{ "SPARE-1", "10.95.192.47" },
|
||||
{ "SPARE-2", "10.95.192.48" },
|
||||
{ "SPARE-3", "10.95.192.49" },
|
||||
{ "SPARE-4", "10.95.192.50" },
|
||||
{ "SPARE-5", "10.95.192.51" },
|
||||
};
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
545
ADO2025/PI6/Helper-2025-06-02.cs
Normal file
545
ADO2025/PI6/Helper-2025-06-02.cs
Normal file
@ -0,0 +1,545 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
using IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250602 {
|
||||
|
||||
private record Record(string Text, string Host, int Port, string[] Segments, bool StateContainsDisabled);
|
||||
|
||||
private record Status(string CellInstanceName,
|
||||
string CommunicationState,
|
||||
string CurrentActiveVersion,
|
||||
string CurrentHost,
|
||||
string ErrorDescription,
|
||||
string Host,
|
||||
string IsReadyForRestart,
|
||||
string NPort,
|
||||
int Port,
|
||||
string StartTime,
|
||||
string Startable,
|
||||
string State,
|
||||
string StopTime,
|
||||
string Text);
|
||||
|
||||
internal static void EquipmentAutomationFrameworkCellInstanceStateImageVerbIf(ILogger<Worker> logger, List<string> args) {
|
||||
string path;
|
||||
Status status;
|
||||
Record? record;
|
||||
string verbBy = args[2];
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
logger.LogInformation(args[3]);
|
||||
string[] cellInstanceNames = args[3].Split('~');
|
||||
Dictionary<string, Record> records = GetEquipmentAutomationFrameworkCellInstanceStatus(development: false, staging: false, production: true);
|
||||
foreach (string cellInstanceName in cellInstanceNames) {
|
||||
if (!records.TryGetValue(cellInstanceName, out record)) {
|
||||
logger.LogWarning("{cellInstance} not found!", cellInstanceName);
|
||||
continue;
|
||||
}
|
||||
if (records[cellInstanceName].StateContainsDisabled) {
|
||||
logger.LogWarning("{cellInstance} not found!", cellInstanceName);
|
||||
}
|
||||
status = GetEquipmentAutomationFrameworkCellInstanceStateImageVerbIf(logger, verbBy, cellInstanceName, record);
|
||||
path = $"/images/{cellInstanceName}_{status.State}.jpg";
|
||||
logger.LogInformation("{host}) {cellInstanceName} => {state} <{path}>", record.Host, cellInstanceName, status.State, path);
|
||||
}
|
||||
}
|
||||
|
||||
private static Status GetEquipmentAutomationFrameworkCellInstanceStateImageVerbIf(ILogger<Worker> logger, string verbBy, string cellInstanceName, Record record) {
|
||||
Status result;
|
||||
Dictionary<string, DateTime> equipmentAutomationFrameworkTriggers = [];
|
||||
if (!equipmentAutomationFrameworkTriggers.ContainsKey(cellInstanceName)) {
|
||||
equipmentAutomationFrameworkTriggers.Add(cellInstanceName, DateTime.MinValue);
|
||||
}
|
||||
result = EquipmentAutomationFrameworkCellInstanceStatus(cellInstanceName, record);
|
||||
if (equipmentAutomationFrameworkTriggers[cellInstanceName] < DateTime.Now.AddSeconds(-60)) {
|
||||
if (result.State == "Offline") {
|
||||
EquipmentAutomationFrameworkCellInstanceStart(record.Host, record.Port, cellInstanceName, verbBy);
|
||||
logger.LogInformation("Start invoked for {cellName}", cellInstanceName);
|
||||
} else if (result.State == "Warning") {
|
||||
EquipmentAutomationFrameworkCellInstanceRestart(record.Host, record.Port, cellInstanceName, verbBy);
|
||||
logger.LogInformation("Restart invoked for {cellName}", cellInstanceName);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Dictionary<string, Record> GetEquipmentAutomationFrameworkCellInstanceStatus(bool development, bool staging, bool production) {
|
||||
Dictionary<string, Record> results = [];
|
||||
string key;
|
||||
string host;
|
||||
string text;
|
||||
string state;
|
||||
string response;
|
||||
bool stop = false;
|
||||
string[] segments;
|
||||
string[] cellNames;
|
||||
byte[] responseBytes;
|
||||
string responseAfter;
|
||||
#pragma warning disable SYSLIB0014
|
||||
WebClient webClient = new();
|
||||
#pragma warning restore SYSLIB0014
|
||||
string disabled = "Disabled";
|
||||
UnicodeCategory unicodeCategory;
|
||||
StringBuilder stringBuilder = new();
|
||||
EquipmentAutomationFrameworkCellInstanceParseCheck();
|
||||
Dictionary<char, char> unicodeReplaces = GetUnicodeReplaces();
|
||||
List<UnicodeCategory> unicodeCategories = GetUnicodeCategory();
|
||||
ReadOnlyCollection<string> urls = GetUrls(development, staging, production);
|
||||
// Dictionary<UnicodeCategory, List<char>> unicodeCategoriesList = new Dictionary<UnicodeCategory, List<char>>();
|
||||
byte[] bodyBytes = [86, 2, 11, 1, 115, 4, 11, 1, 97, 6, 86, 8, 68, 10, 30, 0, 130, 153, 48, 104, 116, 116, 112, 58, 47, 47, 116, 101, 109, 112, 117, 114, 105, 46, 111, 114, 103, 47, 73, 83, 116, 97, 116, 117, 115, 81, 117, 101, 114, 121, 47, 71, 101, 116, 70, 97, 99, 116, 111, 114, 121, 83, 116, 97, 116, 117, 115, 68, 26, 173, 181, 241, 2, 149, 65, 209, 208, 66, 143, 234, 233, 157, 246, 118, 78, 238, 68, 44, 68, 42, 171, 20, 1, 68, 12, 30, 0, 130, 153, 49, 104, 116, 116, 112, 58, 47, 47, 101, 97, 102, 45, 112, 114, 111, 100, 46, 109, 101, 115, 46, 105, 110, 102, 105, 110, 101, 111, 110, 46, 99, 111, 109, 58, 57, 48, 48, 51, 47, 83, 116, 97, 116, 117, 115, 81, 117, 101, 114, 121, 1, 86, 14, 64, 16, 71, 101, 116, 70, 97, 99, 116, 111, 114, 121, 83, 116, 97, 116, 117, 115, 8, 19, 104, 116, 116, 112, 58, 47, 47, 116, 101, 109, 112, 117, 114, 105, 46, 111, 114, 103, 47, 64, 16, 105, 110, 99, 108, 117, 100, 101, 65, 103, 101, 110, 116, 76, 105, 115, 116, 135, 64, 17, 105, 110, 99, 108, 117, 100, 101, 83, 116, 97, 116, 117, 115, 76, 105, 115, 116, 135, 64, 23, 101, 120, 116, 101, 110, 100, 101, 100, 83, 116, 97, 116, 117, 115, 67, 101, 108, 108, 78, 97, 109, 101, 115, 9, 1, 98, 57, 104, 116, 116, 112, 58, 47, 47, 115, 99, 104, 101, 109, 97, 115, 46, 109, 105, 99, 114, 111, 115, 111, 102, 116, 46, 99, 111, 109, 47, 50, 48, 48, 51, 47, 49, 48, 47, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 47, 65, 114, 114, 97, 121, 115, 9, 1, 105, 41, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97, 45, 105, 110, 115, 116, 97, 110, 99, 101, 95, 6, 115, 116, 114, 105, 110, 103, 153, 20, 66, 73, 79, 82, 65, 68, 53, 95, 70, 105, 108, 101, 65, 114, 99, 104, 105, 118, 101, 114, 1, 1, 1, 1];
|
||||
foreach (string url in urls) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
segments = url.Split(':');
|
||||
host = segments[0];
|
||||
if (segments.Length == 0 || !int.TryParse(segments[1], out int port)) {
|
||||
port = 80;
|
||||
}
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+msbin1");
|
||||
responseBytes = webClient.UploadData($"http://{host}:{port}/StatusQuery", bodyBytes);
|
||||
// File.WriteAllText(@"L:\Tmp\a.txt", BitConverter.ToString(responseBytes));
|
||||
response = Encoding.UTF8.GetString(responseBytes);
|
||||
foreach (char c in response) {
|
||||
unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
|
||||
if (unicodeCategory == UnicodeCategory.Control && unicodeReplaces.ContainsKey(c)) {
|
||||
_ = stringBuilder.Append(unicodeReplaces[c]);
|
||||
} else if (unicodeCategories.Contains(unicodeCategory)) {
|
||||
_ = stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
responseAfter = stringBuilder.ToString();
|
||||
cellNames = responseAfter.Split(new string[] { "CellName" }, StringSplitOptions.None);
|
||||
foreach (string segment in cellNames) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
key = string.Empty;
|
||||
state = string.Empty;
|
||||
segments = segment.Split(new string[] { "WindowsName" }, StringSplitOptions.None);
|
||||
if (segments.Length != 2) {
|
||||
continue;
|
||||
}
|
||||
text = segments[0];
|
||||
segments = text.Replace('\r', ' ').Replace('\n', ' ').Split(' ');
|
||||
for (int i = 0; i < segments.Length - 3; i++) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(segments[i]) && string.IsNullOrEmpty(key)) {
|
||||
key = segments[i].Trim();
|
||||
} else if (segments[i].StartsWith("State")) {
|
||||
state = segments[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (key.EndsWith("a")) {
|
||||
key = key[..^1];
|
||||
}
|
||||
if (!results.ContainsKey(key)) {
|
||||
results.Add(key, new Record(Text: text, Host: host, Port: port, Segments: segments, StateContainsDisabled: state.Contains(disabled)));
|
||||
} else if (results[key].StateContainsDisabled) {
|
||||
results[key] = new Record(Text: text, Host: host, Port: port, Segments: segments, StateContainsDisabled: state.Contains(disabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<string> GetUrls(bool development, bool staging, bool production) {
|
||||
List<string> results = [];
|
||||
if (development) {
|
||||
results.Add("eaf-dev.mes.infineon.com:9003");
|
||||
}
|
||||
if (staging) {
|
||||
results.Add("eaf-staging.mes.infineon.com:9003");
|
||||
}
|
||||
if (production) {
|
||||
results.Add("eaf-prod.mes.infineon.com:9003");
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static List<UnicodeCategory> GetUnicodeCategory() {
|
||||
List<UnicodeCategory> unicodeCategories = [
|
||||
// UnicodeCategory.Control, // 33 - <20>
|
||||
UnicodeCategory.UppercaseLetter, // 25 - ABCDEFGHIJKLMNOPQRSTUVWXY
|
||||
UnicodeCategory.LowercaseLetter, // 25 - abcdefghiklmnopqrstuvwxyz
|
||||
UnicodeCategory.DecimalDigitNumber, // 10 - 0123456789
|
||||
UnicodeCategory.OtherPunctuation, // 10 - !"#%&,./:@
|
||||
UnicodeCategory.ClosePunctuation, // 2 - )]
|
||||
UnicodeCategory.MathSymbol, // 2 - |؈
|
||||
UnicodeCategory.OpenPunctuation, // 2 - ([
|
||||
// UnicodeCategory.OtherSymbol, // 1 - <20>
|
||||
UnicodeCategory.DashPunctuation, // 1 - -
|
||||
UnicodeCategory.ConnectorPunctuation, // 1 - _
|
||||
UnicodeCategory.ModifierSymbol, // 1 - `
|
||||
UnicodeCategory.NonSpacingMark, // 1 - ̵
|
||||
UnicodeCategory.SpaceSeparator, // 1 -
|
||||
UnicodeCategory.CurrencySymbol, // 1 - $
|
||||
];
|
||||
return unicodeCategories;
|
||||
}
|
||||
|
||||
private static void EquipmentAutomationFrameworkCellInstanceParseCheck() {
|
||||
Envelope? envelope;
|
||||
string xmlStart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:6eb7a538-0b2b-4d04-8f2a-ab50e1e5338a</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlStart891 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/StartAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:38977fa4-262a-42fb-8df7-d8d3074820b2</a:RelatesTo></s:Header><s:Body><StartAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlStart748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlStart707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string xmlStop621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:97f7aeb4-015f-440b-b0ff-a2a5aa4f4ab9</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlStop889 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/StopAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:04b8b0ea-8576-4756-b456-8a817cd10826</a:RelatesTo></s:Header><s:Body><StopAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlStop748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlStop707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string xmlRestart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:e228a621-e7ab-4ebf-97ba-5571cb5f4ad7</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlRestart895 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/RestartAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:efaeaf12-4aa0-4cd1-8296-05019e47261a</a:RelatesTo></s:Header><s:Body><RestartAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlRestart748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlRestart707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string[] xmlSets = [xmlStart621, xmlStart891, xmlStart748, xmlStart707, xmlStop621, xmlStop889, xmlStop748, xmlStop707, xmlRestart621, xmlRestart895, xmlRestart748, xmlRestart707];
|
||||
foreach (string xmlSet in xmlSets) {
|
||||
envelope = ParseXML<Envelope>(xmlSet, throwExceptions: true);
|
||||
}
|
||||
}
|
||||
|
||||
private static T? ParseXML<T>(string value, bool throwExceptions) where T : class {
|
||||
object? result = null;
|
||||
try {
|
||||
Stream stream = ToStream(value.Trim());
|
||||
XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
|
||||
#pragma warning disable IL2026, IL2090
|
||||
XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes());
|
||||
result = xmlSerializer.Deserialize(xmlReader);
|
||||
#pragma warning restore IL2026, IL2090
|
||||
stream.Dispose();
|
||||
} catch (Exception) {
|
||||
if (throwExceptions) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return result as T;
|
||||
}
|
||||
|
||||
private static Stream ToStream(string value) {
|
||||
MemoryStream memoryStream = new();
|
||||
StreamWriter streamWriter = new(memoryStream);
|
||||
streamWriter.Write(value);
|
||||
streamWriter.Flush();
|
||||
memoryStream.Position = 0;
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
private static Dictionary<char, char> GetUnicodeReplaces() {
|
||||
Dictionary<char, char> results = new() {
|
||||
{ '\u0000', ' ' },
|
||||
{ '\u0001', ' ' },
|
||||
{ '\u0002', ' ' },
|
||||
{ '\u0003', ' ' },
|
||||
{ '\u0004', ' ' },
|
||||
{ '\u0005', ' ' },
|
||||
{ '\u0006', ' ' },
|
||||
{ '\u0007', ' ' },
|
||||
{ '\u0008', ' ' },
|
||||
{ '\u0009', '\t' },
|
||||
{ '\u000A', '\r' },
|
||||
{ '\u000B', '\r' },
|
||||
{ '\u000C', '\t' },
|
||||
{ '\u000D', '\r' },
|
||||
{ '\u000E', ' ' },
|
||||
{ '\u000F', ' ' },
|
||||
{ '\u0010', ' ' },
|
||||
{ '\u0011', ' ' },
|
||||
{ '\u0012', ' ' },
|
||||
{ '\u0013', ' ' },
|
||||
{ '\u0014', ' ' },
|
||||
{ '\u0015', ' ' },
|
||||
{ '\u0016', ' ' },
|
||||
{ '\u0017', ' ' },
|
||||
{ '\u0018', ' ' },
|
||||
{ '\u0019', ' ' },
|
||||
{ '\u001A', ' ' },
|
||||
{ '\u001B', ' ' },
|
||||
{ '\u001C', '\r' },
|
||||
{ '\u001D', '\t' },
|
||||
{ '\u001E', '\t' },
|
||||
{ '\u001F', '\t' },
|
||||
{ '\u007F', ' ' },
|
||||
// C1
|
||||
{ '\u0080', '\t' },
|
||||
{ '\u0081', ' ' },
|
||||
{ '\u0082', ' ' },
|
||||
{ '\u0083', ' ' },
|
||||
{ '\u0084', ' ' },
|
||||
{ '\u0085', '\r' },
|
||||
{ '\u0086', ' ' },
|
||||
{ '\u0087', ' ' },
|
||||
{ '\u0088', '\t' },
|
||||
{ '\u0089', '\t' },
|
||||
{ '\u008A', '\t' },
|
||||
{ '\u008B', '\r' },
|
||||
{ '\u008C', ' ' },
|
||||
{ '\u008D', ' ' },
|
||||
{ '\u008E', ' ' },
|
||||
{ '\u008F', ' ' },
|
||||
{ '\u0090', ' ' },
|
||||
{ '\u0091', ' ' },
|
||||
{ '\u0092', ' ' },
|
||||
{ '\u0093', ' ' },
|
||||
{ '\u0094', ' ' },
|
||||
{ '\u0095', ' ' },
|
||||
{ '\u0096', ' ' },
|
||||
{ '\u0097', ' ' },
|
||||
{ '\u0098', ' ' },
|
||||
{ '\u0099', ' ' },
|
||||
{ '\u009A', ' ' },
|
||||
{ '\u009B', ' ' },
|
||||
{ '\u009C', ' ' },
|
||||
{ '\u009D', ' ' },
|
||||
{ '\u009E', ' ' },
|
||||
{ '\u009F', ' ' }
|
||||
};
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Status EquipmentAutomationFrameworkCellInstanceStatus(string cellInstanceName, Record record) {
|
||||
Status result;
|
||||
bool stop = false;
|
||||
string state = string.Empty;
|
||||
string stopTime = string.Empty;
|
||||
string startTime = string.Empty;
|
||||
string startable = string.Empty;
|
||||
string currentHost = string.Empty;
|
||||
string errorDescription = string.Empty;
|
||||
string isReadyForRestart = string.Empty;
|
||||
string communicationState = string.Empty;
|
||||
string currentActiveVersion = string.Empty;
|
||||
for (int i = 0; i < record.Segments.Length - 3; i++) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
if (string.IsNullOrEmpty(state) && record.Segments[i].StartsWith("State")) {
|
||||
state = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(startable) && record.Segments[i].Contains("Startable")) {
|
||||
startable = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(stopTime) && record.Segments[i].StartsWith("StopTime")) {
|
||||
stopTime = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(currentHost) && record.Segments[i].Contains("CurrentHost")) {
|
||||
currentHost = $"{record.Segments[i]} {record.Segments[i + 1]} {record.Segments[i + 2]}";
|
||||
} else if (string.IsNullOrEmpty(errorDescription) && record.Segments[i].StartsWith("ErrorDescription")) {
|
||||
errorDescription = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(communicationState) && record.Segments[i].StartsWith("CommunicationState")) {
|
||||
communicationState = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(isReadyForRestart) && record.Segments[i].StartsWith("IsReadyForRestart")) {
|
||||
isReadyForRestart = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(currentActiveVersion) && record.Segments[i].Contains("CurrentActiveVersion")) {
|
||||
currentActiveVersion = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(startTime) && record.Segments[i].Contains("StartTime")) {
|
||||
startTime = $"{record.Segments[i + 1]} {record.Segments[i + 2]} {record.Segments[i + 3]}".Split('\t')[0];
|
||||
}
|
||||
}
|
||||
if (errorDescription != "a") {
|
||||
string[] segments = record.Text.Split(new string[] { "ErrorDescription" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (segments.Length > 1) {
|
||||
segments = segments[1].Split(new string[] { "Info" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
errorDescription = segments[0].Trim();
|
||||
}
|
||||
}
|
||||
string nPort;
|
||||
Dictionary<string, string> nPorts = GetnPorts();
|
||||
if (!nPorts.ContainsKey(cellInstanceName)) {
|
||||
nPort = string.Empty;
|
||||
} else {
|
||||
nPort = nPorts[cellInstanceName];
|
||||
}
|
||||
if (state.EndsWith("a")) {
|
||||
state = state[0..^1];
|
||||
}
|
||||
if (state == "Running" && communicationState == "Not") {
|
||||
state = "Warning";
|
||||
}
|
||||
result = new(Host: record.Host,
|
||||
Port: record.Port,
|
||||
Text: record.Text,
|
||||
NPort: nPort,
|
||||
State: state,
|
||||
CellInstanceName: cellInstanceName,
|
||||
StopTime: stopTime,
|
||||
StartTime: startTime,
|
||||
Startable: startable,
|
||||
CurrentHost: currentHost,
|
||||
ErrorDescription: errorDescription,
|
||||
IsReadyForRestart: isReadyForRestart,
|
||||
CommunicationState: communicationState,
|
||||
CurrentActiveVersion: currentActiveVersion);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> GetnPorts() {
|
||||
Dictionary<string, string> results = new() {
|
||||
{ "TENCOR1", "10.95.192.31" },
|
||||
{ "TENCOR2", "10.95.192.32" },
|
||||
{ "TENCOR3", "10.95.192.33" },
|
||||
{ "HGCV1", "10.95.192.34" },
|
||||
{ "HGCV2", "10.95.154.17" },
|
||||
{ "HGCV3", "10.95.192.36" },
|
||||
{ "BIORAD2", "10.95.192.37" },
|
||||
{ "BIORAD3", "10.95.192.38" },
|
||||
{ "CDE2", "10.95.192.39" },
|
||||
{ "CDE3", "10.95.154.19" },
|
||||
{ "CDE5", "10.95.192.40" },
|
||||
{ "SPARE-1", "10.95.192.47" },
|
||||
{ "SPARE-2", "10.95.192.48" },
|
||||
{ "SPARE-3", "10.95.192.49" },
|
||||
{ "SPARE-4", "10.95.192.50" },
|
||||
{ "SPARE-5", "10.95.192.51" },
|
||||
};
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void EquipmentAutomationFrameworkCellInstanceRestart(string host, int port, string cellName = "R71-HSMS", string verbBy = @"EC\EcMesEaf") {
|
||||
EquipmentAutomationFrameworkCellInstanceParseCheck();
|
||||
// Restart
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action><a:MessageID>urn:uuid:09fd9303-dcfe-4563-803b-678441b12949</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><CreateSequence xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm"><AcksTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></AcksTo><Offer><Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</Identifier></Offer></CreateSequence></s:Body></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/RestartAllCellInstances</a:Action><a:MessageID>urn:uuid:c9f80db4-a2c2-4e53-9bed-8ba3a60b653c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><RestartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Restarted by EC\ecphares</updateInfo></RestartAllCellInstances></s:Body></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</r:Identifier><r:AcknowledgementRange Lower="1" Upper="1"/></r:SequenceAcknowledgement><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body/></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</r:Identifier><r:AcknowledgementRange Lower="1" Upper="2"/></r:SequenceAcknowledgement><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action><a:MessageID>urn:uuid:3b063df5-e6df-47a5-b530-aa380a4c6a38</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>
|
||||
EquipmentAutomationFrameworkCellInstanceVerb(host, port, cellName, verbBy, restart: true, stop: false, start: false);
|
||||
}
|
||||
|
||||
private static void EquipmentAutomationFrameworkCellInstanceStart(string host, int port, string cellName = "R71-HSMS", string verbBy = @"EC\EcMesEaf") {
|
||||
EquipmentAutomationFrameworkCellInstanceParseCheck();
|
||||
// Start
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action><a:MessageID>urn:uuid:a1188d61-df04-4955-b1e4-b90faff95d4d</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><CreateSequence xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm"><AcksTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></AcksTo><Offer><Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</Identifier></Offer></CreateSequence></s:Body></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/StartAllCellInstances</a:Action><a:MessageID>urn:uuid:8758eec2-b4dc-4338-ba3d-235aa15e634c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><StartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Started by EC\ecphares</updateInfo></StartAllCellInstances></s:Body></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/StartAllCellInstances</a:Action><a:MessageID>urn:uuid:8758eec2-b4dc-4338-ba3d-235aa15e634c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><StartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Started by EC\ecphares</updateInfo></StartAllCellInstances></s:Body></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</r:Identifier><r:AcknowledgementRange Lower="1" Upper="1"/></r:SequenceAcknowledgement><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body/></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</r:Identifier><r:AcknowledgementRange Lower="1" Upper="2"/></r:SequenceAcknowledgement><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action><a:MessageID>urn:uuid:b2bb5329-c846-4cd1-98a8-343136923702</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>
|
||||
EquipmentAutomationFrameworkCellInstanceVerb(host, port, cellName, verbBy, restart: false, stop: false, start: true);
|
||||
}
|
||||
|
||||
private static void EquipmentAutomationFrameworkCellInstanceVerb(string host, int port, string cellName, string verbBy, bool restart, bool stop, bool start) {
|
||||
#pragma warning disable SYSLIB0014
|
||||
WebClient webClient = new();
|
||||
#pragma warning restore SYSLIB0014
|
||||
string xml;
|
||||
string verb;
|
||||
Envelope? envelope;
|
||||
string updateInfoVerb;
|
||||
StringBuilder stringBuilder = new();
|
||||
string cellControllerManager = $"http://{host}:{port}/CellControllerManager";
|
||||
if (!restart && !stop && !start) {
|
||||
throw new Exception();
|
||||
} else if (restart && stop && start) {
|
||||
throw new Exception();
|
||||
} else if (restart) {
|
||||
updateInfoVerb = "Restarted";
|
||||
verb = "RestartAllCellInstances";
|
||||
} else if (stop) {
|
||||
updateInfoVerb = "Stopped";
|
||||
verb = "StopAllCellInstancesResponse";
|
||||
} else if (start) {
|
||||
updateInfoVerb = "Started";
|
||||
verb = "StartAllCellInstances";
|
||||
} else
|
||||
throw new Exception();
|
||||
string headerMessageID621 = Guid.NewGuid().ToString();
|
||||
string bodyIdentifier621 = Guid.NewGuid().ToString();
|
||||
_ = stringBuilder.Append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">").
|
||||
Append("<s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action>").
|
||||
Append("<a:MessageID>urn:uuid:").Append(headerMessageID621).Append("</a:MessageID>").
|
||||
Append("<a:To s:mustUnderstand=\"1\">").Append(cellControllerManager).Append("</a:To>").
|
||||
Append("</s:Header><s:Body><CreateSequence xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><AcksTo>").
|
||||
Append("<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></AcksTo><Offer>").
|
||||
Append("<Identifier>urn:uuid:").Append(bodyIdentifier621).Append("</Identifier>").
|
||||
Append("</Offer></CreateSequence></s:Body></s:Envelope>");
|
||||
xml = stringBuilder.ToString();
|
||||
_ = stringBuilder.Clear();
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+xml; charset=utf-8");
|
||||
xml = webClient.UploadString(cellControllerManager, xml);
|
||||
envelope = ParseXML<Envelope>(xml, throwExceptions: true);
|
||||
if (envelope is null || envelope.Body is null || envelope.Body.CreateSequenceResponse is null || string.IsNullOrEmpty(envelope.Body.CreateSequenceResponse.Identifier)) {
|
||||
throw new Exception("Invalid reply! Example [urn:uuid:f1aa1fa8-9099-48b6-b27f-50e6c098605b]");
|
||||
}
|
||||
string headerSequenceIdentifier895 = envelope.Body.CreateSequenceResponse.Identifier["urn:uuid:".Length..];
|
||||
string headerMessageID895 = Guid.NewGuid().ToString();
|
||||
_ = stringBuilder.Append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">").
|
||||
Append("<s:Header><r:Sequence s:mustUnderstand=\"1\">").
|
||||
Append("<r:Identifier>urn:uuid:").Append(headerSequenceIdentifier895).Append("</r:Identifier>").
|
||||
Append("<r:MessageNumber>1</r:MessageNumber></r:Sequence>").
|
||||
Append("<a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/").Append(verb).Append("</a:Action>").
|
||||
Append("<a:MessageID>urn:uuid:").Append(headerMessageID895).Append("</a:MessageID>").
|
||||
Append("<a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo>").
|
||||
Append("<a:To s:mustUnderstand=\"1\">").Append(cellControllerManager).Append("</a:To>").
|
||||
Append("</s:Header><s:Body>").
|
||||
Append('<').Append(verb).Append(" xmlns=\"http://tempuri.org/\">").
|
||||
Append("<cellInstances xmlns:b=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">").
|
||||
Append("<b:string>").Append(cellName).Append("</b:string>").
|
||||
Append("</cellInstances>").
|
||||
Append("<updateInfo>").Append(updateInfoVerb).Append(" by ").Append(verbBy).Append("</updateInfo>").
|
||||
Append("</").Append(verb).Append('>').
|
||||
Append("</s:Body></s:Envelope>");
|
||||
xml = stringBuilder.ToString();
|
||||
_ = stringBuilder.Clear();
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+xml; charset=utf-8");
|
||||
xml = webClient.UploadString(cellControllerManager, xml);
|
||||
_ = ParseXML<Envelope>(xml, throwExceptions: true);
|
||||
string headerSequenceAcknowledgementIdentifier748 = bodyIdentifier621;
|
||||
string headerSequenceIdentifier748 = headerSequenceIdentifier895;
|
||||
_ = stringBuilder.Append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">").
|
||||
Append("<s:Header><r:SequenceAcknowledgement>").
|
||||
Append("<r:Identifier>urn:uuid:").Append(headerSequenceAcknowledgementIdentifier748).Append("</r:Identifier>").
|
||||
Append("<r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/></r:SequenceAcknowledgement><r:Sequence s:mustUnderstand=\"1\">").
|
||||
Append("<r:Identifier>urn:uuid:").Append(headerSequenceIdentifier748).Append("</r:Identifier>").
|
||||
Append("<r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence>").
|
||||
Append("<a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action>").
|
||||
Append("<a:To s:mustUnderstand=\"1\">").Append(cellControllerManager).Append("</a:To>").
|
||||
Append("</s:Header><s:Body/></s:Envelope>");
|
||||
xml = stringBuilder.ToString();
|
||||
_ = stringBuilder.Clear();
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+xml; charset=utf-8");
|
||||
xml = webClient.UploadString(cellControllerManager, xml);
|
||||
_ = ParseXML<Envelope>(xml, throwExceptions: true);
|
||||
string headerSequenceAcknowledgementIdentifier707 = bodyIdentifier621;
|
||||
string headerMessageID707 = Guid.NewGuid().ToString();
|
||||
string bodyTerminateSequenceIdentifier707 = headerSequenceIdentifier895;
|
||||
_ = stringBuilder.Append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">").
|
||||
Append("<s:Header><r:SequenceAcknowledgement>").
|
||||
Append("<r:Identifier>urn:uuid:").Append(headerSequenceAcknowledgementIdentifier707).Append("</r:Identifier>").
|
||||
Append("<r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/></r:SequenceAcknowledgement>").
|
||||
Append("<a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action>").
|
||||
Append("<a:MessageID>urn:uuid:").Append(headerMessageID707).Append("</a:MessageID>").
|
||||
Append("<a:To s:mustUnderstand=\"1\">").Append(cellControllerManager).Append("</a:To>").
|
||||
Append("</s:Header><s:Body>").
|
||||
Append("<r:TerminateSequence>").
|
||||
Append("<r:Identifier>urn:uuid:").Append(bodyTerminateSequenceIdentifier707).Append("</r:Identifier>").
|
||||
Append("</r:TerminateSequence>").
|
||||
Append("</s:Body></s:Envelope>");
|
||||
xml = stringBuilder.ToString();
|
||||
_ = stringBuilder.Clear();
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+xml; charset=utf-8");
|
||||
xml = webClient.UploadString(cellControllerManager, xml);
|
||||
_ = ParseXML<Envelope>(xml, throwExceptions: true);
|
||||
}
|
||||
|
||||
}
|
89
ADO2025/PI6/Helper-2025-06-18.cs
Normal file
89
ADO2025/PI6/Helper-2025-06-18.cs
Normal file
@ -0,0 +1,89 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250618 {
|
||||
|
||||
private record Record(string Directory, List<string> Files);
|
||||
|
||||
internal static void MoveAllButXOfEach(ILogger<Worker> logger, List<string> args) {
|
||||
int keep = int.Parse(args[5]);
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
string searchPattern = args[2];
|
||||
string split = args[4].Split('~')[0];
|
||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
string destinationDirectory = Path.GetFullPath(args[3].Split('~')[0]);
|
||||
if (destinationDirectory.Contains(sourceDirectory)) {
|
||||
throw new Exception("Not allowed!");
|
||||
}
|
||||
ReadOnlyCollection<string> directories = GetDirectories(sourceDirectory);
|
||||
MoveAllButXOfEachB(logger, searchPattern, sourceDirectory, destinationDirectory, split, keep, directories);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<string> GetDirectories(string sourceDirectory) {
|
||||
List<string> results = [sourceDirectory];
|
||||
results.AddRange(Directory.GetDirectories(sourceDirectory, "*", SearchOption.AllDirectories));
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void MoveAllButXOfEachB(ILogger<Worker> logger, string searchPattern, string sourceDirectory, string destinationDirectory, string split, int keep, ReadOnlyCollection<string> directories) {
|
||||
string[] files;
|
||||
int sourceDirectoryLength = sourceDirectory.Length;
|
||||
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs;
|
||||
foreach (string directory in directories) {
|
||||
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
keyValuePairs = GetFiles(split, files);
|
||||
foreach (KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair in keyValuePairs) {
|
||||
if (keyValuePair.Value.Count <= keep) {
|
||||
continue;
|
||||
} else {
|
||||
MoveAllButXOfEachC(logger, sourceDirectoryLength, destinationDirectory, keyValuePair);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetFiles(string split, string[] files) {
|
||||
Dictionary<string, ReadOnlyCollection<string>> results = [];
|
||||
string key;
|
||||
List<string>? collection;
|
||||
Dictionary<string, List<string>> keyValuePairs = [];
|
||||
foreach (string file in files) {
|
||||
key = Path.GetFileName(file).Split(split)[0];
|
||||
if (!keyValuePairs.TryGetValue(key, out collection)) {
|
||||
keyValuePairs.Add(key, []);
|
||||
if (!keyValuePairs.TryGetValue(key, out collection)) {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
collection.Add(file);
|
||||
}
|
||||
foreach (KeyValuePair<string, List<string>> keyValuePair in keyValuePairs) {
|
||||
results.Add(keyValuePair.Key, keyValuePair.Value.OrderByDescending(l => l).ToArray().AsReadOnly());
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void MoveAllButXOfEachC(ILogger<Worker> logger, int sourceDirectoryLength, string destinationDirectory, KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair) {
|
||||
string file;
|
||||
string checkFile;
|
||||
string checkDirectory;
|
||||
for (int i = 1; i < keyValuePair.Value.Count; i++) {
|
||||
file = keyValuePair.Value[i];
|
||||
checkFile = $"{destinationDirectory}{file[sourceDirectoryLength..]}";
|
||||
checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new Exception();
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
File.Move(file, checkFile);
|
||||
logger.LogInformation("<{file}> moved", file);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
89
ADO2025/PI6/Helper-2025-06-28.cs
Normal file
89
ADO2025/PI6/Helper-2025-06-28.cs
Normal file
@ -0,0 +1,89 @@
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
using DiscUtils.Iso9660;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250628 {
|
||||
|
||||
private record Record(string Path,
|
||||
long Size,
|
||||
long Ticks);
|
||||
|
||||
internal static void LogIsoInformation(ILogger<Worker> logger, List<string> args) {
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
string searchPattern = args[2];
|
||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
string[] searchPatternFiles = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
ReadOnlyCollection<Record> records = GetRecords(searchPatternFiles);
|
||||
LogIsoInformation(logger, records, args[3]);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetRecords(string[] searchPatternFiles) {
|
||||
List<Record> results = [];
|
||||
Record record;
|
||||
string[] files;
|
||||
FileInfo fileInfo;
|
||||
foreach (string searchPatternFile in searchPatternFiles) {
|
||||
fileInfo = new(searchPatternFile);
|
||||
record = new(searchPatternFile, fileInfo.Length, fileInfo.LastWriteTime.Ticks);
|
||||
results.Add(record);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string GetSizeWithSuffix(long value) {
|
||||
string result;
|
||||
int i = 0;
|
||||
string[] SizeSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
if (value < 0) {
|
||||
result = "-" + GetSizeWithSuffix(-value);
|
||||
} else {
|
||||
while (Math.Round(value / 1024f) >= 1) {
|
||||
value /= 1024;
|
||||
i++;
|
||||
}
|
||||
result = string.Format("{0:n1} {1}", value, SizeSuffixes[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void LogIsoInformation(ILogger<Worker> logger, ReadOnlyCollection<Record> records, string letter) {
|
||||
string size;
|
||||
string[] files;
|
||||
List<string> messages = [];
|
||||
Record[] sorted = records.OrderBy(l => l.Ticks).ToArray();
|
||||
string directory = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper");
|
||||
foreach (Record record in sorted) {
|
||||
if (string.IsNullOrEmpty(record.Path)) {
|
||||
using FileStream fileStream = File.OpenRead(record.Path);
|
||||
CDReader reader = new(fileStream, true);
|
||||
files = reader.GetFiles("", "*");
|
||||
foreach (string _ in files) {
|
||||
}
|
||||
}
|
||||
size = GetSizeWithSuffix(record.Size);
|
||||
messages.Add($"#; {size}");
|
||||
messages.Add($"#; {new DateTime(record.Ticks):yyyy-MM-dd HH:mm:ss.fff}");
|
||||
messages.Add($"$driveLetter = \"{letter}:\"");
|
||||
messages.Add($"$isoImg = \"{record.Path}\"");
|
||||
messages.Add("$diskImg = Mount-DiskImage -ImagePath $isoImg -NoDriveLetter");
|
||||
messages.Add("$volInfo = $diskImg | Get-Volume");
|
||||
messages.Add("mountvol $driveLetter $volInfo.UniqueId");
|
||||
messages.Add(string.Empty);
|
||||
}
|
||||
if (Directory.Exists(directory)) {
|
||||
File.WriteAllText(Path.Combine(directory, ".lsv"), string.Join(Environment.NewLine, messages));
|
||||
} else {
|
||||
messages.Reverse();
|
||||
foreach (string message in messages) {
|
||||
logger.LogInformation(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
313
ADO2025/PI6/Helper-2025-07-01.cs
Normal file
313
ADO2025/PI6/Helper-2025-07-01.cs
Normal file
@ -0,0 +1,313 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250701 {
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[JsonSerializable(typeof(JsonElement))]
|
||||
internal partial class JsonElementSourceGenerationContext : JsonSerializerContext {
|
||||
}
|
||||
|
||||
internal static void ProcessDataStandardFormatTo(ILogger<Worker> logger, List<string> args) {
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
logger.LogInformation(args[3]);
|
||||
logger.LogInformation(args[4]);
|
||||
logger.LogInformation(args[5]);
|
||||
logger.LogInformation(args[6]);
|
||||
string[] segments;
|
||||
string timeColumn = args[4];
|
||||
string searchPattern = args[2];
|
||||
int sizeFilter = int.Parse(args[3]);
|
||||
string[] columns = args[5].Split(',');
|
||||
Dictionary<string, string> columnMapping = [];
|
||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
string destinationDirectory = Path.GetFullPath(args[6].Split('~')[0]);
|
||||
foreach (string column in columns) {
|
||||
segments = column.Split('~');
|
||||
columnMapping.Add(segments[0], segments[1]);
|
||||
}
|
||||
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
ProcessDataStandardFormatTo(logger, sourceDirectory, searchPattern, sizeFilter, timeColumn, columnMapping, destinationDirectory, directories);
|
||||
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
|
||||
}
|
||||
|
||||
private static void ProcessDataStandardFormatTo(ILogger<Worker> logger, string sourceDirectory, string searchPattern, int sizeFilter, string timeColumn, Dictionary<string, string> columnMapping, string destinationDirectory, string[] directories) {
|
||||
string? json;
|
||||
string[] files;
|
||||
string markdown;
|
||||
string checkFile;
|
||||
string[] matches;
|
||||
FileInfo fileInfo;
|
||||
string? pipeTable;
|
||||
string? collections;
|
||||
string directoryName;
|
||||
string checkDirectory;
|
||||
foreach (string directory in directories) {
|
||||
if (Path.GetFileName(directory).Contains('-')) {
|
||||
continue;
|
||||
}
|
||||
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files) {
|
||||
fileInfo = new(file);
|
||||
if (fileInfo.LastWriteTime > DateTime.Now.AddSeconds(-5)) {
|
||||
continue;
|
||||
}
|
||||
directoryName = Path.GetFileName(fileInfo.DirectoryName);
|
||||
if (fileInfo.Length > sizeFilter && !directoryName.StartsWith('Z')) {
|
||||
checkDirectory = Path.Combine(sourceDirectory, $"Z{directoryName}");
|
||||
if (!Directory.Exists(checkDirectory)) {
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
}
|
||||
checkFile = Path.Combine(checkDirectory, fileInfo.Name);
|
||||
if (File.Exists(checkFile)) {
|
||||
continue;
|
||||
}
|
||||
File.Move(file, checkFile);
|
||||
continue;
|
||||
}
|
||||
checkDirectory = Path.Combine(destinationDirectory, directoryName);
|
||||
if (!Directory.Exists(checkDirectory)) {
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
}
|
||||
checkFile = Path.Combine(checkDirectory, $"{fileInfo.Name}.md");
|
||||
if (File.Exists(checkFile)) {
|
||||
continue;
|
||||
}
|
||||
collections = GetMarkdown(logger, timeColumn, columnMapping, file, fileInfo.Name);
|
||||
if (string.IsNullOrEmpty(collections)) {
|
||||
logger.LogWarning("collections is null");
|
||||
continue;
|
||||
}
|
||||
File.WriteAllText(checkFile, collections);
|
||||
File.SetLastWriteTime(checkFile, fileInfo.LastAccessTime);
|
||||
if (!string.IsNullOrEmpty(destinationDirectory)) {
|
||||
continue;
|
||||
}
|
||||
json = GetJavaScriptObjectNotation(logger, file);
|
||||
if (string.IsNullOrEmpty(json)) {
|
||||
logger.LogWarning("json is null");
|
||||
continue;
|
||||
}
|
||||
File.WriteAllText($"{checkFile}.md", json);
|
||||
File.SetLastWriteTime($"{checkFile}.md", fileInfo.LastAccessTime);
|
||||
pipeTable = GetPipeTable(logger, json);
|
||||
if (string.IsNullOrEmpty(pipeTable)) {
|
||||
logger.LogWarning("pipeTable is null");
|
||||
continue;
|
||||
}
|
||||
markdown = $"# {fileInfo.Name}{Environment.NewLine}{Environment.NewLine}{pipeTable}{Environment.NewLine}";
|
||||
File.WriteAllText($"{checkFile}.md", markdown);
|
||||
File.SetLastWriteTime($"{checkFile}.md", fileInfo.LastAccessTime);
|
||||
logger.LogInformation("<{checkFile}> was written", checkFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string? GetMarkdown(ILogger<Worker> logger, string timeColumn, Dictionary<string, string> columnMapping, string file, string name) {
|
||||
string? result = null;
|
||||
string[] lines = File.ReadAllLines(file);
|
||||
int? columnTitlesLine = GetProcessDataStandardFormatColumnTitlesLine(lines);
|
||||
if (columnTitlesLine is null) {
|
||||
logger.LogWarning("<{columnTitlesLine}> is null", nameof(columnTitlesLine));
|
||||
} else {
|
||||
if (lines.Length < columnTitlesLine.Value + 1) {
|
||||
logger.LogWarning("<{lines}>(s)", lines.Length);
|
||||
} else {
|
||||
result = GetMarkdown(timeColumn, columnMapping, name, lines, columnTitlesLine);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int? GetProcessDataStandardFormatColumnTitlesLine(string[] lines) {
|
||||
int? result = null;
|
||||
for (int i = 0; i < lines.Length; i++) {
|
||||
if (lines[i].StartsWith("END_OFFSET") && i + 3 < lines.Length) {
|
||||
result = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetKeyValuePairs(int columnTitlesLine, string[] lines) {
|
||||
Dictionary<string, ReadOnlyCollection<string>> results = [];
|
||||
string value;
|
||||
string[] segments;
|
||||
List<List<string>> collections = [];
|
||||
string[] columns = lines[columnTitlesLine].Split('\t');
|
||||
foreach (string column in columns) {
|
||||
collections.Add([]);
|
||||
}
|
||||
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
|
||||
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
||||
break;
|
||||
}
|
||||
segments = lines[i].Split('\t');
|
||||
if (segments.Length > columns.Length) {
|
||||
continue;
|
||||
}
|
||||
for (int c = 0; c < segments.Length; c++) {
|
||||
collections[c].Add(segments[c]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < collections.Count; i++) {
|
||||
if (collections[i].Count > 1) {
|
||||
if (string.IsNullOrEmpty(collections[i][0])) {
|
||||
collections[i][0] = collections[i][1];
|
||||
}
|
||||
if (string.IsNullOrEmpty(collections[i][^1])) {
|
||||
collections[i][^1] = collections[i][^2];
|
||||
}
|
||||
}
|
||||
results.Add(columns[i].Trim('"'), collections[i].AsReadOnly());
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string? GetMarkdown(string timeColumn, Dictionary<string, string> columnMapping, string name, string[] lines, int? columnTitlesLine) {
|
||||
string? result;
|
||||
List<string> charts = [];
|
||||
List<string> results = [];
|
||||
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs = GetKeyValuePairs(columnTitlesLine.Value, lines);
|
||||
string[] columns = keyValuePairs.Keys.OrderBy(l => l).ToArray();
|
||||
if (!columns.Contains(timeColumn)) {
|
||||
result = null;
|
||||
} else {
|
||||
string? alias;
|
||||
string[] mappedColumns = columnMapping.Keys.ToArray();
|
||||
string labels = string.Join(',', keyValuePairs[timeColumn].Select(l => l.Replace(',', '_')));
|
||||
foreach (string column in columns) {
|
||||
if (column == timeColumn) {
|
||||
continue;
|
||||
}
|
||||
if (!columnMapping.TryGetValue(column, out alias) || keyValuePairs[column].Count == 0 || string.IsNullOrEmpty(keyValuePairs[column][0])) {
|
||||
results.Add(string.Concat("## ", column, Environment.NewLine, Environment.NewLine,
|
||||
"- ", string.Join(',', keyValuePairs[column].Select(l => l.Replace(',', '_'))), Environment.NewLine
|
||||
));
|
||||
} else {
|
||||
charts.Add(string.Concat(
|
||||
"## ", column, " - ", alias, Environment.NewLine, Environment.NewLine,
|
||||
"```chart", Environment.NewLine,
|
||||
"{\"type\": \"line\", \"data\": {\"datasets\": [{", Environment.NewLine,
|
||||
"\"label\": \"", column, " - ", alias, "\",", Environment.NewLine,
|
||||
"\"data\": [", string.Join(',', keyValuePairs[column].Select(l => l.Replace(',', '_'))), "],", Environment.NewLine,
|
||||
"\"borderColor\": \"rgb(75, 192, 192)\"", Environment.NewLine,
|
||||
"}],", Environment.NewLine,
|
||||
"\"labels\": [", labels, "]", Environment.NewLine,
|
||||
"}}", Environment.NewLine,
|
||||
"```", Environment.NewLine
|
||||
));
|
||||
}
|
||||
}
|
||||
if (results.Count == 0 && charts.Count == 0) {
|
||||
result = null;
|
||||
} else {
|
||||
string[] segments;
|
||||
results.Add($"## Footer{Environment.NewLine}");
|
||||
results.Insert(0, $"# {name}{Environment.NewLine}");
|
||||
for (int i = columnTitlesLine.Value + 1; i < lines.Length; i++) {
|
||||
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
||||
for (int j = i; j < lines.Length; j++) {
|
||||
results.Add($"- {lines[j]}");
|
||||
}
|
||||
}
|
||||
}
|
||||
results.Add(string.Empty);
|
||||
results.Add(string.Empty);
|
||||
result = $"{string.Join(Environment.NewLine, results)}{string.Join(Environment.NewLine, charts)}";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string? GetJavaScriptObjectNotation(ILogger<Worker> logger, string file) {
|
||||
string? result = null;
|
||||
string[] lines = File.ReadAllLines(file);
|
||||
int? columnTitlesLine = GetProcessDataStandardFormatColumnTitlesLine(lines);
|
||||
if (columnTitlesLine is null) {
|
||||
logger.LogWarning("<{columnTitlesLine}> is null", nameof(columnTitlesLine));
|
||||
} else {
|
||||
if (lines.Length < columnTitlesLine.Value + 1) {
|
||||
logger.LogWarning("<{lines}>(s)", lines.Length);
|
||||
} else {
|
||||
result = GetJavaScriptObjectNotation(columnTitlesLine.Value, [], lines);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string GetJavaScriptObjectNotation(int columnTitlesLine, string[] columns, string[] lines) {
|
||||
#pragma warning disable CA1845, IDE0057
|
||||
string result = "[\n";
|
||||
string line;
|
||||
string value;
|
||||
string[] segments;
|
||||
if (columns.Length == 0) {
|
||||
columns = lines[columnTitlesLine].Split('\t');
|
||||
}
|
||||
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
|
||||
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
||||
break;
|
||||
}
|
||||
line = "{";
|
||||
segments = lines[i].Split('\t');
|
||||
if (segments.Length > columns.Length) {
|
||||
continue;
|
||||
}
|
||||
for (int c = 0; c < segments.Length; c++) {
|
||||
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
line += '"' + columns[c].Trim('"') + '"' + ':' + '"' + value + '"' + ',';
|
||||
}
|
||||
line = line.Substring(0, line.Length - 1) + '}' + ',' + '\n';
|
||||
result += line;
|
||||
}
|
||||
result = result.Substring(0, result.Length - 2) + ']';
|
||||
return result;
|
||||
#pragma warning restore CA1845, IDE0057
|
||||
}
|
||||
|
||||
private static string? GetPipeTable(ILogger<Worker> logger, string json) {
|
||||
string? result = null;
|
||||
string? value;
|
||||
string[]? columns = null;
|
||||
List<string> values = [];
|
||||
List<string> results = [];
|
||||
Dictionary<string, string> keyValuePairs = [];
|
||||
JsonElement jsonElement = JsonSerializer.Deserialize(json, JsonElementSourceGenerationContext.Default.JsonElement);
|
||||
JsonElement[] jsonElements = jsonElement.EnumerateArray().ToArray();
|
||||
foreach (JsonElement j in jsonElements) {
|
||||
values.Clear();
|
||||
keyValuePairs.Clear();
|
||||
foreach (JsonProperty jsonProperty in j.EnumerateObject().ToArray()) {
|
||||
if (columns is null) {
|
||||
JsonProperty[] jsonProperties = j.EnumerateObject().OrderBy(l => l.Name).ToArray();
|
||||
columns = jsonProperties.Select(l => l.Name).ToArray();
|
||||
results.Add($"|{string.Join('|', columns)}|");
|
||||
results.Add($"|{string.Join('|', columns.Select(l => '-'))}|");
|
||||
}
|
||||
keyValuePairs.Add(jsonProperty.Name, jsonProperty.Value.ToString());
|
||||
}
|
||||
foreach (string column in columns) {
|
||||
if (!keyValuePairs.TryGetValue(column, out value)) {
|
||||
values.Add(new string(' ', column.Length));
|
||||
} else {
|
||||
values.Add(value.PadLeft(column.Length, ' '));
|
||||
}
|
||||
}
|
||||
results.Add($"|{string.Join('|', values)}|");
|
||||
}
|
||||
if (results.Count > 0) {
|
||||
result = string.Join(Environment.NewLine, results);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
112
ADO2025/PI6/Helper-2025-07-05.cs
Normal file
112
ADO2025/PI6/Helper-2025-07-05.cs
Normal file
@ -0,0 +1,112 @@
|
||||
|
||||
using System.Drawing;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250705 {
|
||||
|
||||
internal static void ExportFaces(ILogger<Worker> logger, List<string> args) {
|
||||
string checkFile;
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
logger.LogInformation(args[3]);
|
||||
logger.LogInformation(args[4]);
|
||||
logger.LogInformation(args[5]);
|
||||
logger.LogInformation(args[6]);
|
||||
logger.LogInformation(args[7]);
|
||||
string locationDigits = args[6];
|
||||
string[] mp = args[4].Split('~');
|
||||
string[] mwg = args[5].Split('~');
|
||||
string[] xyz = args[3].Split(',');
|
||||
string[] fileNames = args[2].Split('~');
|
||||
string[] wholePercentages = args[7].Split('~');
|
||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
if (mp.Length != mwg.Length || mp.Length != wholePercentages.Length) {
|
||||
logger.LogWarning("Lengths don't match!");
|
||||
} else {
|
||||
foreach (string fileName in fileNames) {
|
||||
checkFile = Path.Combine(sourceDirectory, fileName);
|
||||
if (!File.Exists(checkFile)) {
|
||||
logger.LogWarning("<{file}> doesn't exist!", args[2]);
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < mp.Length; i++) {
|
||||
if (wholePercentages[i].StartsWith("x-")) {
|
||||
logger.LogWarning("Skipping {wholePercentages}", wholePercentages[i]);
|
||||
continue;
|
||||
}
|
||||
Ext(checkFile, xyz, i, mp[i], mwg[i], locationDigits, wholePercentages[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Ext(string checkFile, string[] xyz, int i, string mp, string mwg, string locationDigits, string wholePercentages) {
|
||||
int width = int.Parse(xyz[0]);
|
||||
int height = int.Parse(xyz[1]);
|
||||
string[] mpValues = mp.Split(',');
|
||||
string[] mwgValues = mwg.Split(',');
|
||||
float mpWidth = float.Parse(mpValues[2]) * width;
|
||||
float mpHeight = float.Parse(mpValues[3]) * height;
|
||||
double mpLeft = (float.Parse(mpValues[0]) * width) - (mpWidth * .5);
|
||||
double mpTop = (float.Parse(mpValues[1]) * height) - (mpHeight * .5);
|
||||
Extract(file: checkFile,
|
||||
width: mpWidth,
|
||||
height: mpHeight,
|
||||
left: mpLeft,
|
||||
top: mpTop,
|
||||
suffix: $"-{i}mp.jpg");
|
||||
float mwgWidth = float.Parse(mwgValues[2]) * width;
|
||||
float mwgHeight = float.Parse(mwgValues[3]) * height;
|
||||
double mwgLeft = double.Parse(mwgValues[0]) * width;
|
||||
double mwgTop = double.Parse(mwgValues[1]) * height;
|
||||
Extract(file: checkFile,
|
||||
width: mwgWidth,
|
||||
height: mwgHeight,
|
||||
left: mwgLeft,
|
||||
top: mwgTop,
|
||||
suffix: $"-{i}mwg.jpg");
|
||||
int length = (int.Parse(locationDigits) - 1) / 4;
|
||||
string[] segments =
|
||||
[
|
||||
wholePercentages[..1],
|
||||
wholePercentages.Substring(1, length),
|
||||
wholePercentages.Substring(3, length),
|
||||
wholePercentages.Substring(5, length),
|
||||
wholePercentages.Substring(7, length)
|
||||
];
|
||||
if (string.Join(string.Empty, segments) == wholePercentages) {
|
||||
if (int.TryParse(segments[1], out int xWholePercent)
|
||||
&& int.TryParse(segments[2], out int yWholePercent)
|
||||
&& int.TryParse(segments[3], out int wWholePercent)
|
||||
&& int.TryParse(segments[4], out int hWholePercent)) {
|
||||
float factor = 100;
|
||||
RectangleF rectangleF = new(xWholePercent / factor, yWholePercent / factor, wWholePercent / factor, hWholePercent / factor);
|
||||
float rectangleFWidth = rectangleF.Width * width;
|
||||
float rectangleFHeight = rectangleF.Height * height;
|
||||
double rectangleFLeft = rectangleF.Left * width;
|
||||
double rectangleFTop = rectangleF.Top * height;
|
||||
Extract(file: checkFile,
|
||||
width: rectangleFWidth,
|
||||
height: rectangleFHeight,
|
||||
left: rectangleFLeft,
|
||||
top: rectangleFTop,
|
||||
suffix: $"-{i}whole-percentages.jpg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Extract(string file, float width, float height, double left, double top, string suffix) {
|
||||
RectangleF rectangle = new((float)left, (float)top, width, height);
|
||||
using (Bitmap source = new(file)) {
|
||||
using (Bitmap bitmap = new((int)width, (int)height)) {
|
||||
using (Graphics graphics = Graphics.FromImage(bitmap))
|
||||
graphics.DrawImage(source, new RectangleF(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||
bitmap.Save($"{file}{suffix}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -163,6 +163,20 @@ internal static class HelperDay
|
||||
ADO2025.PI5.Helper20250505.HyperTextMarkupLanguageToPortableDocumentFormat(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-05-19")
|
||||
ADO2025.PI6.Helper20250519.LiveSync(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-05-21")
|
||||
ADO2025.PI6.Helper20250521.MatchDirectory(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-06-01")
|
||||
ADO2025.PI6.Helper20250601.EquipmentAutomationFrameworkStatus(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-06-02")
|
||||
ADO2025.PI6.Helper20250602.EquipmentAutomationFrameworkCellInstanceStateImageVerbIf(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-06-18")
|
||||
ADO2025.PI6.Helper20250618.MoveAllButXOfEach(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-06-28")
|
||||
ADO2025.PI6.Helper20250628.LogIsoInformation(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-07-01")
|
||||
ADO2025.PI6.Helper20250701.ProcessDataStandardFormatTo(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-07-05")
|
||||
ADO2025.PI6.Helper20250705.ExportFaces(logger, args);
|
||||
else
|
||||
throw new Exception(appSettings.Company);
|
||||
}
|
||||
|
@ -17,7 +17,8 @@
|
||||
<PackageReference Include="MetadataExtractor" Version="2.8.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
|
||||
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.16" />
|
||||
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.17" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
|
||||
<PackageReference Include="System.Text.Json" Version="9.0.5" />
|
||||
<PackageReference Include="TextCopy" Version="6.2.1" />
|
||||
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
|
||||
|
@ -16,8 +16,20 @@ internal static partial class HelperMarkdown
|
||||
|
||||
private record Input(string? Destination,
|
||||
string Source,
|
||||
string? ReplaceWithTitle,
|
||||
bool UseProcessStart);
|
||||
|
||||
private record Table(ReadOnlyCollection<string> Columns,
|
||||
int ColumnsLine,
|
||||
ReadOnlyCollection<ReadOnlyCollection<string>> Rows,
|
||||
string? Title);
|
||||
|
||||
private record Block(int Line,
|
||||
string? Json,
|
||||
int RowCount,
|
||||
ReadOnlyCollection<string>? Rows,
|
||||
string? Title);
|
||||
|
||||
private record Record(string Directory,
|
||||
string File,
|
||||
string[] Lines);
|
||||
@ -30,7 +42,7 @@ internal static partial class HelperMarkdown
|
||||
string FileNameWithoutExtension,
|
||||
ReadOnlyDictionary<string, object> FrontMatterYaml,
|
||||
string H1,
|
||||
bool IsGitOthersModifiedAndDeletedExcludingStandard,
|
||||
bool? IsGitOthersModifiedAndDeletedExcludingStandard,
|
||||
bool IsKanbanIndex,
|
||||
bool IsKanbanMarkdown,
|
||||
DateTime LastWriteDateTime,
|
||||
@ -49,15 +61,27 @@ internal static partial class HelperMarkdown
|
||||
|
||||
private record MarkdownFileH1AndRelativePath(MarkdownFile? MarkdownFile, string[]? Lines, string? H1, string? RelativePath);
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[JsonSerializable(typeof(Dictionary<string, object>))]
|
||||
internal partial class DictionaryStringAndObjectSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[JsonSerializable(typeof(Dictionary<string, JsonElement>))]
|
||||
internal partial class DictionaryStringAndJsonElementSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[GeneratedRegex("([A-Z]+(.))")]
|
||||
private static partial Regex UpperCase();
|
||||
|
||||
[GeneratedRegex("(~~)?(#)([a-zA-Z0-9]{6})(~~)?( )")]
|
||||
private static partial Regex HtmlColor();
|
||||
|
||||
[GeneratedRegex("[\\s!?.,@:;|\\\\/\"'`£$%\\^&*{}[\\]()<>~#+\\-=_¬]+")]
|
||||
private static partial Regex InvalidCharacter();
|
||||
|
||||
private static MarkdownExtra GetMarkdownExtra(MarkdownFileAndLines markdownFileAndLines)
|
||||
{
|
||||
MarkdownExtra result;
|
||||
@ -301,10 +325,10 @@ internal static partial class HelperMarkdown
|
||||
if (!directoryInfo.Exists || (!string.IsNullOrEmpty(directoryInfo.LinkTarget) && !Directory.Exists(directoryInfo.LinkTarget)))
|
||||
continue;
|
||||
collection.AddRange(GetFiles(appSettings, directoryInfo, SearchOption.TopDirectoryOnly));
|
||||
foreach (FileInfo file in collection)
|
||||
results.Add(file);
|
||||
foreach (FileInfo fileInfo in collection)
|
||||
results.Add(fileInfo);
|
||||
}
|
||||
return new(results);
|
||||
return (from l in results orderby l.FullName select l).ToArray().AsReadOnly();
|
||||
}
|
||||
|
||||
internal static LineNumber GetLineNumbers(FileInfo fileInfo)
|
||||
@ -525,7 +549,7 @@ internal static partial class HelperMarkdown
|
||||
h1Check = $"# {h1[2..]}";
|
||||
if (h1Check.Length == h1.Length && h1Check != h1)
|
||||
{
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
lines[markdownFile.LineNumber.H1.Value] = h1Check;
|
||||
File.WriteAllLines(markdownFile.File, lines);
|
||||
@ -541,7 +565,7 @@ internal static partial class HelperMarkdown
|
||||
checkName = Path.Combine(markdownFile.Directory, checkFileName);
|
||||
if (checkName == markdownFile.File)
|
||||
continue;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
File.Move(markdownFile.File, checkName);
|
||||
result += 1;
|
||||
@ -658,6 +682,7 @@ internal static partial class HelperMarkdown
|
||||
Input result;
|
||||
string? destination = null;
|
||||
bool useProcessStart = false;
|
||||
string? replaceWithTitle = null;
|
||||
string source = Path.GetFullPath(args[0]);
|
||||
for (int i = 1; i < args.Count; i++)
|
||||
{
|
||||
@ -667,6 +692,8 @@ internal static partial class HelperMarkdown
|
||||
useProcessStart = args[i + 1] == "true";
|
||||
else if (args[i][1] == 'd')
|
||||
destination = Path.GetFullPath(args[i + 1]);
|
||||
else if (args[i][1] == 't')
|
||||
replaceWithTitle = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -678,11 +705,11 @@ internal static partial class HelperMarkdown
|
||||
if (!Directory.Exists(destination))
|
||||
_ = Directory.CreateDirectory(destination);
|
||||
}
|
||||
result = new(destination, source, useProcessStart);
|
||||
result = new(Destination: destination, Source: source, ReplaceWithTitle: replaceWithTitle, UseProcessStart: useProcessStart);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, MarkdownFileAndLines> GetRelativeToCollection(AppSettings appSettings, Input input, ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles)
|
||||
private static ReadOnlyDictionary<string, MarkdownFileAndLines> GetRelativeToCollection(AppSettings appSettings, Input input, ReadOnlyCollection<string>? gitOthersModifiedAndDeletedExcludingStandardFiles)
|
||||
{
|
||||
Dictionary<string, MarkdownFileAndLines> results = [];
|
||||
string h1;
|
||||
@ -696,17 +723,22 @@ internal static partial class HelperMarkdown
|
||||
string fileNameWithoutExtension;
|
||||
ReadOnlyCollection<string> lines;
|
||||
ReadOnlyDictionary<string, object> frontMatterYaml;
|
||||
bool isGitOthersModifiedAndDeletedExcludingStandard;
|
||||
bool? isGitOthersModifiedAndDeletedExcludingStandard;
|
||||
ReadOnlyCollection<FileInfo> files = GetFiles(appSettings, input);
|
||||
foreach (FileInfo fileInfo in files)
|
||||
{ // cSpell:disable
|
||||
if (fileInfo.DirectoryName is null)
|
||||
continue;
|
||||
key = Path.GetRelativePath(input.Source, fileInfo.FullName);
|
||||
if (gitOthersModifiedAndDeletedExcludingStandardFiles is null)
|
||||
isGitOthersModifiedAndDeletedExcludingStandard = null;
|
||||
else
|
||||
{
|
||||
isWithinSource = fileInfo.FullName.Contains(input.Source);
|
||||
isGitOthersModifiedAndDeletedExcludingStandard = gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(fileInfo.FullName);
|
||||
if (!isWithinSource && results.ContainsKey(key))
|
||||
continue;
|
||||
}
|
||||
lineNumber = GetLineNumbers(fileInfo);
|
||||
lines = lineNumber.Lines;
|
||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
|
||||
@ -716,7 +748,7 @@ internal static partial class HelperMarkdown
|
||||
(type, h1) = GetTypeAndH1(appSettings, h1, lines, lineNumber);
|
||||
else
|
||||
{
|
||||
if (!isGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (isGitOthersModifiedAndDeletedExcludingStandard is not null && !isGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
type = appSettings.DefaultNoteType;
|
||||
File.WriteAllLines(fileInfo.FullName, ["---", $"type: {type}\"", "---", string.Empty, $"# {h1}"]);
|
||||
@ -724,20 +756,20 @@ internal static partial class HelperMarkdown
|
||||
}
|
||||
isKanbanMarkdown = fileInfo.Name.EndsWith(".knb.md");
|
||||
isKanbanIndex = fileNameWithoutExtension == "index" && type.StartsWith("kanb", StringComparison.OrdinalIgnoreCase);
|
||||
markdownFile = new(fileInfo.CreationTime,
|
||||
fileInfo.DirectoryName,
|
||||
fileInfo.Extension,
|
||||
fileInfo.FullName,
|
||||
fileInfo.Name,
|
||||
fileNameWithoutExtension,
|
||||
frontMatterYaml,
|
||||
h1,
|
||||
isGitOthersModifiedAndDeletedExcludingStandard,
|
||||
isKanbanIndex,
|
||||
isKanbanMarkdown,
|
||||
fileInfo.LastWriteTime,
|
||||
lineNumber,
|
||||
type);
|
||||
markdownFile = new(CreationDateTime: fileInfo.CreationTime,
|
||||
Directory: fileInfo.DirectoryName,
|
||||
Extension: fileInfo.Extension,
|
||||
File: fileInfo.FullName,
|
||||
FileName: fileInfo.Name,
|
||||
FileNameWithoutExtension: fileNameWithoutExtension,
|
||||
FrontMatterYaml: frontMatterYaml,
|
||||
H1: h1,
|
||||
IsGitOthersModifiedAndDeletedExcludingStandard: isGitOthersModifiedAndDeletedExcludingStandard,
|
||||
IsKanbanIndex: isKanbanIndex,
|
||||
IsKanbanMarkdown: isKanbanMarkdown,
|
||||
LastWriteDateTime: fileInfo.LastWriteTime,
|
||||
LineNumber: lineNumber,
|
||||
Type: type);
|
||||
results.Add(key, new(markdownFile, lines.ToArray()));
|
||||
} // cSpell:restore
|
||||
return new(results);
|
||||
@ -763,7 +795,7 @@ internal static partial class HelperMarkdown
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (markdownFile.IsKanbanMarkdown)
|
||||
continue;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
if (markdownFile.LineNumber.FrontMatterYamlEnd is null)
|
||||
continue;
|
||||
@ -797,7 +829,7 @@ internal static partial class HelperMarkdown
|
||||
circularReference = false;
|
||||
lines = relativeTo.Value.Lines;
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
@ -859,7 +891,7 @@ internal static partial class HelperMarkdown
|
||||
found = false;
|
||||
lines = relativeTo.Value.Lines;
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
@ -912,7 +944,7 @@ internal static partial class HelperMarkdown
|
||||
write = false;
|
||||
lines = relativeTo.Value.Lines;
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (!input.UseProcessStart && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (!input.UseProcessStart && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
@ -940,7 +972,7 @@ internal static partial class HelperMarkdown
|
||||
}
|
||||
if (!write)
|
||||
continue;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
File.WriteAllLines(markdownFile.File, lines);
|
||||
result += 1;
|
||||
@ -975,7 +1007,7 @@ internal static partial class HelperMarkdown
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (markdownFile.IsKanbanIndex)
|
||||
continue;
|
||||
if (!input.UseProcessStart && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (!input.UseProcessStart && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
if (!File.Exists(markdownFile.File))
|
||||
continue;
|
||||
@ -1040,7 +1072,7 @@ internal static partial class HelperMarkdown
|
||||
}
|
||||
if (!write)
|
||||
continue;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
File.WriteAllLines(markdownFile.File, lines);
|
||||
result += 1;
|
||||
@ -1057,20 +1089,14 @@ internal static partial class HelperMarkdown
|
||||
MarkdownFileAndLines? markdownFileAndLines = GetKanbanIndexMarkdownFileAndLines(relativeToCollection);
|
||||
if (markdownFileAndLines is not null && File.Exists(markdownFileAndLines.MarkdownFile.File))
|
||||
{
|
||||
ReadOnlyDictionary<string, List<Card>> columnsToCards;
|
||||
ReadOnlyDictionary<string, List<Card>> columnsToCards = GetColumnsToCards(input, relativeToCollection, markdownFileAndLines);
|
||||
string jsonFile = Path.Combine(input.Destination, $"{nameof(columnsToCards)}.json");
|
||||
if (File.Exists(jsonFile))
|
||||
File.Delete(jsonFile);
|
||||
columnsToCards = GetColumnsToCards(input, relativeToCollection, markdownFileAndLines);
|
||||
if (columnsToCards.Count == 0)
|
||||
File.WriteAllText(jsonFile, "{}");
|
||||
else
|
||||
{
|
||||
string json = JsonSerializer.Serialize(columnsToCards, ColumnsAndCardsSourceGenerationContext.Default.ReadOnlyDictionaryStringListCard);
|
||||
string old = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile);
|
||||
string json = columnsToCards.Count == 0 ? "{}" : JsonSerializer.Serialize(columnsToCards, ColumnsAndCardsSourceGenerationContext.Default.ReadOnlyDictionaryStringListCard);
|
||||
if (json != old)
|
||||
File.WriteAllText(jsonFile, json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static (string type, string h1) GetTypeAndH1(AppSettings appSettings, string h1, ReadOnlyCollection<string> lines, LineNumber lineNumber)
|
||||
{
|
||||
@ -1122,7 +1148,7 @@ internal static partial class HelperMarkdown
|
||||
results.Insert(0, string.Empty);
|
||||
}
|
||||
results.Insert(0, "---");
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
{
|
||||
results.Insert(0, updatedLine);
|
||||
results.Insert(0, createdLine);
|
||||
@ -1140,7 +1166,7 @@ internal static partial class HelperMarkdown
|
||||
}
|
||||
if (markdownFile.LineNumber.Type is null)
|
||||
results.Insert(markdownFile.LineNumber.FrontMatterYamlEnd.Value, typeLine);
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
{
|
||||
if (markdownFile.LineNumber.Updated is null)
|
||||
results.Insert(markdownFile.LineNumber.FrontMatterYamlEnd.Value, updatedLine);
|
||||
@ -1176,7 +1202,7 @@ internal static partial class HelperMarkdown
|
||||
}
|
||||
if (results.Count == lines.Length && string.Join('\r', lines) == string.Join('\r', results))
|
||||
continue;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
File.WriteAllLines(markdownFile.File, results);
|
||||
File.SetLastWriteTime(markdownFile.File, markdownFile.LastWriteDateTime);
|
||||
@ -1235,7 +1261,351 @@ internal static partial class HelperMarkdown
|
||||
logger.LogInformation("{updated} Markdown file(s) were updated", updated);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(input.Destination))
|
||||
{
|
||||
SaveColumnToCards(input, relativeToCollection);
|
||||
SaveTablesToJson(appSettings, logger, input);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SaveTablesToJson(AppSettings appSettings, ILogger<Worker> logger, Input input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input.Destination))
|
||||
throw new NotSupportedException();
|
||||
string old;
|
||||
string json;
|
||||
string[] lines;
|
||||
string fileName;
|
||||
List<Block> blocks;
|
||||
string directoryName;
|
||||
List<string>? jsonLines;
|
||||
MarkdownFile markdownFile;
|
||||
List<string> fileNames = [];
|
||||
ReadOnlyCollection<Table> tables;
|
||||
Dictionary<string, List<string>> results = [];
|
||||
ReadOnlyCollection<Block> javaScriptObjectNotationBlocks;
|
||||
ReadOnlyCollection<Block> yetAnotherMarkupLanguageBlocks;
|
||||
ReadOnlyDictionary<string, MarkdownFileAndLines> relativeToCollection = GetRelativeToCollection(appSettings, input, gitOthersModifiedAndDeletedExcludingStandardFiles: null);
|
||||
foreach (KeyValuePair<string, MarkdownFileAndLines> relativeTo in relativeToCollection)
|
||||
{
|
||||
if (relativeTo.Value.Lines.Length == 0)
|
||||
continue;
|
||||
lines = relativeTo.Value.Lines;
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (markdownFile.IsKanbanIndex)
|
||||
continue;
|
||||
if (markdownFile.IsKanbanMarkdown)
|
||||
continue;
|
||||
if (markdownFile.FileName.StartsWith("index.yml.md"))
|
||||
continue;
|
||||
if (!File.Exists(markdownFile.File))
|
||||
continue;
|
||||
tables = GetTables(lines);
|
||||
javaScriptObjectNotationBlocks = GetJavaScriptObjectNotationBlocks(lines);
|
||||
yetAnotherMarkupLanguageBlocks = GetYetAnotherMarkupLanguageBlocks(lines);
|
||||
if (tables.Count == 0 && javaScriptObjectNotationBlocks.Count == 0 && yetAnotherMarkupLanguageBlocks.Count == 0)
|
||||
continue;
|
||||
fileName = Path.Combine(input.Destination, $"{markdownFile.FileNameWithoutExtension}.json");
|
||||
if (fileNames.Contains(fileName))
|
||||
continue;
|
||||
fileNames.Add(fileName);
|
||||
blocks = [];
|
||||
blocks.AddRange(GetBlocks(tables));
|
||||
blocks.AddRange(javaScriptObjectNotationBlocks);
|
||||
blocks.AddRange(GetBlocks(logger, markdownFile, yetAnotherMarkupLanguageBlocks));
|
||||
if (blocks.Count == 0)
|
||||
continue;
|
||||
directoryName = Path.GetFileName(Path.Combine(input.Destination, markdownFile.Directory));
|
||||
if (!results.TryGetValue(directoryName, out jsonLines))
|
||||
{
|
||||
results.Add(directoryName, []);
|
||||
if (!results.TryGetValue(directoryName, out jsonLines))
|
||||
throw new Exception();
|
||||
}
|
||||
json = GetJson(input, markdownFile, blocks.AsReadOnly());
|
||||
jsonLines.Add(json);
|
||||
}
|
||||
foreach (KeyValuePair<string, List<string>> keyValuePair in results)
|
||||
{
|
||||
json = string.Concat('[', Environment.NewLine, string.Join($",{Environment.NewLine}", keyValuePair.Value), Environment.NewLine, ']');
|
||||
fileName = Path.Combine(input.Destination, $"{keyValuePair.Key}.json");
|
||||
old = !File.Exists(fileName) ? string.Empty : File.ReadAllText(fileName);
|
||||
if (json != old)
|
||||
{
|
||||
File.WriteAllText(fileName, json);
|
||||
logger.LogInformation("Updated json file for <{fileName}>", fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Table> GetTables(string[] lines)
|
||||
{
|
||||
List<Table> results = [];
|
||||
Table table;
|
||||
string? title;
|
||||
string[] segments;
|
||||
int? columnsLine = null;
|
||||
List<ReadOnlyCollection<string>> rows = [];
|
||||
string[]? columns = null;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (columns is null && (!lines[i].StartsWith('|') || !lines[i].EndsWith('|') || i + 3 >= lines.Length))
|
||||
continue;
|
||||
if (columns is null && (lines[i + 1].Length < 3 || lines[i + 1][0] != '|' || (lines[i + 1][1] is not ':' and not '-')))
|
||||
continue;
|
||||
if (columns is null)
|
||||
{
|
||||
columnsLine = i;
|
||||
segments = lines[i][1..^1].Split('|');
|
||||
columns = (from l in segments select l.Trim()).ToArray();
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
segments = lines[i].Length < 3 ? [] : lines[i][1..^1].Split('|');
|
||||
rows.Add((from l in segments select l.Trim()).ToArray().AsReadOnly());
|
||||
if (columns is not null && columnsLine is not null && string.IsNullOrEmpty(lines[i]))
|
||||
{
|
||||
if (columnsLine.Value - 2 > 0 && lines[columnsLine.Value - 2].StartsWith('#'))
|
||||
title = lines[columnsLine.Value - 2];
|
||||
else if (columnsLine.Value - 4 > 0 && lines[columnsLine.Value - 4].StartsWith('#'))
|
||||
title = lines[columnsLine.Value - 4];
|
||||
else
|
||||
title = null;
|
||||
rows.RemoveAt(rows.Count - 1);
|
||||
table = new(columns.AsReadOnly(), columnsLine.Value, rows.AsReadOnly(), title);
|
||||
results.Add(table);
|
||||
columnsLine = null;
|
||||
columns = null;
|
||||
rows = [];
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string GetParamCase(string value)
|
||||
{
|
||||
string result;
|
||||
StringBuilder stringBuilder = new(value);
|
||||
Match[] matches = UpperCase().Matches(value).ToArray();
|
||||
for (int i = matches.Length - 1; i > -1; i--)
|
||||
_ = stringBuilder.Insert(matches[i].Index, '-');
|
||||
string[] segments = InvalidCharacter().Split(stringBuilder.ToString().ToLower());
|
||||
result = string.Join('-', segments).Trim('-');
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Block> GetBlocks(ReadOnlyCollection<Table> tables)
|
||||
{
|
||||
List<Block> results = [];
|
||||
Block block;
|
||||
string json;
|
||||
foreach (Table table in tables)
|
||||
{
|
||||
if (table.Title is null)
|
||||
continue;
|
||||
if (table.Rows.Count == 0)
|
||||
continue;
|
||||
json = GetJson(table);
|
||||
block = new(Line: table.ColumnsLine, Json: json, RowCount: table.Rows.Count, Rows: null, Title: table.Title);
|
||||
results.Add(block);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string GetJson(Table table)
|
||||
{
|
||||
string result;
|
||||
string line;
|
||||
string value;
|
||||
string[] segments;
|
||||
List<string> lines = [];
|
||||
for (int i = 0; i < table.Rows.Count; i++)
|
||||
{
|
||||
line = "{";
|
||||
segments = table.Rows[i].ToArray();
|
||||
if (segments.Length != table.Columns.Count)
|
||||
break;
|
||||
for (int c = 0; c < segments.Length; c++)
|
||||
{
|
||||
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
line += string.Concat('"', table.Columns[c].Trim('"'), '"', ':', '"', value, '"', ',');
|
||||
}
|
||||
line = string.Concat(line[..^1], '}');
|
||||
lines.Add(line);
|
||||
}
|
||||
result = string.Concat('[', Environment.NewLine, string.Join($",{Environment.NewLine}", lines), Environment.NewLine, ']');
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Block> GetJavaScriptObjectNotationBlocks(string[] lines)
|
||||
{
|
||||
List<Block> results = [];
|
||||
string json;
|
||||
string? title;
|
||||
int? blockLine = null;
|
||||
List<string> rows = [];
|
||||
Block javaScriptObjectNotationBlock;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (blockLine is null && !lines[i].StartsWith("```json"))
|
||||
continue;
|
||||
if (blockLine is null)
|
||||
{
|
||||
blockLine = i;
|
||||
continue;
|
||||
}
|
||||
rows.Add(lines[i]);
|
||||
if (blockLine is not null && lines[i] == "```")
|
||||
{
|
||||
rows.RemoveAt(rows.Count - 1);
|
||||
if (blockLine.Value - 2 > 0 && lines[blockLine.Value - 2].StartsWith('#'))
|
||||
title = lines[blockLine.Value - 2];
|
||||
else if (blockLine.Value - 4 > 0 && lines[blockLine.Value - 4].StartsWith('#'))
|
||||
title = lines[blockLine.Value - 4];
|
||||
else
|
||||
title = null;
|
||||
if (string.IsNullOrEmpty(title))
|
||||
continue;
|
||||
json = string.Join(Environment.NewLine, rows);
|
||||
javaScriptObjectNotationBlock = new(Line: blockLine.Value, Json: json, RowCount: rows.Count, Rows: null, Title: title);
|
||||
results.Add(javaScriptObjectNotationBlock);
|
||||
blockLine = null;
|
||||
rows = [];
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Block> GetYetAnotherMarkupLanguageBlocks(string[] lines)
|
||||
{
|
||||
List<Block> results = [];
|
||||
string? title = null;
|
||||
int? blockLine = null;
|
||||
List<string> rows = [];
|
||||
Block yetAnotherMarkupLanguageBlock;
|
||||
if (lines[0] == "---")
|
||||
{
|
||||
for (int i = 1; i < lines.Length; i++)
|
||||
{
|
||||
rows.Add(lines[i]);
|
||||
if (lines[i] == "---")
|
||||
{
|
||||
rows.RemoveAt(rows.Count - 1);
|
||||
yetAnotherMarkupLanguageBlock = new(Line: 0, Json: null, RowCount: rows.Count, Rows: rows.AsReadOnly(), Title: title);
|
||||
results.Add(yetAnotherMarkupLanguageBlock);
|
||||
rows = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
rows = [];
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (blockLine is null && !lines[i].StartsWith("```yml") && !lines[i].StartsWith("```yaml"))
|
||||
continue;
|
||||
if (blockLine is null)
|
||||
{
|
||||
blockLine = i;
|
||||
continue;
|
||||
}
|
||||
rows.Add(lines[i]);
|
||||
if (blockLine is not null && lines[i] == "```")
|
||||
{
|
||||
rows.RemoveAt(rows.Count - 1);
|
||||
if (blockLine.Value - 2 > 0 && lines[blockLine.Value - 2].StartsWith('#'))
|
||||
title = lines[blockLine.Value - 2];
|
||||
else if (blockLine.Value - 4 > 0 && lines[blockLine.Value - 4].StartsWith('#'))
|
||||
title = lines[blockLine.Value - 4];
|
||||
else
|
||||
title = null;
|
||||
yetAnotherMarkupLanguageBlock = new(Line: blockLine.Value, Json: null, RowCount: rows.Count, Rows: rows.AsReadOnly(), Title: title);
|
||||
results.Add(yetAnotherMarkupLanguageBlock);
|
||||
blockLine = null;
|
||||
rows = [];
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Block> GetBlocks(ILogger<Worker> logger, MarkdownFile markdownFile, ReadOnlyCollection<Block> yetAnotherMarkupLanguageBlocks)
|
||||
{
|
||||
List<Block> results = [];
|
||||
string key;
|
||||
Block block;
|
||||
string json;
|
||||
string text;
|
||||
Dictionary<string, object>? keyValuePairs;
|
||||
Dictionary<string, object> keyValuePairsB = [];
|
||||
#pragma warning disable IL3050
|
||||
IDeserializer deserializer = new DeserializerBuilder().Build();
|
||||
#pragma warning restore IL3050
|
||||
foreach (Block yaml in yetAnotherMarkupLanguageBlocks)
|
||||
{
|
||||
if (yaml.Rows is null || yaml.RowCount == 0)
|
||||
continue;
|
||||
if (yaml.Title is null && yaml.Line != 0)
|
||||
continue;
|
||||
text = string.Join(Environment.NewLine, yaml.Rows);
|
||||
try
|
||||
{ keyValuePairs = deserializer.Deserialize<Dictionary<string, object>>(text); }
|
||||
catch (Exception)
|
||||
{
|
||||
keyValuePairs = null;
|
||||
logger.LogWarning("Invalid yaml file for <{file}>", markdownFile.FileName);
|
||||
}
|
||||
if (keyValuePairs is null)
|
||||
continue;
|
||||
keyValuePairsB.Clear();
|
||||
foreach (KeyValuePair<string, object> keyValuePair in keyValuePairs)
|
||||
{
|
||||
key = GetParamCase(keyValuePair.Key);
|
||||
if (keyValuePairsB.ContainsKey(key))
|
||||
continue;
|
||||
if (keyValuePair.Value is IDictionary<object, object>)
|
||||
{
|
||||
logger.LogWarning("yaml contains a dictionary not allowed in AOT <{file}>", markdownFile.FileName);
|
||||
break;
|
||||
}
|
||||
else if (keyValuePair.Value is not ICollection<object> collection)
|
||||
keyValuePairsB.Add(key, keyValuePair.Value);
|
||||
else
|
||||
keyValuePairsB.Add(key, string.Join(',', collection));
|
||||
}
|
||||
try
|
||||
{ json = JsonSerializer.Serialize(keyValuePairsB, DictionaryStringAndObjectSourceGenerationContext.Default.DictionaryStringObject); }
|
||||
catch (Exception)
|
||||
{
|
||||
logger.LogWarning("yaml contains special values not allowed in AOT <{file}>", markdownFile.FileName);
|
||||
continue;
|
||||
}
|
||||
block = new(Line: yaml.Line, Json: json, RowCount: yaml.Rows.Count, Rows: null, Title: yaml.Title);
|
||||
results.Add(block);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string GetJson(Input input, MarkdownFile markdownFile, ReadOnlyCollection<Block> blocks)
|
||||
{
|
||||
string result;
|
||||
string paramCase;
|
||||
List<string> lines = [];
|
||||
string fileNameParamCase = GetParamCase(markdownFile.FileNameWithoutExtension);
|
||||
foreach (Block block in blocks.OrderBy(l => l.Line))
|
||||
{
|
||||
paramCase = block.Title is null ? $"Line-{block.Line}" : GetParamCase(block.Title);
|
||||
if (!string.IsNullOrEmpty(input.ReplaceWithTitle) && paramCase == input.ReplaceWithTitle)
|
||||
paramCase = $"{fileNameParamCase}-{block.Line}";
|
||||
lines.Add($"\"{paramCase}\": {block.Json}");
|
||||
}
|
||||
result = string.Concat('{',
|
||||
Environment.NewLine,
|
||||
$"\"{fileNameParamCase}\": ",
|
||||
'{',
|
||||
Environment.NewLine,
|
||||
string.Join($",{Environment.NewLine}", lines),
|
||||
Environment.NewLine,
|
||||
'}',
|
||||
Environment.NewLine,
|
||||
'}');
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
7
Scripts/markdown.js
Normal file
7
Scripts/markdown.js
Normal file
@ -0,0 +1,7 @@
|
||||
// import data from './oi-metrology-viewer-0-Line-yaml.json' with { type: 'json' };
|
||||
// import data from '../.vscode/oi-metrology-viewer-0-Line-yaml.json' with { type: 'json' };
|
||||
import data from '../.vscode/.helper/hosts-legend-table.json' with { type: 'json' };
|
||||
|
||||
data.forEach(element => {
|
||||
console.log(element.Concat);
|
||||
});
|
Reference in New Issue
Block a user