11 Commits

Author SHA1 Message Date
6ce555a08a Add logging functionality for equipment availability tracking (Day-Helper-2025-12-03) 2025-12-03 09:37:57 -07:00
e4a3e0a64b write-identifiers (Day-Helper-2025-07-26) 2025-11-30 11:03:32 -07:00
74341fa5eb Better support for yaml within Markdown Helper
Stratus merge
2025-11-27 20:35:09 -07:00
a33436bc4e Refactor exception handling to remove specific exception types in multiple helper classes 2025-11-23 13:21:43 -07:00
90608efa85 log-to-trace (Day-Helper-2025-11-23)
move-back (Day-Helper-2025-11-22)

stratus-split (Day-Helper-2025-11-18)

Set last write time for renamed files in Rename method
2025-11-22 16:46:16 -07:00
1010bcb772 Update project to target .NET 10.0 and adjust related configurations 2025-11-15 13:57:26 -07:00
e11f80dc1c Add helper classes for XML parsing and directory zipping
- Implemented ArrayOfRuntimeInstanceStatusReport and related classes for XML deserialization.
- Added methods to download XML data, parse it, and serialize it to JSON format.
- Created functionality to zip run directories based on specified patterns and delete original files.
- Enhanced logging for better traceability during file processing and zipping operations.
2025-11-14 17:27:05 -07:00
097a6c0130 Enhance Rename functionality to create a 'DUP' directory for duplicate files and improve logging for file operations 2025-11-10 17:07:55 -07:00
23db474f53 Add CombineFiles functionality for Day-Helper-2025-10-22 and update related configurations 2025-11-07 10:29:39 -07:00
46590d48cd update launch.json and helper files to use J: drive paths 2025-09-29 18:21:11 -07:00
7a2492f14b rename-then-find-first-and-last (Day-Helper-2025-09-26) 2025-09-29 16:06:06 -07:00
41 changed files with 3297 additions and 1206 deletions

244
.vscode/launch.json vendored
View File

@ -9,70 +9,87 @@
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build",
"program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/File-Folder-Helper.dll",
"program": "${workspaceFolder}/bin/Debug/net10.0/win-x64/File-Folder-Helper.dll",
"args": [
"s",
"X",
"A:/6-Other-Large-Z/Linux-Ubuntu-Affirm/etc/nginx/include~B:/6-Other-Large-Z/Linux-Ubuntu-BCHS/etc/nginx/include~J:/6-Other-Large-Z/Linux-Ubuntu-JMLC/etc/nginx/include~P:/6-Other-Large-Z/Linux-Ubuntu-Phares/etc/nginx/include",
"Day-Helper-2025-09-08",
"*.conf",
"/etc/nginx/include/",
"server_name",
"proxy_pass~root",
"oauth2",
"\\\\mesfs.infineon.com\\EC_EAFLog\\Production\\Logs\\EAF-Info-Warn-002-061-001-Trace",
"Day-Helper-2025-12-03",
"*.trc",
"102400",
"s",
"X",
"P:/6-Other-Large-Z/Current-Results/A2)People/c9dbce3b/([])/File-Folder-Helper/638443643487798783/638443643487798783",
"Day-Helper-2024-05-18",
"people.json",
"person",
"ownerId,name,birthDate",
"c76905af-c06a-4a78-a9a7-c32f5b58e793",
"yyyy-MM-dd",
"1900-01-01",
"s",
"X",
"P:/1-Images-A/Images-0b793904",
"Day-Helper-2025-07-26",
"4e+9",
"L:/Git/AA/Rename/.vscode/.UserSecrets/secrets.json",
".avif~.bmp~.gif~.heic~.insp~.jp2~.jpe~.jpeg~.jpg~.jxl~.png~.psd~.raw~.rw2~.svg~.tif~.tiff~.webp~.3gp~.3gpp~.avi~.dvr-ms~.flv~.insv~.m2t~.m2ts~.m4v~.mkv~.mov~.mp4~.mpe~.mpeg~.mpg~.mts~.ts~.webm~.wmv",
"P:/6-Other-Large-Z/Current-Results/C)Resize/0b793904/Original",
"(helper)",
"s",
"X",
"P:/1-Images-A/Images-0b793904",
"Day-Helper-2024-12-17",
".job.json",
"thumbs.db~sync.ffs_db~verify.json~.html",
"I:/0-ISO-A",
"D:/5-Other-Small/Disk/Snap2HTML/Snap2HTML.exe",
"s",
"X",
"P:/Tmp/Phares/Helper-2025-07-20",
"D:/Tmp/Phares",
"Day-Helper-2025-07-20",
"871467010009.jpg",
"L:/Git/AA/Rename/.vscode/.UserSecrets/secrets.json",
"A:/()/638432064000000000.51/1401-08-03_02/2023/X+441981864000000000/871467010009.444090906.jpg.png",
"P:/6-Other-Large-Z/Current-Results/E)Distance/0b793904/()/638432064000000000.51/1401-08-03_02/2023/X+441981864000000000/871467010009.444090906.jpg.png",
"*.png",
"D:/{}/DisneyWorld 2019/Magic Kingdom/871467010009.jpg.xmp",
"P:/{}/DisneyWorld 2019/Magic Kingdom/871467010009.jpg.xmp",
"*.xmp",
"{}-output",
"P:/5-Other-Small/(helper)",
"true",
"s",
"M",
"J:/5-Other-Small/Notes/Infineon",
"-d",
"J:/5-Other-Small/Notes/Infineon/.vscode/helper",
"-t",
"fcrespo82.markdown-table-formatter",
"-e",
"J:/5-Other-Small/Notes/Infineon/.User",
"s",
"X",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/Log",
"Day-Helper-2025-07-10",
"R*",
"EAF_INFO*",
"\\\\mesfs.infineon.com\\EC_EAFLog\\Production\\Logs\\EAF-Info-Warn-002-059-000",
"Day-Helper-2025-11-23",
"EAF_R*.info",
"yyyy-MM-dd~HH:mm:ss,fff",
"13",
"EAF Version~Shutdown triggered~Lost connection~EAF Backbone terminating~Publishing Connection Lost Transaction",
"2025-11-18 13:59:59,999",
"256",
"\\\\mesfs.infineon.com\\EC_EAFLog\\Production\\Logs\\EAF-Info-Warn-002-059-000-Trace",
".trc",
"s",
"X",
"D:/ProgramData/EC_Characterization_Si/Dummy/Stratus",
"Day-Helper-2025-11-18",
"Bad.txt",
"Elapsed",
"DataBiorad",
"s",
"X",
"D:/Tmp",
"Day-Helper-2025-11-13",
"http://messa08ec.infineon.com:9003/StatusQueryV2/instance/statuses",
"Status-Query-V2-Instance-Statuses",
"s",
"X",
"\\\\mesfs.infineon.com\\EC_Characterization_Si\\_Archive-2024\\BIORAD2\\2024_Week_01\\2024-01-01\\-TMID-_2024-01-01_06;05_AM_822702806",
"Day-Helper-2025-11-14",
"*.pdsf",
"yyyy-MM-dd",
"yyyy_Week_##",
"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:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/WorkWeek",
"Day-Helper-2025-11-11",
"*.json",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/WorkWeekOrder",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/WorkWeekOrderWithFiltered",
"s",
"X",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/JavaScriptObjectNotation",
"Day-Helper-2025-07-09",
"Day-Helper-2025-10-22",
"*.json",
"987654321",
".agg",
"id93,vp93,ProcessState,id154,vp154,SystemState,id78,vp78,LL1State,id83,vp83,LL2State,id176,vp176,TotalWaferCount,id80,vp80,LL1Lotid,id85,vp85,LL2Lotid,id153,vp153,PPSTEPNAME,id221,vp221,LeftDefaultRecipe,id222,vp222,RightDefaultRecipe,id223,vp223,RecipeCompleteMsg",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/Reactor",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/WorkWeek",
"s",
"X",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/PollPath",
@ -86,138 +103,7 @@
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/Markdown",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/KeyValuePairs",
"654321",
"s",
"s",
"X",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/R55",
"Day-Helper-2023-11-30",
"yyMMddhhmmssfff",
"\"vp154\"",
"s",
"X",
"P:/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",
"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",
"Day-Helper-2025-05-19",
"D:/Tmp/phares/VisualStudioCodeLeft",
"z-include-patterns.nsv",
"z-exclude-patterns.nsv",
"http://localhost:5004",
"/api/SyncV1/?",
",L",
".G",
"+~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",
"s",
"X",
"\\\\mesfs.infineon.com\\EC_Characterization_Si\\Archive\\BIORAD4\\2025_Week_16\\2025-04-17",
"Day-Helper-2025-02-19",
"csv-*.pdsf",
"*.pdsf",
"Time,HeaderUniqueId,UniqueId,Date,Wafer,Position,BIORAD4",
",BIORAD4",
",BIORAD4",
"Test|EventId,Date|DateTime,Position|Slot,DeltaThicknessSlotsOneAndTwentyFive|Actual Delta Thick Pts 1 and 25,PercentDeltaThicknessSlotsOneAndTwentyFive|% Delta Thick Pts 1 and 25,MID|Cassette,Lot|Batch,Title|Batch,Wafer|Text,Thickness|Site,MeanThickness|GradeMean,|BIORAD4",
"Time,A_LOGISTICS,B_LOGISTICS,Test,Count,Index,MesEntity,MID,Date,Employee,Lot,PSN,Reactor,Recipe,Cassette,GradeStdDev,HeaderUniqueId,Layer,MeanThickness,PassFail,RDS,Slot,Title,UniqueId,Wafer,Zone,Mean,Position,StdDev,Thickness,ThicknessSlotOne,ThicknessSlotTwentyFive,DeltaThicknessSlotsOneAndTwentyFive,PercentDeltaThicknessSlotsOneAndTwentyFive",
"Time,A_LOGISTICS,B_LOGISTICS,Count,Sequence,MesEntity,Index,Batch,Cassette,DateTime,Destination,Mean,PassFail,Recipe,Reference,Site,Slot,Source,StdDev,Text,GradeMean,GradeStdDev,RDS,PSN,Reactor,Layer,Zone,Employee,InferredLot,Thickness First Slot,Thickness Last Slot,Actual Delta Thick Pts 1 and 25,% Delta Thick Pts 1 and 25,EventId",
"0,1,2,31,3,6,5,8,9,27,7,23,24,13,8,21,-1,25,20,12,22,16,7,-1,19,26,11,16,18,15,-1,-1,29,30",
"s",
"X",
"C:/Users/phares/AppData/Roaming/FreeFileSync",
"Day-Helper-2025-04-21",
"GlobalSettings.xml",
"LastSync|Config",
"s",
"X",
"L:/Tmp/MET08ANLYSDIFAAST230",
"Day-Helper-2025-03-06",
"*.pdsf",
"s",
"X",
"D:/ProgramData/VisualStudioCode|D:/6-Other-Large-Z/Linux-Ubuntu-Phares/home/lphares/dorico",
"Day-Helper-2025-04-07",
"z-include-patterns.nsv",
"z-exclude-patterns.nsv",
"https://isccvm57294f1ed/VisualStudioCode|hxttps://dorico.phares.duckdns.org|hxttps://mestsa006.infineon.com/VisualStudioCode",
"+|G|G|G|-",
"||||",
"666",
"777",
"888",
"999",
"s",
"X",
"C:/Users/PHARES/AppData/Local/IFXApps/gatus",
"Day-Helper-2025-04-04",
"*.json",
".metrics",
"https://messa010ec.infineon.com/metrics",
"gatus_results_endpoint_success",
"666",
"777",
"888",
"999",
""
".json"
],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",

8
.vscode/mklink.md vendored
View File

