Compare commits
23 Commits
b74a6a5267
...
master
Author | SHA1 | Date | |
---|---|---|---|
89bb87bd14 | |||
e7c1fd2221 | |||
fc4449f515 | |||
6ce6c28db1 | |||
2e4aa313fa | |||
116d5e9734 | |||
5ca22b3792 | |||
b98d1e480b | |||
404ffe18f5 | |||
5becc546b2 | |||
0f9d004122 | |||
dd5baba9bc | |||
43527b3356 | |||
8ca489d818 | |||
8f22f188a2 | |||
d23f802cdb | |||
74e9fc33af | |||
aa6461c62d | |||
fad2db46b5 | |||
cc9c5013a9 | |||
23c0ff9683 | |||
919279a917 | |||
0621d0f07e |
1
.gitignore
vendored
1
.gitignore
vendored
@ -336,3 +336,4 @@ ASALocalRun/
|
||||
.extensions-vscode-oss
|
||||
.extensions-vscode-insiders
|
||||
.vscode/.UserSecrets/secrets.json
|
||||
.vscode/.helper
|
||||
|
14
.vscode/download-work-items.http
vendored
14
.vscode/download-work-items.http
vendored
@ -11,3 +11,17 @@ Authorization: Basic {{pat}}
|
||||
GET {{host}}/tfs/FactoryIntegration/_apis/wit/workitems/{{ids}}/updates
|
||||
Accept: application/json
|
||||
Authorization: Basic {{pat}}
|
||||
|
||||
### Iterations
|
||||
|
||||
GET {{host}}/tfs/FactoryIntegration/ART%20SPS/cea9f426-6fb1-4d65-93d5-dbf471056212/_apis/work/teamsettings/iterations?
|
||||
Accept: application/json
|
||||
Authorization: Basic {{pat}}
|
||||
|
||||
###
|
||||
|
||||
DELETE http://localhost:5004/api/SyncV1/?size=4&ticks=638796666663591762&path=d:\Tmp\phares\VisualStudioCode\z-include-patterns - Copy.nsv
|
||||
|
||||
###
|
||||
|
||||
GET http://localhost:5004/api/SyncV1/?size=4&ticks=638796666663591762&path=d:\Tmp\phares\VisualStudioCode\z-include-patterns - Copy.nsv
|
4
.vscode/equipment-automation-framework-cell-instance-status.http
vendored
Normal file
4
.vscode/equipment-automation-framework-cell-instance-status.http
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
@host = eaf-prod.mes.infineon.com:9003
|
||||
|
||||
POST {{host}}/StatusQuery
|
||||
Accept: application/json
|
172
.vscode/launch.json
vendored
172
.vscode/launch.json
vendored
@ -13,43 +13,141 @@
|
||||
"args": [
|
||||
"s",
|
||||
"X",
|
||||
"L:/DevOps/EAF-Mesa-Integration/met08thftirqs408m/bin/Debug",
|
||||
"V:/Tmp/Phares/Pictures/2023 TI2023.6 Fall Samsung",
|
||||
"Day-Helper-2025-07-05",
|
||||
"x-653889110721.jpg~401223300869.jpg",
|
||||
"3648,2736,1~3024,4032,6",
|
||||
"0.341694,0.599963,0.1642,0.279605~0.552357,0.65095,0.195175,0.32383~0.31002,0.42328,0.0379464,0.0459656",
|
||||
"0.259594,0.460161,0.1642,0.279605~0.45477,0.489035,0.195175,0.32383~0.328993,0.446263,0.0379464,0.0459656",
|
||||
"9",
|
||||
"x-825511723~x-444522128~831410304",
|
||||
"s",
|
||||
"X",
|
||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\PollPath",
|
||||
"Day-Helper-2025-07-01",
|
||||
"*.pdsf",
|
||||
"654321",
|
||||
"Time",
|
||||
"id12~CenterTemp,id13~CenterSetpt,id15~FrontTemp,id153~PPSTEPNAME,id154~SystemState,id16~FrontSetpt,id172~LVC1Ratio,id173~LVC1Carrier,id176~TotalWaferCount,i-d-1-7-8~TIME,id18~SideTemp,id183~SCRDrive4,id19~SideSetpt,id193~SCRLOAD4,id21~RearTemp,id22~RearSetpt,id221~LeftDefaultRecipe,id222~RightDefaultRecipe,id223~RecipeCompleteMsg,id25~N2H2Setpt,id26~N2H2Flow,id27~HCLSetpt,id28~HCLFlow,id29~HCLHISetpt,id30~HCLHIFlow,id37~NSRCSetpt,id38~NSRCFlow,id39~NDILSetpt,id40~NDILFlow,id41~NINJSetpt,id42~NINJFlow,id57~LVC1Setpt,id58~LVC1Flow,id61~ROTSetpt,id62~ROTSpeed,id78~LL1State,id79~LL1Init,id80~LL1Lotid,id81~LL1WafersIn,id82~LL1WfrCnt,id83~LL2State,id84~LL2Init,id85~LL2Lotid,id86~LL2WafersIn,id87~LL2WfrCnt,id93~ProcessState",
|
||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\Markdown",
|
||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\KeyValuePairs",
|
||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\JavaScriptObjectNotation",
|
||||
"s",
|
||||
"X",
|
||||
"F:/0-ISO-A",
|
||||
"Day-Helper-2025-06-28",
|
||||
"*.iso",
|
||||
"F",
|
||||
"s",
|
||||
"X",
|
||||
"D:/5-Other-Small",
|
||||
"Day-Helper-2024-12-17",
|
||||
".job.json",
|
||||
"thumbs.db~sync.ffs_db~verify.json~.html",
|
||||
"D:/0-ISO-A",
|
||||
"D:/5-Other-Small/Proxmox/Snap2HTML/Snap2HTML.exe",
|
||||
"s",
|
||||
"M",
|
||||
"D:/5-Other-Small/Notes/EC-Documentation",
|
||||
"-d",
|
||||
"D:/5-Other-Small/Notes/EC-Documentation/.vscode/helper",
|
||||
"s",
|
||||
"X",
|
||||
"D:/5-Other-Small/Proxmox/DiskInfo",
|
||||
"Day-Helper-2025-06-18",
|
||||
"*.json",
|
||||
"D:/5-Other-Small/Proxmox/Disk-Info-Old",
|
||||
"-2025-",
|
||||
"1",
|
||||
"s",
|
||||
"X",
|
||||
"D:/Tmp",
|
||||
"Day-Helper-2025-06-02",
|
||||
"infineon\\MESPhares",
|
||||
"BACKLOG~BIORAD2~BIORAD3~BIORAD4~BIORAD5~CDE4~CDE5~CDE6~DEP08CEPIEPSILON~DEP08SIASM~DEP08SIHTRPLC~EC~HGCV1~HGCV2~HGCV3~MESAFIBACKLOG~MET06AWCT~MET08ANLYSDIFAAST230~MET08AWCT~MET08DDUPSFS6420~MET08DDUPSP1TBI~MET08RESIHGCV~MET08RESIMAPCDE~MET08RESISRP2100~MET08THFTIRQS408M~MET08THFTIRSTRATUS~METCLIMATEC~R29~R32~R36~R47~R55~R57~R61~R62~R65~R70~R72~R73~R74~R75~R77~SP101~SPV01~SRP~TENCOR1~TENCOR2~TENCOR3~TRENDLOG~WC6INCH1~WC6INCH2~WC6INCH3~WC6INCH4~WC8INCH1~WC8INCH2~WC8INCH3",
|
||||
"s",
|
||||
"X",
|
||||
"D:/5-Other-Small/Proxmox/ffnm",
|
||||
"Day-Helper-2025-05-21",
|
||||
"*.pdf",
|
||||
"*.md",
|
||||
"2",
|
||||
"MM-dd-yy",
|
||||
"Trans Date~Effective Date~Description~Withdrawal Deposit~Balance",
|
||||
"s",
|
||||
"X",
|
||||
"D:/Tmp/phares/VisualStudioCode",
|
||||
"Day-Helper-2025-05-19",
|
||||
"D:/Tmp/phares/VisualStudioCode/.vscode/input.json",
|
||||
"s",
|
||||
"X",
|
||||
"D:/Tmp/phares/VisualStudioCode",
|
||||
"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",
|
||||
"Day-Helper-2025-03-05",
|
||||
"isccvm57294f1ed.infineon.com",
|
||||
".vscode/extensions/bennycode.sort-everything-1.4.1",
|
||||
"s",
|
||||
"X",
|
||||
"\\\\mesfs.infineon.com\\EC_Characterization_Si\\Archive\\BIORAD4\\2025_Week_10\\2025-03-03\\03--_2025-03-03_05;54_AM_1292405457",
|
||||
"Day-Helper-2025-02-19",
|
||||
"csv-*.pdsf",
|
||||
"*.pdsf",
|
||||
"Test,Count,MesEntity,HeaderUniqueId,UniqueId,Date,Wafer,Position,BIORAD4",
|
||||
",BIORAD4",
|
||||
",BIORAD4",
|
||||
"MID|Cassette,Lot|Batch,Title|Batch,Wafer|Text,Thickness|Site,MeanThickness|GradeMean,|BIORAD4",
|
||||
"888",
|
||||
"999",
|
||||
"s",
|
||||
"X",
|
||||
"D:/Tmp",
|
||||
"Day-Helper-2025-02-18",
|
||||
"*.pdsf",
|
||||
"A_MES_ENTITY=",
|
||||
"B_SEQUENCE=",
|
||||
"\\\\mesfs.infineon.com\\EC_Characterization_Si\\Archive",
|
||||
"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",
|
||||
"D:/5-Other-Small/Kanban-mestsa003/{}/2025/2025_Week_05/223065",
|
||||
"Day-Helper-2025-02-04",
|
||||
"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",
|
||||
""
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
@ -65,6 +163,26 @@
|
||||
"request": "launch",
|
||||
"name": "node Launch Current Opened File",
|
||||
"program": "${file}"
|
||||
},
|
||||
{
|
||||
"type": "bun",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"request": "launch",
|
||||
"name": "Debug File",
|
||||
"program": "${file}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopOnEntry": false,
|
||||
"watchMode": false
|
||||
},
|
||||
{
|
||||
"type": "bun",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"request": "launch",
|
||||
"name": "Run File",
|
||||
"program": "${file}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"noDebug": true,
|
||||
"watchMode": false
|
||||
}
|
||||
]
|
||||
}
|
34
.vscode/mklink.md
vendored
34
.vscode/mklink.md
vendored
@ -14,18 +14,28 @@ mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.kanbn" "D:\5-Other-Small\Kanban
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.kanbn" "D:\5-Other-Small\Kanban\File-Folder-Helper"
|
||||
```
|
||||
|
||||
```bash
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode"
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-oss"
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-insiders"
|
||||
mkdir "C:\Users\phares\.vscode\extensions\ifx.type-script-helper-1.111.0\net8.0\win-x64\publish"
|
||||
mkdir "C:\Users\phares\.vscode-oss\extensions\ifx.type-script-helper-1.111.0\net8.0\win-x64\publish"
|
||||
mkdir "C:\Users\phares\.vscode-insiders\extensions\ifx.type-script-helper-1.111.0\net8.0\win-x64\publish"
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode" "C:\Users\phares\.vscode\extensions\ifx.type-script-helper-1.111.0"
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-oss" "C:\Users\phares\.vscode-oss\extensions\ifx.type-script-helper-1.111.0"
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-insiders" "C:\Users\phares\.vscode-insiders\extensions\ifx.type-script-helper-1.111.0"
|
||||
```
|
||||
|
||||
```bash Thu Jul 18 2024 13:47:40 GMT-0700 (Mountain Standard Time)
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.vscode\.UserSecrets" "C:\Users\phares\AppData\Roaming\Microsoft\UserSecrets\8da397d4-13ec-4576-9722-3c79cad25563"
|
||||
```
|
||||
|
||||
```bash 1749414316830 = 638850111168300000 = 2025-2.Spring = Sun Jun 08 2025 13:25:16 GMT-0700 (Mountain Standard Time)
|
||||
C:\Users\PHARES\.vscode\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode"
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-oss"
|
||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-insiders"
|
||||
mkdir "C:\Users\phares\.vscode\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64"
|
||||
mkdir "C:\Users\phares\.vscode-oss\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64"
|
||||
mkdir "C:\Users\phares\.vscode-insiders\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64"
|
||||
mklink /J "C:\Users\phares\.vscode\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64\publish" "L:\DevOps\Mesa_FI\File-Folder-Helper\bin\Release\net8.0\win-x64\publish"
|
||||
mklink /J "C:\Users\phares\.vscode-oss\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64\publish" "L:\DevOps\Mesa_FI\File-Folder-Helper\bin\Release\net8.0\win-x64\publish"
|
||||
mklink /J "C:\Users\phares\.vscode-insiders\extensions\infineon-technologies-ag-mesa-fi.infineon-technologies-ag-mesa-fi-cost-of-delay-helper-1.124.0\net8.0\win-x64\publish" "L:\DevOps\Mesa_FI\File-Folder-Helper\bin\Release\net8.0\win-x64\publish"
|
||||
```
|
||||
|
||||
```bash 1749957317559 = 638855541175590000 = 2025-2.Spring = Sat Jun 14 2025 20:15:17 GMT-0700 (Mountain Standard Time)
|
||||
mkdir "L:\DevOps\MESA_FI\file-folder-helper\bin\Release\net8.0\win-x64"
|
||||
mklink /J "L:\DevOps\MESA_FI\file-folder-helper\bin\Release\net8.0\win-x64\publish" "D:\5-Other-Small\Proxmox\publish"
|
||||
```
|
||||
|
||||
```bash 1750459968132 = 638860567681320000 = 2025-3.Summer = Fri Jun 20 2025 15:52:47 GMT-0700 (Mountain Standard Time)
|
||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.vscode\.helper" "D:\5-Other-Small\Notes\Infineon\.vscode\helper"
|
||||
```
|
||||
|
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@ -10,6 +10,8 @@
|
||||
"**/node_modules": true
|
||||
},
|
||||
"cSpell.words": [
|
||||
"abcdefghiklmnopqrstuvwxyz",
|
||||
"Acks",
|
||||
"ASPNETCORE",
|
||||
"BIORAD",
|
||||
"BIRT",
|
||||
@ -19,7 +21,9 @@
|
||||
"Exif",
|
||||
"FAMC",
|
||||
"FAMS",
|
||||
"Gatus",
|
||||
"GIVN",
|
||||
"HGCV",
|
||||
"HUSB",
|
||||
"Immich",
|
||||
"INDI",
|
||||
@ -30,11 +34,13 @@
|
||||
"Linc",
|
||||
"mesfs",
|
||||
"mestsa",
|
||||
"netrm",
|
||||
"NpgSql",
|
||||
"NSFX",
|
||||
"OBJE",
|
||||
"onenote",
|
||||
"PDFC",
|
||||
"pdsf",
|
||||
"Permyriad",
|
||||
"pged",
|
||||
"Phares",
|
||||
@ -42,9 +48,11 @@
|
||||
"Reparse",
|
||||
"Rijndael",
|
||||
"Serilog",
|
||||
"startable",
|
||||
"SUBM",
|
||||
"SURN",
|
||||
"SYSLIB",
|
||||
"TENCOR",
|
||||
"VSTS",
|
||||
"WIQL",
|
||||
"WSJF"
|
||||
|
14
.vscode/tasks.json
vendored
14
.vscode/tasks.json
vendored
@ -228,6 +228,20 @@
|
||||
"type": "shell",
|
||||
"command": "npx jest",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s X Day-Helper-2025-03-20",
|
||||
"type": "shell",
|
||||
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe",
|
||||
"args": [
|
||||
"s",
|
||||
"X",
|
||||
"L:/DevOps/Mesa_FI/File-Folder-Helper",
|
||||
"Day-Helper-2025-03-20",
|
||||
"false",
|
||||
"4"
|
||||
],
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
@ -42,7 +42,7 @@ internal static partial class Helper20240403
|
||||
string keyIndex = args[5];
|
||||
string directory = args[0];
|
||||
logger.LogInformation(directory);
|
||||
string[] columns = args[4].Split('|');
|
||||
string[] columns = args[4].Split('~');
|
||||
DynamicHostConfigurationProtocolConfiguration dynamicHostConfigurationProtocolConfiguration = new(columns, directory, ignore, int.Parse(keyIndex), pattern, primary);
|
||||
AlertIfNewDeviceIsConnected(dynamicHostConfigurationProtocolConfiguration, logger);
|
||||
}
|
||||
|
@ -701,7 +701,7 @@ internal static partial class Helper20240911
|
||||
List<char> spaces = [];
|
||||
List<string> lines = [];
|
||||
ReadOnlyCollection<WorkItem> results;
|
||||
string[] workItemTypes = args[4].Split('|');
|
||||
string[] workItemTypes = args[4].Split('~');
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string destinationDirectory = Path.GetFullPath(args[6]);
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
|
@ -12,7 +12,7 @@ internal static partial class Helper20241212
|
||||
string newFileName;
|
||||
string directoryName;
|
||||
string searchPattern = args[2];
|
||||
string[] searchPatterns = args[3].Split('|');
|
||||
string[] searchPatterns = args[3].Split('~');
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
if (files.Length == 0)
|
||||
|
@ -11,12 +11,34 @@ namespace File_Folder_Helper.ADO2024.PI4;
|
||||
internal static partial class Helper20241217
|
||||
{
|
||||
|
||||
private record Record(string Directory, Job? Job, string Path);
|
||||
private record Job(string AlternatePath, string Directory, string Extension, File[] Files, int FilesCount, double FilesTotalLength, int Keep, Target[] Targets);
|
||||
private record SecureShell();
|
||||
private record ServerMessageBlock(string Path, bool Required);
|
||||
private record Target(SecureShell? SecureShell, ServerMessageBlock? ServerMessageBlock);
|
||||
private record File(long LastWriteTicks, long Length, string RelativePath);
|
||||
private record SecureShell(
|
||||
);
|
||||
|
||||
private record ServerMessageBlock(string Path,
|
||||
bool Required);
|
||||
|
||||
private record Target(SecureShell? SecureShell,
|
||||
ServerMessageBlock? ServerMessageBlock);
|
||||
|
||||
private record File(long LastWriteTicks,
|
||||
long Length,
|
||||
string RelativePath);
|
||||
|
||||
private record Record(string DestinationDirectory,
|
||||
string DirectoryName,
|
||||
Job Job,
|
||||
string Path,
|
||||
string Snap2HyperTextMarkupLanguage,
|
||||
string SourceDirectory);
|
||||
|
||||
private record Job(string? AlternatePath,
|
||||
string Directory,
|
||||
string Extension,
|
||||
File[] Files,
|
||||
int FilesCount,
|
||||
double FilesTotalLength,
|
||||
int Keep,
|
||||
Target[] Targets);
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Job))]
|
||||
@ -30,30 +52,181 @@ internal static partial class Helper20241217
|
||||
{
|
||||
}
|
||||
|
||||
private static IEnumerable<Record> GetRecords(string directory, string searchPattern)
|
||||
private static ReadOnlyCollection<File> GetFiles(string searchPattern, string[] ignoreFileNames, Record record) =>
|
||||
GetFiles(record.SourceDirectory, searchPattern, ignoreFileNames);
|
||||
|
||||
internal static void Backup(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
Job jobNew;
|
||||
string path;
|
||||
string? json;
|
||||
string fileName;
|
||||
bool areTheyTheSame;
|
||||
IEnumerable<Record> records;
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
logger.LogInformation(args[3]);
|
||||
logger.LogInformation(args[4]);
|
||||
ReadOnlyCollection<File> files;
|
||||
string searchPattern = args[2];
|
||||
IEnumerable<string> searchPatternFiles;
|
||||
string[] ignoreFileNames = args[3].Split('~');
|
||||
string destination = Path.GetFullPath(args[4]);
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string? snap2HyperTextMarkupLanguage = args.Count < 6 ? null : Path.GetFullPath(args[5]);
|
||||
logger.LogInformation("Searching <{sourceDirectory}> with search pattern {searchPattern}", args[0], searchPattern);
|
||||
if (Debugger.IsAttached)
|
||||
Verify(searchPattern, ignoreFileNames);
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
searchPatternFiles = Directory.EnumerateFiles(sourceDirectory, searchPattern, new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true });
|
||||
}
|
||||
else if (i == 2)
|
||||
{
|
||||
searchPatternFiles = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
records = GetRecords(sourceDirectory, destination, searchPatternFiles);
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (record.Job is null || string.IsNullOrEmpty(record.Job.Extension))
|
||||
continue;
|
||||
logger.LogInformation("Searching <{directory}>", record.SourceDirectory);
|
||||
if (snap2HyperTextMarkupLanguage is not null && System.IO.File.Exists(snap2HyperTextMarkupLanguage))
|
||||
WriteSnap2HyperTextMarkupLanguage(logger, snap2HyperTextMarkupLanguage, record);
|
||||
files = GetFiles(searchPattern, ignoreFileNames, record);
|
||||
jobNew = GetJob(searchPattern, ignoreFileNames, record, files);
|
||||
json = JsonSerializer.Serialize(jobNew, JobSourceGenerationContext.Default.Job);
|
||||
areTheyTheSame = GetAreTheyTheSame(logger, searchPattern, ignoreFileNames, record, jobNew);
|
||||
if (areTheyTheSame)
|
||||
{
|
||||
WriteAllText(record.Path, json);
|
||||
continue;
|
||||
}
|
||||
fileName = $"{record.DirectoryName}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss-fff}{record.Job.Extension}";
|
||||
path = Path.Combine(record.DestinationDirectory, fileName);
|
||||
logger.LogInformation("Writing <{path}> extension", path);
|
||||
WritePassedExtension(record, files, record.DirectoryName, path);
|
||||
logger.LogInformation("Wrote <{path}> extension", path);
|
||||
logger.LogInformation("Moved <{path}> extension", path);
|
||||
WriteAllText(record, json, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Verify(string searchPattern, string[] ignoreFileNames)
|
||||
{
|
||||
List<Target> targets = [
|
||||
new(new SecureShell(), null),
|
||||
new(null, new ServerMessageBlock("\\\\mesfs.infineon.com\\EC_APC\\DEV", true))
|
||||
];
|
||||
string directory = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper");
|
||||
if (!Directory.Exists(directory))
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
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();
|
||||
Job job = new(AlternatePath: "C:/Users/phares",
|
||||
Directory: directory,
|
||||
Extension: ".iso",
|
||||
Files: collection.ToArray(),
|
||||
FilesCount: files.Count,
|
||||
FilesTotalLength: filesTotalLength,
|
||||
Keep: 3,
|
||||
Targets: targets.ToArray());
|
||||
string json = JsonSerializer.Serialize(job, JobSourceGenerationContext.Default.Job);
|
||||
WriteAllText(path, json);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<File> GetFilteredFiles(string searchPattern, string[] ignoreFileNames, ReadOnlyCollection<File> files)
|
||||
{
|
||||
List<File> results = [];
|
||||
string fileName;
|
||||
foreach (File file in files)
|
||||
{
|
||||
if (file.RelativePath == searchPattern)
|
||||
continue;
|
||||
fileName = Path.GetFileName(file.RelativePath);
|
||||
if (fileName == searchPattern)
|
||||
throw new Exception("Found nested file!");
|
||||
if (ignoreFileNames.Any(l => l == fileName))
|
||||
continue;
|
||||
if (file.Length == 0)
|
||||
continue;
|
||||
results.Add(file);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static IEnumerable<Record> GetRecords(string directory, string destination, IEnumerable<string> files)
|
||||
{
|
||||
Job? job;
|
||||
string json;
|
||||
Record record;
|
||||
string fileName;
|
||||
string directoryName;
|
||||
IEnumerable<string> files = Directory.EnumerateFiles(directory, searchPattern, new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true });
|
||||
string sourceDirectory;
|
||||
string destinationDirectory;
|
||||
string snap2HyperTextMarkupLanguage;
|
||||
foreach (string file in files)
|
||||
{
|
||||
fileName = Path.GetFileName(file);
|
||||
directoryName = Path.GetDirectoryName(file) ?? throw new Exception();
|
||||
sourceDirectory = Path.GetDirectoryName(file) ?? throw new Exception();
|
||||
directoryName = Path.GetFileName(sourceDirectory);
|
||||
if (!fileName.StartsWith('.'))
|
||||
{
|
||||
System.IO.File.Move(file, Path.Combine(directoryName, $".{fileName}"));
|
||||
System.IO.File.Move(file, Path.Combine(sourceDirectory, $".{fileName}"));
|
||||
continue;
|
||||
}
|
||||
json = System.IO.File.ReadAllText(file);
|
||||
snap2HyperTextMarkupLanguage = Path.Combine(sourceDirectory, ".html");
|
||||
if (string.IsNullOrEmpty(json) || json is "{}" or "[]")
|
||||
job = null;
|
||||
else
|
||||
job = JsonSerializer.Deserialize(json, JobSourceGenerationContext.Default.Job);
|
||||
record = new(directoryName, job, file);
|
||||
job ??= new(AlternatePath: null,
|
||||
Directory: directory,
|
||||
Extension: ".iso",
|
||||
Files: [],
|
||||
FilesCount: 0,
|
||||
FilesTotalLength: 0,
|
||||
Keep: 3,
|
||||
Targets: []);
|
||||
destinationDirectory = $"{destination}{sourceDirectory[2..]}";
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
_ = Directory.CreateDirectory(destinationDirectory);
|
||||
record = new(DestinationDirectory: destinationDirectory,
|
||||
DirectoryName: directoryName,
|
||||
Job: job,
|
||||
Path: file,
|
||||
Snap2HyperTextMarkupLanguage: snap2HyperTextMarkupLanguage,
|
||||
SourceDirectory: sourceDirectory);
|
||||
yield return record;
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteSnap2HyperTextMarkupLanguage(ILogger<Worker> logger, string snap2HyperTextMarkupLanguage, Record record)
|
||||
{
|
||||
string title = Path.GetFileName(record.SourceDirectory);
|
||||
ProcessStartInfo processStartInfo = new()
|
||||
{
|
||||
Arguments = $"-path:\"{record.SourceDirectory}\" -outfile:\"{record.Snap2HyperTextMarkupLanguage}\" -title:\"{title}\" -hidden -silent",
|
||||
FileName = snap2HyperTextMarkupLanguage,
|
||||
RedirectStandardError = true,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
WorkingDirectory = record.SourceDirectory
|
||||
};
|
||||
Process? process = Process.Start(processStartInfo) ?? throw new Exception("Process should not be null.");
|
||||
process.WaitForExit();
|
||||
logger.LogInformation($"Snap2HyperTextMarkupLanguage: {process.StandardOutput.ReadToEnd()}{Environment.NewLine}{process.StandardError.ReadToEnd()}{Environment.NewLine}{process.ExitCode}");
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<File> GetFiles(string directory, string searchPattern, string[] ignoreFileNames)
|
||||
{
|
||||
List<File> results = [];
|
||||
@ -72,89 +245,97 @@ internal static partial class Helper20241217
|
||||
relativePath = Path.GetRelativePath(directory, fileInfo.FullName).Replace(';', '_');
|
||||
if (relativePath.StartsWith(".."))
|
||||
relativePath = relativePath[3..];
|
||||
file = new(fileInfo.LastWriteTime.Ticks, fileInfo.Length, relativePath);
|
||||
file = new(LastWriteTicks: fileInfo.LastWriteTime.Ticks, Length: fileInfo.Length, RelativePath: relativePath);
|
||||
results.Add(file);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<File> GetFiles(string searchPattern, string[] ignoreFileNames, Record record) =>
|
||||
GetFiles(record.Directory, searchPattern, ignoreFileNames);
|
||||
|
||||
private static string? GetJsonIfNotEqual(string searchPattern, string[] ignoreFileNames, Record record, Job job, ReadOnlyCollection<File> files)
|
||||
private static Job GetJob(string searchPattern, string[] ignoreFileNames, Record record, ReadOnlyCollection<File> files)
|
||||
{
|
||||
string? result;
|
||||
string? jsonNew;
|
||||
string? jsonOld;
|
||||
string fileName;
|
||||
int ignoreCount = 0;
|
||||
double filesTotalLengthNew = 0;
|
||||
File[] filesArray = files.ToArray();
|
||||
double filesTotalLengthOld = job.FilesTotalLength;
|
||||
foreach (File file in files)
|
||||
filesTotalLengthNew += file.Length;
|
||||
Job jobNew = new(job.AlternatePath,
|
||||
record.Directory,
|
||||
job.Extension,
|
||||
filesArray,
|
||||
files.Count,
|
||||
filesTotalLengthNew,
|
||||
job.Keep,
|
||||
job.Targets);
|
||||
result = JsonSerializer.Serialize(jobNew, JobSourceGenerationContext.Default.Job);
|
||||
if (filesTotalLengthNew != filesTotalLengthOld)
|
||||
{
|
||||
filesTotalLengthOld = 0;
|
||||
foreach (File file in job.Files)
|
||||
{
|
||||
fileName = Path.GetFileName(file.RelativePath);
|
||||
if (fileName == searchPattern || ignoreFileNames.Any(l => l == fileName))
|
||||
{
|
||||
ignoreCount += 1;
|
||||
continue;
|
||||
}
|
||||
if (file.Length == 0)
|
||||
{
|
||||
ignoreCount += 1;
|
||||
continue;
|
||||
}
|
||||
filesTotalLengthOld += file.Length;
|
||||
}
|
||||
}
|
||||
if (filesTotalLengthNew != filesTotalLengthOld || files.Count != (job.Files.Length - ignoreCount))
|
||||
{
|
||||
jsonNew = null;
|
||||
jsonOld = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonNew = JsonSerializer.Serialize((from l in filesArray orderby l.RelativePath.Length, l.RelativePath select l).ToArray(), FilesSourceGenerationContext.Default.FileArray);
|
||||
jsonOld = JsonSerializer.Serialize((from l in job.Files orderby l.RelativePath.Length, l.RelativePath where l.RelativePath != searchPattern select l).ToArray(), FilesSourceGenerationContext.Default.FileArray);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(jsonNew) && !string.IsNullOrEmpty(jsonOld) && jsonNew == jsonOld)
|
||||
result = null;
|
||||
Job result;
|
||||
ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, files);
|
||||
double filesTotalLengthNew = collection.Select(l => l.Length).Sum();
|
||||
result = new(AlternatePath: record.Job.AlternatePath,
|
||||
Directory: record.SourceDirectory,
|
||||
Extension: record.Job.Extension,
|
||||
Files: collection.ToArray(),
|
||||
FilesCount: collection.Count,
|
||||
FilesTotalLength: filesTotalLengthNew,
|
||||
Keep: record.Job.Keep,
|
||||
Targets: record.Job.Targets);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void WriteISO(char destinationDriveLetter, Record record, ReadOnlyCollection<File> files, string path, string directoryName)
|
||||
private static bool GetAreTheyTheSame(ILogger<Worker> logger, string searchPattern, string[] ignoreFileNames, Record record, Job jobNew)
|
||||
{
|
||||
string checkFile = $"{destinationDriveLetter}{path[1..]}";
|
||||
string checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new Exception();
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
CDBuilder builder = new() { UseJoliet = true, VolumeIdentifier = directoryName.Length < 25 ? directoryName : directoryName[..25] };
|
||||
foreach (File file in files)
|
||||
_ = builder.AddFile(file.RelativePath, Path.Combine(record.Directory, file.RelativePath));
|
||||
builder.Build(checkFile);
|
||||
bool result;
|
||||
ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, record.Job.Files.AsReadOnly());
|
||||
int filesCountOld = collection.Count;
|
||||
int filesCountNew = jobNew.Files.Length;
|
||||
if (filesCountNew != filesCountOld)
|
||||
{
|
||||
result = false;
|
||||
logger.LogInformation("<{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();
|
||||
if (filesTotalLengthNew != filesTotalLengthOld)
|
||||
{
|
||||
result = false;
|
||||
logger.LogInformation("<{directory}> file length has changed {filesTotalLengthNew} != {filesTotalLengthOld}", record.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);
|
||||
}
|
||||
else
|
||||
{
|
||||
string jsonNew = JsonSerializer.Serialize(jobNew.Files, FilesSourceGenerationContext.Default.FileArray);
|
||||
string jsonOld = JsonSerializer.Serialize(collection.ToArray(), FilesSourceGenerationContext.Default.FileArray);
|
||||
if (jsonNew == jsonOld)
|
||||
result = true;
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", "old.json"), jsonOld);
|
||||
WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", "new.json"), jsonNew);
|
||||
}
|
||||
logger.LogInformation("<{directory}> file serialized are different {filesTotalLengthNew} != {filesTotalLengthOld}", record.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void WriteZIP(char destinationDriveLetter, Record record, ReadOnlyCollection<File> files, string path)
|
||||
private static void WriteAllText(string path, string text)
|
||||
{
|
||||
string checkFile = $"{destinationDriveLetter}{path[1..]}";
|
||||
string checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new Exception();
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
using ZipArchive zip = ZipFile.Open(checkFile, ZipArchiveMode.Create);
|
||||
string check = !System.IO.File.Exists(path) ? string.Empty : System.IO.File.ReadAllText(path);
|
||||
if (check != text)
|
||||
System.IO.File.WriteAllText(path, text);
|
||||
}
|
||||
|
||||
private static void WritePassedExtension(Record record, ReadOnlyCollection<File> files, string directoryName, string path)
|
||||
{
|
||||
if (record.Job.Extension.Equals(".iso", StringComparison.OrdinalIgnoreCase))
|
||||
WriteISO(record, files, path, directoryName);
|
||||
else if (record.Job.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase))
|
||||
WriteZIP(record, files, path);
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static void WriteISO(Record record, ReadOnlyCollection<File> files, string path, string directoryName)
|
||||
{
|
||||
CDBuilder builder = new() { UseJoliet = true, VolumeIdentifier = directoryName.Length < 25 ? directoryName : directoryName[..25] };
|
||||
foreach (File file in files)
|
||||
_ = builder.AddFile(file.RelativePath, Path.Combine(record.SourceDirectory, file.RelativePath));
|
||||
builder.Build(path);
|
||||
}
|
||||
|
||||
private static void WriteZIP(Record record, ReadOnlyCollection<File> files, string path)
|
||||
{
|
||||
using ZipArchive zip = ZipFile.Open(path, ZipArchiveMode.Create);
|
||||
string directoryEntry;
|
||||
List<string> directoryEntries = [];
|
||||
foreach (File file in files)
|
||||
@ -166,170 +347,16 @@ internal static partial class Helper20241217
|
||||
_ = zip.CreateEntry(file.RelativePath);
|
||||
}
|
||||
foreach (File file in files)
|
||||
_ = zip.CreateEntryFromFile(Path.Combine(record.Directory, file.RelativePath), file.RelativePath);
|
||||
_ = zip.CreateEntryFromFile(Path.Combine(record.SourceDirectory, file.RelativePath), file.RelativePath);
|
||||
}
|
||||
|
||||
private static void WriteExtension(char destinationDriveLetter, Record record, Job job, ReadOnlyCollection<File> files, string path)
|
||||
private static void WriteAllText(Record record, string text, string path)
|
||||
{
|
||||
string directoryName = Path.GetFileName(record.Directory);
|
||||
if (job.Extension.Equals(".iso", StringComparison.OrdinalIgnoreCase))
|
||||
WriteISO(destinationDriveLetter, record, files, path, directoryName);
|
||||
else if (job.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase))
|
||||
WriteZIP(destinationDriveLetter, record, files, path);
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static void PushTo(ServerMessageBlock serverMessageBlock, string path)
|
||||
{
|
||||
string remotePath = Path.Combine(serverMessageBlock.Path, Path.GetFileName(path));
|
||||
System.IO.File.Copy(path, remotePath);
|
||||
}
|
||||
|
||||
private static void PushTo(string directory, string path)
|
||||
{
|
||||
string remotePath = Path.Combine(directory, Path.GetFileName(path));
|
||||
System.IO.File.Copy(path, remotePath);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Exception> PushTo(Job job, string path)
|
||||
{
|
||||
List<Exception> results = [];
|
||||
foreach (Target target in job.Targets)
|
||||
{
|
||||
if (target.SecureShell is not null)
|
||||
continue;
|
||||
else if (target.ServerMessageBlock is not null)
|
||||
{
|
||||
try
|
||||
{ PushTo(target.ServerMessageBlock, path); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (target.ServerMessageBlock.Required)
|
||||
results.Add(ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void DeleteOld(Job job, ServerMessageBlock serverMessageBlock, string path)
|
||||
{
|
||||
List<string> results = [];
|
||||
string[] files = Directory.GetFiles(serverMessageBlock.Path, $"*{job.Extension}", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
if (file == path)
|
||||
continue;
|
||||
results.Add(file);
|
||||
}
|
||||
for (int i = job.Keep - 1; i < results.Count; i++)
|
||||
System.IO.File.Delete(results[i]);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Exception> DeleteOld(Job job, string path)
|
||||
{
|
||||
List<Exception> results = [];
|
||||
foreach (Target target in job.Targets)
|
||||
{
|
||||
if (target.SecureShell is not null)
|
||||
continue;
|
||||
else if (target.ServerMessageBlock is not null)
|
||||
{
|
||||
try
|
||||
{ DeleteOld(job, target.ServerMessageBlock, path); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (target.ServerMessageBlock.Required)
|
||||
results.Add(ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void Verify(string searchPattern, string[] ignoreFileNames)
|
||||
{
|
||||
List<Target> targets = [
|
||||
new(new SecureShell(), null),
|
||||
new(null, new ServerMessageBlock("\\\\mesfs.infineon.com\\EC_APC\\DEV", true))
|
||||
];
|
||||
string directory = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper");
|
||||
if (!Directory.Exists(directory))
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
ReadOnlyCollection<File> files = GetFiles(directory, searchPattern, ignoreFileNames);
|
||||
double filesTotalLength = 0;
|
||||
foreach (File file in files)
|
||||
filesTotalLength += file.Length;
|
||||
Job job = new(
|
||||
"C:/Users/phares",
|
||||
directory,
|
||||
"*.iso",
|
||||
files.ToArray(),
|
||||
files.Count,
|
||||
filesTotalLength,
|
||||
3,
|
||||
targets.ToArray());
|
||||
string json = JsonSerializer.Serialize(job, JobSourceGenerationContext.Default.Job);
|
||||
System.IO.File.WriteAllText(Path.Combine(directory, "verify.json"), json);
|
||||
}
|
||||
|
||||
internal static void Backup(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
string path;
|
||||
string? json;
|
||||
string directoryName;
|
||||
ReadOnlyCollection<File> files;
|
||||
string searchPattern = args[2];
|
||||
ReadOnlyCollection<Exception> exceptions;
|
||||
string[] ignoreFileNames = args[3].Split('|');
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
char destinationDriveLetter = args[4].Split(':')[0][0];
|
||||
logger.LogInformation("Searching <{sourceDirectory}> with search pattern {searchPattern}", args[0], searchPattern);
|
||||
if (Debugger.IsAttached)
|
||||
Verify(searchPattern, ignoreFileNames);
|
||||
IEnumerable<Record> records = GetRecords(sourceDirectory, searchPattern);
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (record.Job is null || record.Job.Targets.Length == 0 || string.IsNullOrEmpty(record.Job.Extension))
|
||||
continue;
|
||||
logger.LogInformation("Searching <{directory}>", record.Directory);
|
||||
files = GetFiles(searchPattern, ignoreFileNames, record);
|
||||
json = GetJsonIfNotEqual(searchPattern, ignoreFileNames, record, record.Job, files);
|
||||
if (string.IsNullOrEmpty(json))
|
||||
continue;
|
||||
directoryName = Path.GetFileName(record.Directory);
|
||||
path = Path.Combine(record.Directory, $"{directoryName}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss-fff}{record.Job.Extension}");
|
||||
logger.LogInformation("Writing <{directory}> extension", record.Directory);
|
||||
WriteExtension(destinationDriveLetter, record, record.Job, files, path);
|
||||
logger.LogInformation("Pushing <{directory}> extension", record.Directory);
|
||||
exceptions = PushTo(record.Job, path);
|
||||
if (exceptions.Count != 0)
|
||||
{
|
||||
foreach (Exception exception in exceptions)
|
||||
logger.LogError(exception, exception.Message);
|
||||
PushTo(record.Job.AlternatePath, path);
|
||||
}
|
||||
System.IO.File.WriteAllText(record.Path, json);
|
||||
System.IO.File.Delete(path);
|
||||
logger.LogInformation("Deleting old <{directory}> extension", record.Directory);
|
||||
exceptions = DeleteOld(record.Job, path);
|
||||
if (exceptions.Count != 0)
|
||||
{
|
||||
foreach (Exception exception in exceptions)
|
||||
logger.LogError(exception, exception.Message);
|
||||
}
|
||||
}
|
||||
if (Debugger.IsAttached && records.Count() == 0)
|
||||
{
|
||||
files = GetFiles(sourceDirectory, searchPattern, ignoreFileNames);
|
||||
json = JsonSerializer.Serialize(files.ToArray(), FilesSourceGenerationContext.Default.FileArray);
|
||||
System.IO.File.WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", ".json"), json);
|
||||
}
|
||||
WriteAllText(record.Path, text);
|
||||
System.IO.File.Copy(record.Path, $"{path}.json");
|
||||
string checkFile = Path.Combine(record.SourceDirectory, ".html");
|
||||
if (System.IO.File.Exists(checkFile))
|
||||
System.IO.File.Copy(checkFile, $"{path}.html");
|
||||
}
|
||||
|
||||
}
|
@ -45,7 +45,7 @@ internal static partial class Helper20250114
|
||||
internal static void Rename(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
string dateFormat = args[3];
|
||||
string[] searchPatterns = args[2].Split('|');
|
||||
string[] searchPatterns = args[2].Split('~');
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
foreach (string searchPattern in searchPatterns)
|
||||
Rename(logger, sourceDirectory, searchPattern, dateFormat);
|
||||
|
381
ADO2025/PI5/.editorconfig
Normal file
381
ADO2025/PI5/.editorconfig
Normal file
@ -0,0 +1,381 @@
|
||||
[*.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 = false
|
||||
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_line_after_token_in_arrow_expression_clause_experimental = true
|
||||
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
|
||||
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
|
||||
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 = error # 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 = error # 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 = error # 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_diagnostic.IDE2000.severity = error # IDE2000: Allow multiple blank lines
|
||||
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 = true
|
||||
dotnet_sort_system_directives_first = true
|
||||
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
|
||||
|
||||
# Question
|
||||
csharp_prefer_simple_using_statement = false # Question
|
||||
csharp_style_expression_bodied_constructors = when_on_single_line:none # Question
|
||||
csharp_style_expression_bodied_properties = true # Question
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning # Question
|
||||
csharp_style_pattern_matching_over_as_with_null_check = false # Question
|
||||
csharp_style_prefer_pattern_matching = false # Question
|
||||
csharp_style_prefer_range_operator = false # Question
|
||||
csharp_style_prefer_switch_expression = false # Question
|
||||
csharp_style_unused_value_assignment_preference = unused_local_variable # Question
|
||||
csharp_style_unused_value_expression_statement_preference = false # Question
|
||||
csharp_style_var_elsewhere = false:none # Question
|
||||
csharp_style_var_for_built_in_types = false:none # Question
|
||||
csharp_style_var_when_type_is_apparent = false:warning # Question
|
||||
dotnet_diagnostic.CA1001.severity = none # Question - Types that own disposable fields should be disposable
|
||||
dotnet_diagnostic.CA1051.severity = none # Question - Do not declare visible instance fields
|
||||
dotnet_diagnostic.CA1416.severity = none # Question - This call site is reachable on all platforms.
|
||||
dotnet_diagnostic.CA1510.severity = none # Question - Use
|
||||
dotnet_diagnostic.CA1834.severity = none # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
|
||||
dotnet_diagnostic.CA1860.severity = none # Question - Avoid using
|
||||
dotnet_diagnostic.CA1862.severity = none # Question - Prefer using
|
||||
dotnet_diagnostic.CA2208.severity = none # Question - Instantiate argument exceptions correctly
|
||||
dotnet_diagnostic.CA2211.severity = none # Question - Non-constant fields should not be visible
|
||||
dotnet_diagnostic.CA2249.severity = none # Question - Use
|
||||
dotnet_diagnostic.CA2253.severity = none # Question - Named placeholders should not be numeric values
|
||||
dotnet_diagnostic.CS0103.severity = none # Question - The name
|
||||
dotnet_diagnostic.CS0168.severity = none # Question - The variable
|
||||
dotnet_diagnostic.CS0219.severity = none # Question - The variable
|
||||
dotnet_diagnostic.CS0612.severity = none # Question - is obsolete
|
||||
dotnet_diagnostic.CS0618.severity = none # Question - Compiler Warning (level 2)
|
||||
dotnet_diagnostic.CS0659.severity = none # Question - Compiler Warning (level 3)
|
||||
dotnet_diagnostic.CS8019.severity = warning # Question - Unnecessary using directive.
|
||||
dotnet_diagnostic.CS8600.severity = none # Question - Converting null literal or possible null value to non-nullable type
|
||||
dotnet_diagnostic.CS8602.severity = none # Question - Dereference of a possibly null reference.
|
||||
dotnet_diagnostic.CS8603.severity = none # Question - Possible null reference return
|
||||
dotnet_diagnostic.CS8604.severity = none # Question - Possible null reference argument for parameter.
|
||||
dotnet_diagnostic.CS8618.severity = none # Question - Non-nullable variable must contain a non-null value when exiting constructor
|
||||
dotnet_diagnostic.CS8625.severity = none # Question - Cannot convert null literal to non-nullable reference type.
|
||||
dotnet_diagnostic.CS8629.severity = none # Question - Nullable value type may be null
|
||||
dotnet_diagnostic.CS8765.severity = none # Question - Nullability of type of parameter
|
||||
dotnet_diagnostic.IDE0005.severity = none # Question - Remove unnecessary using directives
|
||||
dotnet_diagnostic.IDE0008.severity = warning # Question - Use explicit type instead of
|
||||
dotnet_diagnostic.IDE0017.severity = none # Question - Object initialization can be simplified
|
||||
dotnet_diagnostic.IDE0019.severity = none # Question - Use pattern matching
|
||||
dotnet_diagnostic.IDE0021.severity = none # Question - Use expression body for constructor
|
||||
dotnet_diagnostic.IDE0022.severity = none # Question - Use expression body for method
|
||||
dotnet_diagnostic.IDE0025.severity = none # Question - Use expression body for property
|
||||
dotnet_diagnostic.IDE0027.severity = none # Question - Use expression body for accessor
|
||||
dotnet_diagnostic.IDE0028.severity = none # Question - Use collection initializers or expressions
|
||||
dotnet_diagnostic.IDE0031.severity = none # Question - Null check can be simplified
|
||||
dotnet_diagnostic.IDE0032.severity = none # Question - Use auto property
|
||||
dotnet_diagnostic.IDE0037.severity = none # Question - Member name can be simplified
|
||||
dotnet_diagnostic.IDE0041.severity = none # Question - Null check can be simplified
|
||||
dotnet_diagnostic.IDE0047.severity = none # Question - Parentheses preferences
|
||||
dotnet_diagnostic.IDE0049.severity = warning # Question - Name can be simplified
|
||||
dotnet_diagnostic.IDE0051.severity = none # Question - Remove unused private member
|
||||
dotnet_diagnostic.IDE0053.severity = none # Question - Use expression body for lambdas
|
||||
dotnet_diagnostic.IDE0054.severity = none # Question - Use compound assignment
|
||||
dotnet_diagnostic.IDE0055.severity = none # Question - Formatting rule
|
||||
dotnet_diagnostic.IDE0057.severity = none # Question - Substring can be simplified
|
||||
dotnet_diagnostic.IDE0058.severity = none # Question - Remove unnecessary expression value
|
||||
dotnet_diagnostic.IDE0059.severity = none # Question - Unnecessary assignment of a value to
|
||||
dotnet_diagnostic.IDE0060.severity = none # Question - Remove unused parameter
|
||||
dotnet_diagnostic.IDE0063.severity = none # Question - Use simple
|
||||
dotnet_diagnostic.IDE0065.severity = none # Question -
|
||||
dotnet_diagnostic.IDE0066.severity = none # Question - Use
|
||||
dotnet_diagnostic.IDE0078.severity = none # Question - Use pattern matching (may change code meaning)
|
||||
dotnet_diagnostic.IDE0090.severity = warning # Question - Simplify new expression
|
||||
dotnet_diagnostic.IDE0100.severity = error # Question - Remove redundant equality
|
||||
dotnet_diagnostic.IDE0160.severity = warning # Question - Use block-scoped namespace
|
||||
dotnet_diagnostic.IDE0161.severity = warning # Question - Namespace declaration preferences
|
||||
dotnet_diagnostic.IDE0270.severity = none # Question - Null check can be simplified
|
||||
dotnet_diagnostic.IDE0300.severity = none # Question - Collection initialization can be simplified
|
||||
dotnet_diagnostic.IDE1006.severity = none # Question - Use collection expression for builder dotnet_style_prefer_collection_expression
|
||||
dotnet_style_null_propagation = false # Question
|
||||
dotnet_style_object_initializer = false # Question
|
||||
dotnet_style_prefer_auto_properties = false # Question
|
||||
dotnet_style_allow_statement_immediately_after_block_experimental = true # Question
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = false:warning # Question
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = false # Question
|
@ -1,13 +1,37 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Globalization;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250218
|
||||
{
|
||||
internal static partial class Helper20250218 {
|
||||
|
||||
private static void MoveToArchive(ILogger<Worker> logger, string searchMES, string searchSequence, string destinationRoot, string[] files)
|
||||
{
|
||||
internal static void MoveToArchive(ILogger<Worker> logger, List<string> args) {
|
||||
string checkDirectory;
|
||||
string searchMES = args[4];
|
||||
string searchPattern = args[3];
|
||||
string searchSequence = args[5];
|
||||
string destinationRoot = args[6];
|
||||
string checkDirectoryName = args[2];
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string directory in directories) {
|
||||
checkDirectory = Path.Combine(directory, checkDirectoryName);
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
continue;
|
||||
MoveToArchive(logger, searchPattern, searchMES, searchSequence, destinationRoot, checkDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
private static void MoveToArchive(ILogger<Worker> logger, string searchPattern, string searchMES, string searchSequence, string destinationRoot, string checkDirectory) {
|
||||
string[] files = Directory.GetFiles(checkDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
if (files.Length == 0)
|
||||
logger.LogInformation("<{files}>(s)", files.Length);
|
||||
else
|
||||
MoveToArchive(logger, searchMES, searchSequence, destinationRoot, files);
|
||||
}
|
||||
|
||||
private static void MoveToArchive(ILogger<Worker> logger, string searchMES, string searchSequence, string destinationRoot, string[] files) {
|
||||
string mes;
|
||||
string text;
|
||||
string sequence;
|
||||
@ -20,8 +44,7 @@ internal static partial class Helper20250218
|
||||
string[] segmentsC;
|
||||
string checkDirectory;
|
||||
Calendar calendar = new CultureInfo("en-US").Calendar;
|
||||
foreach (string file in files)
|
||||
{
|
||||
foreach (string file in files) {
|
||||
fileInfo = new(file);
|
||||
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
|
||||
continue;
|
||||
@ -37,20 +60,17 @@ internal static partial class Helper20250218
|
||||
segmentsC = Path.GetFileName(fileInfo.DirectoryName).Split('-');
|
||||
weekOfYear = $"{fileInfo.LastWriteTime.Year}_Week_{calendar.GetWeekOfYear(fileInfo.LastWriteTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
|
||||
checkDirectory = Path.GetFullPath(Path.Combine(destinationRoot, mes, weekOfYear, fileInfo.LastWriteTime.ToString("yyyy-MM-dd")));
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
{
|
||||
if (!Directory.Exists(checkDirectory)) {
|
||||
logger.LogInformation("<{checkDirectory}>", checkDirectory);
|
||||
continue;
|
||||
}
|
||||
matches = Directory.GetDirectories(checkDirectory, sequence, SearchOption.AllDirectories);
|
||||
if (matches.Length != 1)
|
||||
{
|
||||
if (matches.Length != 1) {
|
||||
logger.LogInformation("!= 1 <{checkDirectory}>", checkDirectory);
|
||||
continue;
|
||||
}
|
||||
checkFile = segmentsC.Length == 2 ? Path.Combine(matches[0], $"csv-{segmentsC[1]}-{fileInfo.Name}") : Path.Combine(matches[0], $"csv-{fileInfo.Name}");
|
||||
if (File.Exists(checkFile))
|
||||
{
|
||||
if (File.Exists(checkFile)) {
|
||||
logger.LogInformation("csv- {segmentsC} <{checkDirectory}>", segmentsC.Length, checkDirectory);
|
||||
continue;
|
||||
}
|
||||
@ -58,18 +78,6 @@ internal static partial class Helper20250218
|
||||
}
|
||||
}
|
||||
|
||||
internal static void MoveToArchive(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
string searchMES = args[3];
|
||||
string searchPattern = args[2];
|
||||
string searchSequence = args[4];
|
||||
string destinationRoot = args[5];
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
logger.LogInformation("<{files}>(s)", files.Length);
|
||||
MoveToArchive(logger, searchMES, searchSequence, destinationRoot, files);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// L:\DevOps\MESA_FI\file-folder-helper\bin\Debug\net8.0\win-x64>dotnet File-Folder-Helper.dll X D:/Tmp Day-Helper-2025-02-18 *.pdsf A_MES_ENTITY= B_SEQUENCE= \\mesfs.infineon.com\EC_Characterization_Si\Archive
|
||||
// L:\DevOps\MESA_FI\file-folder-helper\bin\Debug\net8.0\win-x64>dotnet File-Folder-Helper.dll X \\mesfs.infineon.com\EC_EDA\Production\Traces Day-Helper-2025-02-18 Source *.pdsf A_MES_ENTITY= B_SEQUENCE= \\mesfs.infineon.com\EC_Characterization_Si\Archive
|
@ -1,111 +1,288 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250219
|
||||
{
|
||||
internal static partial class Helper20250219 {
|
||||
|
||||
private record ProcessDataStandardFormat(ReadOnlyCollection<string> Body,
|
||||
ReadOnlyCollection<string> Columns,
|
||||
string Logistics);
|
||||
ReadOnlyCollection<string> Logistics,
|
||||
long? Sequence);
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(JsonElement[]))]
|
||||
private partial class JsonElementCollectionSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
private partial class JsonElementCollectionSourceGenerationContext : JsonSerializerContext {
|
||||
}
|
||||
|
||||
private static ProcessDataStandardFormat GetLogisticsColumnsAndBody(string path, string[]? lines)
|
||||
{
|
||||
ProcessDataStandardFormat result;
|
||||
string segment;
|
||||
List<string> body = [];
|
||||
List<string> columns = [];
|
||||
StringBuilder logistics = new();
|
||||
lines ??= File.ReadAllLines(path);
|
||||
string[] segments;
|
||||
if (lines.Length < 7)
|
||||
segments = [];
|
||||
else
|
||||
segments = lines[6].Trim().Split('\t');
|
||||
for (int c = 0; c < segments.Length; c++)
|
||||
{
|
||||
segment = segments[c][1..^1];
|
||||
if (!columns.Contains(segment))
|
||||
columns.Add(segment);
|
||||
else
|
||||
{
|
||||
for (short i = 1; i < short.MaxValue; i++)
|
||||
{
|
||||
segment = string.Concat(segment, "_", i);
|
||||
if (!columns.Contains(segment))
|
||||
{
|
||||
columns.Add(segment);
|
||||
break;
|
||||
private record ProcessDataStandardFormatMapping(ReadOnlyCollection<string> BackfillColumns,
|
||||
ReadOnlyCollection<int> ColumnIndices,
|
||||
ReadOnlyCollection<string> IgnoreColumns,
|
||||
ReadOnlyCollection<string> IndexOnlyColumns,
|
||||
ReadOnlyDictionary<string, string> KeyValuePairs,
|
||||
ReadOnlyCollection<string> NewColumnNames,
|
||||
ReadOnlyCollection<string> OldColumnNames);
|
||||
|
||||
internal static void Compare(ILogger<Worker> logger, List<string> args) {
|
||||
string[] segmentsB;
|
||||
List<string> distinct = [];
|
||||
string searchPattern = args[2];
|
||||
string searchPatternB = args[3];
|
||||
string[] segments = args[7].Split(',');
|
||||
Dictionary<string, string> keyValuePairs = [];
|
||||
ReadOnlyCollection<string> ignore = args[4].Split(',').AsReadOnly();
|
||||
ReadOnlyCollection<string> backfill = args[5].Split(',').AsReadOnly();
|
||||
ReadOnlyCollection<string> indexOnly = args[6].Split(',').AsReadOnly();
|
||||
ReadOnlyCollection<string> oldColumnNames = args[8].Split(',').AsReadOnly();
|
||||
ReadOnlyCollection<string> newColumnNames = args[9].Split(',').AsReadOnly();
|
||||
ReadOnlyCollection<int> columnIndices = args[10].Split(',').Select(int.Parse).ToArray().AsReadOnly();
|
||||
foreach (string segment in segments) {
|
||||
segmentsB = segment.Split('|');
|
||||
if (segmentsB.Length != 2)
|
||||
continue;
|
||||
if (distinct.Contains(segmentsB[0]))
|
||||
continue;
|
||||
distinct.Add(segmentsB[0]);
|
||||
keyValuePairs.Add(segmentsB[0], segmentsB[1]);
|
||||
}
|
||||
ProcessDataStandardFormatMapping processDataStandardFormatMapping = new(BackfillColumns: backfill,
|
||||
ColumnIndices: columnIndices,
|
||||
NewColumnNames: newColumnNames,
|
||||
IgnoreColumns: ignore,
|
||||
IndexOnlyColumns: indexOnly,
|
||||
KeyValuePairs: keyValuePairs.AsReadOnly(),
|
||||
OldColumnNames: oldColumnNames);
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
logger.LogInformation("<{files}>(s)", files.Length);
|
||||
Compare(logger, sourceDirectory.Length, searchPatternB, processDataStandardFormatMapping, files);
|
||||
}
|
||||
|
||||
private static void Compare(ILogger<Worker> logger, int sourceDirectoryLength, string searchPattern, ProcessDataStandardFormatMapping pdsfMapping, string[] files) {
|
||||
bool compare;
|
||||
string directory;
|
||||
string[] matches;
|
||||
string directorySegment;
|
||||
string[] directoryFiles;
|
||||
const int columnsLine = 6;
|
||||
JsonElement[]? jsonElementsNew;
|
||||
JsonElement[]? jsonElementsOld;
|
||||
ProcessDataStandardFormat processDataStandardFormat;
|
||||
FileInfo[] collection = files.Select(l => new FileInfo(l)).ToArray();
|
||||
foreach (FileInfo fileInfo in collection) {
|
||||
directory = fileInfo.DirectoryName ?? throw new Exception();
|
||||
directoryFiles = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
matches = (from l in directoryFiles where l != fileInfo.FullName select l).ToArray();
|
||||
if (matches.Length < 1)
|
||||
continue;
|
||||
directorySegment = directory[sourceDirectoryLength..];
|
||||
processDataStandardFormat = GetProcessDataStandardFormat(logger, fileInfo.LastWriteTime, pdsfMapping.NewColumnNames.Count, columnsLine, fileInfo.FullName, lines: null);
|
||||
jsonElementsNew = GetArray(logger, pdsfMapping.NewColumnNames.Count, processDataStandardFormat, lookForNumbers: false);
|
||||
if (jsonElementsNew is null)
|
||||
continue;
|
||||
if (pdsfMapping.OldColumnNames.Count == pdsfMapping.ColumnIndices.Count) {
|
||||
processDataStandardFormat = GetProcessDataStandardFormat(logger, pdsfMapping, jsonElementsNew, processDataStandardFormat);
|
||||
Write(logger, fileInfo, processDataStandardFormat);
|
||||
}
|
||||
}
|
||||
bool lookForLogistics = false;
|
||||
for (int r = 7; r < lines.Length; r++)
|
||||
{
|
||||
if (lines[r].StartsWith("NUM_DATA_ROWS"))
|
||||
lookForLogistics = true;
|
||||
if (!lookForLogistics)
|
||||
{
|
||||
body.Add(lines[r]);
|
||||
foreach (string match in matches) {
|
||||
processDataStandardFormat = GetProcessDataStandardFormat(logger, fileInfo.LastWriteTime, pdsfMapping.OldColumnNames.Count, columnsLine, match, lines: null);
|
||||
jsonElementsOld = GetArray(logger, pdsfMapping.OldColumnNames.Count, processDataStandardFormat, lookForNumbers: false);
|
||||
if (jsonElementsOld is null || jsonElementsOld.Length != jsonElementsNew.Length) {
|
||||
logger.LogWarning("! <{match}> (jsonElementsOld.Length:{jsonElementsOld} != jsonElementsNew.Length:{jsonElementsNew})", match, jsonElementsOld?.Length, jsonElementsNew.Length);
|
||||
continue;
|
||||
}
|
||||
if (lines[r].StartsWith("LOGISTICS_1"))
|
||||
{
|
||||
for (int i = r; i < lines.Length; i++)
|
||||
{
|
||||
if (lines[r].StartsWith("END_HEADER"))
|
||||
break;
|
||||
_ = logistics.AppendLine(lines[i]);
|
||||
compare = Compare(logger, pdsfMapping, directorySegment, jsonElementsNew, jsonElementsOld);
|
||||
if (!compare) {
|
||||
logger.LogWarning("! <{match}>", match);
|
||||
continue;
|
||||
}
|
||||
logger.LogInformation("<{match}>", match);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool Compare(ILogger<Worker> logger, ProcessDataStandardFormatMapping processDataStandardFormatMapping, string directory, JsonElement[] jsonElementsNew, JsonElement[] jsonElementsOld) {
|
||||
bool result;
|
||||
int? q;
|
||||
string valueNew;
|
||||
string valueOld;
|
||||
List<string> columns = [];
|
||||
JsonProperty jsonPropertyOld;
|
||||
JsonProperty jsonPropertyNew;
|
||||
List<string> columnPairs = [];
|
||||
JsonProperty[] jsonPropertiesOld;
|
||||
JsonProperty[] jsonPropertiesNew;
|
||||
List<string> unknownColumns = [];
|
||||
List<string> differentColumns = [];
|
||||
int last = jsonElementsOld.Length - 1;
|
||||
List<string> sameAfterSpaceSplitColumns = [];
|
||||
for (int i = last; i > -1; i--) {
|
||||
if (jsonElementsOld[i].ValueKind != JsonValueKind.Object) {
|
||||
unknownColumns.Add(string.Empty);
|
||||
break;
|
||||
}
|
||||
jsonPropertiesOld = jsonElementsOld[i].EnumerateObject().ToArray();
|
||||
jsonPropertiesNew = jsonElementsNew[i].EnumerateObject().ToArray();
|
||||
for (int p = 0; p < jsonPropertiesOld.Length; p++) {
|
||||
jsonPropertyOld = jsonPropertiesOld[p];
|
||||
valueOld = jsonPropertyOld.Value.ToString();
|
||||
if (processDataStandardFormatMapping.KeyValuePairs.TryGetValue(jsonPropertyOld.Name, out string? name) && !string.IsNullOrEmpty(name)) {
|
||||
q = TryGetPropertyIndex(jsonPropertiesNew, name);
|
||||
if (q is null && i == 0)
|
||||
unknownColumns.Add($"{jsonPropertyOld.Name}|{name}");
|
||||
} else {
|
||||
q = TryGetPropertyIndex(jsonPropertiesNew, jsonPropertyOld.Name);
|
||||
if (q is null) {
|
||||
if (i == 0)
|
||||
unknownColumns.Add(jsonPropertyOld.Name);
|
||||
}
|
||||
result = new(Body: body.AsReadOnly(),
|
||||
Columns: columns.AsReadOnly(),
|
||||
logistics.ToString());
|
||||
}
|
||||
if (q is null) {
|
||||
if (processDataStandardFormatMapping.IgnoreColumns.Contains(jsonPropertyOld.Name)) {
|
||||
if (i == last) {
|
||||
columns.Add("-1");
|
||||
columnPairs.Add($"{jsonPropertyOld.Name}:");
|
||||
logger.LogDebug("{p} )) {jsonPropertyOld.Name} **", p, jsonPropertyOld.Name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (i == last) {
|
||||
columns.Add("-1");
|
||||
columnPairs.Add($"{jsonPropertyOld.Name}:");
|
||||
if (!string.IsNullOrEmpty(valueOld))
|
||||
logger.LogDebug("{p} )) {jsonPropertyOld.Name} ??", p, jsonPropertyOld.Name);
|
||||
}
|
||||
} else {
|
||||
jsonPropertyNew = jsonPropertiesNew[q.Value];
|
||||
if (i == last) {
|
||||
columns.Add(q.Value.ToString());
|
||||
columnPairs.Add($"{jsonPropertyOld.Name}:{jsonPropertyNew.Name}");
|
||||
}
|
||||
valueNew = jsonPropertyNew.Value.ToString();
|
||||
if (i == last)
|
||||
logger.LogDebug("{p} )) {jsonPropertyOld.Name} ~~ {q.Value} => {jsonPropertyNew.Name}", p, jsonPropertyOld.Name, q.Value, jsonPropertyNew.Name);
|
||||
if (valueNew != valueOld && !differentColumns.Contains(jsonPropertyOld.Name)) {
|
||||
if (valueNew.Length >= 2 && valueNew.Split(' ')[0] == valueOld)
|
||||
sameAfterSpaceSplitColumns.Add(jsonPropertyOld.Name);
|
||||
else {
|
||||
if (processDataStandardFormatMapping.BackfillColumns.Contains(jsonPropertyOld.Name) && i != last)
|
||||
continue;
|
||||
if (processDataStandardFormatMapping.IndexOnlyColumns.Contains(jsonPropertyOld.Name) && int.TryParse(jsonPropertyOld.Name[^2..], out int index) && i != index - 1)
|
||||
continue;
|
||||
logger.LogWarning("For [{jsonProperty.Name}] <{directory}> doesn't match (valueNew:{valueNew} != valueOld:{valueOld})!", jsonPropertyOld.Name, directory, valueNew, valueOld);
|
||||
differentColumns.Add(jsonPropertyOld.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i == last) {
|
||||
logger.LogInformation(string.Join(',', columns));
|
||||
logger.LogInformation($"{string.Join(';', columnPairs)};");
|
||||
}
|
||||
}
|
||||
result = unknownColumns.Count == 0 && differentColumns.Count == 0 && sameAfterSpaceSplitColumns.Count == 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static JsonElement[]? GetArray(ProcessDataStandardFormat processDataStandardFormat, bool lookForNumbers = false)
|
||||
{
|
||||
private static int? TryGetPropertyIndex(JsonProperty[] jsonProperties, string propertyName) {
|
||||
int? result = null;
|
||||
for (int i = 0; i < jsonProperties.Length; i++) {
|
||||
if (jsonProperties[i].Name != propertyName)
|
||||
continue;
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
if (result is null) {
|
||||
for (int i = 0; i < jsonProperties.Length; i++) {
|
||||
if (jsonProperties[i].Name[0] != propertyName[0])
|
||||
continue;
|
||||
if (jsonProperties[i].Name.Length != propertyName.Length)
|
||||
continue;
|
||||
if (jsonProperties[i].Name != propertyName)
|
||||
continue;
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ProcessDataStandardFormat GetProcessDataStandardFormat(ILogger<Worker> logger, DateTime lastWriteTime, int expectedColumns, int columnsLine, string path, string[]? lines) {
|
||||
ProcessDataStandardFormat result;
|
||||
long sequence;
|
||||
string[] segments;
|
||||
List<string> body = [];
|
||||
List<string> logistics = [];
|
||||
bool lookForLogistics = false;
|
||||
lines ??= File.ReadAllLines(path);
|
||||
if (lines.Length <= columnsLine)
|
||||
segments = [];
|
||||
else {
|
||||
segments = lines[columnsLine].Split('\t');
|
||||
if (segments.Length != expectedColumns) {
|
||||
logger.LogWarning("{segments} != {expectedColumns}", segments.Length, expectedColumns);
|
||||
segments = [];
|
||||
}
|
||||
}
|
||||
string[] columns = segments.Select(l => l.Trim('"')).ToArray();
|
||||
for (int r = columnsLine + 1; r < lines.Length; r++) {
|
||||
if (lines[r].StartsWith("NUM_DATA_ROWS"))
|
||||
lookForLogistics = true;
|
||||
if (!lookForLogistics) {
|
||||
body.Add(lines[r]);
|
||||
continue;
|
||||
}
|
||||
if (lines[r].StartsWith("LOGISTICS_1")) {
|
||||
for (int i = r; i < lines.Length; i++) {
|
||||
if (lines[r].StartsWith("END_HEADER"))
|
||||
break;
|
||||
logistics.Add(lines[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (logistics.Count == 0)
|
||||
sequence = lastWriteTime.Ticks;
|
||||
else {
|
||||
segments = logistics[0].Split("SEQUENCE=");
|
||||
sequence = segments.Length < 2 || !long.TryParse(segments[1].Split(';')[0], out long s) ? lastWriteTime.Ticks : s;
|
||||
}
|
||||
result = new(Body: body.AsReadOnly(),
|
||||
Columns: columns.AsReadOnly(),
|
||||
Logistics: logistics.AsReadOnly(),
|
||||
Sequence: sequence);
|
||||
return result;
|
||||
}
|
||||
|
||||
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();
|
||||
else
|
||||
{
|
||||
else {
|
||||
string value;
|
||||
string[] segments;
|
||||
List<string> lines = [];
|
||||
StringBuilder stringBuilder = new();
|
||||
foreach (string bodyLine in processDataStandardFormat.Body)
|
||||
{
|
||||
foreach (string bodyLine in processDataStandardFormat.Body) {
|
||||
_ = stringBuilder.Clear();
|
||||
_ = stringBuilder.Append('{');
|
||||
segments = bodyLine.Trim().Split('\t');
|
||||
if (!lookForNumbers)
|
||||
{
|
||||
for (int c = 1; c < segments.Length; c++)
|
||||
{
|
||||
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
|
||||
segments = bodyLine.Split('\t');
|
||||
if (segments.Length != expectedColumns) {
|
||||
logger.LogWarning("{segments} != {expectedColumns}", segments.Length, expectedColumns);
|
||||
continue;
|
||||
}
|
||||
if (!lookForNumbers) {
|
||||
for (int c = 0; c < segments.Length; c++) {
|
||||
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\",");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int c = 1; c < segments.Length; c++)
|
||||
{
|
||||
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
|
||||
} else {
|
||||
for (int c = 0; c < segments.Length; c++) {
|
||||
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
if (string.IsNullOrEmpty(value))
|
||||
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,");
|
||||
else if (value.All(char.IsDigit))
|
||||
@ -124,182 +301,72 @@ internal static partial class Helper20250219
|
||||
return results;
|
||||
}
|
||||
|
||||
private static int? TryGetPropertyIndex(JsonProperty[] jsonProperties, string propertyName)
|
||||
{
|
||||
int? result = null;
|
||||
for (int i = 0; i < jsonProperties.Length; i++)
|
||||
{
|
||||
if (jsonProperties[i].Name != propertyName)
|
||||
continue;
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
if (result is null)
|
||||
{
|
||||
for (int i = 0; i < jsonProperties.Length; i++)
|
||||
{
|
||||
if (jsonProperties[i].Name[0] != propertyName[0])
|
||||
continue;
|
||||
if (jsonProperties[i].Name.Length != propertyName.Length)
|
||||
continue;
|
||||
if (jsonProperties[i].Name != propertyName)
|
||||
continue;
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool Compare(ILogger<Worker> logger, ReadOnlyCollection<string> ignore, ReadOnlyCollection<string> backfill, ReadOnlyCollection<string> indexOnly, ReadOnlyDictionary<string, string> keyValuePairs, string directory, JsonElement[] jsonElementsNew, JsonElement[] jsonElementsOld)
|
||||
{
|
||||
bool result;
|
||||
int? q;
|
||||
string valueNew;
|
||||
string valueOld;
|
||||
JsonProperty jsonPropertyOld;
|
||||
JsonProperty jsonPropertyNew;
|
||||
JsonProperty[] jsonPropertiesOld;
|
||||
JsonProperty[] jsonPropertiesNew;
|
||||
private static ProcessDataStandardFormat GetProcessDataStandardFormat(ILogger<Worker> logger, ProcessDataStandardFormatMapping processDataStandardFormatMapping, JsonElement[] jsonElements, ProcessDataStandardFormat processDataStandardFormat) {
|
||||
ProcessDataStandardFormat result;
|
||||
int column;
|
||||
string value;
|
||||
List<string> values = [];
|
||||
List<string> results = [];
|
||||
JsonProperty jsonProperty;
|
||||
JsonProperty[] jsonProperties;
|
||||
List<string> unknownColumns = [];
|
||||
List<string> differentColumns = [];
|
||||
int last = jsonElementsOld.Length - 1;
|
||||
List<string> sameAfterSpaceSplitColumns = [];
|
||||
for (int i = last; i > 0; i--)
|
||||
{
|
||||
if (jsonElementsOld[i].ValueKind != JsonValueKind.Object)
|
||||
{
|
||||
for (int i = 0; i < jsonElements.Length; i++) {
|
||||
values.Clear();
|
||||
if (jsonElements[i].ValueKind != JsonValueKind.Object) {
|
||||
unknownColumns.Add(string.Empty);
|
||||
break;
|
||||
}
|
||||
jsonPropertiesOld = jsonElementsOld[i].EnumerateObject().ToArray();
|
||||
jsonPropertiesNew = jsonElementsNew[i].EnumerateObject().ToArray();
|
||||
for (int p = 0; p < jsonPropertiesOld.Length; p++)
|
||||
{
|
||||
jsonPropertyOld = jsonPropertiesOld[p];
|
||||
valueOld = jsonPropertyOld.Value.ToString();
|
||||
if (ignore.Contains(jsonPropertyOld.Name))
|
||||
{
|
||||
if (i == last)
|
||||
logger.LogDebug("{p} )) {jsonPropertyOld.Name} **", p, jsonPropertyOld.Name);
|
||||
jsonProperties = jsonElements[i].EnumerateObject().ToArray();
|
||||
if (jsonProperties.Length != processDataStandardFormatMapping.NewColumnNames.Count) {
|
||||
logger.LogWarning("{jsonProperties} != {NewColumnNames}", jsonProperties.Length, processDataStandardFormatMapping.NewColumnNames.Count);
|
||||
continue;
|
||||
}
|
||||
if (keyValuePairs.TryGetValue(jsonPropertyOld.Name, out string? name) && !string.IsNullOrEmpty(name))
|
||||
{
|
||||
q = TryGetPropertyIndex(jsonPropertiesNew, name);
|
||||
if (q is null && i == 0)
|
||||
unknownColumns.Add($"{jsonPropertyOld.Name}|{name}");
|
||||
for (int c = 0; c < processDataStandardFormatMapping.ColumnIndices.Count; c++) {
|
||||
column = processDataStandardFormatMapping.ColumnIndices[c];
|
||||
if (column == -1)
|
||||
value = processDataStandardFormatMapping.OldColumnNames[c];
|
||||
else {
|
||||
jsonProperty = jsonProperties[column];
|
||||
value = jsonProperty.Value.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
q = TryGetPropertyIndex(jsonPropertiesNew, jsonPropertyOld.Name);
|
||||
if (q is null)
|
||||
{
|
||||
if (i == 0)
|
||||
unknownColumns.Add(jsonPropertyOld.Name);
|
||||
values.Add(value);
|
||||
}
|
||||
results.Add(string.Join('\t', values));
|
||||
}
|
||||
if (q is null)
|
||||
{
|
||||
if (i == last && !string.IsNullOrEmpty(valueOld))
|
||||
logger.LogDebug("{p} )) {jsonPropertyOld.Name} ??", p, jsonPropertyOld.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonPropertyNew = jsonPropertiesNew[q.Value];
|
||||
valueNew = jsonPropertyNew.Value.ToString();
|
||||
if (i == last)
|
||||
logger.LogDebug("{p} )) {jsonPropertyOld.Name} ~~ {q.Value} => {jsonPropertyNew.Name}", p, jsonPropertyOld.Name, q.Value, jsonPropertyNew.Name);
|
||||
if (valueNew != valueOld && !differentColumns.Contains(jsonPropertyOld.Name))
|
||||
{
|
||||
if (valueNew.Length >= 2 && valueNew.Split(' ')[0] == valueOld)
|
||||
sameAfterSpaceSplitColumns.Add(jsonPropertyOld.Name);
|
||||
else
|
||||
{
|
||||
if (backfill.Contains(jsonPropertyOld.Name) && i != last)
|
||||
continue;
|
||||
if (indexOnly.Contains(jsonPropertyOld.Name) && int.TryParse(jsonPropertyOld.Name[^2..], out int index) && i != index - 1)
|
||||
continue;
|
||||
logger.LogWarning("For [{jsonProperty.Name}] <{directory}> doesn't match (valueNew:{valueNew} != valueOld:{valueOld})!", jsonPropertyOld.Name, directory, valueNew, valueOld);
|
||||
differentColumns.Add(jsonPropertyOld.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = unknownColumns.Count == 0 && differentColumns.Count == 0 && sameAfterSpaceSplitColumns.Count == 0;
|
||||
result = new(Body: new(results),
|
||||
Columns: processDataStandardFormatMapping.OldColumnNames,
|
||||
Logistics: processDataStandardFormat.Logistics,
|
||||
Sequence: processDataStandardFormat.Sequence);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void Compare(ILogger<Worker> logger, int sourceDirectoryLength, ReadOnlyCollection<string> ignore, ReadOnlyCollection<string> backfill, ReadOnlyCollection<string> indexOnly, ReadOnlyDictionary<string, string> keyValuePairs, string searchPattern, string[] files)
|
||||
{
|
||||
bool isMatch;
|
||||
string directory;
|
||||
string[] matches;
|
||||
string directorySegment;
|
||||
string[] directoryFiles;
|
||||
JsonElement[]? jsonElementsNew;
|
||||
JsonElement[]? jsonElementsOld;
|
||||
ProcessDataStandardFormat processDataStandardFormat;
|
||||
FileInfo[] collection = files.Select(l => new FileInfo(l)).ToArray();
|
||||
string[] sorted = (from l in collection orderby l.CreationTime descending select l.FullName).ToArray();
|
||||
foreach (string file in sorted)
|
||||
{
|
||||
directory = Path.GetDirectoryName(file) ?? throw new Exception();
|
||||
directoryFiles = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
matches = (from l in directoryFiles where l != file select l).ToArray();
|
||||
if (matches.Length < 1)
|
||||
continue;
|
||||
directorySegment = directory[sourceDirectoryLength..];
|
||||
processDataStandardFormat = GetLogisticsColumnsAndBody(file, lines: null);
|
||||
jsonElementsNew = GetArray(processDataStandardFormat);
|
||||
if (jsonElementsNew is null)
|
||||
continue;
|
||||
foreach (string match in matches)
|
||||
{
|
||||
processDataStandardFormat = GetLogisticsColumnsAndBody(match, lines: null);
|
||||
jsonElementsOld = GetArray(processDataStandardFormat);
|
||||
if (jsonElementsOld is null || jsonElementsOld.Length != jsonElementsNew.Length)
|
||||
{
|
||||
logger.LogWarning("! <{match}> (jsonElementsOld.Length:{jsonElementsOld} != jsonElementsNew.Length:{jsonElementsNew})", match, jsonElementsOld?.Length, jsonElementsNew.Length);
|
||||
continue;
|
||||
}
|
||||
isMatch = Compare(logger, ignore, backfill, indexOnly, keyValuePairs, directorySegment, jsonElementsNew, jsonElementsOld);
|
||||
if (!isMatch)
|
||||
{
|
||||
logger.LogWarning("! <{match}>", match);
|
||||
continue;
|
||||
}
|
||||
logger.LogInformation("<{match}>", match);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Compare(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
string[] segmentsB;
|
||||
List<string> distinct = [];
|
||||
string searchPattern = args[2];
|
||||
string searchPatternB = args[3];
|
||||
string[] segments = args[7].Split(',');
|
||||
Dictionary<string, string> keyValuePairs = [];
|
||||
ReadOnlyCollection<string> ignore = args[4].Split(',').AsReadOnly();
|
||||
ReadOnlyCollection<string> backfill = args[5].Split(',').AsReadOnly();
|
||||
ReadOnlyCollection<string> indexOnly = args[6].Split(',').AsReadOnly();
|
||||
foreach (string segment in segments)
|
||||
{
|
||||
segmentsB = segment.Split('|');
|
||||
if (segmentsB.Length != 2)
|
||||
continue;
|
||||
if (distinct.Contains(segmentsB[0]))
|
||||
continue;
|
||||
distinct.Add(segmentsB[0]);
|
||||
keyValuePairs.Add(segmentsB[0], segmentsB[1]);
|
||||
}
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
logger.LogInformation("<{files}>(s)", files.Length);
|
||||
Compare(logger, sourceDirectory.Length, ignore, backfill, indexOnly, keyValuePairs.AsReadOnly(), searchPatternB, files);
|
||||
private static void Write(ILogger<Worker> logger, FileInfo fileInfo, ProcessDataStandardFormat processDataStandardFormat) {
|
||||
List<string> results = [];
|
||||
if (processDataStandardFormat.Sequence is null)
|
||||
throw new NullReferenceException(nameof(processDataStandardFormat.Sequence));
|
||||
string endOffset = "E#######T";
|
||||
string dataOffset = "D#######T";
|
||||
string headerOffset = "H#######T";
|
||||
string format = "MM/dd/yyyy HH:mm:ss";
|
||||
string startTime = new DateTime(processDataStandardFormat.Sequence.Value).ToString(format);
|
||||
results.Add("HEADER_TAG\tHEADER_VALUE");
|
||||
results.Add("FORMAT\t2.00");
|
||||
results.Add("NUMBER_PASSES\t0001");
|
||||
results.Add($"HEADER_OFFSET\t{headerOffset}");
|
||||
results.Add($"DATA_OFFSET\t{dataOffset}");
|
||||
results.Add($"END_OFFSET\t{endOffset}");
|
||||
results.Add($"\"{string.Join("\"\t\"", processDataStandardFormat.Columns)}\"");
|
||||
results.AddRange(processDataStandardFormat.Body);
|
||||
results.Add($"NUM_DATA_ROWS\t{processDataStandardFormat.Body.Count.ToString().PadLeft(9, '0')}");
|
||||
results.Add($"NUM_DATA_COLUMNS\t{processDataStandardFormat.Columns.Count.ToString().PadLeft(9, '0')}");
|
||||
results.Add("DELIMITER\t;");
|
||||
results.Add($"START_TIME_FORMAT\t{format}");
|
||||
results.Add($"START_TIME\t{startTime}");
|
||||
results.Add("LOGISTICS_COLUMN\tA_LOGISTICS");
|
||||
results.Add("LOGISTICS_COLUMN\tB_LOGISTICS");
|
||||
results.AddRange(processDataStandardFormat.Logistics);
|
||||
File.WriteAllText($"{fileInfo.FullName}.tsv", string.Join(Environment.NewLine, results));
|
||||
logger.LogDebug("<{fileInfo}>", fileInfo);
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +1,35 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250228
|
||||
{
|
||||
internal static partial class Helper20250228 {
|
||||
|
||||
private record Record(string TableName, ReadOnlyCollection<string> Columns, ReadOnlyCollection<string[]> Rows);
|
||||
|
||||
private static ReadOnlyCollection<Record> GetRecords(string headerA, string headerB, string file)
|
||||
{
|
||||
internal static void PostgresDumpToJson(ILogger<Worker> logger, List<string> args) {
|
||||
string searchPattern = args[2];
|
||||
string headerA = args[3].Replace('_', ' ');
|
||||
string headerB = args[4].Replace('_', ' ');
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
if (files.Length != 1)
|
||||
logger.LogWarning("<{files}>(s)", files.Length);
|
||||
else
|
||||
PostgresDumpToJson(logger, headerA, headerB, files[0]);
|
||||
}
|
||||
|
||||
private static void PostgresDumpToJson(ILogger<Worker> logger, string headerA, string headerB, string file) {
|
||||
ReadOnlyCollection<Record> records = GetRecords(headerA, headerB, file);
|
||||
if (records.Count > 0)
|
||||
WriteFile(file, records);
|
||||
else
|
||||
logger.LogWarning("<{records}>(s)", records.Count);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetRecords(string headerA, string headerB, string file) {
|
||||
List<Record> results = [];
|
||||
string line;
|
||||
string[] segmentsA;
|
||||
@ -23,11 +42,9 @@ internal static partial class Helper20250228
|
||||
string? tableName = null;
|
||||
string[] lines = File.ReadAllLines(file);
|
||||
ReadOnlyCollection<string>? columns = null;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
for (int i = 0; i < lines.Length; i++) {
|
||||
line = lines[i];
|
||||
if (tableName is null)
|
||||
{
|
||||
if (tableName is null) {
|
||||
segmentsA = line.Split(headerA);
|
||||
if (segmentsA.Length != 2)
|
||||
continue;
|
||||
@ -45,18 +62,14 @@ internal static partial class Helper20250228
|
||||
continue;
|
||||
segmentsE = segmentsB[0].Split(' ');
|
||||
tableName = segmentsE[0];
|
||||
}
|
||||
else if (columns is null)
|
||||
} else if (columns is null)
|
||||
break;
|
||||
else
|
||||
{
|
||||
else {
|
||||
rows = [];
|
||||
for (int j = i + 1; j < lines.Length; j++)
|
||||
{
|
||||
for (int j = i + 1; j < lines.Length; j++) {
|
||||
i = j;
|
||||
segmentsF = lines[j].Split('\t');
|
||||
if (segmentsF.Length != columns.Count)
|
||||
{
|
||||
if (segmentsF.Length != columns.Count) {
|
||||
if (rows.Count > 0)
|
||||
results.Add(new(TableName: tableName, Columns: columns, Rows: rows.AsReadOnly()));
|
||||
break;
|
||||
@ -70,26 +83,24 @@ internal static partial class Helper20250228
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void WriteFile(string file, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
private static void WriteFile(string file, ReadOnlyCollection<Record> records) {
|
||||
List<string> results = [];
|
||||
string json;
|
||||
string text;
|
||||
Dictionary<string, string?> keyValuePairs = [];
|
||||
foreach (Record record in records)
|
||||
{
|
||||
foreach (Record record in records) {
|
||||
results.Clear();
|
||||
foreach (string[] row in record.Rows)
|
||||
{
|
||||
foreach (string[] row in record.Rows) {
|
||||
keyValuePairs.Clear();
|
||||
for (int i = 0; i < row.Length; i++)
|
||||
{
|
||||
for (int i = 0; i < row.Length; i++) {
|
||||
if (row[i] == "\\N")
|
||||
keyValuePairs.Add(record.Columns[i], null);
|
||||
else
|
||||
keyValuePairs.Add(record.Columns[i], row[i]);
|
||||
}
|
||||
#pragma warning disable IL3050, IL2026
|
||||
json = JsonSerializer.Serialize(keyValuePairs);
|
||||
#pragma warning restore IL3050, IL2026
|
||||
results.Add(json);
|
||||
}
|
||||
text = string.Join($",{Environment.NewLine}", results);
|
||||
@ -97,26 +108,4 @@ internal static partial class Helper20250228
|
||||
}
|
||||
}
|
||||
|
||||
private static void PostgresDumpToJson(ILogger<Worker> logger, string headerA, string headerB, string file)
|
||||
{
|
||||
ReadOnlyCollection<Record> records = GetRecords(headerA, headerB, file);
|
||||
if (records.Count > 0)
|
||||
WriteFile(file, records);
|
||||
else
|
||||
logger.LogWarning("<{records}>(s)", records.Count);
|
||||
}
|
||||
|
||||
internal static void PostgresDumpToJson(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
string searchPattern = args[2];
|
||||
string headerA = args[3].Replace('_', ' ');
|
||||
string headerB = args[4].Replace('_', ' ');
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
if (files.Length != 1)
|
||||
logger.LogWarning("<{files}>(s)", files.Length);
|
||||
else
|
||||
PostgresDumpToJson(logger, headerA, headerB, files[0]);
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +1,12 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250301
|
||||
{
|
||||
internal static partial class Helper20250301 {
|
||||
|
||||
private static ReadOnlyCollection<string> CopyFiles(char split, string workingDirectory, string directory, string[] files)
|
||||
{
|
||||
List<string> results = [];
|
||||
string fileName;
|
||||
string checkFile;
|
||||
string checkDirectory = Path.Combine(workingDirectory, directory);
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
foreach (string file in files)
|
||||
{
|
||||
fileName = Path.GetFileName(file).Split(split)[^1];
|
||||
checkFile = Path.Combine(checkDirectory, fileName);
|
||||
if (File.Exists(checkFile))
|
||||
File.Delete(checkFile);
|
||||
File.Copy(file, checkFile);
|
||||
results.Add(fileName);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void PocketBaseImportWithDeno(ILogger<Worker> logger, char split, string workingDirectory, string scriptName, string directory, string[] files)
|
||||
{
|
||||
string checkFile = Path.Combine(workingDirectory, scriptName);
|
||||
if (!File.Exists(checkFile))
|
||||
logger.LogWarning("<{checkFile}> doesn't exist!", checkFile);
|
||||
else
|
||||
{
|
||||
ReadOnlyCollection<string> fileNames = CopyFiles(split, workingDirectory, directory, files);
|
||||
if (fileNames.Count == 0)
|
||||
logger.LogWarning("<{fileNames}>(s)", fileNames.Count);
|
||||
else
|
||||
{
|
||||
foreach (string fileName in fileNames)
|
||||
logger.LogInformation("deno run --unstable --allow-read --allow-env --allow-net {scriptName} --id=true --input={fileName}", scriptName, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void PocketBaseImportWithDeno(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
internal static void PocketBaseImportWithDeno(ILogger<Worker> logger, List<string> args) {
|
||||
char split = args[3][0];
|
||||
string directory = args[6];
|
||||
string scriptName = args[5];
|
||||
@ -59,4 +20,37 @@ internal static partial class Helper20250301
|
||||
PocketBaseImportWithDeno(logger, split, workingDirectory, scriptName, directory, files);
|
||||
}
|
||||
|
||||
private static void PocketBaseImportWithDeno(ILogger<Worker> logger, char split, string workingDirectory, string scriptName, string directory, string[] files) {
|
||||
string checkFile = Path.Combine(workingDirectory, scriptName);
|
||||
if (!File.Exists(checkFile))
|
||||
logger.LogWarning("<{checkFile}> doesn't exist!", checkFile);
|
||||
else {
|
||||
ReadOnlyCollection<string> fileNames = CopyFiles(split, workingDirectory, directory, files);
|
||||
if (fileNames.Count == 0)
|
||||
logger.LogWarning("<{fileNames}>(s)", fileNames.Count);
|
||||
else {
|
||||
foreach (string fileName in fileNames)
|
||||
logger.LogInformation("deno run --unstable --allow-read --allow-env --allow-net {scriptName} --id=true --input={fileName}", scriptName, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<string> CopyFiles(char split, string workingDirectory, string directory, string[] files) {
|
||||
List<string> results = [];
|
||||
string fileName;
|
||||
string checkFile;
|
||||
string checkDirectory = Path.Combine(workingDirectory, directory);
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
foreach (string file in files) {
|
||||
fileName = Path.GetFileName(file).Split(split)[^1];
|
||||
checkFile = Path.Combine(checkDirectory, fileName);
|
||||
if (File.Exists(checkFile))
|
||||
File.Delete(checkFile);
|
||||
File.Copy(file, checkFile);
|
||||
results.Add(fileName);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
}
|
@ -1,131 +1,19 @@
|
||||
using File_Folder_Helper.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
|
||||
using File_Folder_Helper.Models;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250305
|
||||
{
|
||||
internal static partial class Helper20250305 {
|
||||
|
||||
private static readonly HttpClient _HttpClient = new();
|
||||
|
||||
private record Record(Uri URI, string Path, DateTime LastModified, int? TotalSeconds);
|
||||
|
||||
private static ReadOnlyCollection<NginxFileSystem>? GetCollection(string format, TimeZoneInfo timeZoneInfo, Uri uri)
|
||||
{
|
||||
List<NginxFileSystem>? results;
|
||||
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(uri);
|
||||
taskHttpResponseMessage.Wait();
|
||||
if (!taskHttpResponseMessage.Result.IsSuccessStatusCode)
|
||||
results = null;
|
||||
else
|
||||
{
|
||||
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
taskString.Wait();
|
||||
if (taskString.Result.StartsWith('<'))
|
||||
results = null;
|
||||
else
|
||||
{
|
||||
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
|
||||
if (nginxFileSystems is null)
|
||||
results = null;
|
||||
else
|
||||
{
|
||||
results = [];
|
||||
NginxFileSystem nginxFileSystem;
|
||||
for (int i = 0; i < nginxFileSystems.Length; i++)
|
||||
{
|
||||
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
|
||||
results.Add(nginxFileSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return results?.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetRecords(string format, TimeZoneInfo timeZoneInfo, string host, ReadOnlyCollection<string> directoryNames, string compareDirectory)
|
||||
{
|
||||
List<Record> results = [];
|
||||
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}");
|
||||
ReadOnlyCollection<NginxFileSystem>? nginxFileSystems = GetCollection(format, timeZoneInfo, uri);
|
||||
if (nginxFileSystems is not null)
|
||||
{
|
||||
NginxFileSystem nginxFileSystem;
|
||||
ReadOnlyCollection<Record> records;
|
||||
string checkDirectory = $"{compareDirectory}\\{string.Join('\\', directoryNames)}";
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
for (int i = 0; i < nginxFileSystems.Count; i++)
|
||||
{
|
||||
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
|
||||
if (nginxFileSystem.Type == "file")
|
||||
{
|
||||
Record? record = CompareFile(host, directoryNames, compareDirectory, nginxFileSystem);
|
||||
if (record is not null)
|
||||
results.Add(record);
|
||||
}
|
||||
else
|
||||
{
|
||||
records = CompareDirectory(format, timeZoneInfo, host, directoryNames, compareDirectory, nginxFileSystem);
|
||||
foreach (Record record in records)
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> CompareDirectory(string format, TimeZoneInfo timeZoneInfo, string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem)
|
||||
{
|
||||
ReadOnlyCollection<Record> results;
|
||||
List<string> collection = directoryNames.ToList();
|
||||
collection.Add(nginxFileSystem.Name);
|
||||
results = GetRecords(format, timeZoneInfo, host, collection.AsReadOnly(), compareDirectory);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Record? CompareFile(string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem)
|
||||
{
|
||||
Record? result;
|
||||
if (nginxFileSystem.LastModified is null || nginxFileSystem.Length is null)
|
||||
result = null;
|
||||
else
|
||||
{
|
||||
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}/{nginxFileSystem.Name}");
|
||||
FileInfo fileInfo = new($"{compareDirectory}\\{string.Join('\\', directoryNames)}\\{nginxFileSystem.Name}");
|
||||
if (!fileInfo.Exists)
|
||||
result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: null);
|
||||
else
|
||||
{
|
||||
int totalSeconds = (int)new TimeSpan(fileInfo.LastWriteTime.Ticks - nginxFileSystem.LastModified.Value.Ticks).TotalSeconds;
|
||||
if (totalSeconds is not < 2 or not > -2)
|
||||
result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: totalSeconds);
|
||||
else if (fileInfo.Length != nginxFileSystem.Length.Value)
|
||||
result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: 0);
|
||||
else
|
||||
result = null;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void Download(Record record)
|
||||
{
|
||||
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(record.URI);
|
||||
taskHttpResponseMessage.Wait();
|
||||
if (taskHttpResponseMessage.Result.IsSuccessStatusCode)
|
||||
{
|
||||
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
taskString.Wait();
|
||||
File.WriteAllText(record.Path, taskString.Result);
|
||||
File.SetLastWriteTime(record.Path, record.LastModified);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void WriteNginxFileSystemDelta(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
internal static void WriteNginxFileSystemDelta(ILogger<Worker> logger, List<string> args) {
|
||||
string host = args[2];
|
||||
string rootDirectoryName = args[3];
|
||||
string format = NginxFileSystem.GetFormat();
|
||||
@ -136,8 +24,7 @@ internal static partial class Helper20250305
|
||||
#if ShellProgressBar
|
||||
ProgressBar progressBar = new(records.Count, "Downloading", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
|
||||
#endif
|
||||
foreach (Record record in records)
|
||||
{
|
||||
foreach (Record record in records) {
|
||||
#if ShellProgressBar
|
||||
progressBar.Tick();
|
||||
#endif
|
||||
@ -155,4 +42,99 @@ internal static partial class Helper20250305
|
||||
#endif
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetRecords(string format, TimeZoneInfo timeZoneInfo, string host, ReadOnlyCollection<string> directoryNames, string compareDirectory) {
|
||||
List<Record> results = [];
|
||||
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}");
|
||||
ReadOnlyCollection<NginxFileSystem>? nginxFileSystems = GetCollection(format, timeZoneInfo, uri);
|
||||
if (nginxFileSystems is not null) {
|
||||
NginxFileSystem nginxFileSystem;
|
||||
ReadOnlyCollection<Record> records;
|
||||
string checkDirectory = $"{compareDirectory}\\{string.Join('\\', directoryNames)}";
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
for (int i = 0; i < nginxFileSystems.Count; i++) {
|
||||
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
|
||||
if (nginxFileSystem.Type == "file") {
|
||||
Record? record = CompareFile(host, directoryNames, compareDirectory, nginxFileSystem);
|
||||
if (record is not null)
|
||||
results.Add(record);
|
||||
} else {
|
||||
records = CompareDirectory(format, timeZoneInfo, host, directoryNames, compareDirectory, nginxFileSystem);
|
||||
foreach (Record record in records)
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<NginxFileSystem>? GetCollection(string format, TimeZoneInfo timeZoneInfo, Uri uri) {
|
||||
List<NginxFileSystem>? results;
|
||||
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(uri);
|
||||
taskHttpResponseMessage.Wait();
|
||||
if (!taskHttpResponseMessage.Result.IsSuccessStatusCode)
|
||||
results = null;
|
||||
else {
|
||||
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
taskString.Wait();
|
||||
if (taskString.Result.StartsWith('<'))
|
||||
results = null;
|
||||
else {
|
||||
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
|
||||
if (nginxFileSystems is null)
|
||||
results = null;
|
||||
else {
|
||||
results = [];
|
||||
NginxFileSystem nginxFileSystem;
|
||||
for (int i = 0; i < nginxFileSystems.Length; i++) {
|
||||
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
|
||||
results.Add(nginxFileSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return results?.AsReadOnly();
|
||||
}
|
||||
|
||||
private static Record? CompareFile(string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem) {
|
||||
Record? result;
|
||||
if (nginxFileSystem.LastModified is null || nginxFileSystem.Length is null)
|
||||
result = null;
|
||||
else {
|
||||
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}/{nginxFileSystem.Name}");
|
||||
FileInfo fileInfo = new($"{compareDirectory}\\{string.Join('\\', directoryNames)}\\{nginxFileSystem.Name}");
|
||||
if (!fileInfo.Exists)
|
||||
result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: null);
|
||||
else {
|
||||
int totalSeconds = (int)new TimeSpan(fileInfo.LastWriteTime.Ticks - nginxFileSystem.LastModified.Value.Ticks).TotalSeconds;
|
||||
if (totalSeconds is not < 2 or not > -2)
|
||||
result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: totalSeconds);
|
||||
else if (fileInfo.Length != nginxFileSystem.Length.Value)
|
||||
result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: 0);
|
||||
else
|
||||
result = null;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> CompareDirectory(string format, TimeZoneInfo timeZoneInfo, string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem) {
|
||||
ReadOnlyCollection<Record> results;
|
||||
List<string> collection = directoryNames.ToList();
|
||||
collection.Add(nginxFileSystem.Name);
|
||||
results = GetRecords(format, timeZoneInfo, host, collection.AsReadOnly(), compareDirectory);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void Download(Record record) {
|
||||
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(record.URI);
|
||||
taskHttpResponseMessage.Wait();
|
||||
if (taskHttpResponseMessage.Result.IsSuccessStatusCode) {
|
||||
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
taskString.Wait();
|
||||
File.WriteAllText(record.Path, taskString.Result);
|
||||
File.SetLastWriteTime(record.Path, record.LastModified);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -2,94 +2,84 @@ using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250306
|
||||
{
|
||||
internal static partial class Helper20250306 {
|
||||
|
||||
private static int? GetProcessDataStandardFormatColumnTitlesLine(string[] lines)
|
||||
{
|
||||
int? result = null;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (lines[i].StartsWith("END_OFFSET") && i + 2 < lines.Length)
|
||||
{
|
||||
result = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string? ProcessDataStandardFormatToLastDataLine(string[] lines, int columnTitlesLine)
|
||||
{
|
||||
string? result = null;
|
||||
for (int i = columnTitlesLine + 1; i < lines.Length; i++)
|
||||
{
|
||||
if (lines[i].StartsWith("NUM_DATA_ROWS"))
|
||||
{
|
||||
result = lines[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string ProcessDataStandardFormatToJson(int columnTitlesLine, string[] columns, string[] lines)
|
||||
{
|
||||
#pragma warning disable CA1845, IDE0057
|
||||
string result = "[\n";
|
||||
string line;
|
||||
string value;
|
||||
string[] segments;
|
||||
if (columns.Length == 0)
|
||||
columns = lines[columnTitlesLine].Trim().Split('\t');
|
||||
for (int i = columnTitlesLine + 1; i < lines.Length; i++)
|
||||
{
|
||||
line = "{";
|
||||
segments = lines[i].Trim().Split('\t');
|
||||
if (segments.Length != columns.Length)
|
||||
break;
|
||||
for (int c = 1; c < segments.Length; c++)
|
||||
{
|
||||
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
|
||||
line += '"' + columns[c].Trim('"') + '"' + ':' + '"' + value + '"' + ',';
|
||||
}
|
||||
line = line.Substring(0, line.Length - 1) + '}' + ',' + '\n';
|
||||
result += line;
|
||||
}
|
||||
result = result.Substring(0, result.Length - 1) + ']';
|
||||
return result;
|
||||
#pragma warning restore CA1845, IDE0057
|
||||
}
|
||||
|
||||
private static void ProcessDataStandardFormatToJson(ILogger<Worker> logger, string file)
|
||||
{
|
||||
string[] lines = File.ReadAllLines(file);
|
||||
int? columnTitlesLine = GetProcessDataStandardFormatColumnTitlesLine(lines);
|
||||
if (columnTitlesLine is null)
|
||||
logger.LogWarning("<{columnTitlesLine}> is null", nameof(columnTitlesLine));
|
||||
else
|
||||
{
|
||||
string? text = ProcessDataStandardFormatToLastDataLine(lines, columnTitlesLine.Value);
|
||||
File.WriteAllText(".lbl", text);
|
||||
if (lines.Length < columnTitlesLine.Value + 1)
|
||||
logger.LogWarning("<{lines}>(s)", lines.Length);
|
||||
else
|
||||
{
|
||||
string json = ProcessDataStandardFormatToJson(columnTitlesLine.Value, [], lines);
|
||||
File.WriteAllText(".json", json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ProcessDataStandardFormatToJson(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
internal static void ProcessDataStandardFormatToJson(ILogger<Worker> logger, List<string> args) {
|
||||
string searchPattern = args[2];
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
if (files.Length != 1)
|
||||
logger.LogWarning("<{files}>(s)", files.Length);
|
||||
else
|
||||
ProcessDataStandardFormatToJson(logger, files[0]);
|
||||
}
|
||||
|
||||
private static void ProcessDataStandardFormatToJson(ILogger<Worker> logger, string file) {
|
||||
string[] lines = File.ReadAllLines(file);
|
||||
int? columnTitlesLine = GetProcessDataStandardFormatColumnTitlesLine(lines);
|
||||
if (columnTitlesLine is null)
|
||||
logger.LogWarning("<{columnTitlesLine}> is null", nameof(columnTitlesLine));
|
||||
else {
|
||||
string? text = ProcessDataStandardFormatToLastDataLine(lines, columnTitlesLine.Value);
|
||||
File.WriteAllText(Path.Combine(".vscode", "helper", ".lbl"), text);
|
||||
if (lines.Length < columnTitlesLine.Value + 1)
|
||||
logger.LogWarning("<{lines}>(s)", lines.Length);
|
||||
else {
|
||||
string json = ProcessDataStandardFormatToJson(columnTitlesLine.Value, [], lines);
|
||||
File.WriteAllText(Path.Combine(".vscode", "helper", ".json"), json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int? GetProcessDataStandardFormatColumnTitlesLine(string[] lines) {
|
||||
int? result = null;
|
||||
bool foundEndOfFile = false;
|
||||
for (int i = 0; i < lines.Length; i++) {
|
||||
if (lines[i] == "EOF")
|
||||
foundEndOfFile = true;
|
||||
if (foundEndOfFile && lines[i].StartsWith("END_OFFSET") && i + 3 < lines.Length) {
|
||||
result = i + 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string? ProcessDataStandardFormatToLastDataLine(string[] lines, int columnTitlesLine) {
|
||||
string? result = null;
|
||||
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
|
||||
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
||||
result = lines[i - 2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string ProcessDataStandardFormatToJson(int columnTitlesLine, string[] columns, string[] lines) {
|
||||
#pragma warning disable CA1845, IDE0057
|
||||
string result = "[\n";
|
||||
string line;
|
||||
string value;
|
||||
string[] segments;
|
||||
if (columns.Length == 0)
|
||||
columns = lines[columnTitlesLine].Trim().Split('|');
|
||||
int columnsLength = columns.Length - 2;
|
||||
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
|
||||
line = "{";
|
||||
segments = lines[i].Trim().Split('|');
|
||||
if (segments.Length != columnsLength)
|
||||
continue;
|
||||
for (int c = 1; c < segments.Length; c++) {
|
||||
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
line += '"' + columns[c].Trim('"') + '"' + ':' + '"' + value + '"' + ',';
|
||||
}
|
||||
line = line.Substring(0, line.Length - 1) + '}' + ',' + '\n';
|
||||
result += line;
|
||||
}
|
||||
result = result.Substring(0, result.Length - 2) + ']';
|
||||
return result;
|
||||
#pragma warning restore CA1845, IDE0057
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +1,38 @@
|
||||
using File_Folder_Helper.Helpers;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250315
|
||||
{
|
||||
internal static partial class Helper20250315 {
|
||||
|
||||
internal static void Empty(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
string[] searchPatterns = args[2].Split('|');
|
||||
internal static void Empty(ILogger<Worker> logger, List<string> args) {
|
||||
string[] searchPatterns = args[2].Split('~');
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
if (searchPatterns.Length == 1)
|
||||
{
|
||||
if (searchPatterns.Length == 1) {
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPatterns[0], SearchOption.AllDirectories);
|
||||
if (files.Length == 0)
|
||||
logger.LogWarning("<{files}>(s)", files.Length);
|
||||
else
|
||||
{
|
||||
else {
|
||||
string directoryName;
|
||||
string[] directories;
|
||||
foreach (string file in files)
|
||||
{
|
||||
foreach (string file in files) {
|
||||
directoryName = Path.GetDirectoryName(file) ?? throw new Exception();
|
||||
directories = Directory.GetDirectories(directoryName, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string directory in directories)
|
||||
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
string[] files;
|
||||
string checkFile;
|
||||
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
|
||||
foreach (string searchPattern in searchPatterns)
|
||||
{
|
||||
foreach (string searchPattern in searchPatterns) {
|
||||
files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
if (files.Length == 0)
|
||||
logger.LogWarning("<{files}>(s)", files.Length);
|
||||
else
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
else {
|
||||
foreach (string file in files) {
|
||||
checkFile = $"{file}.json";
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
|
@ -1,14 +1,14 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250320
|
||||
{
|
||||
internal static partial class Helper20250320 {
|
||||
|
||||
private record Match(string Name,
|
||||
string Parameters,
|
||||
@ -34,11 +34,9 @@ internal static partial class Helper20250320
|
||||
ReadOnlyCollection<int> ReferenceToLineNumbers,
|
||||
int? ScopeEnum,
|
||||
Search Search,
|
||||
int StartLine)
|
||||
{
|
||||
int StartLine) {
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
public override string ToString() {
|
||||
string result = JsonSerializer.Serialize(this, MethodCollectionCommonSourceGenerationContext.Default.Method);
|
||||
return result;
|
||||
}
|
||||
@ -47,8 +45,7 @@ internal static partial class Helper20250320
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Method[]))]
|
||||
private partial class MethodCollectionCommonSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
private partial class MethodCollectionCommonSourceGenerationContext : JsonSerializerContext {
|
||||
}
|
||||
|
||||
private record MethodWith(int? EndLine,
|
||||
@ -60,11 +57,9 @@ internal static partial class Helper20250320
|
||||
ReadOnlyCollection<int> ReferenceToLineNumbers,
|
||||
int? ScopeEnum,
|
||||
Search Search,
|
||||
int StartLine)
|
||||
{
|
||||
int StartLine) {
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
public override string ToString() {
|
||||
string result = JsonSerializer.Serialize(this, MethodCollectionCommonSourceGenerationContext.Default.Method);
|
||||
return result;
|
||||
}
|
||||
@ -73,8 +68,7 @@ internal static partial class Helper20250320
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(MethodWith[]))]
|
||||
private partial class MethodWithCollectionCommonSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
private partial class MethodWithCollectionCommonSourceGenerationContext : JsonSerializerContext {
|
||||
}
|
||||
|
||||
private const string _Name = "name";
|
||||
@ -88,11 +82,14 @@ internal static partial class Helper20250320
|
||||
[GeneratedRegex(@"[[\]<,>?a-zA-Z0-9_()\s]*?\s[a-z_]{1}[a-zA-Z0-9_]*?,")]
|
||||
private static partial Regex CSharpParameter();
|
||||
|
||||
[GeneratedRegex(@"(?<scope>public|private|internal|protected|\sI[a-zA-Z0-9_]*\.)\s?\b(?<static>static)?\s?\b(?<partial>partial)?\s?\b(?<async>async)?\s?\b(?<result>[\[\]\.\?<,>a-zA-Z0-9_()\s]*?)\s?\b(?<name>[A-Z_]{1}[a-zA-Z0-9_]*)+\((?<parameters>.*)\)")]
|
||||
// VSCode Search ^\s*\b(?<scope>public|private|internal|protected|\sI[a-zA-Z0-9_]*\.)\s?\b(?<static>static)?\s?\b(?<partial>partial)?\s?\b(?<async>async)?\s?\b(?<result>[\[\]\.\?<,>a-zA-Z0-9_()\s]*?)\s?\b(?<name>[A-Z_]{1}[a-zA-Z0-9_])+\((?<parameters>.*)\)\s?\{?$
|
||||
[GeneratedRegex(@"^\s*\b(?<scope>public|private|internal|protected|\sI[a-zA-Z0-9_]*\.)\s?\b(?<static>static)?\s?\b(?<partial>partial)?\s?\b(?<async>async)?\s?\b(?<result>[\[\]\.\?<,>a-zA-Z0-9_()\s]*?)\s?\b(?<name>[A-Z_]{1}[a-zA-Z0-9_]*)+\((?<parameters>.*)\)\s?\{?$")]
|
||||
private static partial Regex CSharpMethodLine();
|
||||
|
||||
internal static void SortCodeMethods(ILogger<Worker> logger, List<string> args, CancellationToken cancellationToken)
|
||||
{
|
||||
private static ReadOnlyCollection<Method> GetSortedMethods(ReadOnlyCollection<Method> methods) =>
|
||||
(from l in methods orderby l.ScopeEnum descending, l.ReferenceToLineNumbers.Count descending, l.Line.Length, l.Match.Name.Length, l.Match.Name select l).ToArray().AsReadOnly();
|
||||
|
||||
internal static void SortCodeMethods(ILogger<Worker> logger, List<string> args, CancellationToken cancellationToken) {
|
||||
bool check;
|
||||
string[] lines;
|
||||
List<string> changed = [];
|
||||
@ -104,16 +101,13 @@ internal static partial class Helper20250320
|
||||
string repositoryDirectory = Path.GetFullPath(args[0]);
|
||||
string[] cSharpFiles = Directory.GetFiles(repositoryDirectory, "*.cs", SearchOption.AllDirectories);
|
||||
ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles = logOnly ? new(cSharpFiles) : Helpers.HelperGit.GetOthersModifiedAndDeletedExcludingStandardFiles(repositoryDirectory, usePathCombine, cancellationToken);
|
||||
foreach (string cSharpFile in cSharpFiles)
|
||||
{
|
||||
foreach (string cSharpFile in cSharpFiles) {
|
||||
if (!gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(cSharpFile))
|
||||
continue;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
for (int i = 0; i < 10; i++) {
|
||||
lines = File.ReadAllLines(cSharpFile);
|
||||
check = SortFile(logger, logOnly, scopeSpaces, cSharpFile, lines);
|
||||
if (check)
|
||||
{
|
||||
if (check) {
|
||||
Thread.Sleep(500);
|
||||
changed.Add($"{i + 1:00}) {cSharpFile}");
|
||||
}
|
||||
@ -123,41 +117,35 @@ internal static partial class Helper20250320
|
||||
}
|
||||
if (changed.Count == 0)
|
||||
logger.LogInformation("No changes :)");
|
||||
else
|
||||
{
|
||||
else {
|
||||
changed.Reverse();
|
||||
foreach (string c in changed)
|
||||
logger.LogInformation(c);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool SortFile(ILogger<Worker> logger, bool logOnly, int scopeSpaces, string cSharpFile, string[] lines)
|
||||
{
|
||||
private static bool SortFile(ILogger<Worker> logger, bool logOnly, int scopeSpaces, string cSharpFile, string[] lines) {
|
||||
bool result;
|
||||
ReadOnlyCollection<Method> methods = GetMethods(logger, scopeSpaces, cSharpFile, lines);
|
||||
if (methods.Count == 0)
|
||||
result = false;
|
||||
else if (methods.Any(l => l.EndLine is null))
|
||||
result = false;
|
||||
else if (logOnly)
|
||||
{
|
||||
else if (logOnly) {
|
||||
foreach (Method method in methods)
|
||||
logger.LogInformation("{cSharpFile} - {Name} has {lines} line(s)", cSharpFile, method.Match.Name, (method.EndLine is null ? 999999 : method.EndLine.Value - method.StartLine).ToString("000000"));
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ReadOnlyCollection<Method> sortedMethods = GetSortedMethods(methods);
|
||||
if (Debugger.IsAttached)
|
||||
File.WriteAllText(Path.Combine(".vscode", "helper", ".txt"), string.Join(Environment.NewLine, sortedMethods.Select(l => $"{l.Match.Name} => {l.Parameters.Count}")));
|
||||
File.WriteAllText(Path.Combine(".vscode", "helper", ".json"), JsonSerializer.Serialize(sortedMethods.ToArray(), MethodCollectionCommonSourceGenerationContext.Default.MethodArray));
|
||||
ReadOnlyCollection<MethodWith> collection = GetCollection(logger, lines, sortedMethods);
|
||||
result = WriteAllLines(cSharpFile, lines, collection);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Method> GetMethods(ILogger<Worker> logger, int scopeSpaces, string cSharpFile, string[] lines)
|
||||
{
|
||||
private static ReadOnlyCollection<Method> GetMethods(ILogger<Worker> logger, int scopeSpaces, string cSharpFile, string[] lines) {
|
||||
List<Method> results = [];
|
||||
int check;
|
||||
int blocks;
|
||||
@ -176,8 +164,7 @@ internal static partial class Helper20250320
|
||||
Regex parameterRegex = CSharpParameter();
|
||||
ReadOnlyDictionary<string, string> parameters;
|
||||
System.Text.RegularExpressions.Match regularExpressionsMatch;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
for (int i = 0; i < lines.Length; i++) {
|
||||
check = GetNumberOfStartSpaces(lines, i);
|
||||
if (check != scopeSpaces)
|
||||
continue;
|
||||
@ -215,17 +202,17 @@ internal static partial class Helper20250320
|
||||
firstLine = lines[startLine].Trim();
|
||||
else
|
||||
firstLine = lines[startLine + 1].Trim();
|
||||
isLinq = !lines[i + 1].StartsWith("#pragma") && !lines[i + 1].StartsWith("#nullable") && lines[i + 1].Trim() != "{";
|
||||
isLinq = !lines[i + 1].StartsWith("#pragma") && !lines[i + 1].StartsWith("#nullable") && lines[i].Trim()[^1] != '{' && lines[i + 1].Trim() != "{";
|
||||
if (isLinq)
|
||||
blocks++;
|
||||
endLine = null;
|
||||
for (int j = i + 1; j < lines.Length; j++)
|
||||
{
|
||||
if (lines[i].Trim()[^1] == '{')
|
||||
blocks++;
|
||||
for (int j = i + 1; j < lines.Length; j++) {
|
||||
innerLine = lines[j].Trim();
|
||||
if (innerLine.StartsWith("#pragma") || innerLine.StartsWith("#nullable"))
|
||||
continue;
|
||||
if (isLinq && string.IsNullOrEmpty(innerLine))
|
||||
{
|
||||
if (isLinq && string.IsNullOrEmpty(innerLine)) {
|
||||
if (line.EndsWith(';'))
|
||||
blocks--;
|
||||
}
|
||||
@ -240,11 +227,9 @@ internal static partial class Helper20250320
|
||||
break;
|
||||
}
|
||||
referenceToLineNumbers = GetReferenceToLineNumbers(lines: lines, start: 0, end: lines.Length, i: i, search: search, parameters: parameters);
|
||||
if (referenceToLineNumbers.Count == 0)
|
||||
{
|
||||
if (referenceToLineNumbers.Count == 0) {
|
||||
lineSegmentFirst = line.Split(match.Name)[0];
|
||||
if (!lines[i - 1].Trim().StartsWith("[Obsolete"))
|
||||
{
|
||||
if (!lines[i - 1].Trim().StartsWith("[Obsolete")) {
|
||||
if (lineSegmentFirst.StartsWith("private"))
|
||||
logger.LogWarning("// <{cSharpFileName}> {name} with {parameters} parameter(s) <{line}>", Path.GetFileName(cSharpFile), match.Name, parameters, lineSegmentFirst);
|
||||
else
|
||||
@ -269,11 +254,9 @@ internal static partial class Helper20250320
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static int GetNumberOfStartSpaces(string[] lines, int i)
|
||||
{
|
||||
private static int GetNumberOfStartSpaces(string[] lines, int i) {
|
||||
int result = 0;
|
||||
foreach (char @char in lines[i])
|
||||
{
|
||||
foreach (char @char in lines[i]) {
|
||||
if (@char != ' ')
|
||||
break;
|
||||
result += 1;
|
||||
@ -281,11 +264,9 @@ internal static partial class Helper20250320
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int GetScopeEnum(Match match)
|
||||
{
|
||||
private static int GetScopeEnum(Match match) {
|
||||
int result;
|
||||
int value = match.Scope switch
|
||||
{
|
||||
int value = match.Scope switch {
|
||||
"public" => 8000,
|
||||
"internal" => 7000,
|
||||
"protected" => 6000,
|
||||
@ -301,29 +282,36 @@ internal static partial class Helper20250320
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, string> GetParameters(Regex parameterRegex, Match match)
|
||||
{
|
||||
private static ReadOnlyDictionary<string, string> GetParameters(Regex parameterRegex, Match match) {
|
||||
Dictionary<string, string> results = [];
|
||||
string value;
|
||||
string[] segments;
|
||||
System.Text.RegularExpressions.Match[] matches = parameterRegex.Matches($"{match.Parameters},").ToArray();
|
||||
foreach (System.Text.RegularExpressions.Match m in matches)
|
||||
{
|
||||
try {
|
||||
foreach (System.Text.RegularExpressions.Match m in matches) {
|
||||
if (!m.Success)
|
||||
continue;
|
||||
value = m.Value.Trim()[..^1];
|
||||
segments = value.Split(' ');
|
||||
results.Add(segments[^1], value);
|
||||
}
|
||||
} catch (Exception) {
|
||||
results.Clear();
|
||||
System.Text.RegularExpressions.Match m;
|
||||
for (int i = 0; i < matches.Length; i++) {
|
||||
m = matches[i];
|
||||
if (!m.Success)
|
||||
continue;
|
||||
results.Add(i.ToString(), i.ToString());
|
||||
}
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static int GetStartLine(string[] lines, int i)
|
||||
{
|
||||
private static int GetStartLine(string[] lines, int i) {
|
||||
int result = i;
|
||||
string line;
|
||||
for (int j = i - 1; j > -1; j--)
|
||||
{
|
||||
for (int j = i - 1; j > -1; j--) {
|
||||
line = lines[j].Trim();
|
||||
if (!line.StartsWith('[') && !line.StartsWith('#') && !line.StartsWith("/// "))
|
||||
break;
|
||||
@ -332,12 +320,10 @@ internal static partial class Helper20250320
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int GetLineBlockCount(string line, bool isLinq)
|
||||
{
|
||||
private static int GetLineBlockCount(string line, bool isLinq) {
|
||||
int result = 0;
|
||||
bool ignore = false;
|
||||
for (int i = 0; i < line.Length; i++)
|
||||
{
|
||||
for (int i = 0; i < line.Length; i++) {
|
||||
if (line[i] == '\'')
|
||||
i++;
|
||||
else if (!isLinq && !ignore && line[i] == '{')
|
||||
@ -352,27 +338,21 @@ internal static partial class Helper20250320
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<int> GetReferenceToLineNumbers(string[] lines, int start, int end, int i, Search search, ReadOnlyDictionary<string, string> parameters)
|
||||
{
|
||||
private static List<int> GetReferenceToLineNumbers(string[] lines, int start, int end, int i, Search search, ReadOnlyDictionary<string, string> parameters) {
|
||||
List<int> results = [];
|
||||
string[] segments;
|
||||
string[] afterSegments;
|
||||
string lastSegmentBeforeDot;
|
||||
for (int j = start; j < end; j++)
|
||||
{
|
||||
for (int j = start; j < end; j++) {
|
||||
if (j == i)
|
||||
continue;
|
||||
segments = lines[j].Split(search.Name);
|
||||
if (segments.Length == 1)
|
||||
{
|
||||
if (segments.Length == 1) {
|
||||
segments = lines[j].Split(search.Not);
|
||||
if (segments.Length == 1)
|
||||
{
|
||||
if (segments.Length == 1) {
|
||||
segments = lines[j].Split(search.Wrap);
|
||||
if (segments.Length == 1)
|
||||
{
|
||||
if (!lines[j].EndsWith(search.Delegate))
|
||||
{
|
||||
if (segments.Length == 1) {
|
||||
if (!lines[j].EndsWith(search.Delegate)) {
|
||||
segments = lines[j].Split(search.Constructor);
|
||||
if (segments.Length == 1)
|
||||
continue;
|
||||
@ -382,16 +362,12 @@ internal static partial class Helper20250320
|
||||
}
|
||||
if (lines[j].EndsWith(search.Delegate))
|
||||
results.Add(j);
|
||||
else
|
||||
{
|
||||
else {
|
||||
lastSegmentBeforeDot = segments[^1].Split(").")[0];
|
||||
if (parameters.Count == 0)
|
||||
{
|
||||
if (parameters.Count == 0) {
|
||||
if (lastSegmentBeforeDot.Contains(','))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
afterSegments = lastSegmentBeforeDot.Split(',');
|
||||
if (afterSegments.Length != parameters.Count)
|
||||
continue;
|
||||
@ -402,15 +378,10 @@ internal static partial class Helper20250320
|
||||
return results;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Method> GetSortedMethods(ReadOnlyCollection<Method> methods) =>
|
||||
(from l in methods orderby l.ScopeEnum descending, l.ReferenceToLineNumbers.Count descending, l.Line.Length, l.Match.Name.Length, l.Match.Name select l).ToArray().AsReadOnly();
|
||||
|
||||
private static ReadOnlyCollection<MethodWith> GetCollection(ILogger<Worker> logger, string[] lines, ReadOnlyCollection<Method> sortedMethods)
|
||||
{
|
||||
private static ReadOnlyCollection<MethodWith> GetCollection(ILogger<Worker> logger, string[] lines, ReadOnlyCollection<Method> sortedMethods) {
|
||||
List<MethodWith> results = [];
|
||||
List<Method> check = sortedMethods.ToList();
|
||||
foreach (Method method in sortedMethods)
|
||||
{
|
||||
foreach (Method method in sortedMethods) {
|
||||
logger.LogInformation($"{method.Match.Name} => {method.Parameters.Count}");
|
||||
if (method.EndLine is null)
|
||||
continue;
|
||||
@ -422,25 +393,21 @@ internal static partial class Helper20250320
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static MethodWith GetMethodWith(string[] lines, ReadOnlyCollection<Method> methods, List<Method> check, Method method, int methodEndLineValue)
|
||||
{
|
||||
private static MethodWith GetMethodWith(string[] lines, ReadOnlyCollection<Method> methods, List<Method> check, Method method, int methodEndLineValue) {
|
||||
MethodWith methodWith;
|
||||
List<int> referenceToLineNumbers;
|
||||
MethodWith[] sortedReferences;
|
||||
Dictionary<int, MethodWith> references = [];
|
||||
foreach (Method m in methods)
|
||||
{
|
||||
foreach (Method m in methods) {
|
||||
if (m.EndLine is null)
|
||||
continue;
|
||||
if (m == method)
|
||||
continue;
|
||||
referenceToLineNumbers = GetReferenceToLineNumbers(lines: lines, start: method.StartLine, end: methodEndLineValue, i: -1, search: m.Search, parameters: m.Parameters);
|
||||
if (referenceToLineNumbers.Count > 0)
|
||||
{
|
||||
if (referenceToLineNumbers.Count > 0) {
|
||||
if (!check.Remove(m))
|
||||
continue;
|
||||
foreach (int i in referenceToLineNumbers)
|
||||
{
|
||||
foreach (int i in referenceToLineNumbers) {
|
||||
if (references.ContainsKey(i))
|
||||
continue;
|
||||
methodWith = GetMethodWith(lines, methods, check, m, m.EndLine.Value);
|
||||
@ -466,23 +433,20 @@ internal static partial class Helper20250320
|
||||
return methodWith;
|
||||
}
|
||||
|
||||
private static bool WriteAllLines(string cSharpFile, string[] lines, ReadOnlyCollection<MethodWith> collection)
|
||||
{
|
||||
private static bool WriteAllLines(string cSharpFile, string[] lines, ReadOnlyCollection<MethodWith> collection) {
|
||||
bool result;
|
||||
if (Debugger.IsAttached)
|
||||
WriteDebug(collection);
|
||||
List<string> results = [];
|
||||
ReadOnlyCollection<int> methodLines = GetMethodLines(collection);
|
||||
int maxMethodLines = methodLines.Max();
|
||||
for (int i = 0; i < maxMethodLines; i++)
|
||||
{
|
||||
for (int i = 0; i < maxMethodLines; i++) {
|
||||
if (methodLines.Contains(i))
|
||||
continue;
|
||||
results.Add(lines[i]);
|
||||
}
|
||||
List<bool> nests = [true];
|
||||
foreach (MethodWith methodWith in collection)
|
||||
{
|
||||
foreach (MethodWith methodWith in collection) {
|
||||
if (methodWith.EndLine is null)
|
||||
continue;
|
||||
AppendLines(results, nests, lines, methodWith, methodWith.EndLine.Value);
|
||||
@ -493,16 +457,14 @@ internal static partial class Helper20250320
|
||||
string join = string.Join(Environment.NewLine, results);
|
||||
if (join == text)
|
||||
result = false;
|
||||
else
|
||||
{
|
||||
else {
|
||||
result = true;
|
||||
File.WriteAllText(cSharpFile, join);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void WriteDebug(ReadOnlyCollection<MethodWith> collection)
|
||||
{
|
||||
private static void WriteDebug(ReadOnlyCollection<MethodWith> collection) {
|
||||
List<string> results = [];
|
||||
List<bool> nests = [true];
|
||||
foreach (MethodWith methodWith in collection)
|
||||
@ -510,8 +472,7 @@ internal static partial class Helper20250320
|
||||
File.WriteAllText(Path.Combine(".vscode", "helper", ".md"), string.Join(Environment.NewLine, results));
|
||||
}
|
||||
|
||||
private static void AppendLines(List<string> results, List<bool> nests, MethodWith methodWith)
|
||||
{
|
||||
private static void AppendLines(List<string> results, List<bool> nests, MethodWith methodWith) {
|
||||
nests.Add(true);
|
||||
results.Add($" - {new string('#', nests.Count)} {methodWith.Match.Name} => {methodWith.Parameters.Count}");
|
||||
foreach (MethodWith m in methodWith.References)
|
||||
@ -519,12 +480,10 @@ internal static partial class Helper20250320
|
||||
nests.RemoveAt(nests.Count - 1);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<int> GetMethodLines(ReadOnlyCollection<MethodWith> collection)
|
||||
{
|
||||
private static ReadOnlyCollection<int> GetMethodLines(ReadOnlyCollection<MethodWith> collection) {
|
||||
List<int> results = [];
|
||||
List<bool> nests = [true];
|
||||
foreach (MethodWith methodWith in collection)
|
||||
{
|
||||
foreach (MethodWith methodWith in collection) {
|
||||
if (methodWith.EndLine is null)
|
||||
continue;
|
||||
AppendLineNumbers(results, nests, methodWith, methodWith.EndLine.Value);
|
||||
@ -535,13 +494,11 @@ internal static partial class Helper20250320
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static void AppendLineNumbers(List<int> results, List<bool> nests, MethodWith methodWith, int methodWithEndLineValue)
|
||||
{
|
||||
private static void AppendLineNumbers(List<int> results, List<bool> nests, MethodWith methodWith, int methodWithEndLineValue) {
|
||||
nests.Add(true);
|
||||
for (int i = methodWith.StartLine; i < methodWithEndLineValue + 1; i++)
|
||||
results.Add(i);
|
||||
foreach (MethodWith m in methodWith.References)
|
||||
{
|
||||
foreach (MethodWith m in methodWith.References) {
|
||||
if (m.EndLine is null)
|
||||
continue;
|
||||
AppendLineNumbers(results, nests, m, m.EndLine.Value);
|
||||
@ -549,13 +506,11 @@ internal static partial class Helper20250320
|
||||
nests.RemoveAt(nests.Count - 1);
|
||||
}
|
||||
|
||||
private static void AppendLines(List<string> results, List<bool> nests, string[] lines, MethodWith methodWith, int methodWithEndLineValue)
|
||||
{
|
||||
private static void AppendLines(List<string> results, List<bool> nests, string[] lines, MethodWith methodWith, int methodWithEndLineValue) {
|
||||
nests.Add(true);
|
||||
for (int i = methodWith.StartLine; i < methodWithEndLineValue + 1; i++)
|
||||
results.Add(lines[i]);
|
||||
foreach (MethodWith m in methodWith.References)
|
||||
{
|
||||
foreach (MethodWith m in methodWith.References) {
|
||||
if (m.EndLine is null)
|
||||
continue;
|
||||
AppendLines(results, nests, lines, m, m.EndLine.Value);
|
||||
|
@ -1,19 +1,18 @@
|
||||
using File_Folder_Helper.Helpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
using File_Folder_Helper.Helpers;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250321
|
||||
{
|
||||
internal static partial class Helper20250321 {
|
||||
|
||||
private record Record(string Directory,
|
||||
string File,
|
||||
ThreeDeep ThreeDeep)
|
||||
{
|
||||
ThreeDeep ThreeDeep) {
|
||||
|
||||
public static ReadOnlyCollection<Record> GetCollection(string sourceDirectory, string searchPattern, string[] files)
|
||||
{
|
||||
public static ReadOnlyCollection<Record> GetCollection(string sourceDirectory, string searchPattern, string[] files) {
|
||||
List<Record> results = [];
|
||||
Record record;
|
||||
string directory;
|
||||
@ -21,8 +20,7 @@ internal static partial class Helper20250321
|
||||
bool json = searchPattern.Contains(".json");
|
||||
bool check = searchPattern.Split('.').Length == 3;
|
||||
ReadOnlyCollection<ThreeDeep> collection = ThreeDeep.GetCollection(files);
|
||||
foreach (ThreeDeep threeDeep in collection)
|
||||
{
|
||||
foreach (ThreeDeep threeDeep in collection) {
|
||||
if (!json && check)
|
||||
fileNameWithoutExtension = threeDeep.DirectoryName;
|
||||
else if (!json && !check)
|
||||
@ -32,19 +30,15 @@ internal static partial class Helper20250321
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
directory = $"{fileNameWithoutExtension[^1]}{fileNameWithoutExtension[^3..][..2]}";
|
||||
if (json || (!json && !check))
|
||||
{
|
||||
if (json || (!json && !check)) {
|
||||
record = new(Directory: Path.Combine(sourceDirectory, "new-a", directory),
|
||||
File: $"{threeDeep.FileNameWithoutExtension}{threeDeep.Extension}",
|
||||
ThreeDeep: threeDeep);
|
||||
}
|
||||
else if (!json && check)
|
||||
{
|
||||
} else if (!json && check) {
|
||||
record = new(Directory: Path.Combine(sourceDirectory, "new-b", directory, threeDeep.DirectoryName),
|
||||
File: $"{threeDeep.FileNameWithoutExtension}{threeDeep.Extension}",
|
||||
ThreeDeep: threeDeep);
|
||||
}
|
||||
else
|
||||
} else
|
||||
throw new NotImplementedException();
|
||||
results.Add(record);
|
||||
}
|
||||
@ -59,17 +53,14 @@ internal static partial class Helper20250321
|
||||
long Length,
|
||||
string DirectoryName,
|
||||
string ParentDirectoryName,
|
||||
string Root)
|
||||
{
|
||||
string Root) {
|
||||
|
||||
public static ReadOnlyCollection<ThreeDeep> GetCollection(string[] files)
|
||||
{
|
||||
public static ReadOnlyCollection<ThreeDeep> GetCollection(string[] files) {
|
||||
List<ThreeDeep> results = [];
|
||||
ThreeDeep record;
|
||||
FileInfo fileInfo;
|
||||
string parentDirectory;
|
||||
foreach (string file in files)
|
||||
{
|
||||
foreach (string file in files) {
|
||||
fileInfo = new(file);
|
||||
parentDirectory = Path.GetDirectoryName(fileInfo.DirectoryName) ?? throw new Exception();
|
||||
record = new(Extension: Path.GetExtension(file),
|
||||
@ -89,14 +80,12 @@ internal static partial class Helper20250321
|
||||
|
||||
}
|
||||
|
||||
internal static void MoveToLast(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
string[] searchPatterns = args[2].Split('|');
|
||||
internal static void MoveToLast(ILogger<Worker> logger, List<string> args) {
|
||||
string[] searchPatterns = args[2].Split('~');
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
if (searchPatterns.Length == 1)
|
||||
logger.LogInformation("No code for just one!");
|
||||
else
|
||||
{
|
||||
else {
|
||||
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
|
||||
ReadOnlyCollection<Record> collection = GetCollection(logger, searchPatterns, sourceDirectory);
|
||||
if (collection.Count != 0)
|
||||
@ -108,17 +97,14 @@ internal static partial class Helper20250321
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetCollection(ILogger<Worker> logger, string[] searchPatterns, string sourceDirectory)
|
||||
{
|
||||
private static ReadOnlyCollection<Record> GetCollection(ILogger<Worker> logger, string[] searchPatterns, string sourceDirectory) {
|
||||
string[] files;
|
||||
List<Record> results = [];
|
||||
foreach (string searchPattern in searchPatterns)
|
||||
{
|
||||
foreach (string searchPattern in searchPatterns) {
|
||||
files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
if (files.Length == 0)
|
||||
logger.LogWarning("<{files}>(s)", files.Length);
|
||||
else
|
||||
{
|
||||
else {
|
||||
ReadOnlyCollection<Record> collection = Record.GetCollection(sourceDirectory, searchPattern, files);
|
||||
results.AddRange(collection);
|
||||
}
|
||||
@ -126,25 +112,21 @@ internal static partial class Helper20250321
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void UseCollection(ReadOnlyCollection<Record> collection)
|
||||
{
|
||||
private static void UseCollection(ReadOnlyCollection<Record> collection) {
|
||||
string fullPath;
|
||||
string checkFile;
|
||||
List<string> distinct = [];
|
||||
foreach (Record record in collection)
|
||||
{
|
||||
foreach (Record record in collection) {
|
||||
if (distinct.Contains(record.Directory))
|
||||
continue;
|
||||
distinct.Add(record.Directory);
|
||||
}
|
||||
foreach (string directory in distinct)
|
||||
{
|
||||
foreach (string directory in distinct) {
|
||||
if (Directory.Exists(directory))
|
||||
continue;
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
}
|
||||
foreach (Record record in collection)
|
||||
{
|
||||
foreach (Record record in collection) {
|
||||
checkFile = Path.Combine(record.Directory, record.File);
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
|
236
ADO2025/PI5/Helper-2025-04-04.cs
Normal file
236
ADO2025/PI5/Helper-2025-04-04.cs
Normal file
@ -0,0 +1,236 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250404 {
|
||||
|
||||
internal record KafkaProducerSaslOptions(
|
||||
[property: JsonPropertyName("mechanism")] string Mechanism
|
||||
);
|
||||
|
||||
internal record MonitorList(
|
||||
[property: JsonPropertyName("id")] int Id,
|
||||
[property: JsonPropertyName("name")] string Name,
|
||||
[property: JsonPropertyName("description")] string Description,
|
||||
[property: JsonPropertyName("pathName")] string PathName,
|
||||
[property: JsonPropertyName("parent")] int? Parent,
|
||||
[property: JsonPropertyName("childrenIDs")] IReadOnlyList<int> ChildrenIDs,
|
||||
[property: JsonPropertyName("url")] string Url,
|
||||
[property: JsonPropertyName("method")] string Method,
|
||||
[property: JsonPropertyName("hostname")] object Hostname,
|
||||
[property: JsonPropertyName("port")] object Port,
|
||||
[property: JsonPropertyName("maxretries")] int MaxRetries,
|
||||
[property: JsonPropertyName("weight")] int Weight,
|
||||
[property: JsonPropertyName("active")] bool Active,
|
||||
[property: JsonPropertyName("forceInactive")] bool ForceInactive,
|
||||
[property: JsonPropertyName("type")] string Type,
|
||||
[property: JsonPropertyName("timeout")] int Timeout,
|
||||
[property: JsonPropertyName("interval")] int Interval,
|
||||
[property: JsonPropertyName("retryInterval")] int RetryInterval,
|
||||
[property: JsonPropertyName("resendInterval")] int ResendInterval,
|
||||
[property: JsonPropertyName("keyword")] object Keyword,
|
||||
[property: JsonPropertyName("invertKeyword")] bool InvertKeyword,
|
||||
[property: JsonPropertyName("expiryNotification")] bool ExpiryNotification,
|
||||
[property: JsonPropertyName("ignoreTls")] bool IgnoreTls,
|
||||
[property: JsonPropertyName("upsideDown")] bool UpsideDown,
|
||||
[property: JsonPropertyName("packetSize")] int PacketSize,
|
||||
[property: JsonPropertyName("maxredirects")] int MaxRedirects,
|
||||
[property: JsonPropertyName("accepted_statuscodes")] IReadOnlyList<string> AcceptedStatusCodes,
|
||||
[property: JsonPropertyName("dns_resolve_type")] string DnsResolveType,
|
||||
[property: JsonPropertyName("dns_resolve_server")] string DnsResolveServer,
|
||||
[property: JsonPropertyName("dns_last_result")] object DnsLastResult,
|
||||
[property: JsonPropertyName("docker_container")] string DockerContainer,
|
||||
[property: JsonPropertyName("docker_host")] object DockerHost,
|
||||
[property: JsonPropertyName("proxyId")] object ProxyId,
|
||||
[property: JsonPropertyName("notificationIDList")] NotificationIDList NotificationIDList,
|
||||
[property: JsonPropertyName("tags")] IReadOnlyList<object> Tags,
|
||||
[property: JsonPropertyName("maintenance")] bool Maintenance,
|
||||
[property: JsonPropertyName("mqttTopic")] string MqttTopic,
|
||||
[property: JsonPropertyName("mqttSuccessMessage")] string MqttSuccessMessage,
|
||||
[property: JsonPropertyName("databaseQuery")] object DatabaseQuery,
|
||||
[property: JsonPropertyName("authMethod")] string AuthMethod,
|
||||
[property: JsonPropertyName("grpcUrl")] object GrpcUrl,
|
||||
[property: JsonPropertyName("grpcProtobuf")] object GrpcProtobuf,
|
||||
[property: JsonPropertyName("grpcMethod")] object GrpcMethod,
|
||||
[property: JsonPropertyName("grpcServiceName")] object GrpcServiceName,
|
||||
[property: JsonPropertyName("grpcEnableTls")] bool GrpcEnableTls,
|
||||
[property: JsonPropertyName("radiusCalledStationId")] object RadiusCalledStationId,
|
||||
[property: JsonPropertyName("radiusCallingStationId")] object RadiusCallingStationId,
|
||||
[property: JsonPropertyName("game")] object Game,
|
||||
[property: JsonPropertyName("gamedigGivenPortOnly")] bool GameDigGivenPortOnly,
|
||||
[property: JsonPropertyName("httpBodyEncoding")] string HttpBodyEncoding,
|
||||
[property: JsonPropertyName("jsonPath")] object JsonPath,
|
||||
[property: JsonPropertyName("expectedValue")] object ExpectedValue,
|
||||
[property: JsonPropertyName("kafkaProducerTopic")] object KafkaProducerTopic,
|
||||
[property: JsonPropertyName("kafkaProducerBrokers")] IReadOnlyList<object> KafkaProducerBrokers,
|
||||
[property: JsonPropertyName("kafkaProducerSsl")] bool KafkaProducerSsl,
|
||||
[property: JsonPropertyName("kafkaProducerAllowAutoTopicCreation")] bool KafkaProducerAllowAutoTopicCreation,
|
||||
[property: JsonPropertyName("kafkaProducerMessage")] object KafkaProducerMessage,
|
||||
[property: JsonPropertyName("screenshot")] object Screenshot,
|
||||
[property: JsonPropertyName("headers")] object Headers,
|
||||
[property: JsonPropertyName("body")] object Body,
|
||||
[property: JsonPropertyName("grpcBody")] object GrpcBody,
|
||||
[property: JsonPropertyName("grpcMetadata")] object GrpcMetadata,
|
||||
[property: JsonPropertyName("basic_auth_user")] string BasicAuthUser,
|
||||
[property: JsonPropertyName("basic_auth_pass")] string BasicAuthPass,
|
||||
[property: JsonPropertyName("oauth_client_id")] object OauthClientId,
|
||||
[property: JsonPropertyName("oauth_client_secret")] object OauthClientSecret,
|
||||
[property: JsonPropertyName("oauth_token_url")] object OauthTokenUrl,
|
||||
[property: JsonPropertyName("oauth_scopes")] object OauthScopes,
|
||||
[property: JsonPropertyName("oauth_auth_method")] string OauthAuthMethod,
|
||||
[property: JsonPropertyName("pushToken")] string PushToken,
|
||||
[property: JsonPropertyName("databaseConnectionString")] string DatabaseConnectionString,
|
||||
[property: JsonPropertyName("radiusUsername")] object RadiusUsername,
|
||||
[property: JsonPropertyName("radiusPassword")] object RadiusPassword,
|
||||
[property: JsonPropertyName("radiusSecret")] object RadiusSecret,
|
||||
[property: JsonPropertyName("mqttUsername")] string MqttUsername,
|
||||
[property: JsonPropertyName("mqttPassword")] string MqttPassword,
|
||||
[property: JsonPropertyName("authWorkstation")] object AuthWorkstation,
|
||||
[property: JsonPropertyName("authDomain")] object AuthDomain,
|
||||
[property: JsonPropertyName("tlsCa")] object TlsCa,
|
||||
[property: JsonPropertyName("tlsCert")] object TlsCert,
|
||||
[property: JsonPropertyName("tlsKey")] object TlsKey,
|
||||
[property: JsonPropertyName("kafkaProducerSaslOptions")] KafkaProducerSaslOptions KafkaProducerSaslOptions,
|
||||
[property: JsonPropertyName("includeSensitiveData")] bool IncludeSensitiveData
|
||||
);
|
||||
|
||||
internal record NotificationIDList(
|
||||
[property: JsonPropertyName("4")] bool _4
|
||||
);
|
||||
|
||||
internal record NotificationList(
|
||||
[property: JsonPropertyName("id")] int Id,
|
||||
[property: JsonPropertyName("name")] string Name,
|
||||
[property: JsonPropertyName("active")] bool Active,
|
||||
[property: JsonPropertyName("userId")] int UserId,
|
||||
[property: JsonPropertyName("isDefault")] bool IsDefault,
|
||||
[property: JsonPropertyName("config")] string Config
|
||||
);
|
||||
|
||||
internal record Kuma(
|
||||
[property: JsonPropertyName("version")] string Version,
|
||||
[property: JsonPropertyName("notificationList")] IReadOnlyList<NotificationList> NotificationList,
|
||||
[property: JsonPropertyName("monitorList")] IReadOnlyList<MonitorList> MonitorList
|
||||
);
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Kuma))]
|
||||
private partial class KumaCommonSourceGenerationContext : JsonSerializerContext {
|
||||
}
|
||||
|
||||
internal static void KumaToGatus(ILogger<Worker> logger, List<string> args) {
|
||||
string url = args[4];
|
||||
string fileName = args[3];
|
||||
string searchPattern = args[2];
|
||||
ParseMetrics(logger, fileName, url);
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
if (files.Length == 0)
|
||||
logger.LogWarning("<{files}>(s)", files.Length);
|
||||
else
|
||||
KumaToGatus(files);
|
||||
}
|
||||
|
||||
private static void ParseMetrics(ILogger<Worker> logger, string fileName, string url) {
|
||||
FileStream fileStream = new(fileName, FileMode.Truncate);
|
||||
HttpClient httpClient = new();
|
||||
Task<Stream> streamTask = httpClient.GetStreamAsync(url);
|
||||
streamTask.Wait();
|
||||
Task task = streamTask.Result.CopyToAsync(fileStream);
|
||||
task.Wait();
|
||||
ParseMetrics(logger, fileStream);
|
||||
fileStream.Dispose();
|
||||
streamTask.Dispose();
|
||||
httpClient.Dispose();
|
||||
}
|
||||
|
||||
private static void ParseMetrics(ILogger<Worker> _, FileStream __) {
|
||||
// Task<List<IMetric>> metrics = PrometheusMetricsParser.ParseAsync(fileStream);
|
||||
// metrics.Wait();
|
||||
// foreach (IMetric metric in metrics.Result) {
|
||||
// if (metric is not Gauge gauge)
|
||||
// continue;
|
||||
// foreach (GaugeMeasurement gaugeMeasurement in gauge.Measurements) {
|
||||
// if (string.IsNullOrEmpty(metric.Name))
|
||||
// continue;
|
||||
// foreach (KeyValuePair<string, string> keyValuePair in gaugeMeasurement.Labels) {
|
||||
// logger.LogInformation("name:{name}; timestamp:{timestamp}; value:{value}; key-name:{key-name}; key-value:{key-value}",
|
||||
// metric.Name,
|
||||
// gaugeMeasurement.Timestamp,
|
||||
// gaugeMeasurement.Value,
|
||||
// keyValuePair.Key,
|
||||
// keyValuePair.Value);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private static void KumaToGatus(string[] files) {
|
||||
Kuma? kuma;
|
||||
string json;
|
||||
string checkFile;
|
||||
foreach (string file in files) {
|
||||
checkFile = file.ToLower().Replace('_', '-');
|
||||
if (checkFile != file)
|
||||
File.Move(file, checkFile);
|
||||
json = File.ReadAllText(checkFile);
|
||||
kuma = JsonSerializer.Deserialize(json, KumaCommonSourceGenerationContext.Default.Kuma);
|
||||
if (kuma is null)
|
||||
continue;
|
||||
WriteGatus(checkFile, kuma);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteGatus(string file, Kuma kuma) {
|
||||
List<string> results = [
|
||||
string.Empty,
|
||||
$"# set GATUS_CONFIG_PATH=./{Path.GetFileName(file)}.yaml",
|
||||
string.Empty,
|
||||
"endpoints:"
|
||||
];
|
||||
string[] segments;
|
||||
foreach (MonitorList monitorList in kuma.MonitorList) {
|
||||
if (monitorList.Type is not "http" and not "postgres")
|
||||
continue;
|
||||
results.Add($" - name: {monitorList.Name}");
|
||||
results.Add($" group: {monitorList.PathName.Split(' ')[0]}");
|
||||
results.Add($" enabled: {monitorList.Active.ToString().ToLower()}");
|
||||
results.Add($" interval: {monitorList.Interval}s");
|
||||
if (monitorList.Type == "http") {
|
||||
results.Add($" method: {monitorList.Method}");
|
||||
results.Add($" url: \"{monitorList.Url}\"");
|
||||
if (monitorList.AuthMethod == "basic") {
|
||||
results.Add($" # user: \"{monitorList.BasicAuthUser}\"");
|
||||
results.Add($" # password: \"{monitorList.BasicAuthPass}\"");
|
||||
}
|
||||
results.Add(" conditions:");
|
||||
results.Add(" - \"[STATUS] < 300\"");
|
||||
if (monitorList.Url.Contains("https"))
|
||||
results.Add(" - \"[CERTIFICATE_EXPIRATION] > 48h\"");
|
||||
results.Add($" - \"[RESPONSE_TIME] < {monitorList.Timeout}\"");
|
||||
} else if (monitorList.Type == "postgres") {
|
||||
segments = monitorList.DatabaseConnectionString.Split('@');
|
||||
if (segments.Length != 2)
|
||||
continue;
|
||||
results.Add($" # connectionString: \"{monitorList.DatabaseConnectionString}\"");
|
||||
results.Add($" url: \"tcp://{segments[1].Split('/')[0]}\"");
|
||||
results.Add(" conditions:");
|
||||
results.Add(" - \"[CONNECTED] == true\"");
|
||||
} else
|
||||
throw new NotImplementedException();
|
||||
results.Add(" alerts:");
|
||||
results.Add(" - type: email");
|
||||
results.Add(" description: \"healthcheck failed\"");
|
||||
results.Add(" send-on-resolved: true");
|
||||
results.Add(" - type: gotify");
|
||||
results.Add(" description: \"healthcheck failed\"");
|
||||
results.Add(" send-on-resolved: true");
|
||||
results.Add(string.Empty);
|
||||
}
|
||||
File.WriteAllText($"{file}.yaml", string.Join(Environment.NewLine, results));
|
||||
}
|
||||
|
||||
}
|
693
ADO2025/PI5/Helper-2025-04-07.cs
Normal file
693
ADO2025/PI5/Helper-2025-04-07.cs
Normal file
@ -0,0 +1,693 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
using File_Folder_Helper.Models;
|
||||
|
||||
using Microsoft.Extensions.FileSystemGlobbing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
#if ShellProgressBar
|
||||
using ShellProgressBar;
|
||||
#endif
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250407 {
|
||||
|
||||
private record Record(string RelativePath,
|
||||
long Size,
|
||||
long Ticks);
|
||||
|
||||
private record Download(string Directory,
|
||||
string Display,
|
||||
string File,
|
||||
long Size,
|
||||
long Ticks,
|
||||
string UniformResourceLocator);
|
||||
|
||||
private record Segment(Record? Left,
|
||||
string? LeftDirectory,
|
||||
Record? Right,
|
||||
string RightDirectory,
|
||||
string RootUniformResourceLocator);
|
||||
|
||||
private record Logic(char GreaterThan,
|
||||
bool? LeftSideIsNewer,
|
||||
int LeftSideIsNewerIndex,
|
||||
bool? LeftSideOnly,
|
||||
int LeftSideOnlyIndex,
|
||||
char LessThan,
|
||||
char Minus,
|
||||
bool? NotEqualBut,
|
||||
int NotEqualButIndex,
|
||||
char Plus,
|
||||
string[] Raw,
|
||||
bool? RightSideIsNewer,
|
||||
int RightSideIsNewerIndex,
|
||||
bool? RightSideOnly,
|
||||
int RightSideOnlyIndex) {
|
||||
|
||||
internal static Logic? Get(string[] segments) {
|
||||
Logic? result;
|
||||
bool check = true;
|
||||
bool? notEqualBut;
|
||||
bool? leftSideOnly;
|
||||
bool? rightSideOnly;
|
||||
bool? leftSideIsNewer;
|
||||
const char plus = '+';
|
||||
bool? rightSideIsNewer;
|
||||
const char minus = '-';
|
||||
const char lessThan = 'L';
|
||||
const char greaterThan = 'G';
|
||||
const int notEqualButIndex = 2;
|
||||
const int leftSideOnlyIndex = 0;
|
||||
const int rightSideOnlyIndex = 4;
|
||||
const int leftSideIsNewerIndex = 1;
|
||||
const int rightSideIsNewerIndex = 3;
|
||||
if (string.IsNullOrEmpty(segments[leftSideOnlyIndex]))
|
||||
leftSideOnly = null;
|
||||
else if (segments[leftSideOnlyIndex][0] == plus)
|
||||
leftSideOnly = true;
|
||||
else if (segments[leftSideOnlyIndex][0] == minus)
|
||||
leftSideOnly = false;
|
||||
else {
|
||||
check = false;
|
||||
leftSideOnly = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[leftSideIsNewerIndex]))
|
||||
leftSideIsNewer = null;
|
||||
else if (segments[leftSideIsNewerIndex][0] == greaterThan)
|
||||
leftSideIsNewer = true;
|
||||
else if (segments[leftSideIsNewerIndex][0] == lessThan)
|
||||
leftSideIsNewer = false;
|
||||
else {
|
||||
check = false;
|
||||
leftSideIsNewer = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[notEqualButIndex]))
|
||||
notEqualBut = null;
|
||||
else if (segments[notEqualButIndex][0] == greaterThan)
|
||||
notEqualBut = true;
|
||||
else if (segments[notEqualButIndex][0] == lessThan)
|
||||
notEqualBut = false;
|
||||
else {
|
||||
check = false;
|
||||
notEqualBut = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[rightSideIsNewerIndex]))
|
||||
rightSideIsNewer = null;
|
||||
else if (segments[rightSideIsNewerIndex][0] == greaterThan)
|
||||
rightSideIsNewer = true;
|
||||
else if (segments[rightSideIsNewerIndex][0] == lessThan)
|
||||
rightSideIsNewer = false;
|
||||
else {
|
||||
check = false;
|
||||
rightSideIsNewer = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[rightSideOnlyIndex]))
|
||||
rightSideOnly = null;
|
||||
else if (segments[rightSideOnlyIndex][0] == plus)
|
||||
rightSideOnly = true;
|
||||
else if (segments[rightSideOnlyIndex][0] == minus)
|
||||
rightSideOnly = false;
|
||||
else {
|
||||
check = false;
|
||||
rightSideOnly = null;
|
||||
}
|
||||
result = !check ? null : new(GreaterThan: greaterThan,
|
||||
LeftSideIsNewerIndex: leftSideIsNewerIndex,
|
||||
LeftSideIsNewer: leftSideIsNewer,
|
||||
LeftSideOnly: leftSideOnly,
|
||||
LeftSideOnlyIndex: leftSideOnlyIndex,
|
||||
LessThan: lessThan,
|
||||
Minus: minus,
|
||||
NotEqualBut: notEqualBut,
|
||||
NotEqualButIndex: notEqualButIndex,
|
||||
Plus: plus,
|
||||
RightSideIsNewer: rightSideIsNewer,
|
||||
RightSideIsNewerIndex: rightSideIsNewerIndex,
|
||||
RightSideOnly: rightSideOnly,
|
||||
Raw: segments,
|
||||
RightSideOnlyIndex: rightSideOnlyIndex);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private record Review(Segment[]? AreEqual,
|
||||
Segment[]? LeftSideIsNewer,
|
||||
Segment[]? LeftSideOnly,
|
||||
Segment[]? NotEqualBut,
|
||||
Record[]? Records,
|
||||
Segment[]? RightSideIsNewer,
|
||||
Segment[]? RightSideOnly);
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Review))]
|
||||
private partial class ReviewCommonSourceGenerationContext : JsonSerializerContext {
|
||||
}
|
||||
|
||||
internal static void Sync(ILogger<Worker> logger, List<string> args) {
|
||||
Matcher matcher = new();
|
||||
string fileName = $"{args[1]}.json";
|
||||
string[] segments = args[5].Split('~');
|
||||
string rightDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
Logic? logic = segments.Length != 5 ? null : Logic.Get(segments);
|
||||
string includePatternsFile = Path.Combine(rightDirectory, args[2]);
|
||||
string excludePatternsFile = Path.Combine(rightDirectory, args[3]);
|
||||
string[] rootUniformResourceLocators = args.Count < 5 ? [] : args[4].Split('~');
|
||||
matcher.AddIncludePatterns(!File.Exists(includePatternsFile) ? ["*"] : File.ReadAllLines(includePatternsFile));
|
||||
matcher.AddExcludePatterns(!File.Exists(excludePatternsFile) ? ["System Volume Information"] : File.ReadAllLines(excludePatternsFile));
|
||||
ReadOnlyCollection<Record> rightRecords = GetRecords(rightDirectory, matcher);
|
||||
if (rightRecords.Count == 0)
|
||||
logger.LogInformation("No source records");
|
||||
else {
|
||||
string checkFile = Path.Combine(rightDirectory, fileName);
|
||||
Review review = new(AreEqual: null,
|
||||
LeftSideIsNewer: null,
|
||||
LeftSideOnly: null,
|
||||
NotEqualBut: null,
|
||||
Records: rightRecords.ToArray(),
|
||||
RightSideIsNewer: null,
|
||||
RightSideOnly: null);
|
||||
string json = JsonSerializer.Serialize(review, ReviewCommonSourceGenerationContext.Default.Review);
|
||||
WriteAllText(checkFile, json);
|
||||
if (rootUniformResourceLocators.Length == 0)
|
||||
logger.LogInformation("No urls");
|
||||
else {
|
||||
string format = NginxFileSystem.GetFormat();
|
||||
TimeZoneInfo timeZoneInfo = TimeZoneInfo.Local;
|
||||
Sync(logger, rightDirectory, fileName, logic, rootUniformResourceLocators, rightRecords, format, timeZoneInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetRecords(string rightDirectory, Matcher matcher) {
|
||||
List<Record> results = [
|
||||
new(RelativePath: rightDirectory,
|
||||
Size: 0,
|
||||
Ticks: 0)];
|
||||
Record record;
|
||||
FileInfo fileInfo;
|
||||
string relativePath;
|
||||
ReadOnlyCollection<ReadOnlyCollection<string>> collection = Helpers.HelperDirectory.GetFilesCollection(rightDirectory, "*", "*");
|
||||
foreach (ReadOnlyCollection<string> c in collection) {
|
||||
foreach (string f in c) {
|
||||
if (!matcher.Match(rightDirectory, f).HasMatches)
|
||||
continue;
|
||||
fileInfo = new(f);
|
||||
if (fileInfo.Length == 0)
|
||||
continue;
|
||||
relativePath = Path.GetRelativePath(rightDirectory, fileInfo.FullName);
|
||||
record = new(RelativePath: relativePath,
|
||||
Size: fileInfo.Length,
|
||||
Ticks: fileInfo.LastWriteTime.ToUniversalTime().Ticks);
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void WriteAllText(string path, string text) {
|
||||
string check = !File.Exists(path) ? string.Empty : File.ReadAllText(path);
|
||||
if (check != text)
|
||||
File.WriteAllText(path, text);
|
||||
}
|
||||
|
||||
private static void Sync(ILogger<Worker> logger, string rightDirectory, string fileName, Logic? logic, string[] rootUniformResourceLocators, ReadOnlyCollection<Record> rightRecords, string format, TimeZoneInfo timeZoneInfo) {
|
||||
Review? review;
|
||||
foreach (string rootUniformResourceLocator in rootUniformResourceLocators) {
|
||||
if (!rootUniformResourceLocator.StartsWith("https:"))
|
||||
logger.LogInformation("Not supported URL <{url}>", rootUniformResourceLocator);
|
||||
else {
|
||||
review = GetJsonResponse(logger, fileName, rootUniformResourceLocator, format, timeZoneInfo);
|
||||
if (review?.Records is null || review.Records.Length == 0)
|
||||
logger.LogInformation("No response records");
|
||||
else {
|
||||
ReadOnlyCollection<Record> leftRecords = review.Records.AsReadOnly();
|
||||
Sync(logger, rightDirectory, fileName, logic, rightRecords, rootUniformResourceLocator, leftRecords);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Review? GetJsonResponse(ILogger<Worker> logger, string fileName, string rootUniformResourceLocator, string format, TimeZoneInfo timeZoneInfo) {
|
||||
Review? result;
|
||||
Task<string> response;
|
||||
HttpClient httpClient = new();
|
||||
Task<HttpResponseMessage> httpResponseMessage;
|
||||
string url = new(rootUniformResourceLocator.EndsWith('/') ?
|
||||
$"{rootUniformResourceLocator[..^1]}/{fileName}" :
|
||||
$"{rootUniformResourceLocator}/{fileName}");
|
||||
httpResponseMessage = httpClient.GetAsync(rootUniformResourceLocator);
|
||||
httpResponseMessage.Wait();
|
||||
if (!httpResponseMessage.Result.IsSuccessStatusCode) {
|
||||
logger.LogInformation("Failed to download: <{rootUniformResourceLocator}>;", rootUniformResourceLocator);
|
||||
result = null;
|
||||
} else {
|
||||
response = httpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
response.Wait();
|
||||
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(response.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
|
||||
bool isNewest = nginxFileSystems is not null && IsNewest(fileName, format, timeZoneInfo, new(rootUniformResourceLocator), nginxFileSystems);
|
||||
if (nginxFileSystems is null) {
|
||||
logger.LogInformation("Failed to parse: <{rootUniformResourceLocator}>;", rootUniformResourceLocator);
|
||||
result = null;
|
||||
} else if (!isNewest) {
|
||||
logger.LogInformation("Outdated remote file: <{rootUniformResourceLocator}>;", rootUniformResourceLocator);
|
||||
result = null;
|
||||
} else {
|
||||
httpResponseMessage = httpClient.GetAsync(url);
|
||||
httpResponseMessage.Wait();
|
||||
if (!httpResponseMessage.Result.IsSuccessStatusCode) {
|
||||
logger.LogInformation("Failed to download: <{url}>;", url);
|
||||
result = null;
|
||||
} else {
|
||||
response = httpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
response.Wait();
|
||||
result = string.IsNullOrEmpty(response.Result) ?
|
||||
null :
|
||||
JsonSerializer.Deserialize(response.Result, ReviewCommonSourceGenerationContext.Default.Review);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool IsNewest(string fileName, string format, TimeZoneInfo timeZoneInfo, Uri uri, NginxFileSystem[] nginxFileSystems) {
|
||||
bool result;
|
||||
DateTime? match = null;
|
||||
NginxFileSystem nginxFileSystem;
|
||||
DateTime dateTime = DateTime.MinValue;
|
||||
for (int i = 0; i < nginxFileSystems.Length; i++) {
|
||||
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
|
||||
if (nginxFileSystem.LastModified is not null && nginxFileSystem.Name == fileName) {
|
||||
match = nginxFileSystem.LastModified.Value;
|
||||
continue;
|
||||
}
|
||||
if (nginxFileSystem.LastModified is null || nginxFileSystem.LastModified <= dateTime)
|
||||
continue;
|
||||
dateTime = nginxFileSystem.LastModified.Value;
|
||||
}
|
||||
result = match is not null && match.Value > dateTime;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void Sync(ILogger<Worker> logger, string rightDirectory, string fileName, Logic? l, ReadOnlyCollection<Record> rightRecords, string rootUniformResourceLocators, ReadOnlyCollection<Record> leftRecords) {
|
||||
string json;
|
||||
string checkFile;
|
||||
HttpClient httpClient = new();
|
||||
checkFile = Path.Combine(rightDirectory, fileName);
|
||||
if (File.Exists(checkFile))
|
||||
File.Delete(checkFile);
|
||||
ReadOnlyCollection<Segment> areEqual = GetAreEqual(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords);
|
||||
ReadOnlyCollection<Segment> notEqualBut = GetNotEqualBut(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords);
|
||||
ReadOnlyCollection<Segment> leftSideOnly = GetLeftSideOnly(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords);
|
||||
ReadOnlyCollection<Segment> rightSideOnly = GetRightSideOnly(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords);
|
||||
ReadOnlyCollection<Segment> leftSideIsNewer = GetLeftSideIsNewer(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords);
|
||||
ReadOnlyCollection<Segment> rightSideIsNewer = GetRightSideIsNewer(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords);
|
||||
Review review = new(AreEqual: areEqual.ToArray(),
|
||||
LeftSideIsNewer: leftSideIsNewer.ToArray(),
|
||||
LeftSideOnly: leftSideOnly.ToArray(),
|
||||
NotEqualBut: notEqualBut.ToArray(),
|
||||
Records: null,
|
||||
RightSideIsNewer: rightSideIsNewer.ToArray(),
|
||||
RightSideOnly: rightSideOnly.ToArray());
|
||||
json = JsonSerializer.Serialize(review, ReviewCommonSourceGenerationContext.Default.Review);
|
||||
checkFile = Path.Combine(rightDirectory, fileName);
|
||||
WriteAllText(checkFile, json);
|
||||
if (notEqualBut.Count > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Minus && !l.NotEqualBut.Value)
|
||||
logger.LogDebug("Doing nothing with {name}", nameof(Logic.NotEqualBut));
|
||||
if (leftSideOnly.Count > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Minus && !l.LeftSideOnly.Value)
|
||||
throw new NotImplementedException("Not possible with https!");
|
||||
if (leftSideIsNewer.Count > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.LessThan && !l.LeftSideIsNewer.Value)
|
||||
throw new NotImplementedException("Not possible with https!");
|
||||
if (rightSideIsNewer.Count > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.LessThan && !l.RightSideIsNewer.Value)
|
||||
throw new NotImplementedException("Not possible with https!");
|
||||
if (rightSideOnly.Count > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Plus && l.RightSideOnly.Value)
|
||||
throw new NotImplementedException("Not possible with https!");
|
||||
if (rightSideOnly.Count > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Minus && !l.RightSideOnly.Value)
|
||||
DoWork(logger, rightDirectory, httpClient, rightSideOnly, delete: true, download: false);
|
||||
if (leftSideOnly.Count > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Plus && l.LeftSideOnly.Value)
|
||||
DoWork(logger, rightDirectory, httpClient, leftSideOnly, delete: false, download: true);
|
||||
if (leftSideIsNewer.Count > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.GreaterThan && l.LeftSideIsNewer.Value)
|
||||
DoWork(logger, rightDirectory, httpClient, leftSideIsNewer, delete: true, download: true);
|
||||
if (notEqualBut.Count > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Plus && l.NotEqualBut.Value)
|
||||
DoWork(logger, rightDirectory, httpClient, notEqualBut, delete: true, download: true);
|
||||
if (rightSideIsNewer.Count > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.GreaterThan && l.RightSideIsNewer.Value)
|
||||
DoWork(logger, rightDirectory, httpClient, rightSideIsNewer, delete: true, download: true);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetAreEqual(string rightDirectory, string fileName, ReadOnlyCollection<Record> rightRecords, string rootUniformResourceLocators, ReadOnlyCollection<Record> leftRecords) {
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
double totalSeconds;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(rightRecords);
|
||||
foreach (Record r in leftRecords) {
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0) {
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == rightDirectory || r.RelativePath == fileName)
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
|
||||
if (record.Size != r.Size || totalSeconds is > 2 or < -2)
|
||||
continue;
|
||||
segment = new(Left: r,
|
||||
LeftDirectory: checkDirectory,
|
||||
Right: record,
|
||||
RightDirectory: rightDirectory,
|
||||
RootUniformResourceLocator: rootUniformResourceLocators);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(ReadOnlyCollection<Record> records) {
|
||||
Dictionary<string, Record> results = [];
|
||||
foreach (Record record in records)
|
||||
results.Add(record.RelativePath, record);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetNotEqualBut(string rightDirectory, string fileName, ReadOnlyCollection<Record> rightRecords, string rootUniformResourceLocators, ReadOnlyCollection<Record> leftRecords) {
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
double totalSeconds;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(rightRecords);
|
||||
foreach (Record r in leftRecords) {
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0) {
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == rightDirectory || r.RelativePath == fileName)
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
if (record.Size == r.Size)
|
||||
continue;
|
||||
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
|
||||
if (totalSeconds is >= 2 or <= -2)
|
||||
continue;
|
||||
segment = new(Left: r,
|
||||
LeftDirectory: checkDirectory,
|
||||
Right: record,
|
||||
RightDirectory: rightDirectory,
|
||||
RootUniformResourceLocator: rootUniformResourceLocators);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetLeftSideOnly(string rightDirectory, string fileName, ReadOnlyCollection<Record> rightRecords, string rootUniformResourceLocators, ReadOnlyCollection<Record> leftRecords) {
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(rightRecords);
|
||||
foreach (Record r in leftRecords) {
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0) {
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == rightDirectory || r.RelativePath == fileName)
|
||||
continue;
|
||||
if (keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
segment = new(Left: r,
|
||||
LeftDirectory: checkDirectory,
|
||||
Right: record,
|
||||
RightDirectory: rightDirectory,
|
||||
RootUniformResourceLocator: rootUniformResourceLocators);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetRightSideOnly(string rightDirectory, string fileName, ReadOnlyCollection<Record> rightRecords, string rootUniformResourceLocators, ReadOnlyCollection<Record> leftRecords) {
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(leftRecords);
|
||||
foreach (Record r in rightRecords) {
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0) {
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == rightDirectory || r.RelativePath == fileName)
|
||||
continue;
|
||||
if (keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
segment = new(Left: record,
|
||||
LeftDirectory: null,
|
||||
Right: r,
|
||||
RightDirectory: rightDirectory,
|
||||
RootUniformResourceLocator: rootUniformResourceLocators);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetLeftSideIsNewer(string rightDirectory, string fileName, ReadOnlyCollection<Record> rightRecords, string rootUniformResourceLocators, ReadOnlyCollection<Record> leftRecords) {
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
double totalSeconds;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(rightRecords);
|
||||
foreach (Record r in leftRecords) {
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0) {
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == rightDirectory || r.RelativePath == fileName)
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
|
||||
if (totalSeconds is > -2)
|
||||
continue;
|
||||
segment = new(Left: r,
|
||||
LeftDirectory: checkDirectory,
|
||||
Right: record,
|
||||
RightDirectory: rightDirectory,
|
||||
RootUniformResourceLocator: rootUniformResourceLocators);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetRightSideIsNewer(string rightDirectory, string fileName, ReadOnlyCollection<Record> rightRecords, string rootUniformResourceLocators, ReadOnlyCollection<Record> leftRecords) {
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
double totalSeconds;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(leftRecords);
|
||||
foreach (Record r in rightRecords) {
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0) {
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == rightDirectory || r.RelativePath == fileName)
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
|
||||
if (totalSeconds is > -2)
|
||||
continue;
|
||||
segment = new(Left: record,
|
||||
LeftDirectory: null,
|
||||
Right: r,
|
||||
RightDirectory: rightDirectory,
|
||||
RootUniformResourceLocator: rootUniformResourceLocators);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
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; }
|
||||
string size = GetSizeWithSuffix(sum);
|
||||
if (delete) {
|
||||
logger.LogInformation("Starting to delete {count} file(s) [{sum}]", segments.Count, size);
|
||||
DoDeletes(logger, rightDirectory, segments);
|
||||
logger.LogInformation("Deleted {count} file(s) [{sum}]", segments.Count, size);
|
||||
}
|
||||
if (download) {
|
||||
logger.LogInformation("Starting to download {count} file(s) [{sum}]", segments.Count, size);
|
||||
DoDownloads(logger, rightDirectory, segments, httpClient);
|
||||
logger.LogInformation("Downloaded {count} file(s) [{sum}]", segments.Count, size);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetSizeWithSuffix(long value) {
|
||||
string result;
|
||||
int i = 0;
|
||||
string[] SizeSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
if (value < 0) {
|
||||
result = "-" + GetSizeWithSuffix(-value);
|
||||
} else {
|
||||
while (Math.Round(value / 1024f) >= 1) {
|
||||
value /= 1024;
|
||||
i++;
|
||||
}
|
||||
result = string.Format("{0:n1} {1}", value, SizeSuffixes[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string GetDurationWithSuffix(long ticks) {
|
||||
string result;
|
||||
TimeSpan timeSpan = new(DateTime.Now.Ticks - ticks);
|
||||
if (timeSpan.TotalMilliseconds < 1000)
|
||||
result = $"{timeSpan.Milliseconds} ms";
|
||||
else if (timeSpan.TotalMilliseconds < 60000)
|
||||
result = $"{Math.Floor(timeSpan.TotalSeconds)} s";
|
||||
else if (timeSpan.TotalMilliseconds < 3600000)
|
||||
result = $"{Math.Floor(timeSpan.TotalMinutes)} m";
|
||||
else
|
||||
result = $"{Math.Floor(timeSpan.TotalHours)} h";
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void DoDeletes(ILogger<Worker> logger, string rightDirectory, ReadOnlyCollection<Segment> segments) {
|
||||
Record? record;
|
||||
string size;
|
||||
string count = segments.Count.ToString("000000");
|
||||
#if ShellProgressBar
|
||||
ProgressBar progressBar = new(segments.Count, $"Deleting: {count};", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
|
||||
#endif
|
||||
for (int i = 0; i < segments.Count; i++) {
|
||||
#if ShellProgressBar
|
||||
progressBar.Tick();
|
||||
#endif
|
||||
record = segments[i].Right;
|
||||
if (record is null)
|
||||
continue;
|
||||
size = GetSizeWithSuffix(record.Size);
|
||||
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) {
|
||||
logger.LogInformation("Failed to delete: <{RelativePath}> - {size};", record.RelativePath, size);
|
||||
}
|
||||
}
|
||||
#if ShellProgressBar
|
||||
progressBar.Dispose();
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void DoDownloads(ILogger<Worker> logger, string rightDirectory, ReadOnlyCollection<Segment> segments, HttpClient httpClient) {
|
||||
int i = 0;
|
||||
long ticks;
|
||||
string size;
|
||||
string duration;
|
||||
DateTime dateTime;
|
||||
Task<string> response;
|
||||
string count = segments.Count.ToString("000000");
|
||||
ReadOnlyCollection<Download> downloads = GetDownloads(rightDirectory, segments);
|
||||
Task<HttpResponseMessage> httpResponseMessage;
|
||||
#if ShellProgressBar
|
||||
ProgressBar progressBar = new(downloads.Count, $"Downloading: {count};", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
|
||||
#endif
|
||||
foreach (Download download in downloads) {
|
||||
#if ShellProgressBar
|
||||
progressBar.Tick();
|
||||
#endif
|
||||
i += 1;
|
||||
ticks = DateTime.Now.Ticks;
|
||||
size = GetSizeWithSuffix(download.Size);
|
||||
httpResponseMessage = httpClient.GetAsync(download.UniformResourceLocator);
|
||||
httpResponseMessage.Wait(-1);
|
||||
if (!httpResponseMessage.Result.IsSuccessStatusCode)
|
||||
logger.LogInformation("Failed to download: <{checkURL}> - {size};", download.UniformResourceLocator, size);
|
||||
else {
|
||||
response = httpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
response.Wait();
|
||||
try {
|
||||
File.WriteAllText(download.File, response.Result);
|
||||
duration = GetDurationWithSuffix(ticks);
|
||||
dateTime = new DateTime(download.Ticks).ToLocalTime();
|
||||
File.SetLastWriteTime(download.File, dateTime);
|
||||
logger.LogInformation("{i} of {count} - Downloaded: <{checkURL}> - {size} - {timeSpan};",
|
||||
i.ToString("000000"),
|
||||
count,
|
||||
download.Display,
|
||||
size,
|
||||
duration);
|
||||
} catch (Exception) {
|
||||
logger.LogInformation("Failed to download: <{checkURL}> - {size};", download.UniformResourceLocator, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if ShellProgressBar
|
||||
progressBar.Dispose();
|
||||
#endif
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Download> GetDownloads(string rightDirectory, ReadOnlyCollection<Segment> segments) {
|
||||
List<Download> results = [];
|
||||
string checkFile;
|
||||
Download download;
|
||||
string? checkDirectory;
|
||||
List<Download> collection = [];
|
||||
string? checkUniformResourceLocator;
|
||||
foreach (Segment segment in segments) {
|
||||
if (segment.Left is null)
|
||||
continue;
|
||||
checkFile = Path.Combine(rightDirectory, segment.Left.RelativePath);
|
||||
checkDirectory = Path.GetDirectoryName(checkFile);
|
||||
if (string.IsNullOrEmpty(checkDirectory))
|
||||
continue;
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
if (File.Exists(checkFile) && new FileInfo(checkFile).Length == 0)
|
||||
File.Delete(checkFile);
|
||||
checkUniformResourceLocator = ConvertTo(segment.RootUniformResourceLocator, segment.Left.RelativePath);
|
||||
if (string.IsNullOrEmpty(checkUniformResourceLocator))
|
||||
continue;
|
||||
download = new(Directory: checkDirectory,
|
||||
Display: checkUniformResourceLocator[segment.RootUniformResourceLocator.Length..],
|
||||
File: checkFile,
|
||||
Size: segment.Left.Size,
|
||||
Ticks: segment.Left.Ticks,
|
||||
UniformResourceLocator: checkUniformResourceLocator);
|
||||
collection.Add(download);
|
||||
}
|
||||
Download[] sorted = (from l in collection orderby l.Size select l).ToArray();
|
||||
int stop = sorted.Length < 100 ? sorted.Length : 100;
|
||||
for (int i = 0; i < stop; i++)
|
||||
results.Add(sorted[i]);
|
||||
for (int i = sorted.Length - 1; i > stop - 1; i--)
|
||||
results.Add(sorted[i]);
|
||||
if (collection.Count != results.Count)
|
||||
throw new Exception();
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string? ConvertTo(string rootURL, string relativePath) {
|
||||
string? result = rootURL.EndsWith('/') ? rootURL[..^1] : rootURL;
|
||||
string windowsRoot = "c:\\";
|
||||
string windowsMock = $"{windowsRoot}{relativePath}";
|
||||
string fileName = Path.GetFileName(windowsMock);
|
||||
ReadOnlyCollection<string> directoryNames = Helpers.HelperDirectory.GetDirectoryNames(windowsMock);
|
||||
foreach (string directoryName in directoryNames) {
|
||||
if (directoryName == windowsRoot || directoryName == fileName)
|
||||
continue;
|
||||
result = $"{result}/{directoryName}";
|
||||
}
|
||||
result = result == rootURL ? null : $"{result}/{fileName}";
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
47
ADO2025/PI5/Helper-2025-04-21.cs
Normal file
47
ADO2025/PI5/Helper-2025-04-21.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250421 {
|
||||
|
||||
internal static void FreeFileSyncChangeCreatedDate(ILogger<Worker> logger, List<string> args) {
|
||||
string searchPattern = args[2];
|
||||
string[] searchPatterns = args[3].Split('~');
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
if (searchPatterns.Length != 2)
|
||||
throw new NotImplementedException($"Not the correct number of {searchPatterns} were passed!");
|
||||
string lastSyncSearch = $"{searchPatterns[0]}=\"";
|
||||
string configurationFileSearch = $"{searchPatterns[1]}=\"";
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
if (files.Length != 1)
|
||||
logger.LogWarning("<{files}>(s)", files.Length);
|
||||
else
|
||||
ChangeCreatedDate(lastSyncSearch, configurationFileSearch, files[0]);
|
||||
}
|
||||
|
||||
private static void ChangeCreatedDate(string lastSyncSearch, string configurationFileSearch, string sourceFile) {
|
||||
long epoch;
|
||||
string lastSync;
|
||||
string[] segments;
|
||||
string[] segmentsB;
|
||||
DateTime creationTime;
|
||||
string configurationFile;
|
||||
string[] lines = File.ReadAllLines(sourceFile);
|
||||
foreach (string line in lines) {
|
||||
segments = line.Split(lastSyncSearch);
|
||||
if (segments.Length != 2)
|
||||
continue;
|
||||
segmentsB = line.Split(configurationFileSearch);
|
||||
if (segmentsB.Length != 2)
|
||||
continue;
|
||||
lastSync = segments[1].Split('"')[0];
|
||||
if (!long.TryParse(lastSync, out epoch) || epoch == 0)
|
||||
continue;
|
||||
configurationFile = segmentsB[1].Split('"')[0];
|
||||
if (!File.Exists(configurationFile))
|
||||
continue;
|
||||
creationTime = new(DateTimeOffset.UnixEpoch.AddSeconds(epoch).ToLocalTime().Ticks);
|
||||
File.SetCreationTime(configurationFile, creationTime);
|
||||
}
|
||||
}
|
||||
}
|
72
ADO2025/PI5/Helper-2025-04-29.cs
Normal file
72
ADO2025/PI5/Helper-2025-04-29.cs
Normal file
@ -0,0 +1,72 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
|
||||
using File_Folder_Helper.Models;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250429 {
|
||||
|
||||
private record Record(string Directory, string File, bool FileExists);
|
||||
|
||||
internal static void WriteNginxFileSystem(ILogger<Worker> logger, List<string> args) {
|
||||
string searchPattern = args[2];
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
ReadOnlyCollection<Record> subDirectories = GetSubDirectories(searchPattern, sourceDirectory);
|
||||
if (subDirectories.Count == 0)
|
||||
logger.LogWarning("<{results}>(s)", subDirectories.Count);
|
||||
else
|
||||
WriteNginxFileSystem(searchPattern, subDirectories);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetSubDirectories(string searchPattern, string sourceDirectory) {
|
||||
List<Record> results = [];
|
||||
bool exists;
|
||||
Record record;
|
||||
string checkFile;
|
||||
string[] subDirectories;
|
||||
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string directory in directories) {
|
||||
subDirectories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string subDirectory in subDirectories) {
|
||||
checkFile = Path.Combine(subDirectory, $"{searchPattern.Split('*')[^1]}.json");
|
||||
exists = File.Exists(checkFile);
|
||||
record = new(Directory: subDirectory, File: checkFile, FileExists: exists);
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
return results.OrderByDescending(l => l.FileExists).ToArray().AsReadOnly();
|
||||
}
|
||||
|
||||
private static void WriteNginxFileSystem(string searchPattern, ReadOnlyCollection<Record> subDirectories) {
|
||||
string lines;
|
||||
string result;
|
||||
string[] files;
|
||||
FileInfo fileInfo;
|
||||
List<string> results = [];
|
||||
NginxFileSystem nginxFileSystem;
|
||||
foreach (Record record in subDirectories) {
|
||||
results.Clear();
|
||||
files = Directory.GetFiles(record.Directory, searchPattern, SearchOption.AllDirectories);
|
||||
foreach (string file in files) {
|
||||
fileInfo = new(file);
|
||||
nginxFileSystem = new(Name: fileInfo.FullName,
|
||||
LastModified: null,
|
||||
MTime: fileInfo.LastWriteTime.ToUniversalTime().ToString(),
|
||||
URI: null,
|
||||
Type: "file",
|
||||
Length: fileInfo.Length);
|
||||
results.Add(JsonSerializer.Serialize(nginxFileSystem, NginxFileSystemSingleLineSourceGenerationContext.Default.NginxFileSystem));
|
||||
}
|
||||
if (results.Count == 0)
|
||||
continue;
|
||||
result = $"[{Environment.NewLine}{string.Join($",{Environment.NewLine}", results)}{Environment.NewLine}]";
|
||||
lines = !record.FileExists ? string.Empty : File.ReadAllText(record.File);
|
||||
if (result == lines)
|
||||
continue;
|
||||
File.WriteAllText(record.File, result);
|
||||
}
|
||||
}
|
||||
}
|
84
ADO2025/PI5/Helper-2025-05-05.cs
Normal file
84
ADO2025/PI5/Helper-2025-05-05.cs
Normal file
@ -0,0 +1,84 @@
|
||||
#if Html2pdf
|
||||
using iText.Html2pdf;
|
||||
#endif
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
#if Selenium
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Edge;
|
||||
#endif
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI5;
|
||||
|
||||
internal static partial class Helper20250505 {
|
||||
|
||||
// <PackageReference Include="Selenium.WebDriver" Version="4.31.0" />
|
||||
// <PackageReference Include="iText" Version="9.1.0" />
|
||||
// <PackageReference Include="iText.bouncy-castle-adapter" Version="9.1.0" />
|
||||
// <PackageReference Include="iText.commons" Version="9.1.0" />
|
||||
// <PackageReference Include="iText.hyph" Version="9.1.0" />
|
||||
// <PackageReference Include="iText.pdfhtml" Version="6.1.0" />
|
||||
|
||||
internal static void HyperTextMarkupLanguageToPortableDocumentFormat(ILogger<Worker> logger, List<string> args) {
|
||||
if (args.Count == 999)
|
||||
TestA();
|
||||
if (args.Count == 999)
|
||||
TestB();
|
||||
if (args.Count != 999)
|
||||
TestC(logger);
|
||||
}
|
||||
|
||||
private static void TestA() {
|
||||
#if Html2pdf
|
||||
string inputFile = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", ".html");
|
||||
string outputFile = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", "a.pdf");
|
||||
using (FileStream htmlSource = File.Open(inputFile, FileMode.Open))
|
||||
using (FileStream pdfDest = File.Open(outputFile, FileMode.Create)) {
|
||||
ConverterProperties converterProperties = new();
|
||||
HtmlConverter.ConvertToPdf(htmlSource, pdfDest, converterProperties);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void TestB() {
|
||||
#if Html2pdf
|
||||
HttpClient httpClient = new();
|
||||
Task<Stream> stream = httpClient.GetStreamAsync("https://ourrescue.org/");
|
||||
stream.Wait();
|
||||
string outputFile = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", "b.pdf");
|
||||
using (FileStream pdfDest = File.Open(outputFile, FileMode.Create)) {
|
||||
ConverterProperties converterProperties = new();
|
||||
HtmlConverter.ConvertToPdf(stream.Result, pdfDest, converterProperties);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void TestC(ILogger<Worker> logger) {
|
||||
#if Selenium
|
||||
EdgeOptions edgeOptions = new();
|
||||
edgeOptions.AddArgument("--no-sandbox");
|
||||
edgeOptions.AddArgument("--disable-gpu");
|
||||
edgeOptions.AddArgument("--headless=new");
|
||||
edgeOptions.AddArgument("--start-maximized");
|
||||
edgeOptions.AddArgument("--profile-directory=Default");
|
||||
edgeOptions.AddArgument("--browser-version 133.0.3065.82");
|
||||
EdgeDriver edgeDriver = new(edgeOptions);
|
||||
string outputFile = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", ".png");
|
||||
try {
|
||||
// edgeDriver.Navigate().GoToUrl("https://ourrescue.org/");
|
||||
// edgeDriver.Navigate().GoToUrl("https://intranet.infineon.com/");
|
||||
edgeDriver.Navigate().GoToUrl("https://messa020ec.infineon.com:50205/ProductionReport/DailyReport");
|
||||
int fullWidth = int.Parse(edgeDriver.ExecuteScript("return document.body.parentNode.scrollWidth").ToString());
|
||||
int fullHeight = int.Parse(edgeDriver.ExecuteScript("return document.body.parentNode.scrollHeight").ToString());
|
||||
edgeDriver.Manage().Window.Size = new(fullWidth, fullHeight);
|
||||
Screenshot screenshot = edgeDriver.GetScreenshot();
|
||||
screenshot.SaveAsFile(outputFile);
|
||||
} catch (Exception ex) {
|
||||
logger.LogError(ex, ex.Message);
|
||||
}
|
||||
edgeDriver.Close();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
381
ADO2025/PI6/.editorconfig
Normal file
381
ADO2025/PI6/.editorconfig
Normal file
@ -0,0 +1,381 @@
|
||||
[*.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 = false
|
||||
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_line_after_token_in_arrow_expression_clause_experimental = true
|
||||
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
|
||||
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
|
||||
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 = error # 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 = error # 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 = error # 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_diagnostic.IDE2000.severity = error # IDE2000: Allow multiple blank lines
|
||||
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 = true
|
||||
dotnet_sort_system_directives_first = true
|
||||
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
|
||||
|
||||
# Question
|
||||
csharp_prefer_simple_using_statement = false # Question
|
||||
csharp_style_expression_bodied_constructors = when_on_single_line:none # Question
|
||||
csharp_style_expression_bodied_properties = true # Question
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning # Question
|
||||
csharp_style_pattern_matching_over_as_with_null_check = false # Question
|
||||
csharp_style_prefer_pattern_matching = false # Question
|
||||
csharp_style_prefer_range_operator = false # Question
|
||||
csharp_style_prefer_switch_expression = false # Question
|
||||
csharp_style_unused_value_assignment_preference = unused_local_variable # Question
|
||||
csharp_style_unused_value_expression_statement_preference = false # Question
|
||||
csharp_style_var_elsewhere = false:none # Question
|
||||
csharp_style_var_for_built_in_types = false:none # Question
|
||||
csharp_style_var_when_type_is_apparent = false:warning # Question
|
||||
dotnet_diagnostic.CA1001.severity = none # Question - Types that own disposable fields should be disposable
|
||||
dotnet_diagnostic.CA1051.severity = none # Question - Do not declare visible instance fields
|
||||
dotnet_diagnostic.CA1416.severity = none # Question - This call site is reachable on all platforms.
|
||||
dotnet_diagnostic.CA1510.severity = none # Question - Use
|
||||
dotnet_diagnostic.CA1834.severity = none # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
|
||||
dotnet_diagnostic.CA1860.severity = none # Question - Avoid using
|
||||
dotnet_diagnostic.CA1862.severity = none # Question - Prefer using
|
||||
dotnet_diagnostic.CA2208.severity = none # Question - Instantiate argument exceptions correctly
|
||||
dotnet_diagnostic.CA2211.severity = none # Question - Non-constant fields should not be visible
|
||||
dotnet_diagnostic.CA2249.severity = none # Question - Use
|
||||
dotnet_diagnostic.CA2253.severity = none # Question - Named placeholders should not be numeric values
|
||||
dotnet_diagnostic.CS0103.severity = none # Question - The name
|
||||
dotnet_diagnostic.CS0168.severity = none # Question - The variable
|
||||
dotnet_diagnostic.CS0219.severity = none # Question - The variable
|
||||
dotnet_diagnostic.CS0612.severity = none # Question - is obsolete
|
||||
dotnet_diagnostic.CS0618.severity = none # Question - Compiler Warning (level 2)
|
||||
dotnet_diagnostic.CS0659.severity = none # Question - Compiler Warning (level 3)
|
||||
dotnet_diagnostic.CS8019.severity = warning # Question - Unnecessary using directive.
|
||||
dotnet_diagnostic.CS8600.severity = none # Question - Converting null literal or possible null value to non-nullable type
|
||||
dotnet_diagnostic.CS8602.severity = none # Question - Dereference of a possibly null reference.
|
||||
dotnet_diagnostic.CS8603.severity = none # Question - Possible null reference return
|
||||
dotnet_diagnostic.CS8604.severity = none # Question - Possible null reference argument for parameter.
|
||||
dotnet_diagnostic.CS8618.severity = none # Question - Non-nullable variable must contain a non-null value when exiting constructor
|
||||
dotnet_diagnostic.CS8625.severity = none # Question - Cannot convert null literal to non-nullable reference type.
|
||||
dotnet_diagnostic.CS8629.severity = none # Question - Nullable value type may be null
|
||||
dotnet_diagnostic.CS8765.severity = none # Question - Nullability of type of parameter
|
||||
dotnet_diagnostic.IDE0005.severity = none # Question - Remove unnecessary using directives
|
||||
dotnet_diagnostic.IDE0008.severity = warning # Question - Use explicit type instead of
|
||||
dotnet_diagnostic.IDE0017.severity = none # Question - Object initialization can be simplified
|
||||
dotnet_diagnostic.IDE0019.severity = none # Question - Use pattern matching
|
||||
dotnet_diagnostic.IDE0021.severity = none # Question - Use expression body for constructor
|
||||
dotnet_diagnostic.IDE0022.severity = none # Question - Use expression body for method
|
||||
dotnet_diagnostic.IDE0025.severity = none # Question - Use expression body for property
|
||||
dotnet_diagnostic.IDE0027.severity = none # Question - Use expression body for accessor
|
||||
dotnet_diagnostic.IDE0028.severity = none # Question - Use collection initializers or expressions
|
||||
dotnet_diagnostic.IDE0031.severity = none # Question - Null check can be simplified
|
||||
dotnet_diagnostic.IDE0032.severity = none # Question - Use auto property
|
||||
dotnet_diagnostic.IDE0037.severity = none # Question - Member name can be simplified
|
||||
dotnet_diagnostic.IDE0041.severity = none # Question - Null check can be simplified
|
||||
dotnet_diagnostic.IDE0047.severity = none # Question - Parentheses preferences
|
||||
dotnet_diagnostic.IDE0049.severity = warning # Question - Name can be simplified
|
||||
dotnet_diagnostic.IDE0051.severity = none # Question - Remove unused private member
|
||||
dotnet_diagnostic.IDE0053.severity = none # Question - Use expression body for lambdas
|
||||
dotnet_diagnostic.IDE0054.severity = none # Question - Use compound assignment
|
||||
dotnet_diagnostic.IDE0055.severity = none # Question - Formatting rule
|
||||
dotnet_diagnostic.IDE0057.severity = none # Question - Substring can be simplified
|
||||
dotnet_diagnostic.IDE0058.severity = none # Question - Remove unnecessary expression value
|
||||
dotnet_diagnostic.IDE0059.severity = none # Question - Unnecessary assignment of a value to
|
||||
dotnet_diagnostic.IDE0060.severity = none # Question - Remove unused parameter
|
||||
dotnet_diagnostic.IDE0063.severity = none # Question - Use simple
|
||||
dotnet_diagnostic.IDE0065.severity = none # Question -
|
||||
dotnet_diagnostic.IDE0066.severity = none # Question - Use
|
||||
dotnet_diagnostic.IDE0078.severity = none # Question - Use pattern matching (may change code meaning)
|
||||
dotnet_diagnostic.IDE0090.severity = warning # Question - Simplify new expression
|
||||
dotnet_diagnostic.IDE0100.severity = error # Question - Remove redundant equality
|
||||
dotnet_diagnostic.IDE0160.severity = warning # Question - Use block-scoped namespace
|
||||
dotnet_diagnostic.IDE0161.severity = warning # Question - Namespace declaration preferences
|
||||
dotnet_diagnostic.IDE0270.severity = none # Question - Null check can be simplified
|
||||
dotnet_diagnostic.IDE0300.severity = none # Question - Collection initialization can be simplified
|
||||
dotnet_diagnostic.IDE1006.severity = none # Question - Use collection expression for builder dotnet_style_prefer_collection_expression
|
||||
dotnet_style_null_propagation = false # Question
|
||||
dotnet_style_object_initializer = false # Question
|
||||
dotnet_style_prefer_auto_properties = false # Question
|
||||
dotnet_style_allow_statement_immediately_after_block_experimental = true # Question
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = false:warning # Question
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = false # Question
|
277
ADO2025/PI6/Envelope.cs
Normal file
277
ADO2025/PI6/Envelope.cs
Normal file
@ -0,0 +1,277 @@
|
||||
#nullable disable
|
||||
#pragma warning disable CS8603
|
||||
#pragma warning disable CS8632
|
||||
#pragma warning disable IDE1006
|
||||
|
||||
namespace IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
|
||||
|
||||
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
|
||||
[System.Xml.Serialization.XmlRoot(Namespace = "http://www.w3.org/2003/05/soap-envelope", IsNullable = false)]
|
||||
public partial class Envelope
|
||||
{
|
||||
|
||||
private EnvelopeHeader? headerField;
|
||||
|
||||
private EnvelopeBody? bodyField;
|
||||
|
||||
/// <remarks/>
|
||||
public EnvelopeHeader Header
|
||||
{
|
||||
get => this.headerField;
|
||||
set => this.headerField = value;
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public EnvelopeBody Body
|
||||
{
|
||||
get => this.bodyField;
|
||||
set => this.bodyField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
|
||||
public partial class EnvelopeHeader
|
||||
{
|
||||
|
||||
private Sequence? sequenceField;
|
||||
private SequenceAcknowledgement? sequenceAcknowledgementField;
|
||||
private Action? actionField;
|
||||
|
||||
private string? relatesToField;
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public Sequence Sequence
|
||||
{
|
||||
get => this.sequenceField;
|
||||
set => this.sequenceField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public SequenceAcknowledgement SequenceAcknowledgement
|
||||
{
|
||||
get => this.sequenceAcknowledgementField;
|
||||
set => this.sequenceAcknowledgementField = value;
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")]
|
||||
public Action Action
|
||||
{
|
||||
get => this.actionField;
|
||||
set => this.actionField = value;
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")]
|
||||
public string RelatesTo
|
||||
{
|
||||
get => this.relatesToField;
|
||||
set => this.relatesToField = value;
|
||||
}
|
||||
}
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
[System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)]
|
||||
public partial class Sequence
|
||||
{
|
||||
private string? identifierField;
|
||||
private byte messageNumberField;
|
||||
private object? lastMessageField;
|
||||
private byte mustUnderstandField;
|
||||
/// <remarks/>
|
||||
public string Identifier
|
||||
{
|
||||
get => this.identifierField;
|
||||
set => this.identifierField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
public byte MessageNumber
|
||||
{
|
||||
get => this.messageNumberField;
|
||||
set => this.messageNumberField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
public object LastMessage
|
||||
{
|
||||
get => this.lastMessageField;
|
||||
set => this.lastMessageField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
|
||||
public byte mustUnderstand
|
||||
{
|
||||
get => this.mustUnderstandField;
|
||||
set => this.mustUnderstandField = value;
|
||||
}
|
||||
}
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
[System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)]
|
||||
public partial class SequenceAcknowledgement
|
||||
{
|
||||
private string? identifierField;
|
||||
private SequenceAcknowledgementAcknowledgementRange? acknowledgementRangeField;
|
||||
private byte bufferRemainingField;
|
||||
/// <remarks/>
|
||||
public string Identifier
|
||||
{
|
||||
get => this.identifierField;
|
||||
set => this.identifierField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
public SequenceAcknowledgementAcknowledgementRange AcknowledgementRange
|
||||
{
|
||||
get => this.acknowledgementRangeField;
|
||||
set => this.acknowledgementRangeField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.microsoft.com/ws/2006/05/rm")]
|
||||
public byte BufferRemaining
|
||||
{
|
||||
get => this.bufferRemainingField;
|
||||
set => this.bufferRemainingField = value;
|
||||
}
|
||||
}
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public partial class SequenceAcknowledgementAcknowledgementRange
|
||||
{
|
||||
private byte lowerField;
|
||||
private byte upperField;
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttribute()]
|
||||
public byte Lower
|
||||
{
|
||||
get => this.lowerField;
|
||||
set => this.lowerField = value;
|
||||
}
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttribute()]
|
||||
public byte Upper
|
||||
{
|
||||
get => this.upperField;
|
||||
set => this.upperField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2005/08/addressing")]
|
||||
[System.Xml.Serialization.XmlRoot(Namespace = "http://www.w3.org/2005/08/addressing", IsNullable = false)]
|
||||
public partial class Action
|
||||
{
|
||||
|
||||
private byte mustUnderstandField;
|
||||
|
||||
private string? valueField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
|
||||
public byte mustUnderstand
|
||||
{
|
||||
get => this.mustUnderstandField;
|
||||
set => this.mustUnderstandField = value;
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlText()]
|
||||
public string Value
|
||||
{
|
||||
get => this.valueField;
|
||||
set => this.valueField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
|
||||
public partial class EnvelopeBody
|
||||
{
|
||||
|
||||
private CreateSequenceResponse? createSequenceResponseField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public CreateSequenceResponse CreateSequenceResponse
|
||||
{
|
||||
get => this.createSequenceResponseField;
|
||||
set => this.createSequenceResponseField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
[System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)]
|
||||
public partial class CreateSequenceResponse
|
||||
{
|
||||
|
||||
private string? identifierField;
|
||||
|
||||
private CreateSequenceResponseAccept? acceptField;
|
||||
|
||||
/// <remarks/>
|
||||
public string Identifier
|
||||
{
|
||||
get => this.identifierField;
|
||||
set => this.identifierField = value;
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public CreateSequenceResponseAccept Accept
|
||||
{
|
||||
get => this.acceptField;
|
||||
set => this.acceptField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public partial class CreateSequenceResponseAccept
|
||||
{
|
||||
|
||||
private CreateSequenceResponseAcceptAcksTo? acksToField;
|
||||
|
||||
/// <remarks/>
|
||||
public CreateSequenceResponseAcceptAcksTo AcksTo
|
||||
{
|
||||
get => this.acksToField;
|
||||
set => this.acksToField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[Serializable()]
|
||||
[System.ComponentModel.DesignerCategory("code")]
|
||||
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
|
||||
public partial class CreateSequenceResponseAcceptAcksTo
|
||||
{
|
||||
|
||||
private string? addressField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")]
|
||||
public string Address
|
||||
{
|
||||
get => this.addressField;
|
||||
set => this.addressField = value;
|
||||
}
|
||||
}
|
531
ADO2025/PI6/Helper-2025-05-19.cs
Normal file
531
ADO2025/PI6/Helper-2025-05-19.cs
Normal file
@ -0,0 +1,531 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Web;
|
||||
|
||||
using Microsoft.Extensions.FileSystemGlobbing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250519 {
|
||||
|
||||
private record RelativePath(string LeftDirectory,
|
||||
string? RightDirectory,
|
||||
Record[] Records) {
|
||||
|
||||
public override string ToString() {
|
||||
string result = JsonSerializer.Serialize(this, Helper20250519RelativePath.Default.RelativePath);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(RelativePath))]
|
||||
private partial class Helper20250519RelativePath : JsonSerializerContext {
|
||||
}
|
||||
|
||||
private record Review(Segment[]? AreEqual,
|
||||
Segment[]? LeftSideIsNewer,
|
||||
Segment[]? LeftSideOnly,
|
||||
Segment[]? NotEqualBut,
|
||||
Record[]? Records,
|
||||
Segment[]? RightSideIsNewer,
|
||||
Segment[]? RightSideOnly) {
|
||||
|
||||
public override string ToString() {
|
||||
string result = JsonSerializer.Serialize(this, Helper20250519Review.Default.Review);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Review))]
|
||||
private partial class Helper20250519Review : JsonSerializerContext {
|
||||
}
|
||||
|
||||
private record Record(string RelativePath,
|
||||
long Size,
|
||||
long Ticks);
|
||||
|
||||
private record Segment(Record? Left,
|
||||
Record? Right);
|
||||
|
||||
private record Verb(string Directory,
|
||||
string Display,
|
||||
string File,
|
||||
string Multipart,
|
||||
string RelativePath,
|
||||
long Size,
|
||||
long Ticks,
|
||||
string UrlEncodedFile);
|
||||
|
||||
private record Input(string RightDirectory,
|
||||
string LeftDirectory,
|
||||
string IncludePatternsFile,
|
||||
string ExcludePatternsFile,
|
||||
string[] BaseAddresses,
|
||||
string Page,
|
||||
string[] Segments) {
|
||||
|
||||
private static string GetDirectory(List<string> args) =>
|
||||
Path.GetFullPath(args[0].Split('~')[0]);
|
||||
|
||||
internal static Input Get(List<string> args) =>
|
||||
new(RightDirectory: GetDirectory(args),
|
||||
LeftDirectory: Path.GetFullPath(args[2].Split('~')[0]),
|
||||
IncludePatternsFile: Path.Combine(GetDirectory(args), ".vscode", args[3]),
|
||||
ExcludePatternsFile: Path.Combine(GetDirectory(args), ".vscode", args[4]),
|
||||
BaseAddresses: args.Count < 5 ? [] : args[5].Split('~'),
|
||||
Page: args[6],
|
||||
Segments: args[9].Split('~'));
|
||||
|
||||
public override string ToString() {
|
||||
string result = JsonSerializer.Serialize(this, Helper20250519Input.Default.Input);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Input))]
|
||||
private partial class Helper20250519Input : JsonSerializerContext {
|
||||
}
|
||||
|
||||
private record Logic(string Comment,
|
||||
char GreaterThan,
|
||||
bool? LeftSideIsNewer,
|
||||
int LeftSideIsNewerIndex,
|
||||
bool? LeftSideOnly,
|
||||
int LeftSideOnlyIndex,
|
||||
char LessThan,
|
||||
char Minus,
|
||||
bool? NotEqualBut,
|
||||
int NotEqualButIndex,
|
||||
char Plus,
|
||||
string[] Raw,
|
||||
bool? RightSideIsNewer,
|
||||
int RightSideIsNewerIndex,
|
||||
bool? RightSideOnly,
|
||||
int RightSideOnlyIndex) {
|
||||
|
||||
internal static Logic? Get(string[] segments) {
|
||||
Logic? result;
|
||||
bool check = true;
|
||||
bool? notEqualBut;
|
||||
bool? leftSideOnly;
|
||||
bool? rightSideOnly;
|
||||
bool? leftSideIsNewer;
|
||||
const char plus = '+';
|
||||
bool? rightSideIsNewer;
|
||||
const char minus = '-';
|
||||
const char lessThan = 'L';
|
||||
const int commentIndex = 5;
|
||||
const char greaterThan = 'G';
|
||||
const int notEqualButIndex = 2;
|
||||
const int leftSideOnlyIndex = 0;
|
||||
const int rightSideOnlyIndex = 4;
|
||||
const int leftSideIsNewerIndex = 1;
|
||||
const int rightSideIsNewerIndex = 3;
|
||||
string comment = segments[commentIndex];
|
||||
if (string.IsNullOrEmpty(segments[leftSideOnlyIndex])) {
|
||||
leftSideOnly = null;
|
||||
} else if (segments[leftSideOnlyIndex][0] == plus) {
|
||||
leftSideOnly = true;
|
||||
} else if (segments[leftSideOnlyIndex][0] == minus) {
|
||||
leftSideOnly = false;
|
||||
} else {
|
||||
check = false;
|
||||
leftSideOnly = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[leftSideIsNewerIndex])) {
|
||||
leftSideIsNewer = null;
|
||||
} else if (segments[leftSideIsNewerIndex][0] == greaterThan) {
|
||||
leftSideIsNewer = true;
|
||||
} else if (segments[leftSideIsNewerIndex][0] == lessThan) {
|
||||
leftSideIsNewer = false;
|
||||
} else {
|
||||
check = false;
|
||||
leftSideIsNewer = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[notEqualButIndex])) {
|
||||
notEqualBut = null;
|
||||
} else if (segments[notEqualButIndex][0] == greaterThan) {
|
||||
notEqualBut = true;
|
||||
} else if (segments[notEqualButIndex][0] == lessThan) {
|
||||
notEqualBut = false;
|
||||
} else {
|
||||
check = false;
|
||||
notEqualBut = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[rightSideIsNewerIndex])) {
|
||||
rightSideIsNewer = null;
|
||||
} else if (segments[rightSideIsNewerIndex][0] == greaterThan) {
|
||||
rightSideIsNewer = true;
|
||||
} else if (segments[rightSideIsNewerIndex][0] == lessThan) {
|
||||
rightSideIsNewer = false;
|
||||
} else {
|
||||
check = false;
|
||||
rightSideIsNewer = null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(segments[rightSideOnlyIndex])) {
|
||||
rightSideOnly = null;
|
||||
} else if (segments[rightSideOnlyIndex][0] == plus) {
|
||||
rightSideOnly = true;
|
||||
} else if (segments[rightSideOnlyIndex][0] == minus) {
|
||||
rightSideOnly = false;
|
||||
} else {
|
||||
check = false;
|
||||
rightSideOnly = null;
|
||||
}
|
||||
result = !check ? null : new(Comment: comment,
|
||||
GreaterThan: greaterThan,
|
||||
LeftSideIsNewerIndex: leftSideIsNewerIndex,
|
||||
LeftSideIsNewer: leftSideIsNewer,
|
||||
LeftSideOnly: leftSideOnly,
|
||||
LeftSideOnlyIndex: leftSideOnlyIndex,
|
||||
LessThan: lessThan,
|
||||
Minus: minus,
|
||||
NotEqualBut: notEqualBut,
|
||||
NotEqualButIndex: notEqualButIndex,
|
||||
Plus: plus,
|
||||
RightSideIsNewer: rightSideIsNewer,
|
||||
RightSideIsNewerIndex: rightSideIsNewerIndex,
|
||||
RightSideOnly: rightSideOnly,
|
||||
Raw: segments,
|
||||
RightSideOnlyIndex: rightSideOnlyIndex);
|
||||
return result;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
string result = JsonSerializer.Serialize(this, Helper20250519Logic.Default.Logic);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Logic))]
|
||||
private partial class Helper20250519Logic : JsonSerializerContext {
|
||||
}
|
||||
|
||||
internal static void LiveSync(ILogger<Worker> logger, List<string> args) {
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
if (args[2].EndsWith("input.json") && !File.Exists(args[2])) {
|
||||
File.WriteAllText(args[2], "{}");
|
||||
}
|
||||
string? json = !args[2].EndsWith("input.json") ? null : File.ReadAllText(args[2]);
|
||||
Input input = string.IsNullOrEmpty(json)
|
||||
? Input.Get(args)
|
||||
: JsonSerializer.Deserialize(json, Helper20250519Input.Default.Input)
|
||||
?? throw new Exception();
|
||||
Logic? logic = input.Segments.Length != 6 ? null : Logic.Get(input.Segments);
|
||||
if (logic is null || input.BaseAddresses.Length == 0) {
|
||||
logger.LogInformation($"Invalid input!{Environment.NewLine}{input}");
|
||||
} else {
|
||||
Matcher matcher = GetMatcher(input.ExcludePatternsFile, input.IncludePatternsFile);
|
||||
ReadOnlyCollection<Record> records = GetRecords(input.RightDirectory, matcher);
|
||||
if (records.Count == 0) {
|
||||
logger.LogInformation("No source records");
|
||||
} else {
|
||||
RelativePath relativePath = new(LeftDirectory: input.LeftDirectory, RightDirectory: input.RightDirectory, Records: records.ToArray());
|
||||
json = JsonSerializer.Serialize(relativePath, Helper20250519RelativePath.Default.RelativePath);
|
||||
if (string.IsNullOrEmpty(json)) {
|
||||
LiveSync180(logger, logic, input.BaseAddresses, input.Page, relativePath);
|
||||
} else {
|
||||
File.WriteAllText(Path.Combine(input.RightDirectory, ".vscode", $"{nameof(RelativePath)}.json"), json);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Matcher GetMatcher(string excludePatternsFile, string includePatternsFile) {
|
||||
Matcher result = new();
|
||||
result.AddIncludePatterns(!File.Exists(includePatternsFile) ? ["*"] : File.ReadAllLines(includePatternsFile));
|
||||
result.AddExcludePatterns(!File.Exists(excludePatternsFile) ? ["System Volume Information"] : File.ReadAllLines(excludePatternsFile));
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetRecords(string directory, Matcher matcher) {
|
||||
List<Record> results = [
|
||||
new(RelativePath: directory,
|
||||
Size: 0,
|
||||
Ticks: 0)];
|
||||
Record record;
|
||||
FileInfo fileInfo;
|
||||
string relativePath;
|
||||
ReadOnlyCollection<ReadOnlyCollection<string>> collection = Helpers.HelperDirectory.GetFilesCollection(directory, "*", "*");
|
||||
foreach (ReadOnlyCollection<string> c in collection) {
|
||||
foreach (string f in c) {
|
||||
if (!matcher.Match(directory, f).HasMatches) {
|
||||
continue;
|
||||
}
|
||||
fileInfo = new(f);
|
||||
if (fileInfo.Length == 0) {
|
||||
continue;
|
||||
}
|
||||
relativePath = Path.GetRelativePath(directory, fileInfo.FullName);
|
||||
record = new(RelativePath: relativePath,
|
||||
Size: fileInfo.Length,
|
||||
Ticks: fileInfo.LastWriteTime.ToUniversalTime().Ticks);
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void LiveSync180(ILogger<Worker> logger, Logic logic, string[] baseAddresses, string page, RelativePath relativePath) {
|
||||
Review? review;
|
||||
Task<string> response;
|
||||
Task<HttpResponseMessage> httpResponseMessage;
|
||||
string json = JsonSerializer.Serialize(relativePath, Helper20250519RelativePath.Default.RelativePath);
|
||||
foreach (string baseAddress in baseAddresses) {
|
||||
if (!baseAddress.StartsWith("http:")) {
|
||||
logger.LogInformation("Not supported URL <{url}>", baseAddress);
|
||||
} else {
|
||||
HttpClient httpClient = new();
|
||||
httpClient.BaseAddress = new(baseAddress);
|
||||
StringContent stringContent = new(json, Encoding.UTF8, "application/json");
|
||||
httpResponseMessage = httpClient.PostAsync(page, stringContent);
|
||||
httpResponseMessage.Wait();
|
||||
if (!httpResponseMessage.Result.IsSuccessStatusCode) {
|
||||
logger.LogInformation("Failed to download: <{uniformResourceLocator}>;", httpClient.BaseAddress);
|
||||
} else {
|
||||
response = httpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
response.Wait();
|
||||
review = JsonSerializer.Deserialize(response.Result, Helper20250519Review.Default.Review);
|
||||
if (review is null) {
|
||||
logger.LogInformation("Failed to download: <{uniformResourceLocator}>;", httpClient.BaseAddress);
|
||||
continue;
|
||||
}
|
||||
LiveSync(logger, logic, page, relativePath, httpClient, review);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void LiveSync(ILogger<Worker> logger, Logic l, string page, RelativePath relativePath, HttpClient httpClient, Review review) {
|
||||
if (review.NotEqualBut?.Length > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Minus && !l.NotEqualBut.Value) {
|
||||
logger.LogDebug("Doing nothing with {name}", nameof(Logic.NotEqualBut));
|
||||
}
|
||||
if (review.LeftSideOnly?.Length > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Minus && !l.LeftSideOnly.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.LeftDirectory, (from x in review.LeftSideOnly select x.Left).ToArray().AsReadOnly(), HttpMethod.Delete, delete: false);
|
||||
}
|
||||
if (review.LeftSideIsNewer?.Length > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.LessThan && !l.LeftSideIsNewer.Value) {
|
||||
throw new Exception(); // LiveSync(logger, page, relativePath, httpClient, relativePath.LeftDirectory, (from x in review.LeftSideIsNewer select x.Left).ToArray().AsReadOnly(), HttpMethod.Patch, delete: true);
|
||||
}
|
||||
if (review.RightSideIsNewer?.Length > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.LessThan && !l.RightSideIsNewer.Value) {
|
||||
throw new Exception(); // LiveSync(logger, page, relativePath, httpClient, relativePath.RightDirectory, (from x in review.RightSideIsNewer select x.Right).ToArray().AsReadOnly(), HttpMethod.Patch, delete: true);
|
||||
}
|
||||
if (review.RightSideOnly?.Length > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Plus && l.RightSideOnly.Value) {
|
||||
throw new Exception(); // LiveSync(logger, page, relativePath, httpClient, relativePath.RightDirectory, (from x in review.RightSideOnly select x.Right).ToArray().AsReadOnly(), HttpMethod.Put, delete: false);
|
||||
}
|
||||
if (review.RightSideOnly?.Length > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Minus && !l.RightSideOnly.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.RightDirectory, (from x in review.RightSideOnly select x.Right).ToArray().AsReadOnly(), httpMethod: null, delete: true);
|
||||
}
|
||||
if (review.LeftSideOnly?.Length > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Plus && l.LeftSideOnly.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.LeftDirectory, (from x in review.LeftSideOnly select x.Left).ToArray().AsReadOnly(), HttpMethod.Get, delete: false);
|
||||
}
|
||||
if (review.LeftSideIsNewer?.Length > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.GreaterThan && l.LeftSideIsNewer.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.LeftDirectory, (from x in review.LeftSideIsNewer select x.Left).ToArray().AsReadOnly(), HttpMethod.Get, delete: true);
|
||||
}
|
||||
if (review.NotEqualBut?.Length > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Plus && l.NotEqualBut.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.LeftDirectory, (from x in review.NotEqualBut select x.Left).ToArray().AsReadOnly(), HttpMethod.Get, delete: true);
|
||||
}
|
||||
if (review.RightSideIsNewer?.Length > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.GreaterThan && l.RightSideIsNewer.Value) {
|
||||
LiveSync(logger, page, relativePath, httpClient, relativePath.RightDirectory, (from x in review.RightSideIsNewer select x.Right).ToArray().AsReadOnly(), HttpMethod.Get, delete: true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void LiveSync(ILogger<Worker> logger, string page, RelativePath relativePath, HttpClient httpClient, string directory, ReadOnlyCollection<Record> records, HttpMethod? httpMethod, bool delete) {
|
||||
long sum;
|
||||
try { sum = records.Sum(l => l.Size); } catch (Exception) { sum = 0; }
|
||||
string size = GetSizeWithSuffix(sum);
|
||||
if (delete) {
|
||||
logger.LogInformation("Starting to delete {count} file(s) [{sum}]", records.Count, size);
|
||||
PreformDeletes(logger, relativePath.RightDirectory, records);
|
||||
logger.LogInformation("Deleted {count} file(s) [{sum}]", records.Count, size);
|
||||
}
|
||||
if (httpMethod is not null) {
|
||||
logger.LogInformation("Starting to {httpMethod} {count} file(s) [{sum}]", httpMethod.ToString().ToLower(), records.Count, size);
|
||||
Preform(logger, page, directory, records, httpClient, httpMethod);
|
||||
logger.LogInformation("{httpMethod}'ed {count} file(s) [{sum}]", httpMethod.ToString(), records.Count, size);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetSizeWithSuffix(long value) {
|
||||
string result;
|
||||
int i = 0;
|
||||
string[] SizeSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
if (value < 0) {
|
||||
result = "-" + GetSizeWithSuffix(-value);
|
||||
} else {
|
||||
while (Math.Round(value / 1024f) >= 1) {
|
||||
value /= 1024;
|
||||
i++;
|
||||
}
|
||||
result = string.Format("{0:n1} {1}", value, SizeSuffixes[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void PreformDeletes(ILogger<Worker> logger, string directory, ReadOnlyCollection<Record> records) {
|
||||
string size;
|
||||
Record? record;
|
||||
string count = records.Count.ToString("000000");
|
||||
#if ShellProgressBar
|
||||
ProgressBar progressBar = new(records.Count, $"Deleting: {count};", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
|
||||
#endif
|
||||
for (int i = 0; i < records.Count; i++) {
|
||||
#if ShellProgressBar
|
||||
progressBar.Tick();
|
||||
#endif
|
||||
record = records[i];
|
||||
if (record is null) {
|
||||
continue;
|
||||
}
|
||||
size = GetSizeWithSuffix(record.Size);
|
||||
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) {
|
||||
logger.LogInformation("Failed to delete: <{RelativePath}> - {size};", record.RelativePath, size);
|
||||
}
|
||||
}
|
||||
#if ShellProgressBar
|
||||
progressBar.Dispose();
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void Preform(ILogger<Worker> logger, string page, string directory, ReadOnlyCollection<Record> records, HttpClient httpClient, HttpMethod httpMethod) {
|
||||
Verb verb;
|
||||
long ticks;
|
||||
string size;
|
||||
string iValue;
|
||||
string duration;
|
||||
DateTime dateTime;
|
||||
Task<string> response;
|
||||
HttpRequestMessage httpRequestMessage;
|
||||
Task<HttpResponseMessage> httpResponseMessage;
|
||||
string count = records.Count.ToString("000000");
|
||||
MultipartFormDataContent multipartFormDataContent;
|
||||
ReadOnlyCollection<Verb> collection = GetVerbCollection(directory, records);
|
||||
#if ShellProgressBar
|
||||
ProgressBar progressBar = new(downloads.Count, $"{httpMethod}ing: {count};", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
|
||||
#endif
|
||||
for (int i = 0; i < collection.Count; i++) {
|
||||
verb = collection[i];
|
||||
#if ShellProgressBar
|
||||
progressBar.Tick();
|
||||
#endif
|
||||
ticks = DateTime.Now.Ticks;
|
||||
iValue = (i + 1).ToString("000000");
|
||||
size = GetSizeWithSuffix(verb.Size);
|
||||
if (httpMethod == HttpMethod.Get || httpMethod == HttpMethod.Delete) {
|
||||
httpRequestMessage = new(httpMethod, $"{page}size={verb.Size}&ticks={verb.Ticks}&path={verb.UrlEncodedFile}");
|
||||
} else if (httpMethod == HttpMethod.Patch || httpMethod == HttpMethod.Put) {
|
||||
httpRequestMessage = new(httpMethod, $"{page}path={verb.Directory}");
|
||||
multipartFormDataContent = new();
|
||||
multipartFormDataContent.Add(new ByteArrayContent(File.ReadAllBytes(verb.File)), "formFiles", verb.Multipart);
|
||||
multipartFormDataContent.Add(new StringContent(verb.Directory), "path", iValue);
|
||||
httpRequestMessage.Content = multipartFormDataContent;
|
||||
} else
|
||||
throw new NotImplementedException();
|
||||
httpResponseMessage = httpClient.SendAsync(httpRequestMessage);
|
||||
httpResponseMessage.Wait(-1);
|
||||
if (!httpResponseMessage.Result.IsSuccessStatusCode) {
|
||||
logger.LogInformation("Failed to {httpMethod}: <{display}> - {size};", httpMethod, verb.Display, size);
|
||||
} else {
|
||||
try {
|
||||
if (httpMethod != HttpMethod.Get) {
|
||||
duration = GetDurationWithSuffix(ticks);
|
||||
} else {
|
||||
response = httpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
response.Wait();
|
||||
File.WriteAllText(verb.File, response.Result);
|
||||
duration = GetDurationWithSuffix(ticks);
|
||||
dateTime = new DateTime(verb.Ticks).ToLocalTime();
|
||||
File.SetLastWriteTime(verb.File, dateTime);
|
||||
}
|
||||
logger.LogInformation("{i} of {count} - {httpMethod}'ed: <{display}> - {size} - {timeSpan};",
|
||||
iValue,
|
||||
count,
|
||||
httpMethod,
|
||||
verb.Display,
|
||||
size,
|
||||
duration);
|
||||
} catch (Exception) {
|
||||
logger.LogInformation("Failed to {httpMethod}: <{display}> - {size};", httpMethod, verb.Display, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if ShellProgressBar
|
||||
progressBar.Dispose();
|
||||
#endif
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Verb> GetVerbCollection(string directory, ReadOnlyCollection<Record> records) {
|
||||
List<Verb> results = [];
|
||||
Verb verb;
|
||||
string checkFile;
|
||||
string checkFileName;
|
||||
string? checkDirectory;
|
||||
List<Verb> collection = [];
|
||||
foreach (Record record in records) {
|
||||
checkFile = Path.Combine(directory, record.RelativePath);
|
||||
checkFileName = Path.GetFileName(checkFile);
|
||||
checkDirectory = Path.GetDirectoryName(checkFile);
|
||||
if (string.IsNullOrEmpty(checkDirectory)) {
|
||||
continue;
|
||||
}
|
||||
if (!Directory.Exists(checkDirectory)) {
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
}
|
||||
if (File.Exists(checkFile) && new FileInfo(checkFile).Length == 0) {
|
||||
File.Delete(checkFile);
|
||||
}
|
||||
verb = new(Directory: checkDirectory,
|
||||
Display: $"{checkFileName}{Environment.NewLine}{checkDirectory}",
|
||||
File: checkFile,
|
||||
Multipart: $"RelativePath:{record.RelativePath}|Size:{record.Size}|Ticks:{record.Ticks};",
|
||||
RelativePath: record.RelativePath,
|
||||
Size: record.Size,
|
||||
Ticks: record.Ticks,
|
||||
UrlEncodedFile: HttpUtility.UrlEncode(checkFile));
|
||||
collection.Add(verb);
|
||||
}
|
||||
Verb[] sorted = (from l in collection orderby l.Size select l).ToArray();
|
||||
int stop = sorted.Length < 100 ? sorted.Length : 100;
|
||||
for (int i = 0; i < stop; i++) {
|
||||
results.Add(sorted[i]);
|
||||
}
|
||||
for (int i = sorted.Length - 1; i > stop - 1; i--) {
|
||||
results.Add(sorted[i]);
|
||||
}
|
||||
if (collection.Count != results.Count) {
|
||||
throw new Exception();
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string GetDurationWithSuffix(long ticks) {
|
||||
string result;
|
||||
TimeSpan timeSpan = new(DateTime.Now.Ticks - ticks);
|
||||
if (timeSpan.TotalMilliseconds < 1000) {
|
||||
result = $"{timeSpan.Milliseconds} ms";
|
||||
} else if (timeSpan.TotalMilliseconds < 60000) {
|
||||
result = $"{Math.Floor(timeSpan.TotalSeconds)} s";
|
||||
} else if (timeSpan.TotalMilliseconds < 3600000) {
|
||||
result = $"{Math.Floor(timeSpan.TotalMinutes)} m";
|
||||
} else {
|
||||
result = $"{Math.Floor(timeSpan.TotalHours)} h";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
184
ADO2025/PI6/Helper-2025-05-21.cs
Normal file
184
ADO2025/PI6/Helper-2025-05-21.cs
Normal file
@ -0,0 +1,184 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250521 {
|
||||
|
||||
[GeneratedRegex(@"[~\-,.0-9]")]
|
||||
private static partial Regex Number();
|
||||
|
||||
[GeneratedRegex(@"[^\u0020-\u007E]")]
|
||||
private static partial Regex ASCII();
|
||||
|
||||
private record Record(string Directory, string FileNameWithoutExtension);
|
||||
|
||||
private record LineCheck(string[] Segments, DateTime TransactionDate, DateTime EffectiveDate) {
|
||||
|
||||
internal static LineCheck Get(int dateLineSegmentCount, string datePattern, string line) {
|
||||
LineCheck result;
|
||||
string[] segments = line.Split(' ');
|
||||
if (segments.Length >= dateLineSegmentCount
|
||||
&& segments[0].Length == datePattern.Length
|
||||
&& segments[1].Length == datePattern.Length
|
||||
&& DateTime.TryParseExact(segments[0], datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime transactionDate)
|
||||
&& DateTime.TryParseExact(segments[1], datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime effectiveDate)) {
|
||||
result = new(Segments: segments, TransactionDate: transactionDate, EffectiveDate: effectiveDate);
|
||||
} else {
|
||||
result = new(Segments: segments, TransactionDate: DateTime.MinValue, EffectiveDate: DateTime.MinValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private record RecordB(int I,
|
||||
DateTime TransactionDate,
|
||||
DateTime EffectiveDate,
|
||||
string Description,
|
||||
decimal WithdrawalOrDeposit,
|
||||
decimal Balance);
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(RecordB[]))]
|
||||
private partial class Helper20250521RecordB : JsonSerializerContext {
|
||||
}
|
||||
|
||||
internal static void MatchDirectory(ILogger<Worker> logger, List<string> args) {
|
||||
Record record;
|
||||
string datePattern = args[5];
|
||||
string searchPattern = args[2];
|
||||
string searchPatternB = args[3];
|
||||
string columns = args[6].Replace('~', ',');
|
||||
int dateLineSegmentCount = int.Parse(args[4]);
|
||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
ReadOnlyDictionary<string, string> keyValuePairs = GetKeyValuePairs(searchPattern, sourceDirectory);
|
||||
MoveMatchDirectory(searchPatternB, keyValuePairs, sourceDirectory);
|
||||
ReadOnlyCollection<RecordB> records = GetRecords(searchPatternB, sourceDirectory, dateLineSegmentCount, datePattern, columns);
|
||||
WriteRecords(sourceDirectory, records);
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, string> GetKeyValuePairs(string searchPattern, string sourceDirectory) {
|
||||
Dictionary<string, string> results = [];
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
foreach (string file in files) {
|
||||
results.Add(Path.GetFileNameWithoutExtension(file), Path.GetDirectoryName(file));
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void MoveMatchDirectory(string searchPatternB, ReadOnlyDictionary<string, string> keyValuePairs, string sourceDirectory) {
|
||||
string checkFile;
|
||||
string fileNameWithoutExtension;
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPatternB, SearchOption.AllDirectories);
|
||||
foreach (string file in files) {
|
||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
|
||||
if (!keyValuePairs.TryGetValue(fileNameWithoutExtension, out string? match))
|
||||
continue;
|
||||
checkFile = Path.Combine(match, Path.GetFileName(file));
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
File.Move(file, checkFile);
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<RecordB> GetRecords(string searchPatternB, string sourceDirectory, int dateLineSegmentCount, string datePattern, string columns) {
|
||||
List<RecordB> results = [];
|
||||
string line;
|
||||
string[] lines;
|
||||
RecordB? record;
|
||||
LineCheck lineCheck;
|
||||
string[] files = Directory.GetFiles(sourceDirectory, searchPatternB, SearchOption.AllDirectories);
|
||||
foreach (string file in files) {
|
||||
lines = File.ReadAllLines(file);
|
||||
for (int i = 0; i < lines.Length; i++) {
|
||||
line = lines[i];
|
||||
if (string.IsNullOrEmpty(line)) {
|
||||
continue;
|
||||
}
|
||||
lineCheck = LineCheck.Get(dateLineSegmentCount, datePattern, line);
|
||||
if (lineCheck.EffectiveDate == DateTime.MinValue || lineCheck.TransactionDate == DateTime.MinValue) {
|
||||
continue;
|
||||
} else {
|
||||
record = GetRecord(dateLineSegmentCount, datePattern, lines, i, lineCheck.Segments, lineCheck.TransactionDate, lineCheck.EffectiveDate);
|
||||
if (record is not null) {
|
||||
i = record.I;
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static RecordB? GetRecord(int dateLineSegmentCount, string datePattern, string[] lines, int i, string[] segments, DateTime transactionDate, DateTime effectiveDate) {
|
||||
RecordB? result = null;
|
||||
string line;
|
||||
RecordB record;
|
||||
LineCheck lineCheck;
|
||||
List<string> collection = [];
|
||||
for (int j = i + 1; j < lines.Length; j++) {
|
||||
line = lines[j];
|
||||
if (string.IsNullOrEmpty(line)) {
|
||||
continue;
|
||||
}
|
||||
lineCheck = LineCheck.Get(dateLineSegmentCount, datePattern, line);
|
||||
if (lineCheck.EffectiveDate == DateTime.MinValue || lineCheck.TransactionDate == DateTime.MinValue) {
|
||||
collection.Add(line);
|
||||
} else {
|
||||
if (lineCheck.Segments.Length > dateLineSegmentCount) {
|
||||
collection.Insert(0, string.Join(' ', lineCheck.Segments.Skip(2)));
|
||||
}
|
||||
result = GetRecord(transactionDate, effectiveDate, collection.AsReadOnly(), j - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result is null && collection.Count > 0) {
|
||||
result = GetRecord(transactionDate, effectiveDate, collection.AsReadOnly(), lines.Length - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static RecordB GetRecord(DateTime transactionDate, DateTime effectiveDate, ReadOnlyCollection<string> collection, int i) {
|
||||
RecordB? result;
|
||||
List<string> verified = [];
|
||||
foreach (string check in collection) {
|
||||
if (Number().Replace(check, string.Empty).Length != 0) {
|
||||
verified.Clear();
|
||||
} else {
|
||||
verified.Add(check);
|
||||
}
|
||||
if (verified.Count == 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (verified.Count != 2) {
|
||||
result = null;
|
||||
} else {
|
||||
decimal balance = decimal.Parse(verified[^1]);
|
||||
decimal withdrawalOrDeposit = decimal.Parse(verified[^2]);
|
||||
string description = ASCII().Replace(string.Join(' ', collection.SkipLast(2)), string.Empty);
|
||||
result = new(I: i,
|
||||
TransactionDate: transactionDate,
|
||||
EffectiveDate: effectiveDate,
|
||||
Description: description,
|
||||
WithdrawalOrDeposit: withdrawalOrDeposit,
|
||||
Balance: balance);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void WriteRecords(string sourceDirectory, ReadOnlyCollection<RecordB> records) {
|
||||
string json = JsonSerializer.Serialize(records.ToArray(), Helper20250521RecordB.Default.RecordBArray);
|
||||
string sourceDirectoryVsCode = Path.Combine(sourceDirectory, ".vscode");
|
||||
if (!Directory.Exists(sourceDirectoryVsCode))
|
||||
_ = Directory.CreateDirectory(sourceDirectoryVsCode);
|
||||
File.WriteAllText(Path.Combine(sourceDirectoryVsCode, $"{DateTime.Now.Ticks}.json"), json);
|
||||
}
|
||||
|
||||
}
|
394
ADO2025/PI6/Helper-2025-06-01.cs
Normal file
394
ADO2025/PI6/Helper-2025-06-01.cs
Normal file
@ -0,0 +1,394 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
using IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250601 {
|
||||
|
||||
private static readonly bool _IsEnvironment_Development = false;
|
||||
|
||||
private record Record(string Text, string Host, int Port, string[] Segments, bool StateContainsDisabled);
|
||||
|
||||
private record Status(string CellInstanceName,
|
||||
string CommunicationState,
|
||||
string CurrentActiveVersion,
|
||||
string CurrentHost,
|
||||
string ErrorDescription,
|
||||
string Host,
|
||||
string IsReadyForRestart,
|
||||
string NPort,
|
||||
int Port,
|
||||
string StartTime,
|
||||
string Startable,
|
||||
string State,
|
||||
string StopTime,
|
||||
string Text);
|
||||
|
||||
internal static void EquipmentAutomationFrameworkStatus(ILogger<Worker> logger, List<string> args) {
|
||||
Status status;
|
||||
Record? record;
|
||||
List<string[]> messages;
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
string[] cellInstanceNames = args[2].Split('~');
|
||||
Dictionary<string, Record> records;
|
||||
if (_IsEnvironment_Development) {
|
||||
records = GetEquipmentAutomationFrameworkCellInstanceStatus(development: true, staging: false, production: false);
|
||||
} else {
|
||||
records = GetEquipmentAutomationFrameworkCellInstanceStatus(development: false, staging: true, production: true);
|
||||
}
|
||||
foreach (string cellInstanceName in cellInstanceNames) {
|
||||
if (!records.TryGetValue(cellInstanceName, out record)) {
|
||||
logger.LogWarning("{cellInstance} not found!", cellInstanceName);
|
||||
continue;
|
||||
}
|
||||
status = EquipmentAutomationFrameworkCellInstanceStatus(cellInstanceName, record);
|
||||
logger.LogInformation("{host}) {cellInstanceName} => {status}", record.Host, cellInstanceName, status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, Record> GetEquipmentAutomationFrameworkCellInstanceStatus(bool development, bool staging, bool production) {
|
||||
Dictionary<string, Record> results = [];
|
||||
string key;
|
||||
string host;
|
||||
string text;
|
||||
string state;
|
||||
string response;
|
||||
bool stop = false;
|
||||
string[] segments;
|
||||
string[] cellNames;
|
||||
byte[] responseBytes;
|
||||
string responseAfter;
|
||||
#pragma warning disable SYSLIB0014
|
||||
WebClient webClient = new();
|
||||
#pragma warning restore SYSLIB0014
|
||||
string disabled = "Disabled";
|
||||
UnicodeCategory unicodeCategory;
|
||||
StringBuilder stringBuilder = new();
|
||||
EquipmentAutomationFrameworkCellInstanceParseCheck();
|
||||
Dictionary<char, char> unicodeReplaces = GetUnicodeReplaces();
|
||||
List<UnicodeCategory> unicodeCategories = GetUnicodeCategory();
|
||||
ReadOnlyCollection<string> urls = GetUrls(development, staging, production);
|
||||
// Dictionary<UnicodeCategory, List<char>> unicodeCategoriesList = new Dictionary<UnicodeCategory, List<char>>();
|
||||
byte[] bodyBytes = [86, 2, 11, 1, 115, 4, 11, 1, 97, 6, 86, 8, 68, 10, 30, 0, 130, 153, 48, 104, 116, 116, 112, 58, 47, 47, 116, 101, 109, 112, 117, 114, 105, 46, 111, 114, 103, 47, 73, 83, 116, 97, 116, 117, 115, 81, 117, 101, 114, 121, 47, 71, 101, 116, 70, 97, 99, 116, 111, 114, 121, 83, 116, 97, 116, 117, 115, 68, 26, 173, 181, 241, 2, 149, 65, 209, 208, 66, 143, 234, 233, 157, 246, 118, 78, 238, 68, 44, 68, 42, 171, 20, 1, 68, 12, 30, 0, 130, 153, 49, 104, 116, 116, 112, 58, 47, 47, 101, 97, 102, 45, 112, 114, 111, 100, 46, 109, 101, 115, 46, 105, 110, 102, 105, 110, 101, 111, 110, 46, 99, 111, 109, 58, 57, 48, 48, 51, 47, 83, 116, 97, 116, 117, 115, 81, 117, 101, 114, 121, 1, 86, 14, 64, 16, 71, 101, 116, 70, 97, 99, 116, 111, 114, 121, 83, 116, 97, 116, 117, 115, 8, 19, 104, 116, 116, 112, 58, 47, 47, 116, 101, 109, 112, 117, 114, 105, 46, 111, 114, 103, 47, 64, 16, 105, 110, 99, 108, 117, 100, 101, 65, 103, 101, 110, 116, 76, 105, 115, 116, 135, 64, 17, 105, 110, 99, 108, 117, 100, 101, 83, 116, 97, 116, 117, 115, 76, 105, 115, 116, 135, 64, 23, 101, 120, 116, 101, 110, 100, 101, 100, 83, 116, 97, 116, 117, 115, 67, 101, 108, 108, 78, 97, 109, 101, 115, 9, 1, 98, 57, 104, 116, 116, 112, 58, 47, 47, 115, 99, 104, 101, 109, 97, 115, 46, 109, 105, 99, 114, 111, 115, 111, 102, 116, 46, 99, 111, 109, 47, 50, 48, 48, 51, 47, 49, 48, 47, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 47, 65, 114, 114, 97, 121, 115, 9, 1, 105, 41, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97, 45, 105, 110, 115, 116, 97, 110, 99, 101, 95, 6, 115, 116, 114, 105, 110, 103, 153, 20, 66, 73, 79, 82, 65, 68, 53, 95, 70, 105, 108, 101, 65, 114, 99, 104, 105, 118, 101, 114, 1, 1, 1, 1];
|
||||
foreach (string url in urls) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
segments = url.Split(':');
|
||||
host = segments[0];
|
||||
if (segments.Length == 0 || !int.TryParse(segments[1], out int port)) {
|
||||
port = 80;
|
||||
}
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+msbin1");
|
||||
responseBytes = webClient.UploadData($"http://{host}:{port}/StatusQuery", bodyBytes);
|
||||
// File.WriteAllText(@"L:\Tmp\a.txt", BitConverter.ToString(responseBytes));
|
||||
response = Encoding.UTF8.GetString(responseBytes);
|
||||
foreach (char c in response) {
|
||||
unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
|
||||
if (unicodeCategory == UnicodeCategory.Control && unicodeReplaces.ContainsKey(c)) {
|
||||
_ = stringBuilder.Append(unicodeReplaces[c]);
|
||||
} else if (unicodeCategories.Contains(unicodeCategory)) {
|
||||
_ = stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
responseAfter = stringBuilder.ToString();
|
||||
cellNames = responseAfter.Split(new string[] { "CellName" }, StringSplitOptions.None);
|
||||
foreach (string segment in cellNames) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
key = string.Empty;
|
||||
state = string.Empty;
|
||||
segments = segment.Split(new string[] { "WindowsName" }, StringSplitOptions.None);
|
||||
if (segments.Length != 2) {
|
||||
continue;
|
||||
}
|
||||
text = segments[0];
|
||||
segments = text.Replace('\r', ' ').Replace('\n', ' ').Split(' ');
|
||||
for (int i = 0; i < segments.Length - 3; i++) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(segments[i]) && string.IsNullOrEmpty(key)) {
|
||||
key = segments[i].Trim();
|
||||
} else if (segments[i].StartsWith("State")) {
|
||||
state = segments[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (key.EndsWith("a")) {
|
||||
key = key[..^1];
|
||||
}
|
||||
if (!results.ContainsKey(key)) {
|
||||
results.Add(key, new Record(Text: text, Host: host, Port: port, Segments: segments, StateContainsDisabled: state.Contains(disabled)));
|
||||
} else if (results[key].StateContainsDisabled) {
|
||||
results[key] = new Record(Text: text, Host: host, Port: port, Segments: segments, StateContainsDisabled: state.Contains(disabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<string> GetUrls(bool development, bool staging, bool production) {
|
||||
List<string> results = [];
|
||||
if (development) {
|
||||
results.Add("eaf-dev.mes.infineon.com:9003");
|
||||
}
|
||||
if (staging) {
|
||||
results.Add("eaf-staging.mes.infineon.com:9003");
|
||||
}
|
||||
if (production) {
|
||||
results.Add("eaf-prod.mes.infineon.com:9003");
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static List<UnicodeCategory> GetUnicodeCategory() {
|
||||
List<UnicodeCategory> unicodeCategories = [
|
||||
// UnicodeCategory.Control, // 33 - <20>
|
||||
UnicodeCategory.UppercaseLetter, // 25 - ABCDEFGHIJKLMNOPQRSTUVWXY
|
||||
UnicodeCategory.LowercaseLetter, // 25 - abcdefghiklmnopqrstuvwxyz
|
||||
UnicodeCategory.DecimalDigitNumber, // 10 - 0123456789
|
||||
UnicodeCategory.OtherPunctuation, // 10 - !"#%&,./:@
|
||||
UnicodeCategory.ClosePunctuation, // 2 - )]
|
||||
UnicodeCategory.MathSymbol, // 2 - |؈
|
||||
UnicodeCategory.OpenPunctuation, // 2 - ([
|
||||
// UnicodeCategory.OtherSymbol, // 1 - <20>
|
||||
UnicodeCategory.DashPunctuation, // 1 - -
|
||||
UnicodeCategory.ConnectorPunctuation, // 1 - _
|
||||
UnicodeCategory.ModifierSymbol, // 1 - `
|
||||
UnicodeCategory.NonSpacingMark, // 1 - ̵
|
||||
UnicodeCategory.SpaceSeparator, // 1 -
|
||||
UnicodeCategory.CurrencySymbol, // 1 - $
|
||||
];
|
||||
return unicodeCategories;
|
||||
}
|
||||
|
||||
private static void EquipmentAutomationFrameworkCellInstanceParseCheck() {
|
||||
Envelope? envelope;
|
||||
string xmlStart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:6eb7a538-0b2b-4d04-8f2a-ab50e1e5338a</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlStart891 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/StartAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:38977fa4-262a-42fb-8df7-d8d3074820b2</a:RelatesTo></s:Header><s:Body><StartAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlStart748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlStart707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string xmlStop621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:97f7aeb4-015f-440b-b0ff-a2a5aa4f4ab9</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlStop889 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/StopAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:04b8b0ea-8576-4756-b456-8a817cd10826</a:RelatesTo></s:Header><s:Body><StopAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlStop748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlStop707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string xmlRestart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:e228a621-e7ab-4ebf-97ba-5571cb5f4ad7</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlRestart895 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/RestartAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:efaeaf12-4aa0-4cd1-8296-05019e47261a</a:RelatesTo></s:Header><s:Body><RestartAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlRestart748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlRestart707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string[] xmlSets = [xmlStart621, xmlStart891, xmlStart748, xmlStart707, xmlStop621, xmlStop889, xmlStop748, xmlStop707, xmlRestart621, xmlRestart895, xmlRestart748, xmlRestart707];
|
||||
foreach (string xmlSet in xmlSets) {
|
||||
envelope = ParseXML<Envelope>(xmlSet, throwExceptions: true);
|
||||
}
|
||||
}
|
||||
|
||||
private static T? ParseXML<T>(string value, bool throwExceptions) where T : class {
|
||||
object? result = null;
|
||||
try {
|
||||
Stream stream = ToStream(value.Trim());
|
||||
XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
|
||||
#pragma warning disable IL2026, IL2090
|
||||
XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes());
|
||||
result = xmlSerializer.Deserialize(xmlReader);
|
||||
#pragma warning restore IL2026, IL2090
|
||||
stream.Dispose();
|
||||
} catch (Exception) {
|
||||
if (throwExceptions) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return result as T;
|
||||
}
|
||||
|
||||
private static Stream ToStream(string value) {
|
||||
MemoryStream memoryStream = new();
|
||||
StreamWriter streamWriter = new(memoryStream);
|
||||
streamWriter.Write(value);
|
||||
streamWriter.Flush();
|
||||
memoryStream.Position = 0;
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
private static Dictionary<char, char> GetUnicodeReplaces() {
|
||||
Dictionary<char, char> results = new() {
|
||||
{ '\u0000', ' ' },
|
||||
{ '\u0001', ' ' },
|
||||
{ '\u0002', ' ' },
|
||||
{ '\u0003', ' ' },
|
||||
{ '\u0004', ' ' },
|
||||
{ '\u0005', ' ' },
|
||||
{ '\u0006', ' ' },
|
||||
{ '\u0007', ' ' },
|
||||
{ '\u0008', ' ' },
|
||||
{ '\u0009', '\t' },
|
||||
{ '\u000A', '\r' },
|
||||
{ '\u000B', '\r' },
|
||||
{ '\u000C', '\t' },
|
||||
{ '\u000D', '\r' },
|
||||
{ '\u000E', ' ' },
|
||||
{ '\u000F', ' ' },
|
||||
{ '\u0010', ' ' },
|
||||
{ '\u0011', ' ' },
|
||||
{ '\u0012', ' ' },
|
||||
{ '\u0013', ' ' },
|
||||
{ '\u0014', ' ' },
|
||||
{ '\u0015', ' ' },
|
||||
{ '\u0016', ' ' },
|
||||
{ '\u0017', ' ' },
|
||||
{ '\u0018', ' ' },
|
||||
{ '\u0019', ' ' },
|
||||
{ '\u001A', ' ' },
|
||||
{ '\u001B', ' ' },
|
||||
{ '\u001C', '\r' },
|
||||
{ '\u001D', '\t' },
|
||||
{ '\u001E', '\t' },
|
||||
{ '\u001F', '\t' },
|
||||
{ '\u007F', ' ' },
|
||||
// C1
|
||||
{ '\u0080', '\t' },
|
||||
{ '\u0081', ' ' },
|
||||
{ '\u0082', ' ' },
|
||||
{ '\u0083', ' ' },
|
||||
{ '\u0084', ' ' },
|
||||
{ '\u0085', '\r' },
|
||||
{ '\u0086', ' ' },
|
||||
{ '\u0087', ' ' },
|
||||
{ '\u0088', '\t' },
|
||||
{ '\u0089', '\t' },
|
||||
{ '\u008A', '\t' },
|
||||
{ '\u008B', '\r' },
|
||||
{ '\u008C', ' ' },
|
||||
{ '\u008D', ' ' },
|
||||
{ '\u008E', ' ' },
|
||||
{ '\u008F', ' ' },
|
||||
{ '\u0090', ' ' },
|
||||
{ '\u0091', ' ' },
|
||||
{ '\u0092', ' ' },
|
||||
{ '\u0093', ' ' },
|
||||
{ '\u0094', ' ' },
|
||||
{ '\u0095', ' ' },
|
||||
{ '\u0096', ' ' },
|
||||
{ '\u0097', ' ' },
|
||||
{ '\u0098', ' ' },
|
||||
{ '\u0099', ' ' },
|
||||
{ '\u009A', ' ' },
|
||||
{ '\u009B', ' ' },
|
||||
{ '\u009C', ' ' },
|
||||
{ '\u009D', ' ' },
|
||||
{ '\u009E', ' ' },
|
||||
{ '\u009F', ' ' }
|
||||
};
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Status EquipmentAutomationFrameworkCellInstanceStatus(string cellInstanceName, Record record) {
|
||||
Status result;
|
||||
bool stop = false;
|
||||
string state = string.Empty;
|
||||
string stopTime = string.Empty;
|
||||
string startTime = string.Empty;
|
||||
string startable = string.Empty;
|
||||
string currentHost = string.Empty;
|
||||
string errorDescription = string.Empty;
|
||||
string isReadyForRestart = string.Empty;
|
||||
string communicationState = string.Empty;
|
||||
string currentActiveVersion = string.Empty;
|
||||
for (int i = 0; i < record.Segments.Length - 3; i++) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
if (string.IsNullOrEmpty(state) && record.Segments[i].StartsWith("State")) {
|
||||
state = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(startable) && record.Segments[i].Contains("Startable")) {
|
||||
startable = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(stopTime) && record.Segments[i].StartsWith("StopTime")) {
|
||||
stopTime = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(currentHost) && record.Segments[i].Contains("CurrentHost")) {
|
||||
currentHost = $"{record.Segments[i]} {record.Segments[i + 1]} {record.Segments[i + 2]}";
|
||||
} else if (string.IsNullOrEmpty(errorDescription) && record.Segments[i].StartsWith("ErrorDescription")) {
|
||||
errorDescription = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(communicationState) && record.Segments[i].StartsWith("CommunicationState")) {
|
||||
communicationState = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(isReadyForRestart) && record.Segments[i].StartsWith("IsReadyForRestart")) {
|
||||
isReadyForRestart = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(currentActiveVersion) && record.Segments[i].Contains("CurrentActiveVersion")) {
|
||||
currentActiveVersion = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(startTime) && record.Segments[i].Contains("StartTime")) {
|
||||
startTime = $"{record.Segments[i + 1]} {record.Segments[i + 2]} {record.Segments[i + 3]}".Split('\t')[0];
|
||||
}
|
||||
}
|
||||
if (errorDescription != "a") {
|
||||
string[] segments = record.Text.Split(new string[] { "ErrorDescription" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (segments.Length > 1) {
|
||||
segments = segments[1].Split(new string[] { "Info" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
errorDescription = segments[0].Trim();
|
||||
}
|
||||
}
|
||||
string nPort;
|
||||
Dictionary<string, string> nPorts = GetnPorts();
|
||||
if (!nPorts.ContainsKey(cellInstanceName)) {
|
||||
nPort = string.Empty;
|
||||
} else {
|
||||
nPort = nPorts[cellInstanceName];
|
||||
}
|
||||
if (state.EndsWith("a")) {
|
||||
state = state[0..^1];
|
||||
}
|
||||
if (state == "Running" && communicationState == "Not") {
|
||||
state = "Warning";
|
||||
}
|
||||
result = new(Host: record.Host,
|
||||
Port: record.Port,
|
||||
Text: record.Text,
|
||||
NPort: nPort,
|
||||
State: state,
|
||||
CellInstanceName: cellInstanceName,
|
||||
StopTime: stopTime,
|
||||
StartTime: startTime,
|
||||
Startable: startable,
|
||||
CurrentHost: currentHost,
|
||||
ErrorDescription: errorDescription,
|
||||
IsReadyForRestart: isReadyForRestart,
|
||||
CommunicationState: communicationState,
|
||||
CurrentActiveVersion: currentActiveVersion);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> GetnPorts() {
|
||||
Dictionary<string, string> results = new() {
|
||||
{ "TENCOR1", "10.95.192.31" },
|
||||
{ "TENCOR2", "10.95.192.32" },
|
||||
{ "TENCOR3", "10.95.192.33" },
|
||||
{ "HGCV1", "10.95.192.34" },
|
||||
{ "HGCV2", "10.95.154.17" },
|
||||
{ "HGCV3", "10.95.192.36" },
|
||||
{ "BIORAD2", "10.95.192.37" },
|
||||
{ "BIORAD3", "10.95.192.38" },
|
||||
{ "CDE2", "10.95.192.39" },
|
||||
{ "CDE3", "10.95.154.19" },
|
||||
{ "CDE5", "10.95.192.40" },
|
||||
{ "SPARE-1", "10.95.192.47" },
|
||||
{ "SPARE-2", "10.95.192.48" },
|
||||
{ "SPARE-3", "10.95.192.49" },
|
||||
{ "SPARE-4", "10.95.192.50" },
|
||||
{ "SPARE-5", "10.95.192.51" },
|
||||
};
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
545
ADO2025/PI6/Helper-2025-06-02.cs
Normal file
545
ADO2025/PI6/Helper-2025-06-02.cs
Normal file
@ -0,0 +1,545 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
using IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250602 {
|
||||
|
||||
private record Record(string Text, string Host, int Port, string[] Segments, bool StateContainsDisabled);
|
||||
|
||||
private record Status(string CellInstanceName,
|
||||
string CommunicationState,
|
||||
string CurrentActiveVersion,
|
||||
string CurrentHost,
|
||||
string ErrorDescription,
|
||||
string Host,
|
||||
string IsReadyForRestart,
|
||||
string NPort,
|
||||
int Port,
|
||||
string StartTime,
|
||||
string Startable,
|
||||
string State,
|
||||
string StopTime,
|
||||
string Text);
|
||||
|
||||
internal static void EquipmentAutomationFrameworkCellInstanceStateImageVerbIf(ILogger<Worker> logger, List<string> args) {
|
||||
string path;
|
||||
Status status;
|
||||
Record? record;
|
||||
string verbBy = args[2];
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
logger.LogInformation(args[3]);
|
||||
string[] cellInstanceNames = args[3].Split('~');
|
||||
Dictionary<string, Record> records = GetEquipmentAutomationFrameworkCellInstanceStatus(development: false, staging: false, production: true);
|
||||
foreach (string cellInstanceName in cellInstanceNames) {
|
||||
if (!records.TryGetValue(cellInstanceName, out record)) {
|
||||
logger.LogWarning("{cellInstance} not found!", cellInstanceName);
|
||||
continue;
|
||||
}
|
||||
if (records[cellInstanceName].StateContainsDisabled) {
|
||||
logger.LogWarning("{cellInstance} not found!", cellInstanceName);
|
||||
}
|
||||
status = GetEquipmentAutomationFrameworkCellInstanceStateImageVerbIf(logger, verbBy, cellInstanceName, record);
|
||||
path = $"/images/{cellInstanceName}_{status.State}.jpg";
|
||||
logger.LogInformation("{host}) {cellInstanceName} => {state} <{path}>", record.Host, cellInstanceName, status.State, path);
|
||||
}
|
||||
}
|
||||
|
||||
private static Status GetEquipmentAutomationFrameworkCellInstanceStateImageVerbIf(ILogger<Worker> logger, string verbBy, string cellInstanceName, Record record) {
|
||||
Status result;
|
||||
Dictionary<string, DateTime> equipmentAutomationFrameworkTriggers = [];
|
||||
if (!equipmentAutomationFrameworkTriggers.ContainsKey(cellInstanceName)) {
|
||||
equipmentAutomationFrameworkTriggers.Add(cellInstanceName, DateTime.MinValue);
|
||||
}
|
||||
result = EquipmentAutomationFrameworkCellInstanceStatus(cellInstanceName, record);
|
||||
if (equipmentAutomationFrameworkTriggers[cellInstanceName] < DateTime.Now.AddSeconds(-60)) {
|
||||
if (result.State == "Offline") {
|
||||
EquipmentAutomationFrameworkCellInstanceStart(record.Host, record.Port, cellInstanceName, verbBy);
|
||||
logger.LogInformation("Start invoked for {cellName}", cellInstanceName);
|
||||
} else if (result.State == "Warning") {
|
||||
EquipmentAutomationFrameworkCellInstanceRestart(record.Host, record.Port, cellInstanceName, verbBy);
|
||||
logger.LogInformation("Restart invoked for {cellName}", cellInstanceName);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Dictionary<string, Record> GetEquipmentAutomationFrameworkCellInstanceStatus(bool development, bool staging, bool production) {
|
||||
Dictionary<string, Record> results = [];
|
||||
string key;
|
||||
string host;
|
||||
string text;
|
||||
string state;
|
||||
string response;
|
||||
bool stop = false;
|
||||
string[] segments;
|
||||
string[] cellNames;
|
||||
byte[] responseBytes;
|
||||
string responseAfter;
|
||||
#pragma warning disable SYSLIB0014
|
||||
WebClient webClient = new();
|
||||
#pragma warning restore SYSLIB0014
|
||||
string disabled = "Disabled";
|
||||
UnicodeCategory unicodeCategory;
|
||||
StringBuilder stringBuilder = new();
|
||||
EquipmentAutomationFrameworkCellInstanceParseCheck();
|
||||
Dictionary<char, char> unicodeReplaces = GetUnicodeReplaces();
|
||||
List<UnicodeCategory> unicodeCategories = GetUnicodeCategory();
|
||||
ReadOnlyCollection<string> urls = GetUrls(development, staging, production);
|
||||
// Dictionary<UnicodeCategory, List<char>> unicodeCategoriesList = new Dictionary<UnicodeCategory, List<char>>();
|
||||
byte[] bodyBytes = [86, 2, 11, 1, 115, 4, 11, 1, 97, 6, 86, 8, 68, 10, 30, 0, 130, 153, 48, 104, 116, 116, 112, 58, 47, 47, 116, 101, 109, 112, 117, 114, 105, 46, 111, 114, 103, 47, 73, 83, 116, 97, 116, 117, 115, 81, 117, 101, 114, 121, 47, 71, 101, 116, 70, 97, 99, 116, 111, 114, 121, 83, 116, 97, 116, 117, 115, 68, 26, 173, 181, 241, 2, 149, 65, 209, 208, 66, 143, 234, 233, 157, 246, 118, 78, 238, 68, 44, 68, 42, 171, 20, 1, 68, 12, 30, 0, 130, 153, 49, 104, 116, 116, 112, 58, 47, 47, 101, 97, 102, 45, 112, 114, 111, 100, 46, 109, 101, 115, 46, 105, 110, 102, 105, 110, 101, 111, 110, 46, 99, 111, 109, 58, 57, 48, 48, 51, 47, 83, 116, 97, 116, 117, 115, 81, 117, 101, 114, 121, 1, 86, 14, 64, 16, 71, 101, 116, 70, 97, 99, 116, 111, 114, 121, 83, 116, 97, 116, 117, 115, 8, 19, 104, 116, 116, 112, 58, 47, 47, 116, 101, 109, 112, 117, 114, 105, 46, 111, 114, 103, 47, 64, 16, 105, 110, 99, 108, 117, 100, 101, 65, 103, 101, 110, 116, 76, 105, 115, 116, 135, 64, 17, 105, 110, 99, 108, 117, 100, 101, 83, 116, 97, 116, 117, 115, 76, 105, 115, 116, 135, 64, 23, 101, 120, 116, 101, 110, 100, 101, 100, 83, 116, 97, 116, 117, 115, 67, 101, 108, 108, 78, 97, 109, 101, 115, 9, 1, 98, 57, 104, 116, 116, 112, 58, 47, 47, 115, 99, 104, 101, 109, 97, 115, 46, 109, 105, 99, 114, 111, 115, 111, 102, 116, 46, 99, 111, 109, 47, 50, 48, 48, 51, 47, 49, 48, 47, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 47, 65, 114, 114, 97, 121, 115, 9, 1, 105, 41, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97, 45, 105, 110, 115, 116, 97, 110, 99, 101, 95, 6, 115, 116, 114, 105, 110, 103, 153, 20, 66, 73, 79, 82, 65, 68, 53, 95, 70, 105, 108, 101, 65, 114, 99, 104, 105, 118, 101, 114, 1, 1, 1, 1];
|
||||
foreach (string url in urls) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
segments = url.Split(':');
|
||||
host = segments[0];
|
||||
if (segments.Length == 0 || !int.TryParse(segments[1], out int port)) {
|
||||
port = 80;
|
||||
}
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+msbin1");
|
||||
responseBytes = webClient.UploadData($"http://{host}:{port}/StatusQuery", bodyBytes);
|
||||
// File.WriteAllText(@"L:\Tmp\a.txt", BitConverter.ToString(responseBytes));
|
||||
response = Encoding.UTF8.GetString(responseBytes);
|
||||
foreach (char c in response) {
|
||||
unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
|
||||
if (unicodeCategory == UnicodeCategory.Control && unicodeReplaces.ContainsKey(c)) {
|
||||
_ = stringBuilder.Append(unicodeReplaces[c]);
|
||||
} else if (unicodeCategories.Contains(unicodeCategory)) {
|
||||
_ = stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
responseAfter = stringBuilder.ToString();
|
||||
cellNames = responseAfter.Split(new string[] { "CellName" }, StringSplitOptions.None);
|
||||
foreach (string segment in cellNames) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
key = string.Empty;
|
||||
state = string.Empty;
|
||||
segments = segment.Split(new string[] { "WindowsName" }, StringSplitOptions.None);
|
||||
if (segments.Length != 2) {
|
||||
continue;
|
||||
}
|
||||
text = segments[0];
|
||||
segments = text.Replace('\r', ' ').Replace('\n', ' ').Split(' ');
|
||||
for (int i = 0; i < segments.Length - 3; i++) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(segments[i]) && string.IsNullOrEmpty(key)) {
|
||||
key = segments[i].Trim();
|
||||
} else if (segments[i].StartsWith("State")) {
|
||||
state = segments[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (key.EndsWith("a")) {
|
||||
key = key[..^1];
|
||||
}
|
||||
if (!results.ContainsKey(key)) {
|
||||
results.Add(key, new Record(Text: text, Host: host, Port: port, Segments: segments, StateContainsDisabled: state.Contains(disabled)));
|
||||
} else if (results[key].StateContainsDisabled) {
|
||||
results[key] = new Record(Text: text, Host: host, Port: port, Segments: segments, StateContainsDisabled: state.Contains(disabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<string> GetUrls(bool development, bool staging, bool production) {
|
||||
List<string> results = [];
|
||||
if (development) {
|
||||
results.Add("eaf-dev.mes.infineon.com:9003");
|
||||
}
|
||||
if (staging) {
|
||||
results.Add("eaf-staging.mes.infineon.com:9003");
|
||||
}
|
||||
if (production) {
|
||||
results.Add("eaf-prod.mes.infineon.com:9003");
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static List<UnicodeCategory> GetUnicodeCategory() {
|
||||
List<UnicodeCategory> unicodeCategories = [
|
||||
// UnicodeCategory.Control, // 33 - <20>
|
||||
UnicodeCategory.UppercaseLetter, // 25 - ABCDEFGHIJKLMNOPQRSTUVWXY
|
||||
UnicodeCategory.LowercaseLetter, // 25 - abcdefghiklmnopqrstuvwxyz
|
||||
UnicodeCategory.DecimalDigitNumber, // 10 - 0123456789
|
||||
UnicodeCategory.OtherPunctuation, // 10 - !"#%&,./:@
|
||||
UnicodeCategory.ClosePunctuation, // 2 - )]
|
||||
UnicodeCategory.MathSymbol, // 2 - |؈
|
||||
UnicodeCategory.OpenPunctuation, // 2 - ([
|
||||
// UnicodeCategory.OtherSymbol, // 1 - <20>
|
||||
UnicodeCategory.DashPunctuation, // 1 - -
|
||||
UnicodeCategory.ConnectorPunctuation, // 1 - _
|
||||
UnicodeCategory.ModifierSymbol, // 1 - `
|
||||
UnicodeCategory.NonSpacingMark, // 1 - ̵
|
||||
UnicodeCategory.SpaceSeparator, // 1 -
|
||||
UnicodeCategory.CurrencySymbol, // 1 - $
|
||||
];
|
||||
return unicodeCategories;
|
||||
}
|
||||
|
||||
private static void EquipmentAutomationFrameworkCellInstanceParseCheck() {
|
||||
Envelope? envelope;
|
||||
string xmlStart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:6eb7a538-0b2b-4d04-8f2a-ab50e1e5338a</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlStart891 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/StartAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:38977fa4-262a-42fb-8df7-d8d3074820b2</a:RelatesTo></s:Header><s:Body><StartAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlStart748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlStart707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:f169e50f-5ca8-43cd-a1e9-724840ff5e00</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string xmlStop621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:97f7aeb4-015f-440b-b0ff-a2a5aa4f4ab9</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlStop889 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/StopAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:04b8b0ea-8576-4756-b456-8a817cd10826</a:RelatesTo></s:Header><s:Body><StopAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlStop748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlStop707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:e34d16ad-21d5-4a11-a6dc-5b5b58a74f96</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:c9a4d5b6-435b-49a4-a2f9-d93cd8aecc36</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string xmlRestart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:e228a621-e7ab-4ebf-97ba-5571cb5f4ad7</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
|
||||
string xmlRestart895 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/RestartAllCellInstancesResponse</a:Action><a:RelatesTo>urn:uuid:efaeaf12-4aa0-4cd1-8296-05019e47261a</a:RelatesTo></s:Header><s:Body><RestartAllCellInstancesResponse xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
|
||||
string xmlRestart748 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:Sequence s:mustUnderstand=\"1\"><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action></s:Header><s:Body/></s:Envelope>";
|
||||
string xmlRestart707 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:a1650ed7-34dc-4fac-993f-ed2559c453a2</r:Identifier><r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/><netrm:BufferRemaining xmlns:netrm=\"http://schemas.microsoft.com/ws/2006/05/rm\">8</netrm:BufferRemaining></r:SequenceAcknowledgement><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:50c82506-bd4d-4117-b632-640cf84d556e</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>";
|
||||
string[] xmlSets = [xmlStart621, xmlStart891, xmlStart748, xmlStart707, xmlStop621, xmlStop889, xmlStop748, xmlStop707, xmlRestart621, xmlRestart895, xmlRestart748, xmlRestart707];
|
||||
foreach (string xmlSet in xmlSets) {
|
||||
envelope = ParseXML<Envelope>(xmlSet, throwExceptions: true);
|
||||
}
|
||||
}
|
||||
|
||||
private static T? ParseXML<T>(string value, bool throwExceptions) where T : class {
|
||||
object? result = null;
|
||||
try {
|
||||
Stream stream = ToStream(value.Trim());
|
||||
XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
|
||||
#pragma warning disable IL2026, IL2090
|
||||
XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes());
|
||||
result = xmlSerializer.Deserialize(xmlReader);
|
||||
#pragma warning restore IL2026, IL2090
|
||||
stream.Dispose();
|
||||
} catch (Exception) {
|
||||
if (throwExceptions) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return result as T;
|
||||
}
|
||||
|
||||
private static Stream ToStream(string value) {
|
||||
MemoryStream memoryStream = new();
|
||||
StreamWriter streamWriter = new(memoryStream);
|
||||
streamWriter.Write(value);
|
||||
streamWriter.Flush();
|
||||
memoryStream.Position = 0;
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
private static Dictionary<char, char> GetUnicodeReplaces() {
|
||||
Dictionary<char, char> results = new() {
|
||||
{ '\u0000', ' ' },
|
||||
{ '\u0001', ' ' },
|
||||
{ '\u0002', ' ' },
|
||||
{ '\u0003', ' ' },
|
||||
{ '\u0004', ' ' },
|
||||
{ '\u0005', ' ' },
|
||||
{ '\u0006', ' ' },
|
||||
{ '\u0007', ' ' },
|
||||
{ '\u0008', ' ' },
|
||||
{ '\u0009', '\t' },
|
||||
{ '\u000A', '\r' },
|
||||
{ '\u000B', '\r' },
|
||||
{ '\u000C', '\t' },
|
||||
{ '\u000D', '\r' },
|
||||
{ '\u000E', ' ' },
|
||||
{ '\u000F', ' ' },
|
||||
{ '\u0010', ' ' },
|
||||
{ '\u0011', ' ' },
|
||||
{ '\u0012', ' ' },
|
||||
{ '\u0013', ' ' },
|
||||
{ '\u0014', ' ' },
|
||||
{ '\u0015', ' ' },
|
||||
{ '\u0016', ' ' },
|
||||
{ '\u0017', ' ' },
|
||||
{ '\u0018', ' ' },
|
||||
{ '\u0019', ' ' },
|
||||
{ '\u001A', ' ' },
|
||||
{ '\u001B', ' ' },
|
||||
{ '\u001C', '\r' },
|
||||
{ '\u001D', '\t' },
|
||||
{ '\u001E', '\t' },
|
||||
{ '\u001F', '\t' },
|
||||
{ '\u007F', ' ' },
|
||||
// C1
|
||||
{ '\u0080', '\t' },
|
||||
{ '\u0081', ' ' },
|
||||
{ '\u0082', ' ' },
|
||||
{ '\u0083', ' ' },
|
||||
{ '\u0084', ' ' },
|
||||
{ '\u0085', '\r' },
|
||||
{ '\u0086', ' ' },
|
||||
{ '\u0087', ' ' },
|
||||
{ '\u0088', '\t' },
|
||||
{ '\u0089', '\t' },
|
||||
{ '\u008A', '\t' },
|
||||
{ '\u008B', '\r' },
|
||||
{ '\u008C', ' ' },
|
||||
{ '\u008D', ' ' },
|
||||
{ '\u008E', ' ' },
|
||||
{ '\u008F', ' ' },
|
||||
{ '\u0090', ' ' },
|
||||
{ '\u0091', ' ' },
|
||||
{ '\u0092', ' ' },
|
||||
{ '\u0093', ' ' },
|
||||
{ '\u0094', ' ' },
|
||||
{ '\u0095', ' ' },
|
||||
{ '\u0096', ' ' },
|
||||
{ '\u0097', ' ' },
|
||||
{ '\u0098', ' ' },
|
||||
{ '\u0099', ' ' },
|
||||
{ '\u009A', ' ' },
|
||||
{ '\u009B', ' ' },
|
||||
{ '\u009C', ' ' },
|
||||
{ '\u009D', ' ' },
|
||||
{ '\u009E', ' ' },
|
||||
{ '\u009F', ' ' }
|
||||
};
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Status EquipmentAutomationFrameworkCellInstanceStatus(string cellInstanceName, Record record) {
|
||||
Status result;
|
||||
bool stop = false;
|
||||
string state = string.Empty;
|
||||
string stopTime = string.Empty;
|
||||
string startTime = string.Empty;
|
||||
string startable = string.Empty;
|
||||
string currentHost = string.Empty;
|
||||
string errorDescription = string.Empty;
|
||||
string isReadyForRestart = string.Empty;
|
||||
string communicationState = string.Empty;
|
||||
string currentActiveVersion = string.Empty;
|
||||
for (int i = 0; i < record.Segments.Length - 3; i++) {
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
if (string.IsNullOrEmpty(state) && record.Segments[i].StartsWith("State")) {
|
||||
state = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(startable) && record.Segments[i].Contains("Startable")) {
|
||||
startable = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(stopTime) && record.Segments[i].StartsWith("StopTime")) {
|
||||
stopTime = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(currentHost) && record.Segments[i].Contains("CurrentHost")) {
|
||||
currentHost = $"{record.Segments[i]} {record.Segments[i + 1]} {record.Segments[i + 2]}";
|
||||
} else if (string.IsNullOrEmpty(errorDescription) && record.Segments[i].StartsWith("ErrorDescription")) {
|
||||
errorDescription = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(communicationState) && record.Segments[i].StartsWith("CommunicationState")) {
|
||||
communicationState = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(isReadyForRestart) && record.Segments[i].StartsWith("IsReadyForRestart")) {
|
||||
isReadyForRestart = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(currentActiveVersion) && record.Segments[i].Contains("CurrentActiveVersion")) {
|
||||
currentActiveVersion = record.Segments[i + 1];
|
||||
} else if (string.IsNullOrEmpty(startTime) && record.Segments[i].Contains("StartTime")) {
|
||||
startTime = $"{record.Segments[i + 1]} {record.Segments[i + 2]} {record.Segments[i + 3]}".Split('\t')[0];
|
||||
}
|
||||
}
|
||||
if (errorDescription != "a") {
|
||||
string[] segments = record.Text.Split(new string[] { "ErrorDescription" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (segments.Length > 1) {
|
||||
segments = segments[1].Split(new string[] { "Info" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
errorDescription = segments[0].Trim();
|
||||
}
|
||||
}
|
||||
string nPort;
|
||||
Dictionary<string, string> nPorts = GetnPorts();
|
||||
if (!nPorts.ContainsKey(cellInstanceName)) {
|
||||
nPort = string.Empty;
|
||||
} else {
|
||||
nPort = nPorts[cellInstanceName];
|
||||
}
|
||||
if (state.EndsWith("a")) {
|
||||
state = state[0..^1];
|
||||
}
|
||||
if (state == "Running" && communicationState == "Not") {
|
||||
state = "Warning";
|
||||
}
|
||||
result = new(Host: record.Host,
|
||||
Port: record.Port,
|
||||
Text: record.Text,
|
||||
NPort: nPort,
|
||||
State: state,
|
||||
CellInstanceName: cellInstanceName,
|
||||
StopTime: stopTime,
|
||||
StartTime: startTime,
|
||||
Startable: startable,
|
||||
CurrentHost: currentHost,
|
||||
ErrorDescription: errorDescription,
|
||||
IsReadyForRestart: isReadyForRestart,
|
||||
CommunicationState: communicationState,
|
||||
CurrentActiveVersion: currentActiveVersion);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> GetnPorts() {
|
||||
Dictionary<string, string> results = new() {
|
||||
{ "TENCOR1", "10.95.192.31" },
|
||||
{ "TENCOR2", "10.95.192.32" },
|
||||
{ "TENCOR3", "10.95.192.33" },
|
||||
{ "HGCV1", "10.95.192.34" },
|
||||
{ "HGCV2", "10.95.154.17" },
|
||||
{ "HGCV3", "10.95.192.36" },
|
||||
{ "BIORAD2", "10.95.192.37" },
|
||||
{ "BIORAD3", "10.95.192.38" },
|
||||
{ "CDE2", "10.95.192.39" },
|
||||
{ "CDE3", "10.95.154.19" },
|
||||
{ "CDE5", "10.95.192.40" },
|
||||
{ "SPARE-1", "10.95.192.47" },
|
||||
{ "SPARE-2", "10.95.192.48" },
|
||||
{ "SPARE-3", "10.95.192.49" },
|
||||
{ "SPARE-4", "10.95.192.50" },
|
||||
{ "SPARE-5", "10.95.192.51" },
|
||||
};
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void EquipmentAutomationFrameworkCellInstanceRestart(string host, int port, string cellName = "R71-HSMS", string verbBy = @"EC\EcMesEaf") {
|
||||
EquipmentAutomationFrameworkCellInstanceParseCheck();
|
||||
// Restart
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action><a:MessageID>urn:uuid:09fd9303-dcfe-4563-803b-678441b12949</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><CreateSequence xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm"><AcksTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></AcksTo><Offer><Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</Identifier></Offer></CreateSequence></s:Body></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/RestartAllCellInstances</a:Action><a:MessageID>urn:uuid:c9f80db4-a2c2-4e53-9bed-8ba3a60b653c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><RestartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Restarted by EC\ecphares</updateInfo></RestartAllCellInstances></s:Body></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</r:Identifier><r:AcknowledgementRange Lower="1" Upper="1"/></r:SequenceAcknowledgement><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body/></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</r:Identifier><r:AcknowledgementRange Lower="1" Upper="2"/></r:SequenceAcknowledgement><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action><a:MessageID>urn:uuid:3b063df5-e6df-47a5-b530-aa380a4c6a38</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>
|
||||
EquipmentAutomationFrameworkCellInstanceVerb(host, port, cellName, verbBy, restart: true, stop: false, start: false);
|
||||
}
|
||||
|
||||
private static void EquipmentAutomationFrameworkCellInstanceStart(string host, int port, string cellName = "R71-HSMS", string verbBy = @"EC\EcMesEaf") {
|
||||
EquipmentAutomationFrameworkCellInstanceParseCheck();
|
||||
// Start
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action><a:MessageID>urn:uuid:a1188d61-df04-4955-b1e4-b90faff95d4d</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><CreateSequence xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm"><AcksTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></AcksTo><Offer><Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</Identifier></Offer></CreateSequence></s:Body></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/StartAllCellInstances</a:Action><a:MessageID>urn:uuid:8758eec2-b4dc-4338-ba3d-235aa15e634c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><StartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Started by EC\ecphares</updateInfo></StartAllCellInstances></s:Body></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/StartAllCellInstances</a:Action><a:MessageID>urn:uuid:8758eec2-b4dc-4338-ba3d-235aa15e634c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><StartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Started by EC\ecphares</updateInfo></StartAllCellInstances></s:Body></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</r:Identifier><r:AcknowledgementRange Lower="1" Upper="1"/></r:SequenceAcknowledgement><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body/></s:Envelope>
|
||||
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</r:Identifier><r:AcknowledgementRange Lower="1" Upper="2"/></r:SequenceAcknowledgement><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action><a:MessageID>urn:uuid:b2bb5329-c846-4cd1-98a8-343136923702</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>
|
||||
EquipmentAutomationFrameworkCellInstanceVerb(host, port, cellName, verbBy, restart: false, stop: false, start: true);
|
||||
}
|
||||
|
||||
private static void EquipmentAutomationFrameworkCellInstanceVerb(string host, int port, string cellName, string verbBy, bool restart, bool stop, bool start) {
|
||||
#pragma warning disable SYSLIB0014
|
||||
WebClient webClient = new();
|
||||
#pragma warning restore SYSLIB0014
|
||||
string xml;
|
||||
string verb;
|
||||
Envelope? envelope;
|
||||
string updateInfoVerb;
|
||||
StringBuilder stringBuilder = new();
|
||||
string cellControllerManager = $"http://{host}:{port}/CellControllerManager";
|
||||
if (!restart && !stop && !start) {
|
||||
throw new Exception();
|
||||
} else if (restart && stop && start) {
|
||||
throw new Exception();
|
||||
} else if (restart) {
|
||||
updateInfoVerb = "Restarted";
|
||||
verb = "RestartAllCellInstances";
|
||||
} else if (stop) {
|
||||
updateInfoVerb = "Stopped";
|
||||
verb = "StopAllCellInstancesResponse";
|
||||
} else if (start) {
|
||||
updateInfoVerb = "Started";
|
||||
verb = "StartAllCellInstances";
|
||||
} else
|
||||
throw new Exception();
|
||||
string headerMessageID621 = Guid.NewGuid().ToString();
|
||||
string bodyIdentifier621 = Guid.NewGuid().ToString();
|
||||
_ = stringBuilder.Append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">").
|
||||
Append("<s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action>").
|
||||
Append("<a:MessageID>urn:uuid:").Append(headerMessageID621).Append("</a:MessageID>").
|
||||
Append("<a:To s:mustUnderstand=\"1\">").Append(cellControllerManager).Append("</a:To>").
|
||||
Append("</s:Header><s:Body><CreateSequence xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><AcksTo>").
|
||||
Append("<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></AcksTo><Offer>").
|
||||
Append("<Identifier>urn:uuid:").Append(bodyIdentifier621).Append("</Identifier>").
|
||||
Append("</Offer></CreateSequence></s:Body></s:Envelope>");
|
||||
xml = stringBuilder.ToString();
|
||||
_ = stringBuilder.Clear();
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+xml; charset=utf-8");
|
||||
xml = webClient.UploadString(cellControllerManager, xml);
|
||||
envelope = ParseXML<Envelope>(xml, throwExceptions: true);
|
||||
if (envelope is null || envelope.Body is null || envelope.Body.CreateSequenceResponse is null || string.IsNullOrEmpty(envelope.Body.CreateSequenceResponse.Identifier)) {
|
||||
throw new Exception("Invalid reply! Example [urn:uuid:f1aa1fa8-9099-48b6-b27f-50e6c098605b]");
|
||||
}
|
||||
string headerSequenceIdentifier895 = envelope.Body.CreateSequenceResponse.Identifier["urn:uuid:".Length..];
|
||||
string headerMessageID895 = Guid.NewGuid().ToString();
|
||||
_ = stringBuilder.Append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">").
|
||||
Append("<s:Header><r:Sequence s:mustUnderstand=\"1\">").
|
||||
Append("<r:Identifier>urn:uuid:").Append(headerSequenceIdentifier895).Append("</r:Identifier>").
|
||||
Append("<r:MessageNumber>1</r:MessageNumber></r:Sequence>").
|
||||
Append("<a:Action s:mustUnderstand=\"1\">http://tempuri.org/ICellControllerManager/").Append(verb).Append("</a:Action>").
|
||||
Append("<a:MessageID>urn:uuid:").Append(headerMessageID895).Append("</a:MessageID>").
|
||||
Append("<a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo>").
|
||||
Append("<a:To s:mustUnderstand=\"1\">").Append(cellControllerManager).Append("</a:To>").
|
||||
Append("</s:Header><s:Body>").
|
||||
Append('<').Append(verb).Append(" xmlns=\"http://tempuri.org/\">").
|
||||
Append("<cellInstances xmlns:b=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">").
|
||||
Append("<b:string>").Append(cellName).Append("</b:string>").
|
||||
Append("</cellInstances>").
|
||||
Append("<updateInfo>").Append(updateInfoVerb).Append(" by ").Append(verbBy).Append("</updateInfo>").
|
||||
Append("</").Append(verb).Append('>').
|
||||
Append("</s:Body></s:Envelope>");
|
||||
xml = stringBuilder.ToString();
|
||||
_ = stringBuilder.Clear();
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+xml; charset=utf-8");
|
||||
xml = webClient.UploadString(cellControllerManager, xml);
|
||||
_ = ParseXML<Envelope>(xml, throwExceptions: true);
|
||||
string headerSequenceAcknowledgementIdentifier748 = bodyIdentifier621;
|
||||
string headerSequenceIdentifier748 = headerSequenceIdentifier895;
|
||||
_ = stringBuilder.Append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">").
|
||||
Append("<s:Header><r:SequenceAcknowledgement>").
|
||||
Append("<r:Identifier>urn:uuid:").Append(headerSequenceAcknowledgementIdentifier748).Append("</r:Identifier>").
|
||||
Append("<r:AcknowledgementRange Lower=\"1\" Upper=\"1\"/></r:SequenceAcknowledgement><r:Sequence s:mustUnderstand=\"1\">").
|
||||
Append("<r:Identifier>urn:uuid:").Append(headerSequenceIdentifier748).Append("</r:Identifier>").
|
||||
Append("<r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence>").
|
||||
Append("<a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action>").
|
||||
Append("<a:To s:mustUnderstand=\"1\">").Append(cellControllerManager).Append("</a:To>").
|
||||
Append("</s:Header><s:Body/></s:Envelope>");
|
||||
xml = stringBuilder.ToString();
|
||||
_ = stringBuilder.Clear();
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+xml; charset=utf-8");
|
||||
xml = webClient.UploadString(cellControllerManager, xml);
|
||||
_ = ParseXML<Envelope>(xml, throwExceptions: true);
|
||||
string headerSequenceAcknowledgementIdentifier707 = bodyIdentifier621;
|
||||
string headerMessageID707 = Guid.NewGuid().ToString();
|
||||
string bodyTerminateSequenceIdentifier707 = headerSequenceIdentifier895;
|
||||
_ = stringBuilder.Append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:r=\"http://schemas.xmlsoap.org/ws/2005/02/rm\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">").
|
||||
Append("<s:Header><r:SequenceAcknowledgement>").
|
||||
Append("<r:Identifier>urn:uuid:").Append(headerSequenceAcknowledgementIdentifier707).Append("</r:Identifier>").
|
||||
Append("<r:AcknowledgementRange Lower=\"1\" Upper=\"2\"/></r:SequenceAcknowledgement>").
|
||||
Append("<a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action>").
|
||||
Append("<a:MessageID>urn:uuid:").Append(headerMessageID707).Append("</a:MessageID>").
|
||||
Append("<a:To s:mustUnderstand=\"1\">").Append(cellControllerManager).Append("</a:To>").
|
||||
Append("</s:Header><s:Body>").
|
||||
Append("<r:TerminateSequence>").
|
||||
Append("<r:Identifier>urn:uuid:").Append(bodyTerminateSequenceIdentifier707).Append("</r:Identifier>").
|
||||
Append("</r:TerminateSequence>").
|
||||
Append("</s:Body></s:Envelope>");
|
||||
xml = stringBuilder.ToString();
|
||||
_ = stringBuilder.Clear();
|
||||
webClient.Headers.Clear();
|
||||
webClient.Headers.Add("Accept-Encoding: gzip, deflate");
|
||||
webClient.Headers.Add("Content-Type: application/soap+xml; charset=utf-8");
|
||||
xml = webClient.UploadString(cellControllerManager, xml);
|
||||
_ = ParseXML<Envelope>(xml, throwExceptions: true);
|
||||
}
|
||||
|
||||
}
|
89
ADO2025/PI6/Helper-2025-06-18.cs
Normal file
89
ADO2025/PI6/Helper-2025-06-18.cs
Normal file
@ -0,0 +1,89 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250618 {
|
||||
|
||||
private record Record(string Directory, List<string> Files);
|
||||
|
||||
internal static void MoveAllButXOfEach(ILogger<Worker> logger, List<string> args) {
|
||||
int keep = int.Parse(args[5]);
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
string searchPattern = args[2];
|
||||
string split = args[4].Split('~')[0];
|
||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
string destinationDirectory = Path.GetFullPath(args[3].Split('~')[0]);
|
||||
if (destinationDirectory.Contains(sourceDirectory)) {
|
||||
throw new Exception("Not allowed!");
|
||||
}
|
||||
ReadOnlyCollection<string> directories = GetDirectories(sourceDirectory);
|
||||
MoveAllButXOfEachB(logger, searchPattern, sourceDirectory, destinationDirectory, split, keep, directories);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<string> GetDirectories(string sourceDirectory) {
|
||||
List<string> results = [sourceDirectory];
|
||||
results.AddRange(Directory.GetDirectories(sourceDirectory, "*", SearchOption.AllDirectories));
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void MoveAllButXOfEachB(ILogger<Worker> logger, string searchPattern, string sourceDirectory, string destinationDirectory, string split, int keep, ReadOnlyCollection<string> directories) {
|
||||
string[] files;
|
||||
int sourceDirectoryLength = sourceDirectory.Length;
|
||||
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs;
|
||||
foreach (string directory in directories) {
|
||||
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
keyValuePairs = GetFiles(split, files);
|
||||
foreach (KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair in keyValuePairs) {
|
||||
if (keyValuePair.Value.Count <= keep) {
|
||||
continue;
|
||||
} else {
|
||||
MoveAllButXOfEachC(logger, sourceDirectoryLength, destinationDirectory, keyValuePair);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetFiles(string split, string[] files) {
|
||||
Dictionary<string, ReadOnlyCollection<string>> results = [];
|
||||
string key;
|
||||
List<string>? collection;
|
||||
Dictionary<string, List<string>> keyValuePairs = [];
|
||||
foreach (string file in files) {
|
||||
key = Path.GetFileName(file).Split(split)[0];
|
||||
if (!keyValuePairs.TryGetValue(key, out collection)) {
|
||||
keyValuePairs.Add(key, []);
|
||||
if (!keyValuePairs.TryGetValue(key, out collection)) {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
collection.Add(file);
|
||||
}
|
||||
foreach (KeyValuePair<string, List<string>> keyValuePair in keyValuePairs) {
|
||||
results.Add(keyValuePair.Key, keyValuePair.Value.OrderByDescending(l => l).ToArray().AsReadOnly());
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void MoveAllButXOfEachC(ILogger<Worker> logger, int sourceDirectoryLength, string destinationDirectory, KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair) {
|
||||
string file;
|
||||
string checkFile;
|
||||
string checkDirectory;
|
||||
for (int i = 1; i < keyValuePair.Value.Count; i++) {
|
||||
file = keyValuePair.Value[i];
|
||||
checkFile = $"{destinationDirectory}{file[sourceDirectoryLength..]}";
|
||||
checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new Exception();
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
File.Move(file, checkFile);
|
||||
logger.LogInformation("<{file}> moved", file);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
89
ADO2025/PI6/Helper-2025-06-28.cs
Normal file
89
ADO2025/PI6/Helper-2025-06-28.cs
Normal file
@ -0,0 +1,89 @@
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
using DiscUtils.Iso9660;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250628 {
|
||||
|
||||
private record Record(string Path,
|
||||
long Size,
|
||||
long Ticks);
|
||||
|
||||
internal static void LogIsoInformation(ILogger<Worker> logger, List<string> args) {
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
string searchPattern = args[2];
|
||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
string[] searchPatternFiles = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
||||
ReadOnlyCollection<Record> records = GetRecords(searchPatternFiles);
|
||||
LogIsoInformation(logger, records, args[3]);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetRecords(string[] searchPatternFiles) {
|
||||
List<Record> results = [];
|
||||
Record record;
|
||||
string[] files;
|
||||
FileInfo fileInfo;
|
||||
foreach (string searchPatternFile in searchPatternFiles) {
|
||||
fileInfo = new(searchPatternFile);
|
||||
record = new(searchPatternFile, fileInfo.Length, fileInfo.LastWriteTime.Ticks);
|
||||
results.Add(record);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string GetSizeWithSuffix(long value) {
|
||||
string result;
|
||||
int i = 0;
|
||||
string[] SizeSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
if (value < 0) {
|
||||
result = "-" + GetSizeWithSuffix(-value);
|
||||
} else {
|
||||
while (Math.Round(value / 1024f) >= 1) {
|
||||
value /= 1024;
|
||||
i++;
|
||||
}
|
||||
result = string.Format("{0:n1} {1}", value, SizeSuffixes[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void LogIsoInformation(ILogger<Worker> logger, ReadOnlyCollection<Record> records, string letter) {
|
||||
string size;
|
||||
string[] files;
|
||||
List<string> messages = [];
|
||||
Record[] sorted = records.OrderBy(l => l.Ticks).ToArray();
|
||||
string directory = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper");
|
||||
foreach (Record record in sorted) {
|
||||
if (string.IsNullOrEmpty(record.Path)) {
|
||||
using FileStream fileStream = File.OpenRead(record.Path);
|
||||
CDReader reader = new(fileStream, true);
|
||||
files = reader.GetFiles("", "*");
|
||||
foreach (string _ in files) {
|
||||
}
|
||||
}
|
||||
size = GetSizeWithSuffix(record.Size);
|
||||
messages.Add($"#; {size}");
|
||||
messages.Add($"#; {new DateTime(record.Ticks):yyyy-MM-dd HH:mm:ss.fff}");
|
||||
messages.Add($"$driveLetter = \"{letter}:\"");
|
||||
messages.Add($"$isoImg = \"{record.Path}\"");
|
||||
messages.Add("$diskImg = Mount-DiskImage -ImagePath $isoImg -NoDriveLetter");
|
||||
messages.Add("$volInfo = $diskImg | Get-Volume");
|
||||
messages.Add("mountvol $driveLetter $volInfo.UniqueId");
|
||||
messages.Add(string.Empty);
|
||||
}
|
||||
if (Directory.Exists(directory)) {
|
||||
File.WriteAllText(Path.Combine(directory, ".lsv"), string.Join(Environment.NewLine, messages));
|
||||
} else {
|
||||
messages.Reverse();
|
||||
foreach (string message in messages) {
|
||||
logger.LogInformation(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
313
ADO2025/PI6/Helper-2025-07-01.cs
Normal file
313
ADO2025/PI6/Helper-2025-07-01.cs
Normal file
@ -0,0 +1,313 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250701 {
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[JsonSerializable(typeof(JsonElement))]
|
||||
internal partial class JsonElementSourceGenerationContext : JsonSerializerContext {
|
||||
}
|
||||
|
||||
internal static void ProcessDataStandardFormatTo(ILogger<Worker> logger, List<string> args) {
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
logger.LogInformation(args[3]);
|
||||
logger.LogInformation(args[4]);
|
||||
logger.LogInformation(args[5]);
|
||||
logger.LogInformation(args[6]);
|
||||
string[] segments;
|
||||
string timeColumn = args[4];
|
||||
string searchPattern = args[2];
|
||||
int sizeFilter = int.Parse(args[3]);
|
||||
string[] columns = args[5].Split(',');
|
||||
Dictionary<string, string> columnMapping = [];
|
||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
string destinationDirectory = Path.GetFullPath(args[6].Split('~')[0]);
|
||||
foreach (string column in columns) {
|
||||
segments = column.Split('~');
|
||||
columnMapping.Add(segments[0], segments[1]);
|
||||
}
|
||||
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
ProcessDataStandardFormatTo(logger, sourceDirectory, searchPattern, sizeFilter, timeColumn, columnMapping, destinationDirectory, directories);
|
||||
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
|
||||
}
|
||||
|
||||
private static void ProcessDataStandardFormatTo(ILogger<Worker> logger, string sourceDirectory, string searchPattern, int sizeFilter, string timeColumn, Dictionary<string, string> columnMapping, string destinationDirectory, string[] directories) {
|
||||
string? json;
|
||||
string[] files;
|
||||
string markdown;
|
||||
string checkFile;
|
||||
string[] matches;
|
||||
FileInfo fileInfo;
|
||||
string? pipeTable;
|
||||
string? collections;
|
||||
string directoryName;
|
||||
string checkDirectory;
|
||||
foreach (string directory in directories) {
|
||||
if (Path.GetFileName(directory).Contains('-')) {
|
||||
continue;
|
||||
}
|
||||
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files) {
|
||||
fileInfo = new(file);
|
||||
if (fileInfo.LastWriteTime > DateTime.Now.AddSeconds(-5)) {
|
||||
continue;
|
||||
}
|
||||
directoryName = Path.GetFileName(fileInfo.DirectoryName);
|
||||
if (fileInfo.Length > sizeFilter && !directoryName.StartsWith('Z')) {
|
||||
checkDirectory = Path.Combine(sourceDirectory, $"Z{directoryName}");
|
||||
if (!Directory.Exists(checkDirectory)) {
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
}
|
||||
checkFile = Path.Combine(checkDirectory, fileInfo.Name);
|
||||
if (File.Exists(checkFile)) {
|
||||
continue;
|
||||
}
|
||||
File.Move(file, checkFile);
|
||||
continue;
|
||||
}
|
||||
checkDirectory = Path.Combine(destinationDirectory, directoryName);
|
||||
if (!Directory.Exists(checkDirectory)) {
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
}
|
||||
checkFile = Path.Combine(checkDirectory, $"{fileInfo.Name}.md");
|
||||
if (File.Exists(checkFile)) {
|
||||
continue;
|
||||
}
|
||||
collections = GetMarkdown(logger, timeColumn, columnMapping, file, fileInfo.Name);
|
||||
if (string.IsNullOrEmpty(collections)) {
|
||||
logger.LogWarning("collections is null");
|
||||
continue;
|
||||
}
|
||||
File.WriteAllText(checkFile, collections);
|
||||
File.SetLastWriteTime(checkFile, fileInfo.LastAccessTime);
|
||||
if (!string.IsNullOrEmpty(destinationDirectory)) {
|
||||
continue;
|
||||
}
|
||||
json = GetJavaScriptObjectNotation(logger, file);
|
||||
if (string.IsNullOrEmpty(json)) {
|
||||
logger.LogWarning("json is null");
|
||||
continue;
|
||||
}
|
||||
File.WriteAllText($"{checkFile}.md", json);
|
||||
File.SetLastWriteTime($"{checkFile}.md", fileInfo.LastAccessTime);
|
||||
pipeTable = GetPipeTable(logger, json);
|
||||
if (string.IsNullOrEmpty(pipeTable)) {
|
||||
logger.LogWarning("pipeTable is null");
|
||||
continue;
|
||||
}
|
||||
markdown = $"# {fileInfo.Name}{Environment.NewLine}{Environment.NewLine}{pipeTable}{Environment.NewLine}";
|
||||
File.WriteAllText($"{checkFile}.md", markdown);
|
||||
File.SetLastWriteTime($"{checkFile}.md", fileInfo.LastAccessTime);
|
||||
logger.LogInformation("<{checkFile}> was written", checkFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string? GetMarkdown(ILogger<Worker> logger, string timeColumn, Dictionary<string, string> columnMapping, string file, string name) {
|
||||
string? result = null;
|
||||
string[] lines = File.ReadAllLines(file);
|
||||
int? columnTitlesLine = GetProcessDataStandardFormatColumnTitlesLine(lines);
|
||||
if (columnTitlesLine is null) {
|
||||
logger.LogWarning("<{columnTitlesLine}> is null", nameof(columnTitlesLine));
|
||||
} else {
|
||||
if (lines.Length < columnTitlesLine.Value + 1) {
|
||||
logger.LogWarning("<{lines}>(s)", lines.Length);
|
||||
} else {
|
||||
result = GetMarkdown(timeColumn, columnMapping, name, lines, columnTitlesLine);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int? GetProcessDataStandardFormatColumnTitlesLine(string[] lines) {
|
||||
int? result = null;
|
||||
for (int i = 0; i < lines.Length; i++) {
|
||||
if (lines[i].StartsWith("END_OFFSET") && i + 3 < lines.Length) {
|
||||
result = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetKeyValuePairs(int columnTitlesLine, string[] lines) {
|
||||
Dictionary<string, ReadOnlyCollection<string>> results = [];
|
||||
string value;
|
||||
string[] segments;
|
||||
List<List<string>> collections = [];
|
||||
string[] columns = lines[columnTitlesLine].Split('\t');
|
||||
foreach (string column in columns) {
|
||||
collections.Add([]);
|
||||
}
|
||||
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
|
||||
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
||||
break;
|
||||
}
|
||||
segments = lines[i].Split('\t');
|
||||
if (segments.Length > columns.Length) {
|
||||
continue;
|
||||
}
|
||||
for (int c = 0; c < segments.Length; c++) {
|
||||
collections[c].Add(segments[c]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < collections.Count; i++) {
|
||||
if (collections[i].Count > 1) {
|
||||
if (string.IsNullOrEmpty(collections[i][0])) {
|
||||
collections[i][0] = collections[i][1];
|
||||
}
|
||||
if (string.IsNullOrEmpty(collections[i][^1])) {
|
||||
collections[i][^1] = collections[i][^2];
|
||||
}
|
||||
}
|
||||
results.Add(columns[i].Trim('"'), collections[i].AsReadOnly());
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string? GetMarkdown(string timeColumn, Dictionary<string, string> columnMapping, string name, string[] lines, int? columnTitlesLine) {
|
||||
string? result;
|
||||
List<string> charts = [];
|
||||
List<string> results = [];
|
||||
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs = GetKeyValuePairs(columnTitlesLine.Value, lines);
|
||||
string[] columns = keyValuePairs.Keys.OrderBy(l => l).ToArray();
|
||||
if (!columns.Contains(timeColumn)) {
|
||||
result = null;
|
||||
} else {
|
||||
string? alias;
|
||||
string[] mappedColumns = columnMapping.Keys.ToArray();
|
||||
string labels = string.Join(',', keyValuePairs[timeColumn].Select(l => l.Replace(',', '_')));
|
||||
foreach (string column in columns) {
|
||||
if (column == timeColumn) {
|
||||
continue;
|
||||
}
|
||||
if (!columnMapping.TryGetValue(column, out alias) || keyValuePairs[column].Count == 0 || string.IsNullOrEmpty(keyValuePairs[column][0])) {
|
||||
results.Add(string.Concat("## ", column, Environment.NewLine, Environment.NewLine,
|
||||
"- ", string.Join(',', keyValuePairs[column].Select(l => l.Replace(',', '_'))), Environment.NewLine
|
||||
));
|
||||
} else {
|
||||
charts.Add(string.Concat(
|
||||
"## ", column, " - ", alias, Environment.NewLine, Environment.NewLine,
|
||||
"```chart", Environment.NewLine,
|
||||
"{\"type\": \"line\", \"data\": {\"datasets\": [{", Environment.NewLine,
|
||||
"\"label\": \"", column, " - ", alias, "\",", Environment.NewLine,
|
||||
"\"data\": [", string.Join(',', keyValuePairs[column].Select(l => l.Replace(',', '_'))), "],", Environment.NewLine,
|
||||
"\"borderColor\": \"rgb(75, 192, 192)\"", Environment.NewLine,
|
||||
"}],", Environment.NewLine,
|
||||
"\"labels\": [", labels, "]", Environment.NewLine,
|
||||
"}}", Environment.NewLine,
|
||||
"```", Environment.NewLine
|
||||
));
|
||||
}
|
||||
}
|
||||
if (results.Count == 0 && charts.Count == 0) {
|
||||
result = null;
|
||||
} else {
|
||||
string[] segments;
|
||||
results.Add($"## Footer{Environment.NewLine}");
|
||||
results.Insert(0, $"# {name}{Environment.NewLine}");
|
||||
for (int i = columnTitlesLine.Value + 1; i < lines.Length; i++) {
|
||||
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
||||
for (int j = i; j < lines.Length; j++) {
|
||||
results.Add($"- {lines[j]}");
|
||||
}
|
||||
}
|
||||
}
|
||||
results.Add(string.Empty);
|
||||
results.Add(string.Empty);
|
||||
result = $"{string.Join(Environment.NewLine, results)}{string.Join(Environment.NewLine, charts)}";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string? GetJavaScriptObjectNotation(ILogger<Worker> logger, string file) {
|
||||
string? result = null;
|
||||
string[] lines = File.ReadAllLines(file);
|
||||
int? columnTitlesLine = GetProcessDataStandardFormatColumnTitlesLine(lines);
|
||||
if (columnTitlesLine is null) {
|
||||
logger.LogWarning("<{columnTitlesLine}> is null", nameof(columnTitlesLine));
|
||||
} else {
|
||||
if (lines.Length < columnTitlesLine.Value + 1) {
|
||||
logger.LogWarning("<{lines}>(s)", lines.Length);
|
||||
} else {
|
||||
result = GetJavaScriptObjectNotation(columnTitlesLine.Value, [], lines);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string GetJavaScriptObjectNotation(int columnTitlesLine, string[] columns, string[] lines) {
|
||||
#pragma warning disable CA1845, IDE0057
|
||||
string result = "[\n";
|
||||
string line;
|
||||
string value;
|
||||
string[] segments;
|
||||
if (columns.Length == 0) {
|
||||
columns = lines[columnTitlesLine].Split('\t');
|
||||
}
|
||||
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
|
||||
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
||||
break;
|
||||
}
|
||||
line = "{";
|
||||
segments = lines[i].Split('\t');
|
||||
if (segments.Length > columns.Length) {
|
||||
continue;
|
||||
}
|
||||
for (int c = 0; c < segments.Length; c++) {
|
||||
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
line += '"' + columns[c].Trim('"') + '"' + ':' + '"' + value + '"' + ',';
|
||||
}
|
||||
line = line.Substring(0, line.Length - 1) + '}' + ',' + '\n';
|
||||
result += line;
|
||||
}
|
||||
result = result.Substring(0, result.Length - 2) + ']';
|
||||
return result;
|
||||
#pragma warning restore CA1845, IDE0057
|
||||
}
|
||||
|
||||
private static string? GetPipeTable(ILogger<Worker> logger, string json) {
|
||||
string? result = null;
|
||||
string? value;
|
||||
string[]? columns = null;
|
||||
List<string> values = [];
|
||||
List<string> results = [];
|
||||
Dictionary<string, string> keyValuePairs = [];
|
||||
JsonElement jsonElement = JsonSerializer.Deserialize(json, JsonElementSourceGenerationContext.Default.JsonElement);
|
||||
JsonElement[] jsonElements = jsonElement.EnumerateArray().ToArray();
|
||||
foreach (JsonElement j in jsonElements) {
|
||||
values.Clear();
|
||||
keyValuePairs.Clear();
|
||||
foreach (JsonProperty jsonProperty in j.EnumerateObject().ToArray()) {
|
||||
if (columns is null) {
|
||||
JsonProperty[] jsonProperties = j.EnumerateObject().OrderBy(l => l.Name).ToArray();
|
||||
columns = jsonProperties.Select(l => l.Name).ToArray();
|
||||
results.Add($"|{string.Join('|', columns)}|");
|
||||
results.Add($"|{string.Join('|', columns.Select(l => '-'))}|");
|
||||
}
|
||||
keyValuePairs.Add(jsonProperty.Name, jsonProperty.Value.ToString());
|
||||
}
|
||||
foreach (string column in columns) {
|
||||
if (!keyValuePairs.TryGetValue(column, out value)) {
|
||||
values.Add(new string(' ', column.Length));
|
||||
} else {
|
||||
values.Add(value.PadLeft(column.Length, ' '));
|
||||
}
|
||||
}
|
||||
results.Add($"|{string.Join('|', values)}|");
|
||||
}
|
||||
if (results.Count > 0) {
|
||||
result = string.Join(Environment.NewLine, results);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
112
ADO2025/PI6/Helper-2025-07-05.cs
Normal file
112
ADO2025/PI6/Helper-2025-07-05.cs
Normal file
@ -0,0 +1,112 @@
|
||||
|
||||
using System.Drawing;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.ADO2025.PI6;
|
||||
|
||||
internal static partial class Helper20250705 {
|
||||
|
||||
internal static void ExportFaces(ILogger<Worker> logger, List<string> args) {
|
||||
string checkFile;
|
||||
logger.LogInformation(args[0]);
|
||||
logger.LogInformation(args[1]);
|
||||
logger.LogInformation(args[2]);
|
||||
logger.LogInformation(args[3]);
|
||||
logger.LogInformation(args[4]);
|
||||
logger.LogInformation(args[5]);
|
||||
logger.LogInformation(args[6]);
|
||||
logger.LogInformation(args[7]);
|
||||
string locationDigits = args[6];
|
||||
string[] mp = args[4].Split('~');
|
||||
string[] mwg = args[5].Split('~');
|
||||
string[] xyz = args[3].Split(',');
|
||||
string[] fileNames = args[2].Split('~');
|
||||
string[] wholePercentages = args[7].Split('~');
|
||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||
if (mp.Length != mwg.Length || mp.Length != wholePercentages.Length) {
|
||||
logger.LogWarning("Lengths don't match!");
|
||||
} else {
|
||||
foreach (string fileName in fileNames) {
|
||||
checkFile = Path.Combine(sourceDirectory, fileName);
|
||||
if (!File.Exists(checkFile)) {
|
||||
logger.LogWarning("<{file}> doesn't exist!", args[2]);
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < mp.Length; i++) {
|
||||
if (wholePercentages[i].StartsWith("x-")) {
|
||||
logger.LogWarning("Skipping {wholePercentages}", wholePercentages[i]);
|
||||
continue;
|
||||
}
|
||||
Ext(checkFile, xyz, i, mp[i], mwg[i], locationDigits, wholePercentages[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Ext(string checkFile, string[] xyz, int i, string mp, string mwg, string locationDigits, string wholePercentages) {
|
||||
int width = int.Parse(xyz[0]);
|
||||
int height = int.Parse(xyz[1]);
|
||||
string[] mpValues = mp.Split(',');
|
||||
string[] mwgValues = mwg.Split(',');
|
||||
float mpWidth = float.Parse(mpValues[2]) * width;
|
||||
float mpHeight = float.Parse(mpValues[3]) * height;
|
||||
double mpLeft = (float.Parse(mpValues[0]) * width) - (mpWidth * .5);
|
||||
double mpTop = (float.Parse(mpValues[1]) * height) - (mpHeight * .5);
|
||||
Extract(file: checkFile,
|
||||
width: mpWidth,
|
||||
height: mpHeight,
|
||||
left: mpLeft,
|
||||
top: mpTop,
|
||||
suffix: $"-{i}mp.jpg");
|
||||
float mwgWidth = float.Parse(mwgValues[2]) * width;
|
||||
float mwgHeight = float.Parse(mwgValues[3]) * height;
|
||||
double mwgLeft = double.Parse(mwgValues[0]) * width;
|
||||
double mwgTop = double.Parse(mwgValues[1]) * height;
|
||||
Extract(file: checkFile,
|
||||
width: mwgWidth,
|
||||
height: mwgHeight,
|
||||
left: mwgLeft,
|
||||
top: mwgTop,
|
||||
suffix: $"-{i}mwg.jpg");
|
||||
int length = (int.Parse(locationDigits) - 1) / 4;
|
||||
string[] segments =
|
||||
[
|
||||
wholePercentages[..1],
|
||||
wholePercentages.Substring(1, length),
|
||||
wholePercentages.Substring(3, length),
|
||||
wholePercentages.Substring(5, length),
|
||||
wholePercentages.Substring(7, length)
|
||||
];
|
||||
if (string.Join(string.Empty, segments) == wholePercentages) {
|
||||
if (int.TryParse(segments[1], out int xWholePercent)
|
||||
&& int.TryParse(segments[2], out int yWholePercent)
|
||||
&& int.TryParse(segments[3], out int wWholePercent)
|
||||
&& int.TryParse(segments[4], out int hWholePercent)) {
|
||||
float factor = 100;
|
||||
RectangleF rectangleF = new(xWholePercent / factor, yWholePercent / factor, wWholePercent / factor, hWholePercent / factor);
|
||||
float rectangleFWidth = rectangleF.Width * width;
|
||||
float rectangleFHeight = rectangleF.Height * height;
|
||||
double rectangleFLeft = rectangleF.Left * width;
|
||||
double rectangleFTop = rectangleF.Top * height;
|
||||
Extract(file: checkFile,
|
||||
width: rectangleFWidth,
|
||||
height: rectangleFHeight,
|
||||
left: rectangleFLeft,
|
||||
top: rectangleFTop,
|
||||
suffix: $"-{i}whole-percentages.jpg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Extract(string file, float width, float height, double left, double top, string suffix) {
|
||||
RectangleF rectangle = new((float)left, (float)top, width, height);
|
||||
using (Bitmap source = new(file)) {
|
||||
using (Bitmap bitmap = new((int)width, (int)height)) {
|
||||
using (Graphics graphics = Graphics.FromImage(bitmap))
|
||||
graphics.DrawImage(source, new RectangleF(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||
bitmap.Save($"{file}{suffix}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -151,6 +151,32 @@ internal static class HelperDay
|
||||
ADO2025.PI5.Helper20250320.SortCodeMethods(logger, args, cancellationToken);
|
||||
else if (args[1] == "Day-Helper-2025-03-21")
|
||||
ADO2025.PI5.Helper20250321.MoveToLast(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-04-04")
|
||||
ADO2025.PI5.Helper20250404.KumaToGatus(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-04-07")
|
||||
ADO2025.PI5.Helper20250407.Sync(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-04-21")
|
||||
ADO2025.PI5.Helper20250421.FreeFileSyncChangeCreatedDate(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-04-29")
|
||||
ADO2025.PI5.Helper20250429.WriteNginxFileSystem(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-05-05")
|
||||
ADO2025.PI5.Helper20250505.HyperTextMarkupLanguageToPortableDocumentFormat(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-05-19")
|
||||
ADO2025.PI6.Helper20250519.LiveSync(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-05-21")
|
||||
ADO2025.PI6.Helper20250521.MatchDirectory(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-06-01")
|
||||
ADO2025.PI6.Helper20250601.EquipmentAutomationFrameworkStatus(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-06-02")
|
||||
ADO2025.PI6.Helper20250602.EquipmentAutomationFrameworkCellInstanceStateImageVerbIf(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-06-18")
|
||||
ADO2025.PI6.Helper20250618.MoveAllButXOfEach(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-06-28")
|
||||
ADO2025.PI6.Helper20250628.LogIsoInformation(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-07-01")
|
||||
ADO2025.PI6.Helper20250701.ProcessDataStandardFormatTo(logger, args);
|
||||
else if (args[1] == "Day-Helper-2025-07-05")
|
||||
ADO2025.PI6.Helper20250705.ExportFaces(logger, args);
|
||||
else
|
||||
throw new Exception(appSettings.Company);
|
||||
}
|
||||
|
@ -17,10 +17,11 @@
|
||||
<PackageReference Include="MetadataExtractor" Version="2.8.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
|
||||
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.14" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.5" />
|
||||
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.17" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
|
||||
<PackageReference Include="System.Text.Json" Version="9.0.5" />
|
||||
<PackageReference Include="TextCopy" Version="6.2.1" />
|
||||
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.2.1" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.3.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -41,4 +41,31 @@ internal static class HelperDirectory
|
||||
return new(results);
|
||||
}
|
||||
|
||||
internal static ReadOnlyCollection<ReadOnlyCollection<string>> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter)
|
||||
{
|
||||
List<ReadOnlyCollection<string>> results = [];
|
||||
string[] files;
|
||||
if (!fileSearchFilter.Contains('*'))
|
||||
fileSearchFilter = string.Concat('*', fileSearchFilter);
|
||||
if (!directorySearchFilter.Contains('*'))
|
||||
directorySearchFilter = string.Concat('*', directorySearchFilter);
|
||||
if (!Directory.Exists(directory))
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
results.Add(Directory.GetFiles(directory, fileSearchFilter, SearchOption.TopDirectoryOnly).AsReadOnly());
|
||||
string[] directories = Directory.GetDirectories(directory, directorySearchFilter, SearchOption.TopDirectoryOnly);
|
||||
foreach (string innerDirectory in directories)
|
||||
{
|
||||
try
|
||||
{
|
||||
files = Directory.GetFiles(innerDirectory, fileSearchFilter, SearchOption.AllDirectories);
|
||||
if (files.Length == 0)
|
||||
continue;
|
||||
results.Add(files.AsReadOnly());
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{ continue; }
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
}
|
@ -16,8 +16,20 @@ internal static partial class HelperMarkdown
|
||||
|
||||
private record Input(string? Destination,
|
||||
string Source,
|
||||
string? ReplaceWithTitle,
|
||||
bool UseProcessStart);
|
||||
|
||||
private record Table(ReadOnlyCollection<string> Columns,
|
||||
int ColumnsLine,
|
||||
ReadOnlyCollection<ReadOnlyCollection<string>> Rows,
|
||||
string? Title);
|
||||
|
||||
private record Block(int Line,
|
||||
string? Json,
|
||||
int RowCount,
|
||||
ReadOnlyCollection<string>? Rows,
|
||||
string? Title);
|
||||
|
||||
private record Record(string Directory,
|
||||
string File,
|
||||
string[] Lines);
|
||||
@ -30,7 +42,7 @@ internal static partial class HelperMarkdown
|
||||
string FileNameWithoutExtension,
|
||||
ReadOnlyDictionary<string, object> FrontMatterYaml,
|
||||
string H1,
|
||||
bool IsGitOthersModifiedAndDeletedExcludingStandard,
|
||||
bool? IsGitOthersModifiedAndDeletedExcludingStandard,
|
||||
bool IsKanbanIndex,
|
||||
bool IsKanbanMarkdown,
|
||||
DateTime LastWriteDateTime,
|
||||
@ -49,15 +61,27 @@ internal static partial class HelperMarkdown
|
||||
|
||||
private record MarkdownFileH1AndRelativePath(MarkdownFile? MarkdownFile, string[]? Lines, string? H1, string? RelativePath);
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[JsonSerializable(typeof(Dictionary<string, object>))]
|
||||
internal partial class DictionaryStringAndObjectSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[JsonSerializable(typeof(Dictionary<string, JsonElement>))]
|
||||
internal partial class DictionaryStringAndJsonElementSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[GeneratedRegex("([A-Z]+(.))")]
|
||||
private static partial Regex UpperCase();
|
||||
|
||||
[GeneratedRegex("(~~)?(#)([a-zA-Z0-9]{6})(~~)?( )")]
|
||||
private static partial Regex HtmlColor();
|
||||
|
||||
[GeneratedRegex("[\\s!?.,@:;|\\\\/\"'`£$%\\^&*{}[\\]()<>~#+\\-=_¬]+")]
|
||||
private static partial Regex InvalidCharacter();
|
||||
|
||||
private static MarkdownExtra GetMarkdownExtra(MarkdownFileAndLines markdownFileAndLines)
|
||||
{
|
||||
MarkdownExtra result;
|
||||
@ -301,10 +325,10 @@ internal static partial class HelperMarkdown
|
||||
if (!directoryInfo.Exists || (!string.IsNullOrEmpty(directoryInfo.LinkTarget) && !Directory.Exists(directoryInfo.LinkTarget)))
|
||||
continue;
|
||||
collection.AddRange(GetFiles(appSettings, directoryInfo, SearchOption.TopDirectoryOnly));
|
||||
foreach (FileInfo file in collection)
|
||||
results.Add(file);
|
||||
foreach (FileInfo fileInfo in collection)
|
||||
results.Add(fileInfo);
|
||||
}
|
||||
return new(results);
|
||||
return (from l in results orderby l.FullName select l).ToArray().AsReadOnly();
|
||||
}
|
||||
|
||||
internal static LineNumber GetLineNumbers(FileInfo fileInfo)
|
||||
@ -525,7 +549,7 @@ internal static partial class HelperMarkdown
|
||||
h1Check = $"# {h1[2..]}";
|
||||
if (h1Check.Length == h1.Length && h1Check != h1)
|
||||
{
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
lines[markdownFile.LineNumber.H1.Value] = h1Check;
|
||||
File.WriteAllLines(markdownFile.File, lines);
|
||||
@ -541,7 +565,7 @@ internal static partial class HelperMarkdown
|
||||
checkName = Path.Combine(markdownFile.Directory, checkFileName);
|
||||
if (checkName == markdownFile.File)
|
||||
continue;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
File.Move(markdownFile.File, checkName);
|
||||
result += 1;
|
||||
@ -658,6 +682,7 @@ internal static partial class HelperMarkdown
|
||||
Input result;
|
||||
string? destination = null;
|
||||
bool useProcessStart = false;
|
||||
string? replaceWithTitle = null;
|
||||
string source = Path.GetFullPath(args[0]);
|
||||
for (int i = 1; i < args.Count; i++)
|
||||
{
|
||||
@ -667,6 +692,8 @@ internal static partial class HelperMarkdown
|
||||
useProcessStart = args[i + 1] == "true";
|
||||
else if (args[i][1] == 'd')
|
||||
destination = Path.GetFullPath(args[i + 1]);
|
||||
else if (args[i][1] == 't')
|
||||
replaceWithTitle = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -678,11 +705,11 @@ internal static partial class HelperMarkdown
|
||||
if (!Directory.Exists(destination))
|
||||
_ = Directory.CreateDirectory(destination);
|
||||
}
|
||||
result = new(destination, source, useProcessStart);
|
||||
result = new(Destination: destination, Source: source, ReplaceWithTitle: replaceWithTitle, UseProcessStart: useProcessStart);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, MarkdownFileAndLines> GetRelativeToCollection(AppSettings appSettings, Input input, ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles)
|
||||
private static ReadOnlyDictionary<string, MarkdownFileAndLines> GetRelativeToCollection(AppSettings appSettings, Input input, ReadOnlyCollection<string>? gitOthersModifiedAndDeletedExcludingStandardFiles)
|
||||
{
|
||||
Dictionary<string, MarkdownFileAndLines> results = [];
|
||||
string h1;
|
||||
@ -696,17 +723,22 @@ internal static partial class HelperMarkdown
|
||||
string fileNameWithoutExtension;
|
||||
ReadOnlyCollection<string> lines;
|
||||
ReadOnlyDictionary<string, object> frontMatterYaml;
|
||||
bool isGitOthersModifiedAndDeletedExcludingStandard;
|
||||
bool? isGitOthersModifiedAndDeletedExcludingStandard;
|
||||
ReadOnlyCollection<FileInfo> files = GetFiles(appSettings, input);
|
||||
foreach (FileInfo fileInfo in files)
|
||||
{ // cSpell:disable
|
||||
if (fileInfo.DirectoryName is null)
|
||||
continue;
|
||||
key = Path.GetRelativePath(input.Source, fileInfo.FullName);
|
||||
if (gitOthersModifiedAndDeletedExcludingStandardFiles is null)
|
||||
isGitOthersModifiedAndDeletedExcludingStandard = null;
|
||||
else
|
||||
{
|
||||
isWithinSource = fileInfo.FullName.Contains(input.Source);
|
||||
isGitOthersModifiedAndDeletedExcludingStandard = gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(fileInfo.FullName);
|
||||
if (!isWithinSource && results.ContainsKey(key))
|
||||
continue;
|
||||
}
|
||||
lineNumber = GetLineNumbers(fileInfo);
|
||||
lines = lineNumber.Lines;
|
||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
|
||||
@ -716,7 +748,7 @@ internal static partial class HelperMarkdown
|
||||
(type, h1) = GetTypeAndH1(appSettings, h1, lines, lineNumber);
|
||||
else
|
||||
{
|
||||
if (!isGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (isGitOthersModifiedAndDeletedExcludingStandard is not null && !isGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
type = appSettings.DefaultNoteType;
|
||||
File.WriteAllLines(fileInfo.FullName, ["---", $"type: {type}\"", "---", string.Empty, $"# {h1}"]);
|
||||
@ -724,20 +756,20 @@ internal static partial class HelperMarkdown
|
||||
}
|
||||
isKanbanMarkdown = fileInfo.Name.EndsWith(".knb.md");
|
||||
isKanbanIndex = fileNameWithoutExtension == "index" && type.StartsWith("kanb", StringComparison.OrdinalIgnoreCase);
|
||||
markdownFile = new(fileInfo.CreationTime,
|
||||
fileInfo.DirectoryName,
|
||||
fileInfo.Extension,
|
||||
fileInfo.FullName,
|
||||
fileInfo.Name,
|
||||
fileNameWithoutExtension,
|
||||
frontMatterYaml,
|
||||
h1,
|
||||
isGitOthersModifiedAndDeletedExcludingStandard,
|
||||
isKanbanIndex,
|
||||
isKanbanMarkdown,
|
||||
fileInfo.LastWriteTime,
|
||||
lineNumber,
|
||||
type);
|
||||
markdownFile = new(CreationDateTime: fileInfo.CreationTime,
|
||||
Directory: fileInfo.DirectoryName,
|
||||
Extension: fileInfo.Extension,
|
||||
File: fileInfo.FullName,
|
||||
FileName: fileInfo.Name,
|
||||
FileNameWithoutExtension: fileNameWithoutExtension,
|
||||
FrontMatterYaml: frontMatterYaml,
|
||||
H1: h1,
|
||||
IsGitOthersModifiedAndDeletedExcludingStandard: isGitOthersModifiedAndDeletedExcludingStandard,
|
||||
IsKanbanIndex: isKanbanIndex,
|
||||
IsKanbanMarkdown: isKanbanMarkdown,
|
||||
LastWriteDateTime: fileInfo.LastWriteTime,
|
||||
LineNumber: lineNumber,
|
||||
Type: type);
|
||||
results.Add(key, new(markdownFile, lines.ToArray()));
|
||||
} // cSpell:restore
|
||||
return new(results);
|
||||
@ -763,7 +795,7 @@ internal static partial class HelperMarkdown
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (markdownFile.IsKanbanMarkdown)
|
||||
continue;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
if (markdownFile.LineNumber.FrontMatterYamlEnd is null)
|
||||
continue;
|
||||
@ -797,7 +829,7 @@ internal static partial class HelperMarkdown
|
||||
circularReference = false;
|
||||
lines = relativeTo.Value.Lines;
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
@ -859,7 +891,7 @@ internal static partial class HelperMarkdown
|
||||
found = false;
|
||||
lines = relativeTo.Value.Lines;
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
@ -912,7 +944,7 @@ internal static partial class HelperMarkdown
|
||||
write = false;
|
||||
lines = relativeTo.Value.Lines;
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (!input.UseProcessStart && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (!input.UseProcessStart && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
@ -940,7 +972,7 @@ internal static partial class HelperMarkdown
|
||||
}
|
||||
if (!write)
|
||||
continue;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
File.WriteAllLines(markdownFile.File, lines);
|
||||
result += 1;
|
||||
@ -975,7 +1007,7 @@ internal static partial class HelperMarkdown
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (markdownFile.IsKanbanIndex)
|
||||
continue;
|
||||
if (!input.UseProcessStart && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (!input.UseProcessStart && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
if (!File.Exists(markdownFile.File))
|
||||
continue;
|
||||
@ -1040,7 +1072,7 @@ internal static partial class HelperMarkdown
|
||||
}
|
||||
if (!write)
|
||||
continue;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
File.WriteAllLines(markdownFile.File, lines);
|
||||
result += 1;
|
||||
@ -1057,20 +1089,14 @@ internal static partial class HelperMarkdown
|
||||
MarkdownFileAndLines? markdownFileAndLines = GetKanbanIndexMarkdownFileAndLines(relativeToCollection);
|
||||
if (markdownFileAndLines is not null && File.Exists(markdownFileAndLines.MarkdownFile.File))
|
||||
{
|
||||
ReadOnlyDictionary<string, List<Card>> columnsToCards;
|
||||
ReadOnlyDictionary<string, List<Card>> columnsToCards = GetColumnsToCards(input, relativeToCollection, markdownFileAndLines);
|
||||
string jsonFile = Path.Combine(input.Destination, $"{nameof(columnsToCards)}.json");
|
||||
if (File.Exists(jsonFile))
|
||||
File.Delete(jsonFile);
|
||||
columnsToCards = GetColumnsToCards(input, relativeToCollection, markdownFileAndLines);
|
||||
if (columnsToCards.Count == 0)
|
||||
File.WriteAllText(jsonFile, "{}");
|
||||
else
|
||||
{
|
||||
string json = JsonSerializer.Serialize(columnsToCards, ColumnsAndCardsSourceGenerationContext.Default.ReadOnlyDictionaryStringListCard);
|
||||
string old = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile);
|
||||
string json = columnsToCards.Count == 0 ? "{}" : JsonSerializer.Serialize(columnsToCards, ColumnsAndCardsSourceGenerationContext.Default.ReadOnlyDictionaryStringListCard);
|
||||
if (json != old)
|
||||
File.WriteAllText(jsonFile, json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static (string type, string h1) GetTypeAndH1(AppSettings appSettings, string h1, ReadOnlyCollection<string> lines, LineNumber lineNumber)
|
||||
{
|
||||
@ -1122,7 +1148,7 @@ internal static partial class HelperMarkdown
|
||||
results.Insert(0, string.Empty);
|
||||
}
|
||||
results.Insert(0, "---");
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
{
|
||||
results.Insert(0, updatedLine);
|
||||
results.Insert(0, createdLine);
|
||||
@ -1140,7 +1166,7 @@ internal static partial class HelperMarkdown
|
||||
}
|
||||
if (markdownFile.LineNumber.Type is null)
|
||||
results.Insert(markdownFile.LineNumber.FrontMatterYamlEnd.Value, typeLine);
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
{
|
||||
if (markdownFile.LineNumber.Updated is null)
|
||||
results.Insert(markdownFile.LineNumber.FrontMatterYamlEnd.Value, updatedLine);
|
||||
@ -1176,7 +1202,7 @@ internal static partial class HelperMarkdown
|
||||
}
|
||||
if (results.Count == lines.Length && string.Join('\r', lines) == string.Join('\r', results))
|
||||
continue;
|
||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||
continue;
|
||||
File.WriteAllLines(markdownFile.File, results);
|
||||
File.SetLastWriteTime(markdownFile.File, markdownFile.LastWriteDateTime);
|
||||
@ -1235,7 +1261,351 @@ internal static partial class HelperMarkdown
|
||||
logger.LogInformation("{updated} Markdown file(s) were updated", updated);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(input.Destination))
|
||||
{
|
||||
SaveColumnToCards(input, relativeToCollection);
|
||||
SaveTablesToJson(appSettings, logger, input);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SaveTablesToJson(AppSettings appSettings, ILogger<Worker> logger, Input input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input.Destination))
|
||||
throw new NotSupportedException();
|
||||
string old;
|
||||
string json;
|
||||
string[] lines;
|
||||
string fileName;
|
||||
List<Block> blocks;
|
||||
string directoryName;
|
||||
List<string>? jsonLines;
|
||||
MarkdownFile markdownFile;
|
||||
List<string> fileNames = [];
|
||||
ReadOnlyCollection<Table> tables;
|
||||
Dictionary<string, List<string>> results = [];
|
||||
ReadOnlyCollection<Block> javaScriptObjectNotationBlocks;
|
||||
ReadOnlyCollection<Block> yetAnotherMarkupLanguageBlocks;
|
||||
ReadOnlyDictionary<string, MarkdownFileAndLines> relativeToCollection = GetRelativeToCollection(appSettings, input, gitOthersModifiedAndDeletedExcludingStandardFiles: null);
|
||||
foreach (KeyValuePair<string, MarkdownFileAndLines> relativeTo in relativeToCollection)
|
||||
{
|
||||
if (relativeTo.Value.Lines.Length == 0)
|
||||
continue;
|
||||
lines = relativeTo.Value.Lines;
|
||||
markdownFile = relativeTo.Value.MarkdownFile;
|
||||
if (markdownFile.IsKanbanIndex)
|
||||
continue;
|
||||
if (markdownFile.IsKanbanMarkdown)
|
||||
continue;
|
||||
if (markdownFile.FileName.StartsWith("index.yml.md"))
|
||||
continue;
|
||||
if (!File.Exists(markdownFile.File))
|
||||
continue;
|
||||
tables = GetTables(lines);
|
||||
javaScriptObjectNotationBlocks = GetJavaScriptObjectNotationBlocks(lines);
|
||||
yetAnotherMarkupLanguageBlocks = GetYetAnotherMarkupLanguageBlocks(lines);
|
||||
if (tables.Count == 0 && javaScriptObjectNotationBlocks.Count == 0 && yetAnotherMarkupLanguageBlocks.Count == 0)
|
||||
continue;
|
||||
fileName = Path.Combine(input.Destination, $"{markdownFile.FileNameWithoutExtension}.json");
|
||||
if (fileNames.Contains(fileName))
|
||||
continue;
|
||||
fileNames.Add(fileName);
|
||||
blocks = [];
|
||||
blocks.AddRange(GetBlocks(tables));
|
||||
blocks.AddRange(javaScriptObjectNotationBlocks);
|
||||
blocks.AddRange(GetBlocks(logger, markdownFile, yetAnotherMarkupLanguageBlocks));
|
||||
if (blocks.Count == 0)
|
||||
continue;
|
||||
directoryName = Path.GetFileName(Path.Combine(input.Destination, markdownFile.Directory));
|
||||
if (!results.TryGetValue(directoryName, out jsonLines))
|
||||
{
|
||||
results.Add(directoryName, []);
|
||||
if (!results.TryGetValue(directoryName, out jsonLines))
|
||||
throw new Exception();
|
||||
}
|
||||
json = GetJson(input, markdownFile, blocks.AsReadOnly());
|
||||
jsonLines.Add(json);
|
||||
}
|
||||
foreach (KeyValuePair<string, List<string>> keyValuePair in results)
|
||||
{
|
||||
json = string.Concat('[', Environment.NewLine, string.Join($",{Environment.NewLine}", keyValuePair.Value), Environment.NewLine, ']');
|
||||
fileName = Path.Combine(input.Destination, $"{keyValuePair.Key}.json");
|
||||
old = !File.Exists(fileName) ? string.Empty : File.ReadAllText(fileName);
|
||||
if (json != old)
|
||||
{
|
||||
File.WriteAllText(fileName, json);
|
||||
logger.LogInformation("Updated json file for <{fileName}>", fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Table> GetTables(string[] lines)
|
||||
{
|
||||
List<Table> results = [];
|
||||
Table table;
|
||||
string? title;
|
||||
string[] segments;
|
||||
int? columnsLine = null;
|
||||
List<ReadOnlyCollection<string>> rows = [];
|
||||
string[]? columns = null;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (columns is null && (!lines[i].StartsWith('|') || !lines[i].EndsWith('|') || i + 3 >= lines.Length))
|
||||
continue;
|
||||
if (columns is null && (lines[i + 1].Length < 3 || lines[i + 1][0] != '|' || (lines[i + 1][1] is not ':' and not '-')))
|
||||
continue;
|
||||
if (columns is null)
|
||||
{
|
||||
columnsLine = i;
|
||||
segments = lines[i][1..^1].Split('|');
|
||||
columns = (from l in segments select l.Trim()).ToArray();
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
segments = lines[i].Length < 3 ? [] : lines[i][1..^1].Split('|');
|
||||
rows.Add((from l in segments select l.Trim()).ToArray().AsReadOnly());
|
||||
if (columns is not null && columnsLine is not null && string.IsNullOrEmpty(lines[i]))
|
||||
{
|
||||
if (columnsLine.Value - 2 > 0 && lines[columnsLine.Value - 2].StartsWith('#'))
|
||||
title = lines[columnsLine.Value - 2];
|
||||
else if (columnsLine.Value - 4 > 0 && lines[columnsLine.Value - 4].StartsWith('#'))
|
||||
title = lines[columnsLine.Value - 4];
|
||||
else
|
||||
title = null;
|
||||
rows.RemoveAt(rows.Count - 1);
|
||||
table = new(columns.AsReadOnly(), columnsLine.Value, rows.AsReadOnly(), title);
|
||||
results.Add(table);
|
||||
columnsLine = null;
|
||||
columns = null;
|
||||
rows = [];
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string GetParamCase(string value)
|
||||
{
|
||||
string result;
|
||||
StringBuilder stringBuilder = new(value);
|
||||
Match[] matches = UpperCase().Matches(value).ToArray();
|
||||
for (int i = matches.Length - 1; i > -1; i--)
|
||||
_ = stringBuilder.Insert(matches[i].Index, '-');
|
||||
string[] segments = InvalidCharacter().Split(stringBuilder.ToString().ToLower());
|
||||
result = string.Join('-', segments).Trim('-');
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Block> GetBlocks(ReadOnlyCollection<Table> tables)
|
||||
{
|
||||
List<Block> results = [];
|
||||
Block block;
|
||||
string json;
|
||||
foreach (Table table in tables)
|
||||
{
|
||||
if (table.Title is null)
|
||||
continue;
|
||||
if (table.Rows.Count == 0)
|
||||
continue;
|
||||
json = GetJson(table);
|
||||
block = new(Line: table.ColumnsLine, Json: json, RowCount: table.Rows.Count, Rows: null, Title: table.Title);
|
||||
results.Add(block);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string GetJson(Table table)
|
||||
{
|
||||
string result;
|
||||
string line;
|
||||
string value;
|
||||
string[] segments;
|
||||
List<string> lines = [];
|
||||
for (int i = 0; i < table.Rows.Count; i++)
|
||||
{
|
||||
line = "{";
|
||||
segments = table.Rows[i].ToArray();
|
||||
if (segments.Length != table.Columns.Count)
|
||||
break;
|
||||
for (int c = 0; c < segments.Length; c++)
|
||||
{
|
||||
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
line += string.Concat('"', table.Columns[c].Trim('"'), '"', ':', '"', value, '"', ',');
|
||||
}
|
||||
line = string.Concat(line[..^1], '}');
|
||||
lines.Add(line);
|
||||
}
|
||||
result = string.Concat('[', Environment.NewLine, string.Join($",{Environment.NewLine}", lines), Environment.NewLine, ']');
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Block> GetJavaScriptObjectNotationBlocks(string[] lines)
|
||||
{
|
||||
List<Block> results = [];
|
||||
string json;
|
||||
string? title;
|
||||
int? blockLine = null;
|
||||
List<string> rows = [];
|
||||
Block javaScriptObjectNotationBlock;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (blockLine is null && !lines[i].StartsWith("```json"))
|
||||
continue;
|
||||
if (blockLine is null)
|
||||
{
|
||||
blockLine = i;
|
||||
continue;
|
||||
}
|
||||
rows.Add(lines[i]);
|
||||
if (blockLine is not null && lines[i] == "```")
|
||||
{
|
||||
rows.RemoveAt(rows.Count - 1);
|
||||
if (blockLine.Value - 2 > 0 && lines[blockLine.Value - 2].StartsWith('#'))
|
||||
title = lines[blockLine.Value - 2];
|
||||
else if (blockLine.Value - 4 > 0 && lines[blockLine.Value - 4].StartsWith('#'))
|
||||
title = lines[blockLine.Value - 4];
|
||||
else
|
||||
title = null;
|
||||
if (string.IsNullOrEmpty(title))
|
||||
continue;
|
||||
json = string.Join(Environment.NewLine, rows);
|
||||
javaScriptObjectNotationBlock = new(Line: blockLine.Value, Json: json, RowCount: rows.Count, Rows: null, Title: title);
|
||||
results.Add(javaScriptObjectNotationBlock);
|
||||
blockLine = null;
|
||||
rows = [];
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Block> GetYetAnotherMarkupLanguageBlocks(string[] lines)
|
||||
{
|
||||
List<Block> results = [];
|
||||
string? title = null;
|
||||
int? blockLine = null;
|
||||
List<string> rows = [];
|
||||
Block yetAnotherMarkupLanguageBlock;
|
||||
if (lines[0] == "---")
|
||||
{
|
||||
for (int i = 1; i < lines.Length; i++)
|
||||
{
|
||||
rows.Add(lines[i]);
|
||||
if (lines[i] == "---")
|
||||
{
|
||||
rows.RemoveAt(rows.Count - 1);
|
||||
yetAnotherMarkupLanguageBlock = new(Line: 0, Json: null, RowCount: rows.Count, Rows: rows.AsReadOnly(), Title: title);
|
||||
results.Add(yetAnotherMarkupLanguageBlock);
|
||||
rows = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
rows = [];
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (blockLine is null && !lines[i].StartsWith("```yml") && !lines[i].StartsWith("```yaml"))
|
||||
continue;
|
||||
if (blockLine is null)
|
||||
{
|
||||
blockLine = i;
|
||||
continue;
|
||||
}
|
||||
rows.Add(lines[i]);
|
||||
if (blockLine is not null && lines[i] == "```")
|
||||
{
|
||||
rows.RemoveAt(rows.Count - 1);
|
||||
if (blockLine.Value - 2 > 0 && lines[blockLine.Value - 2].StartsWith('#'))
|
||||
title = lines[blockLine.Value - 2];
|
||||
else if (blockLine.Value - 4 > 0 && lines[blockLine.Value - 4].StartsWith('#'))
|
||||
title = lines[blockLine.Value - 4];
|
||||
else
|
||||
title = null;
|
||||
yetAnotherMarkupLanguageBlock = new(Line: blockLine.Value, Json: null, RowCount: rows.Count, Rows: rows.AsReadOnly(), Title: title);
|
||||
results.Add(yetAnotherMarkupLanguageBlock);
|
||||
blockLine = null;
|
||||
rows = [];
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Block> GetBlocks(ILogger<Worker> logger, MarkdownFile markdownFile, ReadOnlyCollection<Block> yetAnotherMarkupLanguageBlocks)
|
||||
{
|
||||
List<Block> results = [];
|
||||
string key;
|
||||
Block block;
|
||||
string json;
|
||||
string text;
|
||||
Dictionary<string, object>? keyValuePairs;
|
||||
Dictionary<string, object> keyValuePairsB = [];
|
||||
#pragma warning disable IL3050
|
||||
IDeserializer deserializer = new DeserializerBuilder().Build();
|
||||
#pragma warning restore IL3050
|
||||
foreach (Block yaml in yetAnotherMarkupLanguageBlocks)
|
||||
{
|
||||
if (yaml.Rows is null || yaml.RowCount == 0)
|
||||
continue;
|
||||
if (yaml.Title is null && yaml.Line != 0)
|
||||
continue;
|
||||
text = string.Join(Environment.NewLine, yaml.Rows);
|
||||
try
|
||||
{ keyValuePairs = deserializer.Deserialize<Dictionary<string, object>>(text); }
|
||||
catch (Exception)
|
||||
{
|
||||
keyValuePairs = null;
|
||||
logger.LogWarning("Invalid yaml file for <{file}>", markdownFile.FileName);
|
||||
}
|
||||
if (keyValuePairs is null)
|
||||
continue;
|
||||
keyValuePairsB.Clear();
|
||||
foreach (KeyValuePair<string, object> keyValuePair in keyValuePairs)
|
||||
{
|
||||
key = GetParamCase(keyValuePair.Key);
|
||||
if (keyValuePairsB.ContainsKey(key))
|
||||
continue;
|
||||
if (keyValuePair.Value is IDictionary<object, object>)
|
||||
{
|
||||
logger.LogWarning("yaml contains a dictionary not allowed in AOT <{file}>", markdownFile.FileName);
|
||||
break;
|
||||
}
|
||||
else if (keyValuePair.Value is not ICollection<object> collection)
|
||||
keyValuePairsB.Add(key, keyValuePair.Value);
|
||||
else
|
||||
keyValuePairsB.Add(key, string.Join(',', collection));
|
||||
}
|
||||
try
|
||||
{ json = JsonSerializer.Serialize(keyValuePairsB, DictionaryStringAndObjectSourceGenerationContext.Default.DictionaryStringObject); }
|
||||
catch (Exception)
|
||||
{
|
||||
logger.LogWarning("yaml contains special values not allowed in AOT <{file}>", markdownFile.FileName);
|
||||
continue;
|
||||
}
|
||||
block = new(Line: yaml.Line, Json: json, RowCount: yaml.Rows.Count, Rows: null, Title: yaml.Title);
|
||||
results.Add(block);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static string GetJson(Input input, MarkdownFile markdownFile, ReadOnlyCollection<Block> blocks)
|
||||
{
|
||||
string result;
|
||||
string paramCase;
|
||||
List<string> lines = [];
|
||||
string fileNameParamCase = GetParamCase(markdownFile.FileNameWithoutExtension);
|
||||
foreach (Block block in blocks.OrderBy(l => l.Line))
|
||||
{
|
||||
paramCase = block.Title is null ? $"Line-{block.Line}" : GetParamCase(block.Title);
|
||||
if (!string.IsNullOrEmpty(input.ReplaceWithTitle) && paramCase == input.ReplaceWithTitle)
|
||||
paramCase = $"{fileNameParamCase}-{block.Line}";
|
||||
lines.Add($"\"{paramCase}\": {block.Json}");
|
||||
}
|
||||
result = string.Concat('{',
|
||||
Environment.NewLine,
|
||||
$"\"{fileNameParamCase}\": ",
|
||||
'{',
|
||||
Environment.NewLine,
|
||||
string.Join($",{Environment.NewLine}", lines),
|
||||
Environment.NewLine,
|
||||
'}',
|
||||
Environment.NewLine,
|
||||
'}');
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -45,6 +45,12 @@ internal partial class NginxFileSystemSourceGenerationContext : JsonSerializerCo
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[JsonSerializable(typeof(NginxFileSystem))]
|
||||
internal partial class NginxFileSystemSingleLineSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[JsonSerializable(typeof(NginxFileSystem[]))]
|
||||
internal partial class NginxFileSystemCollectionSourceGenerationContext : JsonSerializerContext
|
||||
|
@ -1,88 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
getValue($('gv.thicknessPoints', ''), $('dcp.BIORAD2/csv/Index', '0'));
|
||||
|
||||
function getCollectionParseFloat(collection) {
|
||||
let result = [];
|
||||
let value;
|
||||
for (let i = 0; i < collection.length; i++) {
|
||||
value = parseFloat(collection[i]);
|
||||
result.push(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getSum(collection) {
|
||||
let result = 0;
|
||||
if (!collection || collection.length === 0) {
|
||||
result = 0;
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < collection.length; i++) {
|
||||
result += collection[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getAverage(collection) {
|
||||
let result = null;
|
||||
if (collection == null || collection.length === 0)
|
||||
result = 0;
|
||||
else {
|
||||
let sum = getSum(collection);
|
||||
result = sum / collection.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getValue(thicknessPoints, index) {
|
||||
let result = null;
|
||||
if (index === 13) {
|
||||
if (thicknessPoints != undefined && thicknessPoints.length > 1) {
|
||||
let collection = thicknessPoints[0] === '|' ? thicknessPoints.substring(1).split('|') : thicknessPoints.split('|');
|
||||
let collectionParseFloat = getCollectionParseFloat(collection);
|
||||
let thicknessFourteen3mmEdgeMean = getAverage([[collectionParseFloat[10], collectionParseFloat[11], collectionParseFloat[12], collectionParseFloat[13]]]);
|
||||
let thicknessFourteenMeanFrom = getAverage([[collectionParseFloat[1], collectionParseFloat[2], collectionParseFloat[6], collectionParseFloat[7]]]);
|
||||
result = (thicknessFourteen3mmEdgeMean - thicknessFourteenMeanFrom) / thicknessFourteenMeanFrom * 100;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getVariance(collection) {
|
||||
let result = null;
|
||||
if (collection == null || collection.length === 0)
|
||||
result = null;
|
||||
else {
|
||||
let variance = 0;
|
||||
let t = collection[0];
|
||||
for (let i = 1; i < collection.length; i++) {
|
||||
t += collection[i];
|
||||
const diff = ((i + 1) * collection[i]) - t;
|
||||
variance += diff * diff / ((i + 1.0) * i);
|
||||
}
|
||||
result = variance / (collection.length - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// $('gv.thicknessPoints', '') + '|' + $('dcp.BIORAD2/csv/Thickness', '')
|
||||
// $('gv.thicknessPoints', '') + '|' + $('dcp.BIORAD3/csv/Thickness', '')
|
||||
// $('gv.thicknessPoints', '') + '|' + $('dcp.BIORAD4/csv/Thickness', '')
|
||||
// $('gv.thicknessPoints', '') + '|' + $('dcp.BIORAD5/b-csv/Thickness', '')
|
||||
|
||||
// \\mesfs.infineon.com\EC_Characterization_Si\Archive\BIORAD2\2025_Week_08\2025-02-20\64-659712-4626_2025-02-20_11;50_AM_5144331401\638756490128318288
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
|
||||
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
const thicknessPoints = getCollectionParseFloat('|4.022|3.952|3.936|3.971|3.954|3.976|3.949|3.906|3.967|3.995|3.997|3.932|3.766|3.890'.substring(1).split('|'));
|
||||
const thicknessTenPoints = thicknessPoints.slice(0, 10);
|
||||
const thicknessFourteenCriticalPointsAverage = getAverage(thicknessTenPoints); // 15 // *3.962799999999999
|
||||
const thicknessFourteenCriticalPointsStdDev = Math.sqrt(getVariance(thicknessTenPoints)); // 16 // *0.0318496467798311
|
||||
const thicknessFourteenCenterMean = thicknessPoints[4]; // 17 // 3.954
|
||||
const thicknessFourteenMeanFrom = getAverage([thicknessPoints[1], thicknessPoints[2], thicknessPoints[6], thicknessPoints[7]]); // 18 // *3.954
|
||||
const thicknessFourteen5mmEdgeMean = getAverage([thicknessPoints[0], thicknessPoints[9]]); // 19 // *4.0085
|
||||
const thicknessFourteen3mmEdgeMean = getAverage([thicknessPoints[10], thicknessPoints[11], thicknessPoints[12], thicknessPoints[13]]); // 20 // *3.89625
|
||||
const thicknessFourteen5mmEdgePercent = (thicknessFourteen5mmEdgeMean - thicknessFourteenMeanFrom) / thicknessFourteenMeanFrom * 100; // 21 // *1.848440576764267
|
||||
const thicknessFourteen3mmEdgePercent = (thicknessFourteen3mmEdgeMean - thicknessFourteenMeanFrom) / thicknessFourteenMeanFrom * 100; // 22 // *-1.0036206567998442
|
||||
console.log(thicknessFourteenCriticalPointsAverage);
|
@ -1,4 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
// DateTime normal = DateTime.Now.ToUniversalTime();
|
||||
// logger.LogInformation("Now - ToUniversalTime: {ticks}", normal.Ticks);
|
||||
// DateTime utc1970DateTime = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
@ -16,6 +17,17 @@
|
||||
// console.log("dateText: " + dateText);
|
||||
// DateTime utcMeDateTime = new(1980, 1, 17, 0, 0, 0, DateTimeKind.Utc);
|
||||
// long meTotalSeconds = (long)Math.Floor(fileInfo.LastWriteTime.ToUniversalTime().Subtract(utcMeDateTime).TotalSeconds);
|
||||
|
||||
// epoch: 25201000
|
||||
// ticks: 638665132483790000
|
||||
// dateText: 638665132483790000 - Wed Nov 06 2024 10:55:58 GMT-0700 (Mountain Standard Time)
|
||||
// Now - To: 638665132334594771
|
||||
// 638665135325760000
|
||||
// 638665136814890000
|
||||
// utc1970DateTime: 621355968000000000
|
||||
|
||||
function getDateText() {
|
||||
let result;
|
||||
const now = new Date();
|
||||
const time = now.getTime();
|
||||
const year = now.getFullYear();
|
||||
@ -42,20 +54,53 @@ else if (day < 354)
|
||||
season = season + "6.Fall";
|
||||
else
|
||||
season = season + "7.Winter";
|
||||
let seconds = time.valueOf() + timezoneOffset;
|
||||
let epoch = seconds * 10000;
|
||||
let ticks = epoch + 621355968000000000;
|
||||
let dateText = seconds + " - " + ticks + " - " + now.toString();
|
||||
const seconds = time.valueOf() + timezoneOffset;
|
||||
const epoch = seconds * 10000;
|
||||
const ticks = epoch + 621355968000000000;
|
||||
result = seconds + " - " + ticks + " - " + now.toString();
|
||||
return result;
|
||||
}
|
||||
|
||||
const dateText = getDateText();
|
||||
console.log("dateText: " + dateText);
|
||||
console.log("end");
|
||||
let original = "d:\\5-Other-Small\\Kanban\\Year-Season\\2025\\2025-0.Winter\\1737913505637";
|
||||
let segments = original.split('\\');
|
||||
let path = segments.slice(0, -3).join('\\') + '\\2021\\2021-0.Summer\\123';
|
||||
console.log(path);
|
||||
// epoch: 25201000
|
||||
// ticks: 638665132483790000
|
||||
// dateText: 638665132483790000 - Wed Nov 06 2024 10:55:58 GMT-0700 (Mountain Standard Time)
|
||||
// Now - To: 638665132334594771
|
||||
// 638665135325760000
|
||||
// 638665136814890000
|
||||
// utc1970DateTime: 621355968000000000
|
||||
|
||||
function getPath() {
|
||||
let result;
|
||||
const original = "d:\\5-Other-Small\\Kanban\\Year-Season\\2025\\2025-0.Winter\\1737913505637";
|
||||
const segments = original.split('\\');
|
||||
result = segments.slice(0, -3).join('\\') + '\\2021\\2021-0.Summer\\123';
|
||||
return result;
|
||||
}
|
||||
|
||||
const path = getPath();
|
||||
console.log("path: " + path);
|
||||
|
||||
// https://tickstodatetime.wassupy.com/?ticks=638784250251441727
|
||||
|
||||
function getInfinityQS(value, sequence) {
|
||||
let result;
|
||||
if (sequence.length < 18)
|
||||
result = [value];
|
||||
else {
|
||||
const now = new Date();
|
||||
const epochHour = 36000000000;
|
||||
const epochTicks = 621355968000000000;
|
||||
const timezoneHourOffset = now.getTimezoneOffset() / 60;
|
||||
const timezoneOffset = timezoneHourOffset * epochHour;
|
||||
const milliseconds = (sequence - epochTicks + timezoneOffset) / 10000;
|
||||
const flooredMilliseconds = Math.floor(milliseconds / (60 * 1000)) * (60 * 1000);
|
||||
const ceiledMilliseconds = Math.ceil(milliseconds / (60 * 1000)) * (60 * 1000);
|
||||
result = [(flooredMilliseconds / 1000), (ceiledMilliseconds / 1000)];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const date = '3/26/2025';
|
||||
const infinityQS = 1742853453;
|
||||
const sequence = '638784250251441727';
|
||||
const values = getInfinityQS(date, sequence);
|
||||
console.info("InfinityQS: " + values);
|
||||
if (values[0] < infinityQS && values[1] > infinityQS)
|
||||
console.info("InfinityQS: Pass");
|
||||
else
|
||||
console.warn("InfinityQS: Fail");
|
130
Scripts/hgcv.js
130
Scripts/hgcv.js
@ -1,130 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
function getCollectionParseFloat(collection) {
|
||||
let result = [];
|
||||
let value;
|
||||
for (let i = 0; i < collection.length; i++) {
|
||||
value = parseFloat(collection[i]);
|
||||
result.push(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getSum(collection) {
|
||||
let result = 0;
|
||||
if (!collection || collection.length === 0) {
|
||||
result = 0;
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < collection.length; i++) {
|
||||
result += collection[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getAverage(collection) {
|
||||
let result = null;
|
||||
if (collection == null || collection.length === 0)
|
||||
result = 0;
|
||||
else {
|
||||
let sum = getSum(collection);
|
||||
result = sum / collection.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getVariance(collection) {
|
||||
let result = null;
|
||||
if (collection == null || collection.length === 0)
|
||||
result = null;
|
||||
else {
|
||||
let variance = 0;
|
||||
let t = collection[0];
|
||||
for (let i = 1; i < collection.length; i++) {
|
||||
t += collection[i];
|
||||
const diff = ((i + 1) * collection[i]) - t;
|
||||
variance += diff * diff / ((i + 1.0) * i);
|
||||
}
|
||||
result = variance / (collection.length - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getNineEdgeMeanDelta(edge4mmRhoPoints, edge10mmRhoPoints) {
|
||||
let result;
|
||||
const nine4mmEdgeSum = getSum(edge4mmRhoPoints);
|
||||
const nine10mmEdgeSum = getSum(edge10mmRhoPoints);
|
||||
result = (nine4mmEdgeSum - nine10mmEdgeSum) / nine10mmEdgeSum * 100;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getMax(collection) {
|
||||
let result = collection[0];
|
||||
for (let i = 1; i < collection.length; i++) {
|
||||
if (collection[i] > result) {
|
||||
result = collection[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getMin(collection) {
|
||||
let result = collection[0];
|
||||
for (let i = 1; i < collection.length; i++) {
|
||||
if (collection[i] < result) {
|
||||
result = collection[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getNineResRangePercent(criticalRhoPoints) {
|
||||
let result;
|
||||
const nineCriticalPointsAverage = getAverage(criticalRhoPoints);
|
||||
// result = (Math.max(...criticalRhoPoints) - Math.min(...criticalRhoPoints)) / nineCriticalPointsAverage * 100;
|
||||
// let max = criticalRhoPoints.reduce((a, b) => Math.max(a, b));
|
||||
// let min = criticalRhoPoints.reduce((a, b) => Math.min(a, b));
|
||||
// result = (max - min) / nineCriticalPointsAverage * 100;
|
||||
// let max = criticalRhoPoints.sort((a, b) => b - a);
|
||||
// let min = criticalRhoPoints.sort((a, b) => a - b);
|
||||
// result = (max[0] - min[0]) / nineCriticalPointsAverage * 100;
|
||||
let max = getMax(criticalRhoPoints);
|
||||
let min = getMin(criticalRhoPoints);
|
||||
result = (max - min) / nineCriticalPointsAverage * 100;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getValue(allRhoAvg, index) {
|
||||
let result = null;
|
||||
if (index === 8) {
|
||||
if (allRhoAvg != undefined && allRhoAvg.length > 1) {
|
||||
let collection = allRhoAvg[0] === '|' ? allRhoAvg.substring(1).split('|') : allRhoAvg.split('|');
|
||||
let collectionParseFloat = getCollectionParseFloat(collection);
|
||||
result = average(collectionParseFloat);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
// 1 2 3 4 5 6 7 8 9
|
||||
const allRhoAvg = getCollectionParseFloat('|2.648|3.076|2.877|2.747|2.821|2.765|2.669|2.814|2.876'.substring(1).split('|'));
|
||||
const edge4mmRhoPoints = getCollectionParseFloat('|2.877|2.747|2.669|2.814'.substring(1).split('|'));
|
||||
const edge10mmRhoPoints = getCollectionParseFloat('|3.076|2.821|2.765|2.876'.substring(1).split('|'));
|
||||
const criticalRhoPoints = getCollectionParseFloat('|2.648|3.076|2.821|2.765|2.876'.substring(1).split('|'));
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
// 1 2 3 4 5 6 7 8 9
|
||||
const allPhase = getCollectionParseFloat('|88.874|88.999|89.085|89.029|89.018|89.007|89.049|89.024|89.007'.substring(1).split('|'));
|
||||
const criticalPhasePoints = getCollectionParseFloat('|88.874|88.999|89.018|89.007|89.007'.substring(1).split('|'));
|
||||
|
||||
const nineMean = getAverage(allRhoAvg);
|
||||
const nine4mmEdgeMean = getAverage(edge4mmRhoPoints);
|
||||
const nine10mmEdgeMean = getAverage(edge10mmRhoPoints);
|
||||
const nineCriticalPointsAverage = getAverage(criticalRhoPoints);
|
||||
const nineResRangePercent = getNineResRangePercent(criticalRhoPoints);
|
||||
const nineCriticalPointsStdDev = Math.sqrt(getVariance(criticalRhoPoints));
|
||||
const nineCriticalPointsPhaseAngleAverage = getAverage(criticalPhasePoints);
|
||||
const nineEdgeMeanDelta = getNineEdgeMeanDelta(edge4mmRhoPoints, edge10mmRhoPoints);
|
||||
console.log(nineCriticalPointsStdDev);
|
7
Scripts/markdown.js
Normal file
7
Scripts/markdown.js
Normal file
@ -0,0 +1,7 @@
|
||||
// import data from './oi-metrology-viewer-0-Line-yaml.json' with { type: 'json' };
|
||||
// import data from '../.vscode/oi-metrology-viewer-0-Line-yaml.json' with { type: 'json' };
|
||||
import data from '../.vscode/.helper/hosts-legend-table.json' with { type: 'json' };
|
||||
|
||||
data.forEach(element => {
|
||||
console.log(element.Concat);
|
||||
});
|
@ -147,7 +147,7 @@ public class Worker : BackgroundService
|
||||
_Logger.LogWarning("Must pass a argument!");
|
||||
CreateWindowsShortcut();
|
||||
}
|
||||
else if (Directory.Exists(_Args[0]))
|
||||
else if (Directory.Exists(_Args[0].Split('~')[0]) || Directory.Exists(_Args[0]))
|
||||
{
|
||||
if (!_ConsoleKeys.Contains(consoleKey))
|
||||
{
|
||||
|
Reference in New Issue
Block a user