@ -7,11 +7,11 @@ updated: "2023-10-20T04:00:37.259Z"
# mklink
```bash
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.kanbn" "D:\5-Other-Small\Kanban\File-Folder-Helper"
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.kanbn" "J:\5-Other-Small\Kanban\File-Folder-Helper"
```
```bash
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.kanbn" "D:\5-Other-Small\Kanban\File-Folder-Helper"
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.kanbn" "J:\5-Other-Small\Kanban\File-Folder-Helper"
```
```bash Thu Jul 18 2024 13:47:40 GMT-0700 (Mountain Standard Time)
@ -33,9 +33,9 @@ mklink /J "C:\Users\phares\.vscode-insiders\extensions\infineon-technologies-ag-
```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"
mklink /J "L:\DevOps\MESA_FI\file-folder-helper\bin\Release\net8.0\win-x64\publish" "J:\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"
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.vscode\.helper" "J:\5-Other-Small\Notes\Infineon\.vscode\helper"
```

15
.vscode/settings.json vendored
View File

@ -24,6 +24,7 @@
"BIORAD",
"BIRT",
"CHIL",
"CLHI",
"DEAT",
"digi",
"endianness",
@ -32,11 +33,13 @@
"FAMS",
"Gatus",
"GIVN",
"HCLHI",
"HGCV",
"HUSB",
"Immich",
"INDI",
"Infineon",
"JOBID",
"Kanban",
"kanbn",
"Kofax",
@ -45,20 +48,32 @@
"mesfs",
"mestsa",
"mklink",
"NDIL",
"netrm",
"NINJ",
"NpgSql",
"NSFX",
"NSRC",
"NSRCS",
"OBJE",
"onenote",
"PDFC",
"PDIL",
"pdsf",
"Permyriad",
"pged",
"Phares",
"PINJ",
"PPEXECNAME",
"PPID",
"PPSTEPNAME",
"PSRCS",
"Renci",
"Reparse",
"Rijndael",
"SCRLOAD",
"Serilog",
"SRCS",
"startable",
"SUBM",
"SURN",

40
.vscode/tasks.json vendored
View File

@ -57,11 +57,11 @@
"type": "pickString"
},
{
"default": "net8.0",
"default": "net10.0",
"description": "Which Core Version?",
"id": "CoreVersion",
"options": [
"net8.0"
"net10.0"
],
"type": "pickString"
},
@ -184,11 +184,27 @@
"args": [
"build",
"-r",
"linux-x64",
"win-x64",
"-c",
"Release",
"${workspaceFolder}/File-Folder-Helper.csproj"
],
"command": "dotnet",
"label": "Build Linux",
"label": "Build Release",
"problemMatcher": "$msCompile",
"type": "process"
},
{
"args": [
"build",
"-r",
"linux-x64",
"-c",
"Release",
"${workspaceFolder}/File-Folder-Helper.csproj"
],
"command": "dotnet",
"label": "Build Linux Release",
"problemMatcher": "$msCompile",
"type": "process"
},
@ -344,10 +360,24 @@
"false",
"4"
],
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe",
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net10.0/win-x64/publish/File-Folder-Helper.exe",
"label": "File-Folder-Helper AOT s X Day-Helper-2025-03-20",
"problemMatcher": [],
"type": "shell"
},
{
"args": [
"s",
"X",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/JavaScriptObjectNotation",
"Day-Helper-2025-10-22",
"*.json",
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/WorkWeek"
],
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net10.0/win-x64/publish/File-Folder-Helper.exe",
"label": "File-Folder-Helper AOT s X Day-Helper-2025-10-22",
"problemMatcher": [],
"type": "shell"
}
],
"version": "2.0.0"

View File

@ -932,13 +932,6 @@ public partial class KeePassFileRootDeletedObject
internal static partial class Helper20240105
{
// Folders with these names will be put in the root instead.
private static readonly string[] _BlacklistedFolders =
[
"KeePassHttp Passwords",
"KeePassXC-Browser Passwords"
];
private static readonly string[] _BlacklistedFields = [
"KeePassXC-Browser Settings",
"KeePassHttp Settings"
@ -1152,7 +1145,7 @@ internal static partial class Helper20240105
#pragma warning restore IL2026
stream.Dispose();
}
catch (Exception)
catch
{
if (throwExceptions)
throw;

View File

@ -230,7 +230,7 @@ internal static partial class Helper20240623 {
{
"label": "File-Folder-Helper AOT s X Day-Helper-2024-06-23",
"type": "shell",
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe",
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net10.0/win-x64/publish/File-Folder-Helper.exe",
"args": [
"s",
"X",
@ -243,7 +243,7 @@ internal static partial class Helper20240623 {
"-_[,](",
"##_Done",
".kan",
"D:/5-Other-Small/Kanban/Year-Season",
"J:/5-Other-Small/Kanban/Year-Season",
"316940400000"
],
"problemMatcher": []
@ -530,8 +530,8 @@ internal static partial class Helper20240623 {
private static string? GetInferredCheckDirectory(string directory) {
string? result = null;
List<string> directoryNames = [];
DirectoryInfo directoryInfo;
List<string> directoryNames = [];
string? checkDirectory = directory;
directoryNames.Add(Path.GetFileName(checkDirectory));
string pathRoot = Path.GetPathRoot(directory) ?? throw new Exception();
@ -540,7 +540,6 @@ internal static partial class Helper20240623 {
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot) {
break;
}
directoryInfo = new(checkDirectory);
if (!directoryInfo.Exists) {
directoryNames.Add(directoryInfo.Name);
@ -548,10 +547,15 @@ internal static partial class Helper20240623 {
directoryNames.Reverse();
result = string.IsNullOrEmpty(directoryInfo.LinkTarget) ? checkDirectory : directoryInfo.LinkTarget;
for (int j = 0; j < directoryNames.Count; j++) {
result = Path.GetDirectoryName(result) ?? throw new Exception();
result = Path.GetDirectoryName(result);
if (string.IsNullOrEmpty(result)) {
break;
}
}
foreach (string directoryName in directoryNames) {
result = Path.Combine(result, directoryName);
if (!string.IsNullOrEmpty(result)) {
foreach (string directoryName in directoryNames) {
result = Path.Combine(result, directoryName);
}
}
break;
}
@ -569,7 +573,7 @@ internal static partial class Helper20240623 {
File.WriteAllText(record.FileInfo.FullName, text);
record.FileInfo.Refresh();
string file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Programs", "Microsoft VS Code Insiders", "Code - Insiders.exe");
try { _ = Process.Start(file, $"\"{inferredCheckDirectory}\""); } catch (Exception) { logger.LogWarning("Failed to start code-insiders!"); }
try { _ = Process.Start(file, $"\"{inferredCheckDirectory}\""); } catch { logger.LogWarning("Failed to start code-insiders!"); }
}
private static FileInfo GetIndexFileInfo(ILogger<Worker> logger, Input input, Record record) {

View File

@ -283,7 +283,7 @@ internal static partial class Helper20240911
records = GetKeyValuePairs(keyValuePairs, keyValuePair.Value, nests);
record = new(keyValuePair.Value, parentWorkItem, records);
}
catch (Exception)
catch
{
record = new(keyValuePair.Value, parentWorkItem, new([]));
}

View File

@ -274,7 +274,7 @@ internal static partial class Helper20241108 {
relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related
successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward
record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations);
} catch (Exception) {
} catch {
record = new(keyValuePair.Value, parentWorkItem, [], [], []);
}
results.Add(keyValuePair.Key, record);

View File

@ -125,7 +125,7 @@ internal static partial class Helper20241217 {
string path = Path.Combine(directory, "verify.json");
ReadOnlyCollection<File> files = GetFiles(directory, searchPattern, ignoreFileNames);
ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, files);
double filesTotalLength = collection.Select(l => l.Length).Sum();
double filesTotalLength = collection.Sum(l => l.Length);
Job job = new(AlternatePath: "C:/Users/phares",
Directory: directory,
Extension: ".iso",
@ -235,7 +235,7 @@ internal static partial class Helper20241217 {
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();
double filesTotalLengthNew = collection.Sum(l => l.Length);
result = new(AlternatePath: record.Job.AlternatePath,
Directory: record.SourceDirectory,
Extension: record.Job.Extension,
@ -256,8 +256,8 @@ internal static partial class Helper20241217 {
result = false;
logger.LogWarning("<{directory}> file count has changed {filesCountNew} != {filesCountOld}", record.SourceDirectory, filesCountNew, filesCountOld);
} else {
double filesTotalLengthOld = collection.Select(l => l.Length).Sum();
double filesTotalLengthNew = jobNew.Files.Select(l => l.Length).Sum();
double filesTotalLengthOld = collection.Sum(l => l.Length);
double filesTotalLengthNew = jobNew.Files.Sum(l => l.Length);
if (filesTotalLengthNew != filesTotalLengthOld) {
result = false;
logger.LogWarning("<{directory}> file length has changed {filesTotalLengthNew} != {filesTotalLengthOld}", record.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);

View File

@ -79,7 +79,7 @@ internal static partial class Helper20250204 {
"{",
"\"label\": \"File-Folder-Helper AOT s X Day-Helper-2025-02-04\",",
"\"type\": \"shell\",",
"\"command\": \"L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe\",",
"\"command\": \"L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net10.0/win-x64/publish/File-Folder-Helper.exe\",",
"\"args\": [",
"\"s\",",
"\"X\",",
@ -92,7 +92,7 @@ internal static partial class Helper20250204 {
"{",
"\"label\": \"File-Folder-Helper AOT s X Day-Helper-2024-06-23\",",
"\"type\": \"shell\",",
"\"command\": \"L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe\",",
"\"command\": \"L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net10.0/win-x64/publish/File-Folder-Helper.exe\",",
"\"args\": [",
"\"s\",",
"\"X\",",
@ -155,7 +155,7 @@ internal static partial class Helper20250204 {
string searchPattern = "*.json";
string fullPath = Path.GetFullPath(args[0]);
string sourceDirectory = GetSourceDirectory(fullPath);
string rootDirectory = args.Count < 3 || args[2].Length < 16 ? "D:/5-Other-Small/Kanban-mestsa003/{}" : args[2];
string rootDirectory = args.Count < 3 || args[2].Length < 16 ? "J:/5-Other-Small/Kanban-mestsa003/{}" : args[2];
WriteTaskFile(sourceDirectory, rootDirectory);
string sourceDirectoryName = Path.GetFileName(sourceDirectory);
DirectoryInfo directoryInfo = new(Path.Combine(sourceDirectory, ".kanbn"));

View File

@ -15,7 +15,7 @@ internal static partial class Helper20250219 {
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(JsonElement[]))]
private partial class JsonElementCollectionSourceGenerationContext : JsonSerializerContext {
private partial class Helper20250219JsonElementArraySourceGenerationContext : JsonSerializerContext {
}
private record ProcessDataStandardFormatMapping(ReadOnlyCollection<string> BackfillColumns,
@ -276,7 +276,7 @@ internal static partial class Helper20250219 {
private static JsonElement[]? GetArray(ILogger<Worker> logger, int expectedColumns, ProcessDataStandardFormat processDataStandardFormat, bool lookForNumbers) {
JsonElement[]? results;
if (processDataStandardFormat.Body.Count == 0 || !processDataStandardFormat.Body[0].Contains('\t')) {
results = JsonSerializer.Deserialize("[]", JsonElementCollectionSourceGenerationContext.Default.JsonElementArray) ?? throw new Exception();
results = JsonSerializer.Deserialize("[]", Helper20250219JsonElementArraySourceGenerationContext.Default.JsonElementArray) ?? throw new Exception();
} else {
string value;
string[] segments;
@ -312,7 +312,7 @@ internal static partial class Helper20250219 {
lines.Add(stringBuilder.ToString());
}
string json = $"[{string.Join(',', lines)}]";
results = JsonSerializer.Deserialize(json, JsonElementCollectionSourceGenerationContext.Default.JsonElementArray);
results = JsonSerializer.Deserialize(json, Helper20250219JsonElementArraySourceGenerationContext.Default.JsonElementArray);
}
return results;
}

View File

@ -315,7 +315,7 @@ internal static partial class Helper20250320 {
segments = value.Split(' ');
results.Add(segments[^1], value);
}
} catch (Exception) {
} catch {
results.Clear();
System.Text.RegularExpressions.Match m;
for (int i = 0; i < matches.Length; i++) {

View File

@ -552,7 +552,7 @@ internal static partial class Helper20250407 {
private static void DoWork(ILogger<Worker> logger, string rightDirectory, HttpClient httpClient, ReadOnlyCollection<Segment> segments, bool delete, bool download) {
long sum;
Record[] records = (from l in segments where l.Left is not null select l.Left).ToArray();
try { sum = records.Sum(l => l.Size); } catch (Exception) { sum = 0; }
try { sum = records.Sum(l => l.Size); } catch { sum = 0; }
string size = GetSizeWithSuffix(sum);
if (delete) {
logger.LogInformation("Starting to delete {count} file(s) [{sum}]", segments.Count, size);
@ -601,7 +601,7 @@ internal static partial class Helper20250407 {
try {
File.Delete(Path.Combine(rightDirectory, record.RelativePath));
logger.LogInformation("{i} of {count} - Deleted: <{RelativePath}> - {size};", i.ToString("000000"), count, record.RelativePath, size);
} catch (Exception) {
} catch {
logger.LogInformation("Failed to delete: <{RelativePath}> - {size};", record.RelativePath, size);
}
}
@ -648,7 +648,7 @@ internal static partial class Helper20250407 {
download.Display,
size,
duration);
} catch (Exception) {
} catch {
logger.LogInformation("Failed to download: <{checkURL}> - {size};", download.UniformResourceLocator, size);
}
}

View File

@ -439,7 +439,7 @@ internal static partial class Helper20250519 {
try {
File.Delete(Path.Combine(directory, record.RelativePath));
logger.LogInformation("{i} of {count} - Deleted: <{RelativePath}> - {size};", i.ToString("000000"), count, record.RelativePath, size);
} catch (Exception) {
} catch {
logger.LogInformation("Failed to delete: <{RelativePath}> - {size};", record.RelativePath, size);
}
}
@ -507,7 +507,7 @@ internal static partial class Helper20250519 {
verb.Display,
size,
duration);
} catch (Exception) {
} catch {
logger.LogInformation("Failed to {httpMethod}: <{display}> - {size};", httpMethod, verb.Display, size);
}
}
@ -519,7 +519,7 @@ internal static partial class Helper20250519 {
private static void LiveSync(ILogger<Worker> logger, string page, RelativePath relativePath, HttpClient httpClient, string? directory, ReadOnlyCollection<Record> records, HttpMethod? httpMethod, bool delete) {
long sum;
try { sum = records.Sum(l => l.Size); } catch (Exception) { sum = 0; }
try { sum = records.Sum(l => l.Size); } catch { sum = 0; }
string size = GetSizeWithSuffix(sum);
if (delete) {
logger.LogInformation("Starting to delete {count} file(s) [{sum}]", records.Count, size);

View File

@ -41,7 +41,7 @@ internal static partial class Helper20250601 {
result = xmlSerializer.Deserialize(xmlReader);
#pragma warning restore IL2026, IL2090
stream.Dispose();
} catch (Exception) {
} catch {
if (throwExceptions) {
throw;
}
@ -120,14 +120,14 @@ internal static partial class Helper20250601 {
}
}
responseAfter = stringBuilder.ToString();
cellNames = responseAfter.Split(new string[] { "CellName" }, StringSplitOptions.None);
cellNames = responseAfter.Split(["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);
segments = segment.Split(["WindowsName"], StringSplitOptions.None);
if (segments.Length != 2) {
continue;
}
@ -321,9 +321,9 @@ internal static partial class Helper20250601 {
}
}
if (errorDescription != "a") {
string[] segments = record.Text.Split(new string[] { "ErrorDescription" }, StringSplitOptions.RemoveEmptyEntries);
string[] segments = record.Text.Split(["ErrorDescription"], StringSplitOptions.RemoveEmptyEntries);
if (segments.Length > 1) {
segments = segments[1].Split(new string[] { "Info" }, StringSplitOptions.RemoveEmptyEntries);
segments = segments[1].Split(["Info"], StringSplitOptions.RemoveEmptyEntries);
errorDescription = segments[0].Trim();
}
}

View File

@ -39,7 +39,7 @@ internal static partial class Helper20250602 {
result = xmlSerializer.Deserialize(xmlReader);
#pragma warning restore IL2026, IL2090
stream.Dispose();
} catch (Exception) {
} catch {
if (throwExceptions) {
throw;
}
@ -120,14 +120,14 @@ internal static partial class Helper20250602 {
}
}
responseAfter = stringBuilder.ToString();
cellNames = responseAfter.Split(new string[] { "CellName" }, StringSplitOptions.None);
cellNames = responseAfter.Split(["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);
segments = segment.Split(["WindowsName"], StringSplitOptions.None);
if (segments.Length != 2) {
continue;
}
@ -340,9 +340,9 @@ internal static partial class Helper20250602 {
}
}
if (errorDescription != "a") {
string[] segments = record.Text.Split(new string[] { "ErrorDescription" }, StringSplitOptions.RemoveEmptyEntries);
string[] segments = record.Text.Split(["ErrorDescription"], StringSplitOptions.RemoveEmptyEntries);
if (segments.Length > 1) {
segments = segments[1].Split(new string[] { "Info" }, StringSplitOptions.RemoveEmptyEntries);
segments = segments[1].Split(["Info"], StringSplitOptions.RemoveEmptyEntries);
errorDescription = segments[0].Trim();
}
}

View File

@ -1,6 +1,6 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
@ -10,7 +10,7 @@ internal static partial class Helper20250701 {
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(JsonElement))]
internal partial class JsonElementSourceGenerationContext : JsonSerializerContext {
internal partial class Helper20250701JsonElementSourceGenerationContext : JsonSerializerContext {
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
@ -40,9 +40,14 @@ internal static partial class Helper20250701 {
segments = column.Split('~');
columnMapping.Add(segments[0], segments[1]);
}
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
List<string> directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly).ToList();
if (directories.Count == 0) {
directories.Add(sourceDirectory);
}
ProcessDataStandardFormatTo(logger, sourceDirectory, searchPattern, sizeFilter, timeColumn, extension, columnMapping.AsReadOnly(), destinationDirectory, directories.AsReadOnly());
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
if (directories.Count > 1) {
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
}
}
private static void ProcessDataStandardFormatTo(ILogger<Worker> logger, string sourceDirectory, string searchPattern, int sizeFilter, string timeColumn, string extension, ReadOnlyDictionary<string, string> columnMapping, string destinationDirectory, ReadOnlyCollection<string> directories) {
@ -52,10 +57,12 @@ internal static partial class Helper20250701 {
string markdown;
string checkFile;
FileInfo fileInfo;
string weekOfYear;
string? pipeTable;
string? collections;
string? directoryName;
string checkDirectory;
Calendar calendar = new CultureInfo("en-US").Calendar;
foreach (string directory in directories) {
if (sizeFilter < 987654321 && Path.GetFileName(directory).Contains('-')) {
continue;
@ -70,8 +77,9 @@ internal static partial class Helper20250701 {
if (string.IsNullOrEmpty(directoryName)) {
continue;
}
weekOfYear = $"{fileInfo.LastWriteTime.Year}_Week_{calendar.GetWeekOfYear(fileInfo.LastWriteTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
if (fileInfo.Length > sizeFilter && !directoryName.StartsWith('Z')) {
checkDirectory = Path.Combine(sourceDirectory, $"Z{directoryName}");
checkDirectory = Path.Combine(sourceDirectory, $"Z{directoryName}", weekOfYear);
if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory);
}
@ -82,7 +90,7 @@ internal static partial class Helper20250701 {
File.Move(file, checkFile);
continue;
}
checkDirectory = Path.Combine(destinationDirectory, directoryName);
checkDirectory = Path.Combine(destinationDirectory, directoryName, weekOfYear);
if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory);
}
@ -395,7 +403,7 @@ internal static partial class Helper20250701 {
List<string> values = [];
List<string> results = [];
Dictionary<string, string> keyValuePairs = [];
JsonElement jsonElement = JsonSerializer.Deserialize(json, JsonElementSourceGenerationContext.Default.JsonElement);
JsonElement jsonElement = JsonSerializer.Deserialize(json, Helper20250701JsonElementSourceGenerationContext.Default.JsonElement);
JsonElement[] jsonElements = jsonElement.EnumerateArray().ToArray();
foreach (JsonElement j in jsonElements) {
values.Clear();

View File

@ -7,11 +7,6 @@ namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250709 {
// [JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
// [JsonSerializable(typeof(JsonElement[]))]
// internal partial class Helper20250709JsonElementSourceGenerationContext : JsonSerializerContext {
// }
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Raw))]
private partial class RawSourceGenerationContext : JsonSerializerContext {
@ -124,22 +119,6 @@ internal static partial class Helper20250709 {
[property: JsonPropertyName("LL2WafersIn")] long? LL2WafersIn,
[property: JsonPropertyName("LL2WfrCnt")] long? LL2WfrCnt,
[property: JsonPropertyName("ProcessState")] long? ProcessState);
// [property: JsonPropertyName("A_BASIC_TYPE")] string? ABasicType,
// [property: JsonPropertyName("A_INFO")] string? AInfo,
// [property: JsonPropertyName("A_INFO2")] string? AInfo2,
// [property: JsonPropertyName("A_JOBID")] string? AJobid,
// [property: JsonPropertyName("A_LAYER")] string? ALayer,
// [property: JsonPropertyName("A_LAYER2")] string? ALayer2,
// [property: JsonPropertyName("A_MES_ENTITY")] string? AMesEntity,
// [property: JsonPropertyName("A_MID")] string? AMID,
// [property: JsonPropertyName("A_NULL_DATA")] string? ANullData,
// [property: JsonPropertyName("A_PPID")] string? APPID,
// [property: JsonPropertyName("A_PROCESS_JOBID")] string? AProcessJobid,
// [property: JsonPropertyName("A_PRODUCT")] string? AProduct,
// [property: JsonPropertyName("A_SEQUENCE")] string? ASequence,
// [property: JsonPropertyName("A_WAFER_ID")] string? AWaferId,
// [property: JsonPropertyName("A_WAFER_POS")] string? AWaferPos
// cspell::enable,
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, NumberHandling = JsonNumberHandling.AllowReadingFromString)]
[JsonSerializable(typeof(Reactor))]
@ -158,9 +137,14 @@ internal static partial class Helper20250709 {
int sizeFilter = int.Parse(args[3]);
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string destinationDirectory = Path.GetFullPath(args[6].Split('~')[0]);
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
List<string> directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly).ToList();
if (directories.Count == 0) {
directories.Add(sourceDirectory);
}
JavaScriptObjectNotationTo(sourceDirectory, searchPattern, sizeFilter, extension, destinationDirectory, directories.AsReadOnly());
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
if (directories.Count > 1) {
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
}
}
private static void JavaScriptObjectNotationTo(string sourceDirectory, string searchPattern, int sizeFilter, string extension, string destinationDirectory, ReadOnlyCollection<string> directories) {
@ -215,7 +199,7 @@ internal static partial class Helper20250709 {
foreach (JsonElement jsonElement in raw.Records) {
try {
reactor = JsonSerializer.Deserialize(jsonElement.ToString().Replace("\"\"", "null"), ReactorSourceGenerationContext.Default.Reactor);
} catch (Exception) {
} catch {
reactor = null;
}
if (reactor is null) {

View File

@ -1,98 +1,10 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250710 {
[GeneratedRegex(@"^(?<stream>S[0-9]{1,2})(?<function>F[0-9]{1,2}) W-Bit=(?<wait>[01])")]
private static partial Regex StreamFunction();
internal static void StripLog(ILogger<Worker> logger, List<string> args) {
logger.LogInformation(args[0]);
logger.LogInformation(args[1]);
logger.LogInformation(args[2]);
logger.LogInformation(args[3]);
string searchPattern = args[3];
string directoryPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string[] directories = Directory.GetDirectories(sourceDirectory, directoryPattern, SearchOption.TopDirectoryOnly);
LogToTrace(logger, searchPattern, directories.AsReadOnly());
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
}
private static void LogToTrace(ILogger<Worker> logger, string searchPattern, ReadOnlyCollection<string> directories) {
string[] lines;
string[] files;
string checkFile;
FileInfo fileInfo;
string? directoryName;
const string extension = ".trc";
foreach (string directory in directories) {
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 (string.IsNullOrEmpty(directoryName)) {
continue;
}
checkFile = Path.Combine(directoryName, $"{fileInfo.Name}{extension}");
if (File.Exists(checkFile)) {
continue;
}
lines = File.ReadAllLines(fileInfo.FullName);
LogToTrace(logger, fileInfo, lines, checkFile);
}
}
}
private static void LogToTrace(ILogger<Worker> logger, FileInfo fileInfo, string[] lines, string checkFile) {
string line;
Match match;
string body;
string[] segments;
List<string> log = [];
for (int i = 1; i < lines.Length - 1; i++) {
line = lines[i];
if (!line.StartsWith('S')) {
continue;
}
match = StreamFunction().Match(line);
if (!match.Success) {
continue;
}
segments = lines[i - 1].Split(" ");
if (segments.Length < 2) {
continue;
}
if (!segments[0].Contains(' ')) {
continue;
}
body = GetBody(lines, i, segments[0].Split(' '));
log.Add($"{segments[0]} {line} ~ {body}");
}
if (log.Count > 0) {
File.WriteAllText(checkFile, string.Join(Environment.NewLine, log));
File.SetLastWriteTime(checkFile, fileInfo.LastWriteTime);
logger.LogInformation("<{checkFile}> was written", checkFile);
}
}
private static string GetBody(string[] lines, int i, string[] segments) {
string result;
List<string> results = [];
for (int j = i + 1; j < lines.Length; j++) {
if (lines[j].StartsWith(segments[0])) {
break;
}
results.Add(lines[j].Trim());
}
result = string.Join('_', results);
return result;
}
internal static void StripLog(ILogger<Worker> _, List<string> args) =>
throw new NotImplementedException($"This method has been moved to PI8 version. {string.Join(Environment.NewLine, args)}");
}

View File

@ -17,17 +17,87 @@ internal static partial class Helper20250720 {
private partial class Helper20250720SettingsSourceGenerationContext : JsonSerializerContext {
}
private static void WriteFaceData(ILogger<Worker> logger, string outputDirectoryName, string? originalFile, long? fileNameFirstSegment, ReadOnlyCollection<ExifDirectory> exifDirectories, ReadOnlyCollection<string> digiKamFiles) {
ReadOnlyDictionary<string, FaceFile> keyValuePairs = GetKeyValuePairs(logger, exifDirectories);
if (keyValuePairs.Count > 0) {
WriteFaceData(logger, outputDirectoryName, originalFile, fileNameFirstSegment, digiKamFiles, keyValuePairs);
internal static void WriteFaceData(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]);
logger.LogInformation(args[6]);
logger.LogInformation(args[7]);
logger.LogInformation(args[8]);
logger.LogInformation(args[9]);
logger.LogInformation(args[10]);
string searchPattern = args[5];
bool replace = args[10] == "true";
string outputDirectoryName = args[8];
string jsonFile = Path.GetFullPath(args[3]);
FileInfo faceFileInfo = new(Path.GetFullPath(args[4]));
string searchPatternExtensibleMetadataPlatform = args[7];
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string extensibleMetadataPlatformFile = Path.GetFullPath(args[6]);
string pathRoot = Path.GetPathRoot(faceFileInfo.FullName) ?? throw new Exception();
string rootExtensibleMetadataPlatformPath = Path.GetFullPath(args[9].Split('~')[0]);
string? checkDirectory = Path.GetDirectoryName(extensibleMetadataPlatformFile.Replace("{}", outputDirectoryName));
string originalFile = Path.Combine(sourceDirectory, args[2]);
ReadOnlyDictionary<long, ReadOnlyCollection<string>> keyToExtensibleMetadataPlatformFiles = GetExtensibleMetadataPlatformFiles(searchPatternExtensibleMetadataPlatform, rootExtensibleMetadataPlatformPath, replace);
if (!File.Exists(jsonFile)) {
logger.LogError("json file doesn't exist! <{jsonFile}>", jsonFile);
} else if (!File.Exists(extensibleMetadataPlatformFile)) {
logger.LogError("digiKam file doesn't exist! <{extensibleMetadataPlatformFile}>", extensibleMetadataPlatformFile);
} else if (!File.Exists(originalFile)) {
logger.LogError("Original file doesn't exist! <{checkFile}>", originalFile);
} else if (!Directory.Exists(checkDirectory)) {
logger.LogError("checkDirectory doesn't exist! <{checkDirectory}>", checkDirectory);
} else if (!faceFileInfo.Exists) {
logger.LogError("Face file doesn't exist! <{faceFileInfo}>", faceFileInfo.FullName);
} else {
string json = File.ReadAllText(jsonFile);
Helper20250720Settings? settings = JsonSerializer.Deserialize(json, Helper20250720SettingsSourceGenerationContext.Default.Helper20250720Settings);
if (settings?.ResultSettings is null || settings.ResultSettings.ResultAllInOneSubdirectoryLength < 1 || settings.MetadataSettings is null) {
throw new Exception(nameof(Helper20250720Settings));
}
WriteFaceData69(logger, outputDirectoryName, originalFile, faceFileInfo, extensibleMetadataPlatformFile, settings.ResultSettings, settings.MetadataSettings);
ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> keyToExifDirectories = GetExifDirectories(searchPattern, pathRoot, settings.ResultSettings, settings.MetadataSettings);
if (keyToExifDirectories.Count == 0) {
logger.LogError("Didn't find any valid file(s)!");
} else {
WriteFaceData415(logger, outputDirectoryName, keyToExifDirectories, keyToExtensibleMetadataPlatformFiles);
}
}
}
private static void WriteFaceData(ILogger<Worker> logger, string outputDirectoryName, string? originalFile, long? fileNameFirstSegment, ReadOnlyCollection<string> digiKamFiles, ReadOnlyDictionary<string, FaceFile> keyValuePairs) {
private static void WriteFaceData69(ILogger<Worker> logger, string outputDirectoryName, string originalFile, FileInfo faceFileInfo, string extensibleMetadataPlatformFile, ResultSettings resultSettings, MetadataSettings metadataSettings) {
ExifDirectory? exifDirectory = IMetadata.GetExifDirectory(resultSettings, metadataSettings, faceFileInfo);
if (exifDirectory is null) {
logger.LogError("exifDirectory is null!");
} else {
long id;
string fileNameWithoutExtension;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(faceFileInfo.FullName);
if (!long.TryParse(fileNameWithoutExtension.Split('.')[0], out id)) {
id = -1;
}
long? fileNameFirstSegment = id == -1 ? null : id;
ReadOnlyCollection<ExifDirectory> exifDirectories = new([exifDirectory]);
ReadOnlyCollection<string> extensibleMetadataPlatformFiles = new([extensibleMetadataPlatformFile]);
WriteFaceData87(logger, outputDirectoryName, originalFile, fileNameFirstSegment, exifDirectories, extensibleMetadataPlatformFiles);
}
}
private static void WriteFaceData87(ILogger<Worker> logger, string outputDirectoryName, string? originalFile, long? fileNameFirstSegment, ReadOnlyCollection<ExifDirectory> exifDirectories, ReadOnlyCollection<string> extensibleMetadataPlatformFiles) {
ReadOnlyDictionary<string, FaceFile> faceFiles = GetFaceFiles(logger, exifDirectories);
if (faceFiles.Count > 0) {
WriteFaceData94(logger, outputDirectoryName, originalFile, fileNameFirstSegment, extensibleMetadataPlatformFiles, faceFiles);
}
}
private static void WriteFaceData94(ILogger<Worker> logger, string outputDirectoryName, string? originalFile, long? fileNameFirstSegment, ReadOnlyCollection<string> extensibleMetadataPlatformFiles, ReadOnlyDictionary<string, FaceFile> faceFiles) {
#if xmp
IXmpMeta xmp;
using FileStream stream = File.OpenRead(digiKamFile);
using FileStream stream = File.OpenRead(extensibleMetadataPlatformFile);
xmp = XmpMetaFactory.Parse(stream);
foreach (var property in xmp.Properties) {
logger.LogDebug("Path={property.Path} Namespace={property.Namespace} Value={property.Value}", property.Path, property.Namespace, property.Value);
@ -56,12 +126,12 @@ internal static partial class Helper20250720 {
"xmlns:mwg-rs=\"http://www.metadataworkinggroup.com/schemas/regions/\"",
"</rdf:RDF>"
];
foreach (string digiKamFile in digiKamFiles) {
string[] lines = File.ReadAllLines(digiKamFile);
foreach (string extensibleMetadataPlatformFile in extensibleMetadataPlatformFiles) {
string[] lines = File.ReadAllLines(extensibleMetadataPlatformFile);
List<string> trimmed = lines.Select(l => l.Trim()).ToList();
int? digiKamLine = GetMatchingLine(requiredLines[0], trimmed.AsReadOnly());
if (digiKamLine is null) {
logger.LogError("{fileNameFirstSegment}) Didn't fine digiKam line!", fileNameFirstSegment);
logger.LogError("{fileNameFirstSegment}) Didn't find digiKam line!", fileNameFirstSegment);
} else {
foreach (string requiredLine in requiredLines) {
if (!trimmed.Contains(requiredLine)) {
@ -70,83 +140,27 @@ internal static partial class Helper20250720 {
}
int? rdfLine = GetMatchingLine(requiredLines[^1], trimmed.AsReadOnly());
if (rdfLine is null) {
logger.LogError("{fileNameFirstSegment}) Didn't fine description line!", fileNameFirstSegment);
logger.LogError("{fileNameFirstSegment}) Didn't find description line!", fileNameFirstSegment);
} else {
WriteFaceData(outputDirectoryName, originalFile, keyValuePairs, digiKamFile, trimmed, rdfLine.Value);
WriteFaceData159(outputDirectoryName, originalFile, faceFiles, extensibleMetadataPlatformFile, trimmed, rdfLine.Value);
}
}
}
}
internal static void WriteFaceData(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]);
logger.LogInformation(args[6]);
logger.LogInformation(args[7]);
logger.LogInformation(args[8]);
string searchPattern = args[5];
string searchPatternXMP = args[7];
string outputDirectoryName = args[8];
string jsonFile = Path.GetFullPath(args[3]);
string digiKamFile = Path.GetFullPath(args[6]);
FileInfo faceFileInfo = new(Path.GetFullPath(args[4]));
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string pathRoot = Path.GetPathRoot(faceFileInfo.FullName) ?? throw new Exception();
string? checkDirectory = Path.GetDirectoryName(digiKamFile.Replace("{}", outputDirectoryName));
string originalFile = Path.Combine(sourceDirectory, args[2]);
string pathRootXMP = digiKamFile[..5];
if (!File.Exists(jsonFile)) {
logger.LogError("json file doesn't exist! <{jsonFile}>", jsonFile);
} else if (!File.Exists(digiKamFile)) {
logger.LogError("digiKam file doesn't exist! <{digiKamFile}>", digiKamFile);
} else if (!File.Exists(originalFile)) {
logger.LogError("Original file doesn't exist! <{checkFile}>", originalFile);
} else if (!Directory.Exists(checkDirectory)) {
logger.LogError("checkDirectory doesn't exist! <{checkDirectory}>", checkDirectory);
} else if (!faceFileInfo.Exists) {
logger.LogError("Face file doesn't exist! <{faceFileInfo}>", faceFileInfo.FullName);
} else {
string json = File.ReadAllText(jsonFile);
Helper20250720Settings? settings = JsonSerializer.Deserialize(json, Helper20250720SettingsSourceGenerationContext.Default.Helper20250720Settings);
if (settings?.ResultSettings is null || settings.ResultSettings.ResultAllInOneSubdirectoryLength < 1 || settings.MetadataSettings is null) {
throw new Exception(nameof(Helper20250720Settings));
}
WriteFaceData(logger, outputDirectoryName, originalFile, faceFileInfo, digiKamFile, settings.ResultSettings, settings.MetadataSettings);
ReadOnlyDictionary<long, ReadOnlyCollection<string>> keyValuePairsXMP = GetKeyValuePairs(searchPatternXMP, pathRootXMP);
ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> keyValuePairs = GetKeyValuePairs(searchPattern, pathRoot, settings.ResultSettings, settings.MetadataSettings);
if (keyValuePairs.Count == 0) {
logger.LogError("Didn't find any valid file(s)!");
} else {
WriteFaceData(logger, outputDirectoryName, keyValuePairs, keyValuePairsXMP);
private static int? GetMatchingLine(string digiKamLine, ReadOnlyCollection<string> lines) {
int? result = null;
for (int i = 0; i < lines.Count; i++) {
if (lines[i] == digiKamLine) {
result = i;
break;
}
}
return result;
}
private static void WriteFaceData(ILogger<Worker> logger, string outputDirectoryName, string originalFile, FileInfo faceFileInfo, string digiKamFile, ResultSettings resultSettings, MetadataSettings metadataSettings) {
ExifDirectory? exifDirectory = IMetadata.GetExifDirectory(resultSettings, metadataSettings, faceFileInfo);
if (exifDirectory is null) {
logger.LogError("exifDirectory is null!");
} else {
long id;
string fileNameWithoutExtension;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(faceFileInfo.FullName);
if (!long.TryParse(fileNameWithoutExtension.Split('.')[0], out id)) {
id = -1;
}
long? fileNameFirstSegment = id == -1 ? null : id;
ReadOnlyCollection<string> digiKamFiles = new([digiKamFile]);
ReadOnlyCollection<ExifDirectory> exifDirectories = new([exifDirectory]);
WriteFaceData(logger, outputDirectoryName, originalFile, fileNameFirstSegment, exifDirectories, digiKamFiles);
}
}
private static void WriteFaceData(string outputDirectoryName, string? originalFile, ReadOnlyDictionary<string, FaceFile> keyValuePairs, string digiKamFile, List<string> trimmed, int rdfLine) {
if (keyValuePairs.Count == 0) {
private static void WriteFaceData159(string outputDirectoryName, string? originalFile, ReadOnlyDictionary<string, FaceFile> faceFiles, string extensibleMetadataPlatformFile, List<string> trimmed, int rdfLine) {
if (faceFiles.Count == 0) {
throw new Exception();
}
double h;
@ -160,7 +174,7 @@ internal static partial class Helper20250720 {
string personKey;
FaceFile faceFile;
string descriptionLine = "</rdf:Description>";
faceFile = keyValuePairs.ElementAt(0).Value;
faceFile = faceFiles.ElementAt(0).Value;
if (faceFile.Location is null || faceFile.OutputResolution is null) {
throw new Exception();
}
@ -183,7 +197,7 @@ internal static partial class Helper20250720 {
List<string> hierarchicalSubjectLines = ["<lr:hierarchicalSubject>", "<rdf:Bag>"];
List<string> catalogSetLines = ["<mediapro:CatalogSets>", "<rdf:Bag>"];
List<string> subjectLines = ["<dc:subject>", "<rdf:Bag>"];
foreach (KeyValuePair<string, FaceFile> keyValuePair in keyValuePairs) {
foreach (KeyValuePair<string, FaceFile> keyValuePair in faceFiles) {
personKey = keyValuePair.Key;
faceFile = keyValuePair.Value;
if (faceFile.Location is null || faceFile.OutputResolution is null) {
@ -308,7 +322,7 @@ internal static partial class Helper20250720 {
}
trimmed.Insert(rdfLine - 1, text);
string allText = string.Join(Environment.NewLine, trimmed);
File.WriteAllText(digiKamFile.Replace("{}", outputDirectoryName), allText);
File.WriteAllText(extensibleMetadataPlatformFile.Replace("{}", outputDirectoryName), allText);
if (!string.IsNullOrEmpty(originalFile)) {
if (Debugger.IsAttached) {
File.WriteAllText(".xml", allText);
@ -316,13 +330,36 @@ internal static partial class Helper20250720 {
}
}
private static ReadOnlyDictionary<long, ReadOnlyCollection<string>> GetKeyValuePairs(string searchPattern, string pathRoot) {
private static ReadOnlyDictionary<long, ReadOnlyCollection<string>> GetExtensibleMetadataPlatformFiles(string searchPattern, string pathRoot, bool replace) {
Dictionary<long, ReadOnlyCollection<string>> results = [];
long fileNameFirstSegment;
string text;
string oldText;
string newText;
string[] segments;
List<string>? collection;
long fileNameFirstSegment;
string fileNameWithoutExtension;
Dictionary<long, List<string>> keyValuePairs = [];
string[] files = Directory.GetFiles(pathRoot, searchPattern, SearchOption.AllDirectories);
if (replace) {
string split = "<digiKam:";
foreach (string file in files) {
oldText = File.ReadAllText(file);
segments = oldText.Split(split);
if (segments.Length != 2) {
continue;
}
text = segments[1].Replace(" /", " ").Replace("/<", "<").Replace("/\"", "\"").
Replace(" |", " ").Replace("|<", "<").Replace("|\"", "\"").
Replace("Phares/", "Phares").Replace("Phares|", "Phares").
Replace("Clifton/", "Clifton").Replace("Clifton|", "Clifton");
newText = $"{segments[0]}{split}{text}";
if (oldText == newText) {
continue;
}
File.WriteAllText(file, newText);
}
}
foreach (string file in files) {
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
if (!long.TryParse(fileNameWithoutExtension.Split('.')[0], out fileNameFirstSegment)) {
@ -342,7 +379,7 @@ internal static partial class Helper20250720 {
return results.AsReadOnly();
}
private static ReadOnlyDictionary<string, FaceFile> GetKeyValuePairs(ILogger<Worker> logger, ReadOnlyCollection<ExifDirectory> exifDirectories) {
private static ReadOnlyDictionary<string, FaceFile> GetFaceFiles(ILogger<Worker> logger, ReadOnlyCollection<ExifDirectory> exifDirectories) {
Dictionary<string, FaceFile> results = [];
string? personKey;
FaceFile? faceFile;
@ -368,7 +405,7 @@ internal static partial class Helper20250720 {
return results.AsReadOnly();
}
private static ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> GetKeyValuePairs(string searchPattern, string pathRoot, ResultSettings resultSettings, MetadataSettings metadataSettings) {
private static ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> GetExifDirectories(string searchPattern, string pathRoot, ResultSettings resultSettings, MetadataSettings metadataSettings) {
Dictionary<long, ReadOnlyCollection<ExifDirectory>> results = [];
FileInfo faceFileInfo;
long fileNameFirstSegment;
@ -401,29 +438,18 @@ internal static partial class Helper20250720 {
return results.AsReadOnly();
}
private static void WriteFaceData(ILogger<Worker> logger, string outputDirectoryName, ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> keyValuePairs, ReadOnlyDictionary<long, ReadOnlyCollection<string>> keyValuePairsXMP) {
ReadOnlyCollection<string>? digiKamFiles;
foreach (KeyValuePair<long, ReadOnlyCollection<ExifDirectory>> keyValuePair in keyValuePairs) {
if (!keyValuePairsXMP.TryGetValue(keyValuePair.Key, out digiKamFiles)) {
private static void WriteFaceData415(ILogger<Worker> logger, string outputDirectoryName, ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> keyToExifDirectories, ReadOnlyDictionary<long, ReadOnlyCollection<string>> keyToExtensibleMetadataPlatformFiles) {
ReadOnlyCollection<string>? extensibleMetadataPlatformFiles;
foreach (KeyValuePair<long, ReadOnlyCollection<ExifDirectory>> keyValuePair in keyToExifDirectories) {
if (!keyToExtensibleMetadataPlatformFiles.TryGetValue(keyValuePair.Key, out extensibleMetadataPlatformFiles)) {
logger.LogWarning("{fileNameFirstSegment}) Didn't find a matching file!", keyValuePair.Key);
} else {
string? originalFile = null;
WriteFaceData(logger, outputDirectoryName, originalFile, keyValuePair.Key, keyValuePair.Value, digiKamFiles);
WriteFaceData87(logger, outputDirectoryName, originalFile, keyValuePair.Key, keyValuePair.Value, extensibleMetadataPlatformFiles);
}
}
}
private static int? GetMatchingLine(string digiKamLine, ReadOnlyCollection<string> lines) {
int? result = null;
for (int i = 0; i < lines.Count; i++) {
if (lines[i] == digiKamLine) {
result = i;
break;
}
}
return result;
}
private static void Extract(string file, double width, double height, int left, int top, string suffix) {
#if SystemDrawingCommon
Rectangle rectangle = new(left, top, width, height);

View File

@ -9,15 +9,28 @@ namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250726 {
private record Helper20250726Settings(ResultSettings? ResultSettings, MetadataSettings? MetadataSettings);
private record Helper20250726Identifier(string[] DirectoryNames,
string Extension,
bool? HasDateTimeOriginal,
int Id,
long Length,
string PaddedId,
long Ticks);
private record Record(CombinedEnumAndIndex CombinedEnumAndIndex, FilePath FilePath, bool HasFlagHidden);
private record Record(CombinedEnumAndIndex CombinedEnumAndIndex, FilePath FilePath, bool HasFlagHidden, Helper20250726Identifier? Identifier);
private record Helper20250726Settings(ResultSettings? ResultSettings, MetadataSettings? MetadataSettings);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Helper20250726Settings))]
private partial class Helper20250726SettingsSourceGenerationContext : JsonSerializerContext {
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Helper20250726Identifier[]))]
private partial class Helper20250726IdentifierCollectionSourceGenerationContext : JsonSerializerContext {
}
internal static void CopyToCombinedEnumAndIndexFormat(ILogger<Worker> logger, List<string> args) {
logger.LogInformation(args[0]);
logger.LogInformation(args[1]);
@ -35,6 +48,7 @@ internal static partial class Helper20250726 {
ReadOnlyCollection<Record> records;
string json = File.ReadAllText(jsonFile);
string destinationDirectoryName = args[6];
List<Helper20250726Identifier> identifiers = [];
ReadOnlyDictionary<byte, ReadOnlyCollection<string>> keyValues;
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string destinationDirectory = Path.GetFullPath(args[5].Split('~')[0]);
@ -51,11 +65,13 @@ internal static partial class Helper20250726 {
continue;
}
logger.LogInformation($"Found {files.Length} {searchPattern} files");
keyValuePairs = GetKeyValuePairs(settings.ResultSettings, destinationDirectory, destinationDirectoryName);
records = GetRecords(logger, settings.ResultSettings, settings.MetadataSettings, files);
keyValuePairs = GetKeyValuePairs(settings.ResultSettings, destinationDirectory, destinationDirectoryName);
keyValues = keyValuePairs.ElementAt(0).Value;
CopyToCombinedEnumAndIndexFormat(logger, maxSize, records, keyValues);
identifiers.AddRange(from l in records where l.Identifier is not null select l.Identifier);
}
WriteIdentifiers(logger, destinationDirectory, identifiers.AsReadOnly());
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, destinationDirectory);
}
@ -80,6 +96,7 @@ internal static partial class Helper20250726 {
FilePath filePath;
bool hasFlagHidden;
FileHolder fileHolder;
Helper20250726Identifier? identifier;
CombinedEnumAndIndex combinedEnumAndIndex;
foreach (string file in files) {
fileInfo = new(file);
@ -90,13 +107,43 @@ internal static partial class Helper20250726 {
continue;
}
hasFlagHidden = fileInfo.Attributes.HasFlag(FileAttributes.Hidden);
identifier = GetIdentifier(resultSettings, metadataSettings, filePath);
combinedEnumAndIndex = IPath.GetCombinedEnumAndIndex(resultSettings, filePath);
record = new(CombinedEnumAndIndex: combinedEnumAndIndex, FilePath: filePath, HasFlagHidden: hasFlagHidden);
record = new(CombinedEnumAndIndex: combinedEnumAndIndex, FilePath: filePath, HasFlagHidden: hasFlagHidden, Identifier: identifier);
results.Add(record);
}
return results.AsReadOnly();
}
private static Helper20250726Identifier? GetIdentifier(ResultSettings resultSettings, MetadataSettings metadataSettings, FilePath filePath) {
Helper20250726Identifier? result;
if (filePath.Id is null) {
result = null;
} else {
string paddedId = IId.GetPaddedId(resultSettings, metadataSettings, filePath, index: null);
result = new(DirectoryNames: [],
Extension: filePath.ExtensionLowered,
HasDateTimeOriginal: filePath.HasDateTimeOriginal,
Id: filePath.Id.Value,
Length: filePath.Length,
PaddedId: paddedId,
Ticks: filePath.LastWriteTicks);
}
return result;
}
private static void WriteIdentifiers(ILogger<Worker> logger, string destinationDirectory, ReadOnlyCollection<Helper20250726Identifier> identifiers) {
Helper20250726Identifier[] results = (from l in identifiers where l is not null orderby l.PaddedId select l).ToArray();
string path = Path.Combine(destinationDirectory, ".json");
string? oldJson = !File.Exists(path) ? null : File.ReadAllText(path);
string json = JsonSerializer.Serialize(results, Helper20250726IdentifierCollectionSourceGenerationContext.Default.Helper20250726IdentifierArray);
if (!string.IsNullOrEmpty(oldJson) && oldJson == json) {
logger.LogInformation("File {path} is the same", path);
} else {
File.WriteAllText(path, json);
}
}
private static void CopyToCombinedEnumAndIndexFormat(ILogger<Worker> logger, long maxSize, ReadOnlyCollection<Record> records, ReadOnlyDictionary<byte, ReadOnlyCollection<string>> keyValuePairs) {
string checkFile;
FileInfo fileInfo;

View File

@ -0,0 +1,292 @@
using Microsoft.Extensions.Logging;
using System.Globalization;
namespace File_Folder_Helper.ADO2025.PI7;
internal static partial class Helper20250926 {
internal static void RenameThenFindFirstAndLast(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]);
const char star = '*';
const char underscore = '_';
string searchString = args[3];
string dateTimeFormat = args[4];
int seconds = int.Parse(args[5]);
string[] searchPatterns = args[2].Split('~');
string key = searchString.ToLower().Split(' ')[0];
string[] sourceDirectories = Path.GetFullPath(args[0]).Split('~');
if (args.Count == 999) {
Redo(logger, star, underscore, dateTimeFormat, searchString, key, searchPatterns, sourceDirectories);
}
Rename(logger, star, underscore, dateTimeFormat, searchString, key, searchPatterns, sourceDirectories);
if (seconds > 0) {
FindFirstAndLast(logger, star, underscore, dateTimeFormat, searchString, seconds, searchPatterns, sourceDirectories);
}
}
private static void Redo(ILogger<Worker> logger, char star, char underscore, string dateTimeFormat, string searchString, string key, string[] searchPatterns, string[] sourceDirectories) {
bool found;
string check;
string[] files;
string[] lines;
string fileName;
string checkFile;
string checkPath;
DateTime lastDate;
DateTime firstDate;
string directoryName;
string[] directories;
string? directoryPath;
foreach (string sourceDirectory in sourceDirectories) {
directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string searchPattern in searchPatterns) {
if (searchPattern.Contains(underscore) || !searchPattern.Contains(star)) {
throw new Exception($"{nameof(searchPattern)} must not contain {underscore} and must contain {star}");
}
foreach (string directory in directories) {
directoryName = Path.GetFileName(directory);
files = Directory.GetFiles(directory, searchPattern, SearchOption.AllDirectories);
logger.LogInformation("With search pattern '{SearchPattern}' found {files} file(s)", searchPattern, files.Length);
foreach (string file in files) {
found = false;
lastDate = DateTime.MinValue;
firstDate = DateTime.MinValue;
fileName = Path.GetFileName(file);
directoryPath = Path.GetDirectoryName(file);
if (string.IsNullOrEmpty(directoryPath)) {
logger.LogInformation("skipped (empty) '{directoryPath}'", directoryPath);
continue;
}
try {
lines = File.ReadAllLines(file);
foreach (string line in lines) {
if (!found && line.Contains(searchString)) {
found = true;
}
if (line.Length < dateTimeFormat.Length) {
continue;
}
check = line[..dateTimeFormat.Length];
if (!DateTime.TryParseExact(check, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime logDate)) {
continue;
}
if (firstDate == DateTime.MinValue) {
firstDate = logDate;
}
lastDate = logDate;
}
if (!found) {
checkFile = $"{directoryName}_{firstDate:yyyy-MM-dd_HH-mm-ss}---{lastDate:yyyy-MM-dd_HH-mm-ss}.log";
} else {
checkFile = $"{directoryName}_{firstDate:yyyy-MM-dd_HH-mm-ss}---{lastDate:yyyy-MM-dd_HH-mm-ss}~~~{key}.log";
}
checkPath = Path.Combine(directoryPath, checkFile);
if (checkFile == fileName) {
logger.LogDebug("skipped (match) '{checkFile}'", checkFile);
} else if (File.Exists(checkPath)) {
logger.LogInformation("skipped (exists) '{checkPath}'", checkPath);
} else {
logger.LogInformation("rename to '{checkPath}'", checkPath);
File.Move(file, checkPath);
File.SetLastWriteTime(checkPath, lastDate);
continue;
}
} catch {
logger.LogWarning("skipped (error) {TotalHours} hour(s) -> '{FileInfo}'", file, (DateTime.Now - new FileInfo(file).LastWriteTime).TotalHours);
}
}
}
}
}
}
private static void Rename(ILogger<Worker> logger, char star, char underscore, string dateTimeFormat, string searchString, string key, string[] searchPatterns, string[] sourceDirectories) {
bool found;
string app;
string check;
string level;
string[] files;
string[] lines;
string checkFile;
string checkPath;
DateTime lastDate;
string[] segments;
DateTime firstDate;
string directoryName;
string[] directories;
string destinationDirectoryB;
FileInfo[] fileInfoCollection;
foreach (string sourceDirectory in sourceDirectories) {
directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string searchPattern in searchPatterns) {
if (!searchPattern.Contains(underscore) || !searchPattern.Contains(star)) {
throw new Exception($"{nameof(searchPattern)} must contain {underscore} and {star}");
}
foreach (string directory in directories) {
directoryName = Path.GetFileName(directory);
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
logger.LogInformation("With search pattern '{SearchPattern}' found {files} file(s)", searchPattern, files.Length);
fileInfoCollection = files.Select(f => new FileInfo(f)).ToArray();
foreach (FileInfo fileInfo in fileInfoCollection.OrderBy(f => f.LastWriteTime)) {
if (fileInfo.Length == 0) {
logger.LogDebug("skipped (0k) '{FileInfo}'", fileInfo.FullName);
continue;
} else if (fileInfo.LastWriteTime > DateTime.Now.AddMinutes(-1)) {
logger.LogDebug("skipped (too new) '{FileInfo}'", fileInfo.FullName);
continue;
}
found = false;
lastDate = DateTime.MinValue;
firstDate = DateTime.MinValue;
segments = fileInfo.Name.Split('_');
if (segments.Length < 2) {
logger.LogWarning("File name does not contain expected segments: {fileName}", fileInfo.Name);
continue;
}
app = segments[0];
level = segments[1].Split('.')[0].ToLower();
try {
lines = File.ReadAllLines(fileInfo.FullName);
foreach (string line in lines) {
if (!found && line.Contains(searchString)) {
found = true;
}
if (line.Length < dateTimeFormat.Length) {
continue;
}
check = line[..dateTimeFormat.Length];
if (!DateTime.TryParseExact(check, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime logDate)) {
continue;
}
if (firstDate == DateTime.MinValue) {
firstDate = logDate;
}
lastDate = logDate;
}
if (!found) {
checkFile = $"{app}_{directoryName}_{firstDate:yyyy-MM-dd_HH-mm-ss}---{lastDate:yyyy-MM-dd_HH-mm-ss}.{level}";
} else {
checkFile = $"{app}_{directoryName}_{firstDate:yyyy-MM-dd_HH-mm-ss}---{lastDate:yyyy-MM-dd_HH-mm-ss}~~~{key}.{level}";
}
checkPath = Path.Combine(directory, checkFile);
if (checkFile == fileInfo.Name) {
logger.LogDebug("skipped (match) '{checkFile}'", checkFile);
continue;
}
if (!File.Exists(checkPath)) {
logger.LogInformation("rename to '{checkPath}'", checkPath);
File.Move(fileInfo.FullName, checkPath);
File.SetLastWriteTime(checkPath, lastDate);
continue;
} else {
destinationDirectoryB = Path.Combine(directory, "DUP");
if (!Directory.Exists(destinationDirectoryB)) {
_ = Directory.CreateDirectory(destinationDirectoryB);
}
checkPath = Path.Combine(destinationDirectoryB, checkFile);
if (File.Exists(checkPath)) {
logger.LogInformation("skipped (exists) '{checkPath}'", checkPath);
} else {
logger.LogInformation("rename to '{checkPath}'", checkPath);
File.Move(fileInfo.FullName, checkPath);
File.SetLastWriteTime(checkPath, lastDate);
continue;
}
}
} catch {
logger.LogWarning("skipped (error) {TotalHours} hour(s) -> '{FileInfo}'", (DateTime.Now - fileInfo.LastWriteTime).TotalHours, fileInfo.FullName);
}
}
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, directory);
}
}
}
}
private static void FindFirstAndLast(ILogger<Worker> logger, char star, char underscore, string dateTimeFormat, string searchString, int seconds, string[] searchPatterns, string[] sourceDirectories) {
string line;
string check;
string[] files;
string[] lines;
DateTime lastDate;
double totalHours;
string[] segments;
TimeSpan timeSpan;
DateTime firstDate;
string[] segmentsB;
string directoryName;
string[] directories;
string searchPatternB;
string destinationDirectory;
FileInfo[] fileInfoCollection;
DateTime logDate = DateTime.MinValue;
foreach (string sourceDirectory in sourceDirectories) {
directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string searchPattern in searchPatterns) {
if (!searchPattern.Contains(underscore) || !searchPattern.Contains(star)) {
throw new Exception($"{nameof(searchPattern)} must contain {underscore} and {star}");
}
segments = searchPattern.TrimEnd(star).Split(star);
segmentsB = segments[0].Split(underscore);
foreach (string directory in directories) {
directoryName = Path.GetFileName(directory);
destinationDirectory = Path.Combine(directory, segmentsB[0], segmentsB[1]);
if (!Directory.Exists(destinationDirectory)) {
logger.LogInformation("skipped (doesn't exist) '{destinationDirectory}'", destinationDirectory);
continue;
}
searchPatternB = $"*{segments[^1]}*";
files = Directory.GetFiles(destinationDirectory, searchPatternB, SearchOption.TopDirectoryOnly);
logger.LogInformation("For {destinationDirectory} with search pattern '{SearchPatternB}' found {files} file(s)", destinationDirectory, searchPatternB, files.Length);
fileInfoCollection = files.Select(f => new FileInfo(f)).ToArray();
foreach (FileInfo fileInfo in fileInfoCollection.OrderBy(f => f.LastWriteTime)) {
if (fileInfo.Length == 0) {
logger.LogDebug("skipped (0k) '{FileInfo}'", fileInfo.FullName);
continue;
} else if (fileInfo.LastWriteTime > DateTime.Now.AddMinutes(-1)) {
logger.LogDebug("skipped (too new) '{FileInfo}'", fileInfo.FullName);
continue;
}
lastDate = DateTime.MinValue;
firstDate = DateTime.MinValue;
try {
lines = File.ReadAllLines(fileInfo.FullName);
for (int i = 0; i < lines.Length; i++) {
line = lines[i];
if (!line.Contains(searchString) || lines[i - 1].Length < dateTimeFormat.Length) {
continue;
}
check = lines[i - 1][..dateTimeFormat.Length];
if (!DateTime.TryParseExact(check, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out logDate)) {
continue;
}
timeSpan = logDate - lastDate;
if (firstDate == DateTime.MinValue || timeSpan.TotalSeconds > seconds) {
if (firstDate != DateTime.MinValue) {
totalHours = Math.Round((lastDate - firstDate).TotalHours, 2);
logger.LogInformation("Ran for {totalHours} hour(s) {logDate} - {firstDate} {file}", totalHours, logDate.ToString("HH:mm:ss"), firstDate.ToString("HH:mm:ss"), fileInfo.FullName[directory.Length..]);
}
firstDate = logDate;
}
lastDate = logDate;
}
if (firstDate != DateTime.MinValue && logDate != DateTime.MinValue) {
totalHours = Math.Round((lastDate - firstDate).TotalHours, 2);
logger.LogInformation("Ran for {totalHours} hour(s) {logDate} - {firstDate} {file}", totalHours, logDate.ToString("HH:mm:ss"), firstDate.ToString("HH:mm:ss"), fileInfo.FullName[directory.Length..]);
}
} catch {
logger.LogWarning("skipped (error) {TotalHours} hour(s) -> '{FileInfo}'", (DateTime.Now - fileInfo.LastWriteTime).TotalHours, fileInfo.FullName);
}
}
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, directory);
}
}
}
}
}

View File

@ -0,0 +1,145 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2025.PI7;
internal static partial class Helper20251022 {
private record Root(int Count, JsonElement[] Records, ProcessDataStandardFormat? ProcessDataStandardFormat) {
internal static Root? Get(string file) {
Root? result;
string? json = File.ReadAllText(file);
result = JsonSerializer.Deserialize(json, Helper20251022RootSourceGenerationContext.Default.Root);
if (result is null || result.ProcessDataStandardFormat is null || result.Records.Length == 0) {
result = null;
}
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Root))]
private partial class Helper20251022RootSourceGenerationContext : JsonSerializerContext {
}
[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(JsonElement))]
private partial class Helper20251022JsonElementSourceGenerationContext : JsonSerializerContext {
}
private record ProcessDataStandardFormat([property: JsonPropertyName("Footer")] JsonElement? Footer, [property: JsonPropertyName("LOGISTICS_1")] JsonElement? Logistics);
internal static void CombineFiles(ILogger<Worker> logger, List<string> args) {
logger.LogInformation(args[0]);
logger.LogInformation(args[1]);
logger.LogInformation(args[2]);
logger.LogInformation(args[3]);
string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string destinationDirectory = Path.GetFullPath(args[3].Split('~')[0]);
List<string> directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly).ToList();
if (directories.Count == 0) {
directories.Add(sourceDirectory);
}
ReadOnlyDictionary<string, List<string>> files = GetFiles(logger, searchPattern, directories.AsReadOnly());
CombineFiles(logger, destinationDirectory, files);
}
private static ReadOnlyDictionary<string, List<string>> GetFiles(ILogger<Worker> logger, string searchPattern, ReadOnlyCollection<string> directories) {
Dictionary<string, List<string>> results = [];
string key;
string[] files;
FileInfo fileInfo;
string[] segments;
string weekOfYear;
List<string>? collection;
Calendar calendar = new CultureInfo("en-US").Calendar;
foreach (string directory in directories) {
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
files = files.OrderBy(l => l).ThenBy(l => l.Length).ToArray();
for (int i = 0; i < files.Length; i++) {
fileInfo = new(files[i]);
segments = fileInfo.Name.Split('_');
if (segments.Length < 2) {
logger.LogWarning("{fileInfoName} does not have enough segments!", fileInfo.Name);
continue;
}
weekOfYear = $"{fileInfo.LastWriteTime.Year}_Week_{calendar.GetWeekOfYear(fileInfo.LastWriteTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
key = $"{segments[0]}_{weekOfYear}";
if (!results.TryGetValue(key, out collection)) {
collection = [];
results.Add(key, collection);
}
collection.Add(files[i]);
}
}
return results.AsReadOnly();
}
private static void CombineFiles(ILogger<Worker> logger, string destinationDirectory, ReadOnlyDictionary<string, List<string>> files) {
Root? root;
string json;
string[] lines;
string fileName;
string? jsonOld;
string? jsonFooter;
string? jsonLogistics;
JsonElement jsonElementB;
List<string> segments = [];
List<string> jsonLines = [];
if (!Directory.Exists(destinationDirectory)) {
_ = Directory.CreateDirectory(destinationDirectory);
}
foreach (KeyValuePair<string, List<string>> keyValuePair in files) {
jsonLines.Clear();
fileName = Path.Combine(destinationDirectory, $"{keyValuePair.Key}.json");
foreach (string file in keyValuePair.Value) {
root = Root.Get(file);
if (root is null) {
logger.LogWarning("result is null");
continue;
}
foreach (JsonElement jsonElement in root.Records) {
jsonFooter = root.ProcessDataStandardFormat?.Footer?.ToString();
jsonLogistics = root.ProcessDataStandardFormat?.Logistics?.ToString();
if (string.IsNullOrEmpty(jsonFooter) && string.IsNullOrEmpty(jsonLogistics)) {
jsonLines.Add(jsonElement.ToString());
} else {
segments.Clear();
segments.Add(jsonElement.ToString()[..^1]);
if (!string.IsNullOrEmpty(jsonFooter)) {
segments.Add(",");
lines = jsonFooter[1..^1].Split(Environment.NewLine);
segments.AddRange(lines.Select(l => l.Trim()));
}
if (!string.IsNullOrEmpty(jsonLogistics)) {
segments.Add(",");
lines = jsonLogistics[1..^1].Split(Environment.NewLine);
segments.AddRange(lines.Select(l => l.Trim()));
}
segments.Add("}");
jsonElementB = JsonSerializer.Deserialize(string.Join(' ', segments), Helper20251022JsonElementSourceGenerationContext.Default.JsonElement);
jsonLines.Add(jsonElementB.ToString());
}
}
}
if (jsonLines.Count == 0) {
logger.LogWarning("jsonLines is empty");
continue;
}
json = string.Concat('[', Environment.NewLine, string.Join($",{Environment.NewLine}", jsonLines), Environment.NewLine, ']');
jsonOld = File.Exists(fileName) ? File.ReadAllText(fileName) : null;
if (!string.IsNullOrEmpty(jsonOld) && jsonOld == json) {
logger.LogInformation("{fileName} has no changes", fileName);
continue;
}
File.WriteAllText(fileName, json);
}
}
}

296
ADO2025/PI8/.editorconfig Normal file
View File

@ -0,0 +1,296 @@
[*.md]
end_of_line = crlf
file_header_template = unset
indent_size = 2
indent_style = space
insert_final_newline = false
root = true
tab_width = 2
[*.csproj]
end_of_line = crlf
file_header_template = unset
indent_size = 2
indent_style = space
insert_final_newline = false
root = true
tab_width = 2
[*.cs]
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true
csharp_prefer_braces = true
csharp_prefer_qualified_reference = true:error
csharp_prefer_simple_default_expression = true:warning
csharp_prefer_simple_using_statement = true:warning
csharp_prefer_static_local_function = true:warning
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = false
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
csharp_style_allow_embedded_statements_on_same_line_experimental = true
csharp_style_conditional_delegate_call = true
csharp_style_deconstructed_variable_declaration = false
csharp_style_expression_bodied_accessors = when_on_single_line:warning
csharp_style_expression_bodied_constructors = when_on_single_line:warning
csharp_style_expression_bodied_indexers = when_on_single_line:warning
csharp_style_expression_bodied_lambdas = when_on_single_line:warning
csharp_style_expression_bodied_local_functions = when_on_single_line:warning
csharp_style_expression_bodied_methods = when_on_single_line:warning
csharp_style_expression_bodied_operators = when_on_single_line:warning
csharp_style_expression_bodied_properties = when_on_single_line:warning
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
csharp_style_inlined_variable_declaration = false
csharp_style_namespace_declarations = file_scoped:warning
csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_not_pattern = true:warning
csharp_style_prefer_null_check_over_type_check = true
csharp_style_prefer_pattern_matching = true:warning
csharp_style_prefer_range_operator = true:warning
csharp_style_prefer_switch_expression = true:warning
csharp_style_throw_expression = true
csharp_style_unused_value_assignment_preference = discard_variable:warning
csharp_style_unused_value_expression_statement_preference = discard_variable:warning
csharp_style_var_elsewhere = false:warning
csharp_style_var_for_built_in_types = false:warning
csharp_style_var_when_type_is_apparent = false:warning
csharp_using_directive_placement = outside_namespace
dotnet_analyzer_diagnostic.category-Design.severity = error
dotnet_analyzer_diagnostic.category-Documentation.severity = error
dotnet_analyzer_diagnostic.category-Globalization.severity = none
dotnet_analyzer_diagnostic.category-Interoperability.severity = error
dotnet_analyzer_diagnostic.category-Maintainability.severity = error
dotnet_analyzer_diagnostic.category-Naming.severity = none
dotnet_analyzer_diagnostic.category-Performance.severity = none
dotnet_analyzer_diagnostic.category-Reliability.severity = error
dotnet_analyzer_diagnostic.category-Security.severity = error
dotnet_analyzer_diagnostic.category-SingleFile.severity = error
dotnet_analyzer_diagnostic.category-Style.severity = error
dotnet_analyzer_diagnostic.category-Usage.severity = error
dotnet_code_quality_unused_parameters = all
dotnet_code_quality_unused_parameters = non_public
dotnet_code_quality.CAXXXX.api_surface = private, internal
dotnet_diagnostic.CA1001.severity = error # CA1001: Types that own disposable fields should be disposable
dotnet_diagnostic.CA1051.severity = error # CA1051: Do not declare visible instance fields
dotnet_diagnostic.CA1511.severity = warning # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1513.severity = warning # Use 'ObjectDisposedException.ThrowIf' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1825.severity = warning # CA1825: Avoid zero-length array allocations
dotnet_diagnostic.CA1829.severity = warning # CA1829: Use Length/Count property instead of Count() when available
dotnet_diagnostic.CA1834.severity = warning # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
dotnet_diagnostic.CA1860.severity = error # CA1860: Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
dotnet_diagnostic.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'
dotnet_diagnostic.CA1869.severity = none # CA1869: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead.
dotnet_diagnostic.CA2201.severity = none # CA2201: Exception type System.NullReferenceException is reserved by the runtime
dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template should not vary between calls to 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])'
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name
dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2");
dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant.
dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary
dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement (IDE0010)
dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be removed
dotnet_diagnostic.IDE0048.severity = none # Parentheses preferences (IDE0047 and IDE0048)
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
dotnet_diagnostic.IDE0051.severity = error # Private member '' is unused [, ]
dotnet_diagnostic.IDE0058.severity = warning # IDE0058: Expression value is never used
dotnet_diagnostic.IDE0060.severity = error # IDE0060: Remove unused parameter
dotnet_diagnostic.IDE0074.severity = warning # IDE0074: Use compound assignment
dotnet_diagnostic.IDE0130.severity = none # Namespace does not match folder structure (IDE0130)
dotnet_diagnostic.IDE0270.severity = warning # IDE0270: Null check can be simplified
dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]csharp(IDE0290)
dotnet_diagnostic.IDE0300.severity = error # IDE0300: Collection initialization can be simplified
dotnet_diagnostic.IDE0301.severity = error #IDE0301: Collection initialization can be simplified
dotnet_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified
dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method
dotnet_naming_rule.class_should_be_pascal_case.severity = warning
dotnet_naming_rule.class_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.class_should_be_pascal_case.symbols = class
dotnet_naming_rule.delegate_should_be_pascal_case.severity = warning
dotnet_naming_rule.delegate_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.delegate_should_be_pascal_case.symbols = delegate
dotnet_naming_rule.enum_should_be_pascal_case.severity = warning
dotnet_naming_rule.enum_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.enum_should_be_pascal_case.symbols = enum
dotnet_naming_rule.event_should_be_pascal_case.severity = warning
dotnet_naming_rule.event_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.event_should_be_pascal_case.symbols = event
dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.method_should_be_pascal_case.severity = warning
dotnet_naming_rule.method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.method_should_be_pascal_case.symbols = method
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.private_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.private_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.private_method_should_be_pascal_case.symbols = private_method
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.symbols = private_or_internal_field
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.symbols = private_or_internal_static_field
dotnet_naming_rule.property_should_be_pascal_case.severity = warning
dotnet_naming_rule.property_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.property_should_be_pascal_case.symbols = property
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.symbols = public_or_protected_field
dotnet_naming_rule.static_field_should_be_pascal_case.severity = warning
dotnet_naming_rule.static_field_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_field_should_be_pascal_case.symbols = static_field
dotnet_naming_rule.static_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.static_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_method_should_be_pascal_case.symbols = static_method
dotnet_naming_rule.struct_should_be_pascal_case.severity = warning
dotnet_naming_rule.struct_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.struct_should_be_pascal_case.symbols = struct
dotnet_naming_rule.types_should_be_pascal_case.severity = warning
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.private_of_internal_field.capitalization = pascal_case
dotnet_naming_style.private_of_internal_field.required_prefix = _
dotnet_naming_style.private_of_internal_field.required_suffix =
dotnet_naming_style.private_of_internal_field.word_separator =
dotnet_naming_symbols.abstract_method.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.abstract_method.applicable_kinds = method
dotnet_naming_symbols.abstract_method.required_modifiers = abstract
dotnet_naming_symbols.class.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.class.applicable_kinds = class
dotnet_naming_symbols.class.required_modifiers =
dotnet_naming_symbols.delegate.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.delegate.applicable_kinds = delegate
dotnet_naming_symbols.delegate.required_modifiers =
dotnet_naming_symbols.enum.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.enum.applicable_kinds = enum
dotnet_naming_symbols.enum.required_modifiers =
dotnet_naming_symbols.event.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.event.applicable_kinds = event
dotnet_naming_symbols.event.required_modifiers =
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.method.applicable_accessibilities = public
dotnet_naming_symbols.method.applicable_kinds = method
dotnet_naming_symbols.method.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_symbols.private_method.applicable_accessibilities = private
dotnet_naming_symbols.private_method.applicable_kinds = method
dotnet_naming_symbols.private_method.required_modifiers =
dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected
dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_field.required_modifiers =
dotnet_naming_symbols.private_or_internal_static_field.applicable_accessibilities = internal, private, private_protected
dotnet_naming_symbols.private_or_internal_static_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_static_field.required_modifiers = static
dotnet_naming_symbols.property.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.property.applicable_kinds = property
dotnet_naming_symbols.property.required_modifiers =
dotnet_naming_symbols.public_or_protected_field.applicable_accessibilities = public, protected
dotnet_naming_symbols.public_or_protected_field.applicable_kinds = field
dotnet_naming_symbols.public_or_protected_field.required_modifiers =
dotnet_naming_symbols.static_field.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.static_field.applicable_kinds = field
dotnet_naming_symbols.static_field.required_modifiers = static
dotnet_naming_symbols.static_method.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.static_method.applicable_kinds = method
dotnet_naming_symbols.static_method.required_modifiers = static
dotnet_naming_symbols.struct.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.struct.applicable_kinds = struct
dotnet_naming_symbols.struct.required_modifiers =
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.required_modifiers =
dotnet_remove_unnecessary_suppression_exclusions = 0
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
dotnet_style_allow_multiple_blank_lines_experimental = false:warning
dotnet_style_allow_statement_immediately_after_block_experimental = true
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true:warning
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_namespace_match_folder = true
dotnet_style_null_propagation = true:warning
dotnet_style_object_initializer = true:warning
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_operators = never_if_unnecessary
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
dotnet_style_predefined_type_for_locals_parameters_members = true
dotnet_style_predefined_type_for_member_access = true:warning
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_compound_assignment = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = false
dotnet_style_prefer_conditional_expression_over_return = false
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
dotnet_style_prefer_simplified_boolean_expressions = true:warning
dotnet_style_prefer_simplified_interpolation = true
dotnet_style_qualification_for_event = false:error
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false:error
dotnet_style_qualification_for_property = false:error
dotnet_style_readonly_field = true:warning
dotnet_style_require_accessibility_modifiers = for_non_interface_members
end_of_line = crlf
file_header_template = unset
indent_size = 4
indent_style = space
insert_final_newline = false
root = true
tab_width = 4
# https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1822
# https://github.com/dotnet/aspnetcore/blob/main/.editorconfig
# https://github.com/dotnet/project-system/blob/main/.editorconfig

View File

@ -0,0 +1,646 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2025.PI8;
internal static partial class Helper20251111 {
private record Record([property: JsonPropertyName("Time")] decimal? Time, // Time
[property: JsonPropertyName("A_LOGISTICS")] int? A_LOGISTICS, // A_LOGISTICS
[property: JsonPropertyName("id12")] decimal? Id12, // CenterTemp
[property: JsonPropertyName("id13")] decimal? Id13, // CenterSetPoint
[property: JsonPropertyName("id15")] decimal? Id15, // FrontTemp
[property: JsonPropertyName("id16")] decimal? Id16, // FrontSetPoint
[property: JsonPropertyName("id18")] decimal? Id18, // SideTemp
[property: JsonPropertyName("id19")] decimal? Id19, // SideSetPoint
[property: JsonPropertyName("id21")] decimal? Id21, // RearTemp
[property: JsonPropertyName("id22")] decimal? Id22, // RearSetPoint
[property: JsonPropertyName("id25")] decimal? Id25, // N2H2SetPoint
[property: JsonPropertyName("id26")] decimal? Id26, // N2H2Flow
[property: JsonPropertyName("id29")] decimal? Id29, // HCLHISetPoint
[property: JsonPropertyName("id37")] decimal? Id37, // NSRCSetPoint
[property: JsonPropertyName("id38")] decimal? Id38, // NSRCFlow
[property: JsonPropertyName("id39")] decimal? Id39, // NDILSetPoint
[property: JsonPropertyName("id40")] decimal? Id40, // NDILFlow
[property: JsonPropertyName("id41")] decimal? Id41, // NINJSetPoint
[property: JsonPropertyName("id42")] decimal? Id42, // NINJFlow
[property: JsonPropertyName("id27")] decimal? Id27, // HCLSetPoint
[property: JsonPropertyName("id28")] decimal? Id28, // HCLFlow
[property: JsonPropertyName("id30")] decimal? Id30, // HCLHIFlow
[property: JsonPropertyName("id61")] decimal? Id61, // ROTSetPoint
[property: JsonPropertyName("id62")] decimal? Id62, // ROTSpeed
[property: JsonPropertyName("id173")] decimal? Id173, // LVC1Carrier
[property: JsonPropertyName("id58")] decimal? Id58, // LVC1Flow
[property: JsonPropertyName("id172")] decimal? Id172, // LVC1Ratio
[property: JsonPropertyName("id57")] decimal? Id57, // LVC1SetPoint
[property: JsonPropertyName("id193")] decimal? Id193, // SCRLOAD4
[property: JsonPropertyName("id183")] decimal? Id183, // SCRDrive4
[property: JsonPropertyName("vp93")] int? VP93, // ProcessState
[property: JsonPropertyName("vp154")] int? VP154, // SystemState
[property: JsonPropertyName("vp78")] int? VP78, // LL1State
[property: JsonPropertyName("vp83")] int? VP83, // LL2State
[property: JsonPropertyName("vp176")] int? VP176, // TotalWaferCount
[property: JsonPropertyName("vp79")] int? VP79, // LL1Init
[property: JsonPropertyName("vp81")] int? VP81, // LL1WafersIn
[property: JsonPropertyName("vp82")] int? VP82, // LL1WfrCnt
[property: JsonPropertyName("vp84")] int? VP84, // LL2Init
[property: JsonPropertyName("vp86")] int? VP86, // LL2WafersIn
[property: JsonPropertyName("vp87")] int? VP87, // LL2WfrCnt
[property: JsonPropertyName("vp80")] string? VP80, // LL1LotId
[property: JsonPropertyName("vp85")] string? VP85, // LL2LotId
[property: JsonPropertyName("vp153")] string? VP153, // PPSTEPNAME
[property: JsonPropertyName("vp221")] string? VP221, // LeftDefaultRecipe
[property: JsonPropertyName("vp222")] string? VP222, // RightDefaultRecipe
[property: JsonPropertyName("vp223")] string? VP223, // RecipeCompleteMsg
[property: JsonPropertyName("NUM_DATA_ROWS")] int? NUM_DATA_ROWS, // NUM_DATA_ROWS
[property: JsonPropertyName("NUM_DATA_COLUMNS")] int? NUM_DATA_COLUMNS, // NUM_DATA_COLUMNS
[property: JsonPropertyName("START_TIME_FORMAT")] string? START_TIME_FORMAT, // START_TIME_FORMAT
[property: JsonPropertyName("START_TIME")] string? START_TIME, // START_TIME
[property: JsonPropertyName("LOGISTICS_COLUMN")] string? LOGISTICS_COLUMN, // LOGISTICS_COLUMN
[property: JsonPropertyName("A_BASIC_TYPE")] string? A_BASIC_TYPE, // A_BASIC_TYPE
[property: JsonPropertyName("A_INFO")] string? A_INFO, // A_INFO
[property: JsonPropertyName("A_INFO2")] string? A_INFO2, // A_INFO2
[property: JsonPropertyName("A_JOBID")] string? A_JOBID, // A_JOBID
[property: JsonPropertyName("A_LAYER")] string? A_LAYER, // A_LAYER
[property: JsonPropertyName("A_LAYER2")] string? A_LAYER2, // A_LAYER2
[property: JsonPropertyName("A_MES_ENTITY")] string? A_MES_ENTITY, // A_MES_ENTITY
[property: JsonPropertyName("A_MID")] string? A_MID, // A_MID
[property: JsonPropertyName("A_NULL_DATA")] string? A_NULL_DATA, // A_NULL_DATA
[property: JsonPropertyName("A_PPID")] string? A_PPID, // A_PPID
[property: JsonPropertyName("A_PROCESS_JOBID")] string? A_PROCESS_JOBID, // A_PROCESS_JOBID
[property: JsonPropertyName("A_PRODUCT")] string? A_PRODUCT, // A_PRODUCT
[property: JsonPropertyName("A_SEQUENCE")] string? A_SEQUENCE, // A_SEQUENCE
[property: JsonPropertyName("A_WADER_ID")] string? A_WADER_ID, // A_WADER_ID
[property: JsonPropertyName("A_WAFER_POS")] string? A_WAFER_POS, // A_WAFER_POS
[property: JsonPropertyName("id31")] decimal? Id31, // PSRCSetPoint
[property: JsonPropertyName("id32")] decimal? Id32, // PSRCFlow
[property: JsonPropertyName("id33")] decimal? Id33, // PDILSetPoint
[property: JsonPropertyName("id34")] decimal? Id34, // PDILFlow
[property: JsonPropertyName("id35")] decimal? Id35, // PINJSetPoint
[property: JsonPropertyName("id36")] decimal? Id36, // PINJFlow
[property: JsonPropertyName("vp96")] string? VP96, // PPEXECNAME
[property: JsonPropertyName("A_CHAMBER")] string? A_CHAMBER, // A_CHAMBER
[property: JsonPropertyName("A_SLOT")] string? A_SLOT) { // A_SLOT
internal static ReadOnlyCollection<Record> GetCollection(string file) {
List<Record> results = [];
string json;
Record? result;
string? text = File.ReadAllText(file);
JsonElement[]? jsonElements = JsonSerializer.Deserialize(text, Helper20251111JsonElementArraySourceGenerationContext.Default.JsonElementArray);
if (jsonElements is not null && jsonElements.Length > 0) {
foreach (JsonElement jsonElement in jsonElements) {
json = jsonElement.ToString();
if (json.Contains("vp153\":\"\"")) {
continue;
}
result = JsonSerializer.Deserialize(jsonElement, Helper20251111RecordSourceGenerationContext.Default.Record);
if (result is null) {
continue;
}
results.Add(result);
}
}
return results.AsReadOnly();
}
}
[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.Never, NumberHandling = JsonNumberHandling.AllowReadingFromString)]
[JsonSerializable(typeof(Record))]
private partial class Helper20251111RecordSourceGenerationContext : JsonSerializerContext {
}
[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.Never, NumberHandling = JsonNumberHandling.AllowReadingFromString)]
[JsonSerializable(typeof(Record[]))]
private partial class Helper20251111RecordArraySourceGenerationContext : JsonSerializerContext {
}
private record RecordWith([property: JsonPropertyName("Point")] int Point,
[property: JsonPropertyName("Time")] decimal? Time,
[property: JsonPropertyName("A_LOGISTICS")] int? A_LOGISTICS,
[property: JsonPropertyName("CenterTemp")] decimal? Id12,
[property: JsonPropertyName("CenterSetPoint")] decimal? Id13,
[property: JsonPropertyName("CenterDevFromSetpoint")] decimal? CenterDevFromSetpoint,
[property: JsonPropertyName("FrontTemp")] decimal? Id15,
[property: JsonPropertyName("FrontSetPoint")] decimal? Id16,
[property: JsonPropertyName("FrontDevFromSetpoint")] decimal? FrontDevFromSetpoint,
[property: JsonPropertyName("SideTemp")] decimal? Id18,
[property: JsonPropertyName("SideSetPoint")] decimal? Id19,
[property: JsonPropertyName("SideDevFromSetpoint")] decimal? SideDevFromSetpoint,
[property: JsonPropertyName("RearTemp")] decimal? Id21,
[property: JsonPropertyName("RearSetPoint")] decimal? Id22,
[property: JsonPropertyName("RearDevFromSetpoint")] decimal? RearDevFromSetpoint,
[property: JsonPropertyName("N2H2SetPoint")] decimal? Id25,
[property: JsonPropertyName("N2H2Flow")] decimal? Id26,
[property: JsonPropertyName("N2H2DevFromSetpoint")] decimal? N2H2DevFromSetpoint,
[property: JsonPropertyName("N2H2PercentDevFromSetpoint")] decimal? N2H2PercentDevFromSetpoint,
[property: JsonPropertyName("HCLHISetPoint")] decimal? Id29,
[property: JsonPropertyName("NSRCSetPoint")] decimal? Id37,
[property: JsonPropertyName("NSRCFlow")] decimal? Id38,
[property: JsonPropertyName("NSRCSDevFromSetpoint")] decimal? NSRCSDevFromSetpoint,
[property: JsonPropertyName("NSRCSPercentDevFromSetpoint")] decimal? NSRCSPercentDevFromSetpoint,
[property: JsonPropertyName("NDILSetPoint")] decimal? Id39,
[property: JsonPropertyName("NDILFlow")] decimal? Id40,
[property: JsonPropertyName("NDILDevFromSetpoint")] decimal? NDILDevFromSetpoint,
[property: JsonPropertyName("NDILPercentDevFromSetpoint")] decimal? NDILPercentDevFromSetpoint,
[property: JsonPropertyName("NINJSetPoint")] decimal? Id41,
[property: JsonPropertyName("NINJFlow")] decimal? Id42,
[property: JsonPropertyName("NINJDevFromSetpoint")] decimal? NINJDevFromSetpoint,
[property: JsonPropertyName("NINJPercentDevFromSetpoint")] decimal? NINJPercentDevFromSetpoint,
[property: JsonPropertyName("HCLSetPoint")] decimal? Id27,
[property: JsonPropertyName("HCLFlow")] decimal? Id28,
[property: JsonPropertyName("HCLHIFlow")] decimal? Id30,
[property: JsonPropertyName("HCLHIDevFromSetpoint")] decimal? HCLHIDevFromSetpoint,
[property: JsonPropertyName("HCLHIPercentDevFromSetpoint")] decimal? HCLHIPercentDevFromSetpoint,
[property: JsonPropertyName("HCLDevFromSetpoint")] decimal? HCLDevFromSetpoint,
[property: JsonPropertyName("HCLPercentDevFromSetpoint")] decimal? HCLPercentDevFromSetpoint,
[property: JsonPropertyName("ROTSetPoint")] decimal? Id61,
[property: JsonPropertyName("ROTSpeed")] decimal? Id62,
[property: JsonPropertyName("ROTDevFromSetpoint")] decimal? ROTDevFromSetpoint,
[property: JsonPropertyName("LVC1Carrier")] decimal? Id173,
[property: JsonPropertyName("LVC1Flow")] decimal? Id58,
[property: JsonPropertyName("LVC1Ratio")] decimal? Id172,
[property: JsonPropertyName("LVC1SetPoint")] decimal? Id57,
[property: JsonPropertyName("LVCDevFromSetpoint")] decimal? LVCDevFromSetpoint,
[property: JsonPropertyName("LVCPercentDevFromSetpoint")] decimal? LVCPercentDevFromSetpoint,
[property: JsonPropertyName("SCRLOAD4")] decimal? Id193,
[property: JsonPropertyName("SCRDrive4")] decimal? Id183,
[property: JsonPropertyName("ProcessState")] int? VP93,
[property: JsonPropertyName("SystemState")] int? VP154,
[property: JsonPropertyName("LL1State")] int? VP78,
[property: JsonPropertyName("LL2State")] int? VP83,
[property: JsonPropertyName("TotalWaferCount")] int? VP176,
[property: JsonPropertyName("LL1Init")] int? VP79,
[property: JsonPropertyName("LL1WafersIn")] int? VP81,
[property: JsonPropertyName("LL1WfrCnt")] int? VP82,
[property: JsonPropertyName("LL2Init")] int? VP84,
[property: JsonPropertyName("LL2WafersIn")] int? VP86,
[property: JsonPropertyName("LL2WfrCnt")] int? VP87,
[property: JsonPropertyName("LL1LotId")] string? VP80,
[property: JsonPropertyName("LL2LotId")] string? VP85,
[property: JsonPropertyName("PPSTEPNAME")] string? VP153,
[property: JsonPropertyName("LeftDefaultRecipe")] string? VP221,
[property: JsonPropertyName("RightDefaultRecipe")] string? VP222,
[property: JsonPropertyName("RecipeCompleteMsg")] string? VP223,
[property: JsonPropertyName("NUM_DATA_ROWS")] int? NUM_DATA_ROWS,
[property: JsonPropertyName("NUM_DATA_COLUMNS")] int? NUM_DATA_COLUMNS,
[property: JsonPropertyName("START_TIME_FORMAT")] string? START_TIME_FORMAT,
[property: JsonPropertyName("START_TIME")] string? START_TIME,
[property: JsonPropertyName("LOGISTICS_COLUMN")] string? LOGISTICS_COLUMN,
[property: JsonPropertyName("A_BASIC_TYPE")] string? A_BASIC_TYPE,
[property: JsonPropertyName("A_INFO")] string? A_INFO,
[property: JsonPropertyName("A_INFO2")] string? A_INFO2,
[property: JsonPropertyName("A_JOBID")] string? A_JOBID,
[property: JsonPropertyName("A_LAYER")] string? A_LAYER,
[property: JsonPropertyName("A_LAYER2")] string? A_LAYER2,
[property: JsonPropertyName("A_MES_ENTITY")] string? A_MES_ENTITY,
[property: JsonPropertyName("A_MID")] string? A_MID,
[property: JsonPropertyName("A_NULL_DATA")] string? A_NULL_DATA,
[property: JsonPropertyName("A_PPID")] string? A_PPID,
[property: JsonPropertyName("A_PROCESS_JOBID")] string? A_PROCESS_JOBID,
[property: JsonPropertyName("A_PRODUCT")] string? A_PRODUCT,
[property: JsonPropertyName("A_SEQUENCE")] string? A_SEQUENCE,
[property: JsonPropertyName("A_WADER_ID")] string? A_WADER_ID,
[property: JsonPropertyName("A_WAFER_POS")] string? A_WAFER_POS,
[property: JsonPropertyName("PSRCSetPoint")] decimal? Id31,
[property: JsonPropertyName("PSRCFlow")] decimal? Id32,
[property: JsonPropertyName("PSRCSDevFromSetpoint")] decimal? PSRCSDevFromSetpoint,
[property: JsonPropertyName("PSRCSPercentDevFromSetpoint")] decimal? PSRCSPercentDevFromSetpoint,
[property: JsonPropertyName("PDILSetPoint")] decimal? Id33,
[property: JsonPropertyName("PDILFlow")] decimal? Id34,
[property: JsonPropertyName("PDILDevFromSetpoint")] decimal? PDILDevFromSetpoint,
[property: JsonPropertyName("PDILPercentDevFromSetpoint")] decimal? PDILPercentDevFromSetpoint,
[property: JsonPropertyName("PINJSetPoint")] decimal? Id35,
[property: JsonPropertyName("PINJFlow")] decimal? Id36,
[property: JsonPropertyName("PINJDevFromSetpoint")] decimal? PINJDevFromSetpoint,
[property: JsonPropertyName("PINJPercentDevFromSetpoint")] decimal? PINJPercentDevFromSetpoint,
[property: JsonPropertyName("PPEXECNAME")] string? VP96,
[property: JsonPropertyName("A_CHAMBER")] string? A_CHAMBER,
[property: JsonPropertyName("A_SLOT")] string? A_SLOT) {
internal static RecordWith Get(int i, Record record) {
RecordWith result;
int point = i + 1;
decimal? centerDevFromSetpoint = (record.Id12 is not null && record.Id13 is not null) ? Math.Round(record.Id12.Value - record.Id13.Value, 6) : null;
decimal? frontDevFromSetpoint = (record.Id15 is not null && record.Id16 is not null) ? Math.Round(record.Id15.Value - record.Id16.Value, 6) : null;
decimal? sideDevFromSetpoint = (record.Id18 is not null && record.Id19 is not null) ? Math.Round(record.Id18.Value - record.Id19.Value, 6) : null;
decimal? rearDevFromSetpoint = (record.Id21 is not null && record.Id22 is not null) ? Math.Round(record.Id21.Value - record.Id22.Value, 6) : null;
decimal? n2H2DevFromSetpoint = (record.Id26 is not null && record.Id25 is not null) ? Math.Round(record.Id26.Value - record.Id25.Value, 6) : null;
decimal? n2H2PercentDevFromSetpoint = (record.Id26 is not null && record.Id25 is not null && record.Id25 != 0) ? Math.Round((record.Id26.Value - record.Id25.Value) / record.Id25.Value * 100, 6) : null;
decimal? nSRCSDevFromSetpoint = (record.Id38 is not null && record.Id37 is not null) ? Math.Round(record.Id38.Value - record.Id37.Value, 6) : null;
decimal? nSRCSPercentDevFromSetpoint = (record.Id38 is not null && record.Id37 is not null && record.Id37 != 0) ? Math.Round((record.Id38.Value - record.Id37.Value) / record.Id37.Value * 100, 6) : null;
decimal? nDILDevFromSetpoint = (record.Id40 is not null && record.Id39 is not null) ? Math.Round(record.Id40.Value - record.Id39.Value, 6) : null;
decimal? nDILPercentDevFromSetpoint = (record.Id40 is not null && record.Id39 is not null && record.Id39 != 0) ? Math.Round((record.Id40.Value - record.Id39.Value) / record.Id39.Value * 100, 6) : null;
decimal? nINJDevFromSetpoint = (record.Id42 is not null && record.Id41 is not null) ? Math.Round(record.Id42.Value - record.Id41.Value, 6) : null;
decimal? nINJPercentDevFromSetpoint = (record.Id42 is not null && record.Id41 is not null && record.Id41 != 0) ? Math.Round((record.Id42.Value - record.Id41.Value) / record.Id41.Value * 100, 6) : null;
decimal? pSRCSDevFromSetpoint = (record.Id32 is not null && record.Id31 is not null) ? Math.Round(record.Id32.Value - record.Id31.Value, 6) : null;
decimal? pSRCSPercentDevFromSetpoint = (record.Id32 is not null && record.Id31 is not null && record.Id31 != 0) ? Math.Round((record.Id32.Value - record.Id31.Value) / record.Id31.Value * 100, 6) : null;
decimal? pDILDevFromSetpoint = (record.Id34 is not null && record.Id33 is not null) ? Math.Round(record.Id34.Value - record.Id33.Value, 6) : null;
decimal? pDILPercentDevFromSetpoint = (record.Id34 is not null && record.Id33 is not null && record.Id33 != 0) ? Math.Round((record.Id34.Value - record.Id33.Value) / record.Id33.Value * 100, 6) : null;
decimal? pINJDevFromSetpoint = (record.Id36 is not null && record.Id35 is not null) ? Math.Round(record.Id36.Value - record.Id35.Value, 6) : null;
decimal? pINJPercentDevFromSetpoint = (record.Id36 is not null && record.Id35 is not null && record.Id35 != 0) ? Math.Round((record.Id36.Value - record.Id35.Value) / record.Id35.Value * 100, 6) : null;
decimal? hCLHIDevFromSetpoint = (record.Id30 is not null && record.Id29 is not null) ? Math.Round(record.Id30.Value - record.Id29.Value, 6) : null;
decimal? hCLHIPercentDevFromSetpoint = (record.Id30 is not null && record.Id29 is not null && record.Id29 != 0) ? Math.Round((record.Id30.Value - record.Id29.Value) / record.Id29.Value * 100, 6) : null;
decimal? hCLDevFromSetpoint = (record.Id28 is not null && record.Id27 is not null) ? Math.Round(record.Id28.Value - record.Id27.Value, 6) : null;
decimal? hCLPercentDevFromSetpoint = (record.Id28 is not null && record.Id27 is not null && record.Id27 != 0) ? Math.Round((record.Id28.Value - record.Id27.Value) / record.Id27.Value * 100, 6) : null;
decimal? rOTDevFromSetpoint = (record.Id62 is not null && record.Id61 is not null) ? Math.Round(record.Id62.Value - record.Id61.Value, 6) : null;
decimal? lVCDevFromSetpoint = (record.Id58 is not null && record.Id57 is not null) ? Math.Round(record.Id58.Value - record.Id57.Value, 6) : null;
decimal? lVCPercentDevFromSetpoint = (record.Id58 is not null && record.Id57 is not null && record.Id57 != 0) ? Math.Round((record.Id58.Value - record.Id57.Value) / record.Id57.Value * 100, 6) : null;
if (record.VP223 == "FINISHED: 8/17/2025 0:01:30 CT10_15PH.6_3.0") {
if (record.VP223 == "") { }
}
result = new(Point: point,
Time: record.Time,
A_LOGISTICS: record.A_LOGISTICS,
Id12: record.Id12,
Id13: record.Id13,
CenterDevFromSetpoint: centerDevFromSetpoint,
Id15: record.Id15,
Id16: record.Id16,
FrontDevFromSetpoint: frontDevFromSetpoint,
Id18: record.Id18,
Id19: record.Id19,
SideDevFromSetpoint: sideDevFromSetpoint,
Id21: record.Id21,
Id22: record.Id22,
RearDevFromSetpoint: rearDevFromSetpoint,
Id25: record.Id25,
Id26: record.Id26,
N2H2DevFromSetpoint: n2H2DevFromSetpoint,
N2H2PercentDevFromSetpoint: n2H2PercentDevFromSetpoint,
Id29: record.Id29,
Id37: record.Id37,
Id38: record.Id38,
NSRCSDevFromSetpoint: nSRCSDevFromSetpoint,
NSRCSPercentDevFromSetpoint: nSRCSPercentDevFromSetpoint,
Id39: record.Id39,
Id40: record.Id40,
NDILDevFromSetpoint: nDILDevFromSetpoint,
NDILPercentDevFromSetpoint: nDILPercentDevFromSetpoint,
Id41: record.Id41,
Id42: record.Id42,
NINJDevFromSetpoint: nINJDevFromSetpoint,
NINJPercentDevFromSetpoint: nINJPercentDevFromSetpoint,
Id27: record.Id27,
Id28: record.Id28,
Id30: record.Id30,
HCLHIDevFromSetpoint: hCLHIDevFromSetpoint,
HCLHIPercentDevFromSetpoint: hCLHIPercentDevFromSetpoint,
HCLDevFromSetpoint: hCLDevFromSetpoint,
HCLPercentDevFromSetpoint: hCLPercentDevFromSetpoint,
Id61: record.Id61,
Id62: record.Id62,
ROTDevFromSetpoint: rOTDevFromSetpoint,
Id173: record.Id173,
Id58: record.Id58,
Id172: record.Id172,
Id57: record.Id57,
LVCDevFromSetpoint: lVCDevFromSetpoint,
LVCPercentDevFromSetpoint: lVCPercentDevFromSetpoint,
Id193: record.Id193,
Id183: record.Id183,
VP93: record.VP93,
VP154: record.VP154,
VP78: record.VP78,
VP83: record.VP83,
VP176: record.VP176,
VP79: record.VP79,
VP81: record.VP81,
VP82: record.VP82,
VP84: record.VP84,
VP86: record.VP86,
VP87: record.VP87,
VP80: record.VP80,
VP85: record.VP85,
VP153: record.VP153,
VP221: record.VP221,
VP222: record.VP222,
VP223: record.VP223,
NUM_DATA_ROWS: record.NUM_DATA_ROWS,
NUM_DATA_COLUMNS: record.NUM_DATA_COLUMNS,
START_TIME_FORMAT: record.START_TIME_FORMAT,
START_TIME: record.START_TIME,
LOGISTICS_COLUMN: record.LOGISTICS_COLUMN,
A_BASIC_TYPE: record.A_BASIC_TYPE,
A_INFO: record.A_INFO,
A_INFO2: record.A_INFO2,
A_JOBID: record.A_JOBID,
A_LAYER: record.A_LAYER,
A_LAYER2: record.A_LAYER2,
A_MES_ENTITY: record.A_MES_ENTITY,
A_MID: record.A_MID,
A_NULL_DATA: record.A_NULL_DATA,
A_PPID: record.A_PPID,
A_PROCESS_JOBID: record.A_PROCESS_JOBID,
A_PRODUCT: record.A_PRODUCT,
A_SEQUENCE: record.A_SEQUENCE,
A_WADER_ID: record.A_WADER_ID,
A_WAFER_POS: record.A_WAFER_POS,
Id31: record.Id31,
Id32: record.Id32,
PSRCSDevFromSetpoint: pSRCSDevFromSetpoint,
PSRCSPercentDevFromSetpoint: pSRCSPercentDevFromSetpoint,
Id33: record.Id33,
Id34: record.Id34,
PDILDevFromSetpoint: pDILDevFromSetpoint,
PDILPercentDevFromSetpoint: pDILPercentDevFromSetpoint,
Id35: record.Id35,
Id36: record.Id36,
PINJDevFromSetpoint: pINJDevFromSetpoint,
PINJPercentDevFromSetpoint: pINJPercentDevFromSetpoint,
VP96: record.VP96,
A_CHAMBER: record.A_CHAMBER,
A_SLOT: record.A_SLOT);
return result;
}
internal static ReadOnlyCollection<RecordWith> GetCollection(ReadOnlyCollection<Record> records, bool skipPPStepNameNullData) {
List<RecordWith> results = [];
RecordWith result;
for (int i = 0; i < records.Count; i++) {
if (string.IsNullOrEmpty(records[i].VP153) && skipPPStepNameNullData) {
continue;
}
result = Get(i, records[i]);
results.Add(result);
}
return results.AsReadOnly();
}
}
[JsonSourceGenerationOptions(WriteIndented = false)]
[JsonSerializable(typeof(JsonElement[]))]
private partial class Helper20251111JsonElementArraySourceGenerationContext : JsonSerializerContext {
}
[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, NumberHandling = JsonNumberHandling.AllowReadingFromString)]
[JsonSerializable(typeof(RecordWith[]))]
private partial class Helper20251111RecordWithArraySourceGenerationContext : JsonSerializerContext {
}
internal static void AddAndSortWorkWeekFiles(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]);
string searchPattern = args[2];
const bool skipPPStepNameNullData = true;
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string destinationDirectory = Path.GetFullPath(args[3].Split('~')[0]);
string destinationDirectoryB = Path.GetFullPath(args[4].Split('~')[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
AddAndSortWorkWeekFiles(logger, destinationDirectory, destinationDirectoryB, skipPPStepNameNullData, files);
}
private static void AddAndSortWorkWeekFiles(ILogger<Worker> logger, string destinationDirectory, string destinationDirectoryB, bool skipPPStepNameNullData, string[] files) {
string json;
string fileName;
string? jsonOld;
string checkFile;
ReadOnlyCollection<Record> records;
ReadOnlyCollection<RecordWith> recordsWith;
if (!Directory.Exists(destinationDirectory)) {
_ = Directory.CreateDirectory(destinationDirectory);
}
if (!Directory.Exists(destinationDirectoryB)) {
_ = Directory.CreateDirectory(destinationDirectoryB);
}
foreach (string file in files) {
try {
logger.LogInformation("Processing {file}", file);
records = Record.GetCollection(file);
if (records.Count == 0) {
logger.LogWarning("result.Count == 0");
continue;
}
fileName = Path.GetFileName(file);
checkFile = Path.Combine(destinationDirectory, fileName);
json = JsonSerializer.Serialize(records.ToArray(), Helper20251111RecordArraySourceGenerationContext.Default.RecordArray);
jsonOld = File.Exists(checkFile) ? File.ReadAllText(checkFile) : null;
if (!string.IsNullOrEmpty(jsonOld) && jsonOld == json) {
logger.LogInformation("{fileName} has no changes", checkFile);
} else {
File.WriteAllText(checkFile, json);
WriteCsvFile(checkFile, records);
}
recordsWith = RecordWith.GetCollection(records, skipPPStepNameNullData);
checkFile = Path.Combine(destinationDirectoryB, fileName);
json = JsonSerializer.Serialize(recordsWith.ToArray(), Helper20251111RecordWithArraySourceGenerationContext.Default.RecordWithArray);
jsonOld = File.Exists(checkFile) ? File.ReadAllText(checkFile) : null;
if (!string.IsNullOrEmpty(jsonOld) && jsonOld == json) {
logger.LogInformation("{fileName} has no changes", checkFile);
} else {
File.WriteAllText(checkFile, json);
WriteCsvFile(checkFile, recordsWith);
}
} catch {
logger.LogWarning("Error logging file name a) {file}", file);
logger.LogWarning("Error logging file name b) {file}", file);
logger.LogWarning("Error logging file name c) {file}", file);
}
}
}
private static void WriteCsvFile(string fileName, ReadOnlyCollection<Record> records) {
List<string> lines = ["Time,A_LOGISTICS,id12,id13,id15,id16,id18,id19,id21,id22,id25,id26,id29,id37,id38,id39,id40,id41,id42,id27,id28,id30,id61,id62,id173,id58,id172,id57,id193,id183,vp93,vp154,vp78,vp83,vp176,vp79,vp81,vp82,vp84,vp86,vp87,vp80,vp85,vp153,vp221,vp222,vp223,NUM_DATA_ROWS,NUM_DATA_COLUMNS,START_TIME_FORMAT,START_TIME,LOGISTICS_COLUMN,A_BASIC_TYPE,A_INFO,A_INFO2,A_JOBID,A_LAYER,A_LAYER2,A_MES_ENTITY,A_MID,A_NULL_DATA,A_PPID,A_PROCESS_JOBID,A_PRODUCT,A_SEQUENCE,A_WADER_ID,A_WAFER_POS,id31,id32,id33,id34,id35,id36,vp96,A_CHAMBER,A_SLOT"];
foreach (Record record in records) {
lines.Add(string.Concat(record.Time, ',',
record.A_LOGISTICS, ',',
record.Id12, ',',
record.Id13, ',',
record.Id15, ',',
record.Id16, ',',
record.Id18, ',',
record.Id19, ',',
record.Id21, ',',
record.Id22, ',',
record.Id25, ',',
record.Id26, ',',
record.Id29, ',',
record.Id37, ',',
record.Id38, ',',
record.Id39, ',',
record.Id40, ',',
record.Id41, ',',
record.Id42, ',',
record.Id27, ',',
record.Id28, ',',
record.Id30, ',',
record.Id61, ',',
record.Id62, ',',
record.Id173, ',',
record.Id58, ',',
record.Id172, ',',
record.Id57, ',',
record.Id193, ',',
record.Id183, ',',
record.VP93, ',',
record.VP154, ',',
record.VP78, ',',
record.VP83, ',',
record.VP176, ',',
record.VP79, ',',
record.VP81, ',',
record.VP82, ',',
record.VP84, ',',
record.VP86, ',',
record.VP87, ',',
record.VP80, ',',
record.VP85, ',',
record.VP153, ',',
record.VP221, ',',
record.VP222, ',',
record.VP223, ',',
record.NUM_DATA_ROWS, ',',
record.NUM_DATA_COLUMNS, ',',
record.START_TIME_FORMAT, ',',
record.START_TIME, ',',
record.LOGISTICS_COLUMN, ',',
record.A_BASIC_TYPE, ',',
record.A_INFO, ',',
record.A_INFO2, ',',
record.A_JOBID, ',',
record.A_LAYER, ',',
record.A_LAYER2, ',',
record.A_MES_ENTITY, ',',
record.A_MID, ',',
record.A_NULL_DATA, ',',
record.A_PPID, ',',
record.A_PROCESS_JOBID, ',',
record.A_PRODUCT, ',',
record.A_SEQUENCE, ',',
record.A_WADER_ID, ',',
record.A_WAFER_POS, ',',
record.Id31, ',',
record.Id32, ',',
record.Id33, ',',
record.Id34, ',',
record.Id35, ',',
record.Id36, ',',
record.VP96, ',',
record.A_CHAMBER, ',',
record.A_SLOT));
}
string text = string.Join(Environment.NewLine, lines);
string csvFileName = Path.ChangeExtension(fileName, ".csv");
File.WriteAllText(csvFileName, text);
}
private static void WriteCsvFile(string fileName, ReadOnlyCollection<RecordWith> recordsWith) {
List<string> lines = ["Point,Time,A_LOGISTICS,CenterTemp,CenterSetPoint,CenterDevFromSetpoint,FrontTemp,FrontSetPoint,FrontDevFromSetpoint,SideTemp,SideSetPoint,SideDevFromSetpoint,RearTemp,RearSetPoint,RearDevFromSetpoint,N2H2SetPoint,N2H2Flow,N2H2DevFromSetpoint,N2H2PercentDevFromSetpoint,HCLHISetPoint,NSRCSetPoint,NSRCFlow,NSRCSDevFromSetpoint,NSRCSPercentDevFromSetpoint,NDILSetPoint,NDILFlow,NDILDevFromSetpoint,NDILPercentDevFromSetpoint,NINJSetPoint,NINJFlow,NINJDevFromSetpoint,NINJPercentDevFromSetpoint,HCLSetPoint,HCLFlow,HCLHIFlow,HCLHIDevFromSetpoint,HCLHIPercentDevFromSetpoint,HCLDevFromSetpoint,HCLPercentDevFromSetpoint,ROTSetPoint,ROTSpeed,ROTDevFromSetpoint,LVC1Carrier,LVC1Flow,LVC1Ratio,LVC1SetPoint,LVCDevFromSetpoint,LVCPercentDevFromSetpoint,SCRLOAD4,SCRDrive4,ProcessState,SystemState,LL1State,LL2State,TotalWaferCount,LL1Init,LL1WafersIn,LL1WfrCnt,LL2Init,LL2WafersIn,LL2WfrCnt,LL1LotId,LL2LotId,PPSTEPNAME,LeftDefaultRecipe,RightDefaultRecipe,RecipeCompleteMsg,NUM_DATA_ROWS,NUM_DATA_COLUMNS,START_TIME_FORMAT,START_TIME,LOGISTICS_COLUMN,A_BASIC_TYPE,A_INFO,A_INFO2,A_JOBID,A_LAYER,A_LAYER2,A_MES_ENTITY,A_MID,A_NULL_DATA,A_PPID,A_PROCESS_JOBID,A_PRODUCT,A_SEQUENCE,A_WADER_ID,A_WAFER_POS,PSRCSetPoint,PSRCFlow,PSRCSDevFromSetpoint,PSRCSPercentDevFromSetpoint,PDILSetPoint,PDILFlow,PDILDevFromSetpoint,PDILPercentDevFromSetpoint,PINJSetPoint,PINJFlow,PINJDevFromSetpoint,PINJPercentDevFromSetpoint,PPEXECNAME,A_CHAMBER,A_SLOT"];
foreach (RecordWith record in recordsWith) {
lines.Add(string.Concat(record.Point, ',',
record.Time, ',',
record.A_LOGISTICS, ',',
record.Id12, ',',
record.Id13, ',',
record.CenterDevFromSetpoint, ',',
record.Id15, ',',
record.Id16, ',',
record.FrontDevFromSetpoint, ',',
record.Id18, ',',
record.Id19, ',',
record.SideDevFromSetpoint, ',',
record.Id21, ',',
record.Id22, ',',
record.RearDevFromSetpoint, ',',
record.Id25, ',',
record.Id26, ',',
record.N2H2DevFromSetpoint, ',',
record.N2H2PercentDevFromSetpoint, ',',
record.Id29, ',',
record.Id37, ',',
record.Id38, ',',
record.NSRCSDevFromSetpoint, ',',
record.NSRCSPercentDevFromSetpoint, ',',
record.Id39, ',',
record.Id40, ',',
record.NDILDevFromSetpoint, ',',
record.NDILPercentDevFromSetpoint, ',',
record.Id41, ',',
record.Id42, ',',
record.NINJDevFromSetpoint, ',',
record.NINJPercentDevFromSetpoint, ',',
record.Id27, ',',
record.Id28, ',',
record.Id30, ',',
record.HCLHIDevFromSetpoint, ',',
record.HCLHIPercentDevFromSetpoint, ',',
record.HCLDevFromSetpoint, ',',
record.HCLPercentDevFromSetpoint, ',',
record.Id61, ',',
record.Id62, ',',
record.ROTDevFromSetpoint, ',',
record.Id173, ',',
record.Id58, ',',
record.Id172, ',',
record.Id57, ',',
record.LVCDevFromSetpoint, ',',
record.LVCPercentDevFromSetpoint, ',',
record.Id193, ',',
record.Id183, ',',
record.VP93, ',',
record.VP154, ',',
record.VP78, ',',
record.VP83, ',',
record.VP176, ',',
record.VP79, ',',
record.VP81, ',',
record.VP82, ',',
record.VP84, ',',
record.VP86, ',',
record.VP87, ',',
record.VP80, ',',
record.VP85, ',',
record.VP153, ',',
record.VP221, ',',
record.VP222, ',',
record.VP223, ',',
record.NUM_DATA_ROWS, ',',
record.NUM_DATA_COLUMNS, ',',
record.START_TIME_FORMAT, ',',
record.START_TIME, ',',
record.LOGISTICS_COLUMN, ',',
record.A_BASIC_TYPE, ',',
record.A_INFO, ',',
record.A_INFO2, ',',
record.A_JOBID, ',',
record.A_LAYER, ',',
record.A_LAYER2, ',',
record.A_MES_ENTITY, ',',
record.A_MID, ',',
record.A_NULL_DATA, ',',
record.A_PPID, ',',
record.A_PROCESS_JOBID, ',',
record.A_PRODUCT, ',',
record.A_SEQUENCE, ',',
record.A_WADER_ID, ',',
record.A_WAFER_POS, ',',
record.Id31, ',',
record.Id32, ',',
record.PSRCSDevFromSetpoint, ',',
record.PSRCSPercentDevFromSetpoint, ',',
record.Id33, ',',
record.Id34, ',',
record.PDILDevFromSetpoint, ',',
record.PDILPercentDevFromSetpoint, ',',
record.Id35, ',',
record.Id36, ',',
record.PINJDevFromSetpoint, ',',
record.PINJPercentDevFromSetpoint, ',',
record.VP96, ',',
record.A_CHAMBER, ',',
record.A_SLOT));
}
string text = string.Join(Environment.NewLine, lines);
string csvFileName = Path.ChangeExtension(fileName, ".csv");
File.WriteAllText(csvFileName, text);
}
}

View File

@ -0,0 +1,192 @@
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml;
using System.Xml.Serialization;
namespace File_Folder_Helper.ADO2025.PI8;
#pragma warning disable IDE0027
[Serializable]
[XmlType(Namespace = "http://schemas.datacontract.org/2004/07/EafManagement.Monitoring")]
[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/EafManagement.Monitoring", IsNullable = false)]
public partial class ArrayOfRuntimeInstanceStatusReport {
[XmlElement("RuntimeInstanceStatusReport", Order = 0)]
public RuntimeInstanceStatusReport[]? RuntimeInstanceStatusReport { get; set; }
}
[Serializable]
[XmlType(Namespace = "http://schemas.datacontract.org/2004/07/EafManagement.Monitoring")]
[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/EafManagement.Monitoring", IsNullable = false)]
public partial class RuntimeInstanceStatusReport {
public string? CellInstanceName { get; set; }
public string? CurrentActiveVersion { get; set; }
public string? CurrentHost { get; set; }
public string? CurrentLoggingConfigurationName { get; set; }
public string? CurrentLoggingConfigurationVersion { get; set; }
public EquipmentState[]? EquipmentStates { get; set; }
public string? ErrorDescription { get; set; }
public string? Info { get; set; }
public string? IsAutomatedRestartActive { get; set; }
public string? IsAutomatedRestartRequested { get; set; }
public string? IsPilot { get; set; }
public string? IsReadyForRestart { get; set; }
public string? LastKnownCurrentActiveVersion { get; set; }
public string? MachineName { get; set; }
public string? PilotVersion { get; set; }
public string? RuntimeInstanceName { get; set; }
public string? Startable { get; set; }
public string? StartTime { get; set; }
public string? State { get; set; }
public string? StopTime { get; set; }
public string? TargetActiveVersion { get; set; }
public string? TargetHost { get; set; }
public string? TargetLoggingConfigurationName { get; set; }
public string? TargetLoggingConfigurationVersion { get; set; }
public string? Timestamp { get; set; }
public string? WindowsName { get; set; }
}
[Serializable]
[XmlType(Namespace = "http://schemas.datacontract.org/2004/07/EafManagement.Monitoring")]
[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/EafManagement.Monitoring", IsNullable = false)]
public partial class EquipmentState {
public bool? IsCommunicating { get; set; }
public bool? IsConnected { get; set; }
public string? CommunicationState { get; set; }
public string? Name { get; set; }
}
#pragma warning restore IDE0027
internal static partial class Helper20251113 {
private record Record(
[property: JsonPropertyName("CellInstanceName")] string? CellInstanceName,
[property: JsonPropertyName("CurrentActiveVersion")] string? CurrentActiveVersion,
[property: JsonPropertyName("CurrentHost")] string? CurrentHost,
[property: JsonPropertyName("CurrentLoggingConfigurationName")] string? CurrentLoggingConfigurationName,
[property: JsonPropertyName("CurrentLoggingConfigurationVersion")] string? CurrentLoggingConfigurationVersion,
[property: JsonPropertyName("EquipmentStates")] EquipmentState[]? EquipmentState,
[property: JsonPropertyName("ErrorDescription")] string? ErrorDescription,
[property: JsonPropertyName("Info")] string? Info,
[property: JsonPropertyName("IsAutomatedRestartActive")] bool? IsAutomatedRestartActive,
[property: JsonPropertyName("IsAutomatedRestartRequested")] bool? IsAutomatedRestartRequested,
[property: JsonPropertyName("IsPilot")] bool? IsPilot,
[property: JsonPropertyName("IsReadyForRestart")] bool? IsReadyForRestart,
[property: JsonPropertyName("LastKnownCurrentActiveVersion")] string? LastKnownCurrentActiveVersion,
[property: JsonPropertyName("MachineName")] string? MachineName,
[property: JsonPropertyName("PilotVersion")] object PilotVersion,
[property: JsonPropertyName("RuntimeInstanceName")] string? RuntimeInstanceName,
[property: JsonPropertyName("Startable")] bool? Startable,
[property: JsonPropertyName("StartTime")] string? StartTime,
[property: JsonPropertyName("State")] string? State,
[property: JsonPropertyName("StopTime")] string? StopTime,
[property: JsonPropertyName("TargetActiveVersion")] string? TargetActiveVersion,
[property: JsonPropertyName("TargetHost")] string? TargetHost,
[property: JsonPropertyName("TargetLoggingConfigurationName")] string? TargetLoggingConfigurationName,
[property: JsonPropertyName("TargetLoggingConfigurationVersion")] string? TargetLoggingConfigurationVersion,
[property: JsonPropertyName("Timestamp")] string? Timestamp,
[property: JsonPropertyName("UpdatePeriod")] int? UpdatePeriod,
[property: JsonPropertyName("WindowsName")] string? WindowsName
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Record[]))]
private partial class Helper20251113RecordSourceGenerationContext : JsonSerializerContext {
}
internal static void Parse(ILogger<Worker> logger, List<string> args) {
logger.LogInformation(args[0]);
logger.LogInformation(args[1]);
logger.LogInformation(args[2]);
string xml;
string url = args[2];
string name = args[3];
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
if (!Directory.Exists(sourceDirectory)) {
_ = Directory.CreateDirectory(sourceDirectory);
}
FileInfo fileInfo = new(Path.Combine(sourceDirectory, $"{name}.xml"));
if (fileInfo.Exists && fileInfo.LastWriteTime > DateTime.Now.AddMinutes(-5)) {
logger.LogInformation("File recently exists: {fileName}", fileInfo.FullName);
xml = File.ReadAllText(fileInfo.FullName);
} else {
logger.LogInformation("Downloading from URL: {url}", url);
HttpClient httpClient = new();
HttpResponseMessage httpResponseMessage = httpClient.GetAsync(url).Result;
xml = httpResponseMessage.Content.ReadAsStringAsync().Result;
File.WriteAllText(fileInfo.FullName, xml);
logger.LogInformation("File saved: {fileName}", fileInfo.FullName);
}
Parse(logger, sourceDirectory, name, xml);
}
private static void Parse(ILogger<Worker> logger, string sourceDirectory, string name, string xml) {
ArrayOfRuntimeInstanceStatusReport? arrayOfRuntimeInstanceStatusReport = ParseXML<ArrayOfRuntimeInstanceStatusReport>(xml, throwExceptions: true);
if (arrayOfRuntimeInstanceStatusReport is not null) {
WriteAllText(logger, sourceDirectory, name, arrayOfRuntimeInstanceStatusReport);
}
}
private static T? ParseXML<T>(string value, bool throwExceptions) where T : class {
object? result;
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 {
result = null;
if (throwExceptions) {
throw;
}
}
return result as T;
}
private static MemoryStream ToStream(string value) {
MemoryStream memoryStream = new();
StreamWriter streamWriter = new(memoryStream);
streamWriter.Write(value);
streamWriter.Flush();
memoryStream.Position = 0;
return memoryStream;
}
private static void WriteAllText(ILogger<Worker> logger, string sourceDirectory, string name, ArrayOfRuntimeInstanceStatusReport arrayOfRuntimeInstanceStatusReport) {
string fileName = Path.Combine(sourceDirectory, $"{name}.json");
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
string json = Serialize(jsonSerializerOptions, arrayOfRuntimeInstanceStatusReport)
.Replace("\"\"", "null")
.Replace("\"true\"", "true", StringComparison.CurrentCultureIgnoreCase)
.Replace("\"false\"", "false", StringComparison.CurrentCultureIgnoreCase);
Record[]? records = JsonSerializer.Deserialize(json, Helper20251113RecordSourceGenerationContext.Default.RecordArray);
if (records is not null) {
foreach (Record record in records) {
if (record.Startable is null || !record.Startable.Value) {
continue;
}
logger.LogInformation("CellInstanceName: {CellInstanceName}, MachineName: {MachineName}, State: {State}, ErrorDescription: {ErrorDescription}", record.CellInstanceName, record.MachineName, record.State, record.ErrorDescription);
}
}
File.WriteAllText(fileName, json);
logger.LogInformation("File saved: {fileName}", fileName);
}
private static string Serialize(JsonSerializerOptions jsonSerializerOptions, ArrayOfRuntimeInstanceStatusReport arrayOfRuntimeInstanceStatusReport) =>
#pragma warning disable IL3050, IL2026
JsonSerializer.Serialize(arrayOfRuntimeInstanceStatusReport.RuntimeInstanceStatusReport, jsonSerializerOptions);
#pragma warning restore IL3050, IL2026
}

View File

@ -0,0 +1,125 @@
using Microsoft.Extensions.Logging;
using System.IO.Compression;
namespace File_Folder_Helper.ADO2025.PI8;
internal static partial class Helper20251114 {
internal static void ZipRunDirectories(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]);
string searchPattern = args[2];
string dayDirectoryPattern = args[3];
string weekDirectoryPattern = args[4];
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
if (!Directory.Exists(sourceDirectory)) {
_ = Directory.CreateDirectory(sourceDirectory);
}
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
foreach (string file in files) {
ZipRunDirectory(logger, dayDirectoryPattern, weekDirectoryPattern, file);
}
}
private static void ZipRunDirectory(ILogger<Worker> logger, string dayDirectoryPattern, string weekDirectoryPattern, string file) {
string path;
string ticks;
FileInfo fileInfo;
string subFileName;
string? dayDirectory;
string? runDirectory;
string[] allSubFiles;
string[] runSubFiles;
string? weekDirectory;
ZipArchive zipArchive;
string? ticksDirectory;
string[] ticksSubFiles;
string? dayDirectoryName;
string? runDirectoryName;
string? weekDirectoryName;
string? ticksDirectoryName;
List<string> deleteFiles = [];
for (int i = 0; i < 1; i++) {
try {
fileInfo = new FileInfo(file);
ticks = fileInfo.LastWriteTime.Ticks.ToString();
logger.LogInformation("Processing file: {file}", file);
ticksDirectory = Path.GetDirectoryName(file);
ticksDirectoryName = Path.GetFileName(ticksDirectory);
if (ticksDirectory is null || ticksDirectoryName is null || ticksDirectoryName.Length != ticks.Length) {
logger.LogWarning("Could not get directory name for file: {file}", file);
continue;
}
ticksSubFiles = Directory.GetFiles(ticksDirectory, "*", SearchOption.TopDirectoryOnly);
if (ticksSubFiles.Length == 0) {
logger.LogWarning("No files found in directory: {ticksDirectory}", ticksDirectory);
continue;
}
runDirectory = Path.GetDirectoryName(ticksDirectory);
runDirectoryName = Path.GetFileName(runDirectory);
if (runDirectory is null || runDirectoryName is null) {
logger.LogWarning("Could not get directory name for directory: {ticksDirectory}", ticksDirectory);
continue;
}
dayDirectory = Path.GetDirectoryName(runDirectory);
dayDirectoryName = Path.GetFileName(dayDirectory);
if (dayDirectory is null || dayDirectoryName is null || dayDirectoryName.Length != dayDirectoryPattern.Length) {
logger.LogWarning("Could not get directory name for directory: {runDirectory}", runDirectory);
continue;
}
if (fileInfo.LastWriteTime.ToString(dayDirectoryPattern) != dayDirectoryName) {
logger.LogWarning("Directory name does not match file write time for directory: {dayDirectory}", dayDirectory);
continue;
}
weekDirectory = Path.GetDirectoryName(dayDirectory);
weekDirectoryName = Path.GetFileName(weekDirectory);
if (weekDirectory is null || weekDirectoryName is null || weekDirectoryName.Length != weekDirectoryPattern.Length) {
logger.LogWarning("Could not get directory name for directory: {dayDirectory}", dayDirectory);
continue;
}
path = Path.Combine(dayDirectory, $"{runDirectoryName}.zip");
if (File.Exists(path)) {
logger.LogInformation("Zip file already exists: {zipFile}", path);
continue;
}
logger.LogInformation("Creating zip file: {zipFile}", path);
zipArchive = ZipFile.Open(path, ZipArchiveMode.Create);
foreach (string ticksSubFile in ticksSubFiles) {
subFileName = Path.GetFileName(ticksSubFile);
_ = zipArchive.CreateEntryFromFile(ticksSubFile, $"{ticksDirectoryName}/{subFileName}");
deleteFiles.Add(ticksSubFile);
}
runSubFiles = Directory.GetFiles(runDirectory, "*", SearchOption.TopDirectoryOnly);
if (runSubFiles.Length == 0) {
logger.LogWarning("No files found in directory: {runDirectory}", runDirectory);
continue;
}
foreach (string subFile in runSubFiles) {
subFileName = Path.GetFileName(subFile);
_ = zipArchive.CreateEntryFromFile(subFile, subFileName);
deleteFiles.Add(subFile);
}
zipArchive.Dispose();
File.SetLastWriteTime(path, fileInfo.LastWriteTime);
allSubFiles = Directory.GetFiles(runDirectory, "*", SearchOption.AllDirectories);
if (allSubFiles.Length != deleteFiles.Count) {
logger.LogWarning("File count mismatch for directory: {runDirectory}", runDirectory);
continue;
} else {
foreach (string deleteFile in deleteFiles) {
File.Delete(deleteFile);
}
logger.LogInformation("Deleting run directory: {runDirectory}", runDirectory);
Directory.Delete(runDirectory, recursive: true);
}
break;
} catch (Exception ex) {
logger.LogError(ex, "Error processing file: {file}", file);
break;
}
}
}
}

View File

@ -0,0 +1,65 @@
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI8;
internal static partial class Helper20251118 {
internal static void StratusSplit(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]);
string split = args[3];
string fileName = args[4];
string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
if (searchPattern.Contains('*')) {
ReadFiles(logger, sourceDirectory, searchPattern);
} else {
StratusSplit(logger, split, fileName, sourceDirectory, searchPattern);
}
}
private static void ReadFiles(ILogger<Worker> logger, string sourceDirectory, string searchPattern) {
List<byte> bytes = [];
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
logger.LogInformation($"Read {files.Length} files");
foreach (string file in files) {
foreach (byte @byte in File.ReadAllBytes(file)) {
bytes.Add(@byte);
}
}
if (bytes.Count > 0) {
string bytesFile = Path.Combine(sourceDirectory, $"{DateTime.Now.Ticks}{searchPattern.Replace('*', '_')}");
File.WriteAllBytes(bytesFile, bytes.ToArray());
}
}
private static void StratusSplit(ILogger<Worker> logger, string split, string fileName, string sourceDirectory, string searchPattern) {
string checkFile = Path.Combine(sourceDirectory, searchPattern);
if (!File.Exists(checkFile)) {
logger.LogWarning("File does not exist: {checkFile}", checkFile);
} else {
int i = 0;
string text;
string path;
List<string> collection = [];
string[] lines = File.ReadAllLines(checkFile);
foreach (string line in lines) {
if (!line.Contains(split)) {
collection.Add(line);
} else {
i++;
collection.Add(line);
text = string.Join(Environment.NewLine, collection);
collection.Clear();
path = Path.Combine(sourceDirectory, $"{fileName}{i}.txt");
File.WriteAllText(path, text);
logger.LogInformation("Wrote file: {path}", path);
}
}
}
}
}

View File

@ -0,0 +1,51 @@
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI8;
internal static partial class Helper20251122 {
internal static void MoveBack(ILogger<Worker> logger, List<string> args) {
logger.LogInformation(args[0]);
logger.LogInformation(args[1]);
logger.LogInformation(args[2]);
logger.LogInformation(args[3]);
string fileName;
string directory;
string extension;
string checkFile;
string[] segments;
string checkDirectory;
string parentDirectory;
string parentDirectoryName;
string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string destinationDirectory = Path.GetFullPath(args[3].Split('~')[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
foreach (string file in files) {
directory = Path.GetDirectoryName(file) ?? throw new Exception("Directory name is null");
parentDirectory = Path.GetDirectoryName(directory) ?? throw new Exception("Parent directory is null");
parentDirectoryName = Path.GetFileName(parentDirectory);
fileName = Path.GetFileNameWithoutExtension(file);
extension = Path.GetFileName(directory).ToLower();
segments = fileName.Split('_');
if (segments.Length < 2) {
logger.LogWarning("File name does not contain expected segments: {fileName}", fileName);
continue;
}
checkDirectory = Path.Combine(destinationDirectory, segments[0]);
if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory);
}
checkFile = Path.Combine(checkDirectory, $"{parentDirectoryName}_{fileName}.{extension.ToLower()}");
if (File.Exists(checkFile)) {
logger.LogWarning("File already exists at destination: {checkFile}", checkFile);
continue;
} else {
File.Move(file, checkFile);
logger.LogInformation("Moved file to: {checkFile}", checkFile);
}
}
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, destinationDirectory);
}
}

View File

@ -0,0 +1,203 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.ADO2025.PI8;
internal static partial class Helper20251123 {
[GeneratedRegex(@"^(?<stream>S[0-9]{1,2})(?<function>F[0-9]{1,2}) W-Bit=(?<wait>[01])")]
private static partial Regex StreamFunction();
private record Record(long Ticks, string Line);
internal static void LogToTrace(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]);
logger.LogInformation(args[7]);
logger.LogInformation(args[8]);
logger.LogInformation(args[9]);
string extension = args[9];
string searchPattern = args[2];
int dateTimeFormatUse = int.Parse(args[4]);
int maximumLineLength = int.Parse(args[7]);
string[] containPhrases = args[5].Split('~');
string dateTimeFormat = args[3].Replace('~', ' ');
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string destinationDirectory = Path.GetFullPath(args[8].Split('~')[0]);
string directorySearchPattern = $"{searchPattern.Split('*')[0].Split('_')[1]}*";
DateTime dateTime = DateTime.ParseExact(args[6], dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None);
List<string> directories = Directory.GetDirectories(sourceDirectory, directorySearchPattern, SearchOption.TopDirectoryOnly).ToList();
if (directories.Count == 0) {
directories.Add(sourceDirectory);
}
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs = GetFiles(searchPattern, directories);
if (keyValuePairs.Count == 0 || keyValuePairs.All(l => l.Value.Count == 0)) {
logger.LogWarning("No files found with pattern {searchPattern} in {sourceDirectory}", searchPattern, sourceDirectory);
} else {
LogToTrace(logger, dateTimeFormat, dateTimeFormatUse, dateTime, maximumLineLength, destinationDirectory, extension, containPhrases, keyValuePairs);
}
}
private static ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetFiles(string searchPattern, List<string> directories) {
Dictionary<string, ReadOnlyCollection<string>> results = [];
string[] files;
List<string> collection;
foreach (string directory in directories) {
collection = [];
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
foreach (string file in files) {
collection.Add(file);
}
results.Add(directory, collection.AsReadOnly());
}
return results.AsReadOnly();
}
private static void LogToTrace(ILogger<Worker> logger, string dateTimeFormat, int dateTimeFormatUse, DateTime dateTime, int maximumLineLength, string destinationDirectory, string extension, string[] containPhrases, ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs) {
string key;
Dictionary<string, List<Record>> filtered;
foreach (KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair in keyValuePairs) {
filtered = [];
key = Path.GetFileName(keyValuePair.Key);
foreach (string path in keyValuePair.Value) {
AddFiltered(dateTimeFormat, dateTimeFormatUse, dateTime, containPhrases, filtered, path);
}
LogToTrace(logger, maximumLineLength, destinationDirectory, extension, filtered, key);
}
}
private static void AddFiltered(string dateTimeFormat, int dateTimeFormatUse, DateTime dateTime, string[] containPhrases, Dictionary<string, List<Record>> results, string path) {
string key;
DateTime dateTimeCheck;
List<Record>? collection;
string[] lines = File.ReadAllLines(path);
string keyDateTimeFormat = dateTimeFormat[..dateTimeFormatUse].Replace(' ', '_');
ReadOnlyCollection<Record> records = GetRecords(dateTimeFormat, containPhrases, lines);
foreach (Record record in records) {
dateTimeCheck = new DateTime(record.Ticks);
if (dateTimeCheck < dateTime) {
continue;
}
key = dateTimeCheck.ToString(keyDateTimeFormat);
if (!results.TryGetValue(key, out collection)) {
results.Add(key, []);
}
if (!results.TryGetValue(key, out collection)) {
throw new InvalidOperationException("Collection should exist");
}
collection.Add(record);
}
}
private static ReadOnlyCollection<Record> GetRecords(string dateTimeFormat, string[] containPhrases, string[] lines) {
Record[] results;
string line;
Match match;
string body;
string check;
string checkB;
Record record;
DateTime dateTime;
string[] segments;
List<Record> records = [];
for (int i = 1; i < lines.Length - 1; i++) {
line = lines[i];
if (containPhrases.Any(phrase => line.Contains(phrase))) {
if (line.Length < dateTimeFormat.Length) {
continue;
}
check = line[..dateTimeFormat.Length];
if (!DateTime.TryParseExact(check, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime)) {
continue;
}
record = new Record(dateTime.Ticks, line);
records.Add(record);
continue;
}
if (!line.StartsWith('S')) {
continue;
}
match = StreamFunction().Match(line);
if (!match.Success) {
continue;
}
segments = lines[i - 1].Split(" ");
if (segments.Length < 2) {
continue;
}
checkB = segments[0];
if (!checkB.Contains(' ')) {
continue;
}
if (checkB.Length < dateTimeFormat.Length) {
continue;
}
check = checkB[..dateTimeFormat.Length];
if (!DateTime.TryParseExact(check, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime)) {
continue;
}
body = GetBody(lines, i, checkB.Split(' '));
record = new Record(dateTime.Ticks, $"{checkB} {line} ~ {body}");
records.Add(record);
}
results = (from l in records orderby l.Ticks select l).ToArray();
return results.AsReadOnly();
}
private static string GetBody(string[] lines, int i, string[] segments) {
string result;
List<string> results = [];
for (int j = i + 1; j < lines.Length; j++) {
if (lines[j].StartsWith(segments[0])) {
break;
}
results.Add(lines[j].Trim());
}
result = string.Join('_', results);
return result;
}
private static void LogToTrace(ILogger<Worker> logger, int maximumLineLength, string destinationDirectory, string extension, Dictionary<string, List<Record>> filtered, string key) {
string text;
string[] lines;
string? oldText;
string checkFile;
Record[] records;
string weekOfYear;
DateTime dateTime;
string checkDirectory;
Calendar calendar = new CultureInfo("en-US").Calendar;
foreach (KeyValuePair<string, List<Record>> keyValuePair in filtered) {
records = (from l in keyValuePair.Value orderby l.Ticks select l).ToArray();
if (records.Length == 0) {
logger.LogInformation("No records for {key}_{dateKey}", key, keyValuePair.Key);
continue;
}
dateTime = new DateTime(records[^1].Ticks);
weekOfYear = $"{dateTime.Year}_Week_{calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
lines = (from l in records select l.Line.Length < maximumLineLength ? l.Line : l.Line[..maximumLineLength]).ToArray();
text = string.Join(Environment.NewLine, lines);
checkDirectory = Path.Combine(destinationDirectory, key, weekOfYear);
if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory);
}
checkFile = Path.Combine(checkDirectory, $"{key}_{keyValuePair.Key}{extension}");
oldText = File.Exists(checkFile) ? File.ReadAllText(checkFile) : null;
if (!string.IsNullOrEmpty(oldText) && oldText == text) {
logger.LogInformation("{fileName} has no changes", checkFile);
} else {
File.WriteAllText(checkFile, text);
File.SetLastWriteTime(checkFile, dateTime);
logger.LogInformation("<{checkFile}> was written", checkFile);
}
}
}
}

View File

@ -0,0 +1,86 @@
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI8;
internal static partial class Helper20251203 {
internal static void TraceToMarkdown(ILogger<Worker> logger, List<string> args) {
logger.LogInformation(args[0]);
logger.LogInformation(args[1]);
logger.LogInformation(args[2]);
logger.LogInformation(args[3]);
string newText;
string[] files;
string? oldText;
FileInfo fileInfo;
string destinationPath;
List<string> hours = [];
List<string> lines = [];
List<string> values = [];
string weekDirectoryName;
string[] weekDirectories;
string equipmentDirectoryName;
string searchPattern = args[2];
long size = long.Parse(args[3]);
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string[] equipmentDirectories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string equipmentDirectory in equipmentDirectories) {
equipmentDirectoryName = Path.GetFileName(equipmentDirectory);
weekDirectories = Directory.GetDirectories(equipmentDirectory, "*", SearchOption.TopDirectoryOnly);
lines.Clear();
foreach (string weekDirectory in weekDirectories.OrderByDescending(f => f)) {
hours.Clear();
values.Clear();
weekDirectoryName = Path.GetFileName(weekDirectory);
files = Directory.GetFiles(weekDirectory, searchPattern, SearchOption.TopDirectoryOnly);
logger.LogInformation("Equipment: {equipmentDirectoryName}, Week: {weekDirectoryName}, Files found: {fileCount}", equipmentDirectoryName, weekDirectoryName, files.Length);
foreach (string file in files) {
fileInfo = new(file);
hours.Add(fileInfo.Name[..^3]);
if (fileInfo.Length < size) {
values.Add("0");
} else {
logger.LogInformation("File: {file}, Size: {size}", file, fileInfo.Length);
values.Add("1");
}
}
if (hours.Count == 0 || values.Count == 0) {
logger.LogWarning("No data found for Equipment: {equipmentDirectoryName}, Week: {weekDirectoryName}", equipmentDirectoryName, weekDirectoryName);
} else {
lines.Add($"## Equipment: {equipmentDirectoryName}, Week: {weekDirectoryName}");
lines.Add(string.Empty);
lines.Add("```chart");
lines.Add("{\"type\": \"line\", \"data\": {\"datasets\": [{");
lines.Add($"\"label\": \"Availability - {equipmentDirectoryName} - {weekDirectoryName}\",");
lines.Add("\"data\": [");
lines.Add(string.Join(',', values));
lines.Add("],");
lines.Add("\"borderColor\": \"rgb(75, 192, 192)\"");
lines.Add("}],");
lines.Add("\"labels\": [");
lines.Add(string.Join(',', hours.Select(h => $"\"{h}\"")));
lines.Add("]");
lines.Add("}}");
lines.Add("```");
lines.Add(string.Empty);
}
}
if (lines.Count == 0) {
logger.LogWarning("No data to write for equipment {equipmentDirectoryName}", equipmentDirectoryName);
continue;
}
lines.Insert(0, string.Empty);
lines.Insert(0, $"# Equipment: {equipmentDirectoryName}");
destinationPath = Path.Combine(sourceDirectory, $"{equipmentDirectoryName}_Availability.md");
newText = string.Join(Environment.NewLine, lines);
oldText = File.Exists(destinationPath) ? File.ReadAllText(destinationPath) : null;
if (newText == oldText) {
logger.LogInformation("No changes for availability chart at {destinationPath}", destinationPath);
continue;
}
File.WriteAllLines(destinationPath, lines);
logger.LogInformation("Written availability chart to {destinationPath}", destinationPath);
}
}
}

View File

@ -187,6 +187,24 @@ internal static class HelperDay
ADO2025.PI6.Helper20250726.CopyToCombinedEnumAndIndexFormat(logger, args);
else if (args[1] == "Day-Helper-2025-09-08")
ADO2025.PI7.Helper20250908.DebugProxyPass(logger, args);
else if (args[1] == "Day-Helper-2025-09-26")
ADO2025.PI7.Helper20250926.RenameThenFindFirstAndLast(logger, args);
else if (args[1] == "Day-Helper-2025-10-22")
ADO2025.PI7.Helper20251022.CombineFiles(logger, args);
else if (args[1] == "Day-Helper-2025-11-11")
ADO2025.PI8.Helper20251111.AddAndSortWorkWeekFiles(logger, args);
else if (args[1] == "Day-Helper-2025-11-13")
ADO2025.PI8.Helper20251113.Parse(logger, args);
else if (args[1] == "Day-Helper-2025-11-14")
ADO2025.PI8.Helper20251114.ZipRunDirectories(logger, args);
else if (args[1] == "Day-Helper-2025-11-18")
ADO2025.PI8.Helper20251118.StratusSplit(logger, args);
else if (args[1] == "Day-Helper-2025-11-22")
ADO2025.PI8.Helper20251122.MoveBack(logger, args);
else if (args[1] == "Day-Helper-2025-11-23")
ADO2025.PI8.Helper20251123.LogToTrace(logger, args);
else if (args[1] == "Day-Helper-2025-12-03")
ADO2025.PI8.Helper20251203.TraceToMarkdown(logger, args);
else
throw new Exception(appSettings.Company);
}

View File

@ -111,7 +111,7 @@ internal static partial class Helper20231024
File.WriteAllText($"{drive.Share}\\Tmp\\Phares\\MESA-Users-Drives.bat", bat);
File.WriteAllText($"{drive.Share}\\Tmp\\Phares\\lnk.txt", """"\\messa04ec.infineon.com\EC_SPC_Si\SPC\Projects\Active\ir epi services database.ipj"""");
}
catch (Exception)
catch
{ }
}
}

View File

@ -3,7 +3,7 @@
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<UserSecretsId>8da397d4-13ec-4576-9722-3c79cad25563</UserSecretsId>
@ -14,12 +14,11 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DiscUtils.Iso9660" Version="0.16.13" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
<PackageReference Include="Phares.Metadata" Version="8.0.118.14905" />
<PackageReference Include="Phares.Shared" Version="8.0.118.14905" />
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.19" />
<PackageReference Include="System.Text.Json" Version="9.0.7" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.0" />
<PackageReference Include="Phares.Metadata" Version="10.0.100.116" />
<PackageReference Include="Phares.Shared" Version="10.0.100.116" />
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="10.0.0" />
<PackageReference Include="TextCopy" Version="6.2.1" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="YamlDotNet" Version="16.3.0" />

View File

@ -115,7 +115,7 @@ internal static class HelperDeleteEmptyDirectories
logger.LogInformation("{directoryName}", Path.GetFileName(directory5));
Directory.Delete(directory5, recursive: true);
}
catch (Exception)
catch
{ errorHappened = true; }
}
if (!errorHappened)
@ -125,7 +125,7 @@ internal static class HelperDeleteEmptyDirectories
logger.LogInformation("{directoryName}", Path.GetFileName(directory4));
Directory.Delete(directory4, recursive: true);
}
catch (Exception)
catch
{ errorHappened = true; }
}
}
@ -136,7 +136,7 @@ internal static class HelperDeleteEmptyDirectories
logger.LogInformation("{directoryName}", Path.GetFileName(directory3));
Directory.Delete(directory3, recursive: true);
}
catch (Exception)
catch
{ errorHappened = true; }
}
}
@ -147,7 +147,7 @@ internal static class HelperDeleteEmptyDirectories
logger.LogInformation("{directoryName}", Path.GetFileName(directory2));
Directory.Delete(directory2, recursive: true);
}
catch (Exception)
catch
{ errorHappened = true; }
}
}
@ -158,7 +158,7 @@ internal static class HelperDeleteEmptyDirectories
logger.LogInformation("{directoryName}", Path.GetFileName(directory1));
Directory.Delete(directory1, recursive: true);
}
catch (Exception)
catch
{ errorHappened = true; }
}
}
@ -169,7 +169,7 @@ internal static class HelperDeleteEmptyDirectories
logger.LogInformation("{directoryName}", Path.GetFileName(rootDirectory));
Directory.Delete(rootDirectory, recursive: true);
}
catch (Exception)
catch
{ errorHappened = true; }
}
if (!errorHappened)

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@ internal static class HelperRenameToOldMoveDeleteOldMerge
File.Delete(deleteFile);
break;
}
catch (Exception) { }
catch { }
Thread.Sleep(500);
}
}

View File

@ -102,7 +102,7 @@ internal static partial class HelperZipFilesBy
}
}
}
catch (Exception)
catch
{
logger.LogInformation("<{zipFile}> is invalid!", zipFile);
checkFile = string.Concat(zipFile, ".err");
@ -114,7 +114,7 @@ internal static partial class HelperZipFilesBy
}
try
{ File.Move(zipFile, checkFile); }
catch (Exception) { logger.LogInformation("<{zipFile}> couldn't be moved!", zipFile); }
catch { logger.LogInformation("<{zipFile}> couldn't be moved!", zipFile); }
}
}
return result;
@ -142,7 +142,7 @@ internal static partial class HelperZipFilesBy
}
break;
}
catch (Exception)
catch
{
File.Delete(zipFile);
zipArchiveMode = ZipArchiveMode.Create;
@ -265,7 +265,7 @@ internal static partial class HelperZipFilesBy
if (zipPath is not null && Directory.Exists(zipPath) && !string.IsNullOrEmpty(directoryName))
try
{ Directory.SetLastWriteTime(directoryName, DateTime.Now); }
catch (Exception) { }
catch { }
}
subFiles = Directory.GetFiles(zipDirectory, "*.zip", SearchOption.TopDirectoryOnly);
foreach (string subFile in subFiles)
@ -281,12 +281,12 @@ internal static partial class HelperZipFilesBy
result = true;
File.SetLastWriteTime(subFile, value);
}
catch (Exception) { }
catch { }
}
if (topDirectory != sourceDirectory)
try
{ HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, topDirectory); }
catch (Exception) { }
catch { }
logger.LogInformation("{topDirectory}", topDirectory);
}
return result;

View File

@ -84,7 +84,7 @@ public static class RijndaelEncryption
/// </summary>
/// <param name="salt">The password salt</param>
/// <returns></returns>
#pragma warning disable SYSLIB0022, SYSLIB0041, CA5379
#pragma warning disable SYSLIB0022, SYSLIB0041, CA5379, SYSLIB0060
private static RijndaelManaged NewRijndaelManaged(string salt)
{
ArgumentNullException.ThrowIfNull(salt);

View File

@ -1,7 +0,0 @@
// 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);
});

View File

@ -1,6 +1,6 @@
{
"sdk": {
"rollForward": "latestMinor",
"version": "8.0.113"
"version": "10.0.100"
}
}