Compare commits
9 Commits
404ffe18f5
...
07-09-a
Author | SHA1 | Date | |
---|---|---|---|
342af4a210 | |||
89bb87bd14 | |||
e7c1fd2221 | |||
fc4449f515 | |||
6ce6c28db1 | |||
2e4aa313fa | |||
116d5e9734 | |||
5ca22b3792 | |||
b98d1e480b |
1
.gitignore
vendored
1
.gitignore
vendored
@ -336,3 +336,4 @@ ASALocalRun/
|
|||||||
.extensions-vscode-oss
|
.extensions-vscode-oss
|
||||||
.extensions-vscode-insiders
|
.extensions-vscode-insiders
|
||||||
.vscode/.UserSecrets/secrets.json
|
.vscode/.UserSecrets/secrets.json
|
||||||
|
.vscode/.helper
|
||||||
|
312
.vscode/launch.json
vendored
312
.vscode/launch.json
vendored
@ -1,120 +1,196 @@
|
|||||||
{
|
{
|
||||||
// Use IntelliSense to learn about possible attributes.
|
// Use IntelliSense to learn about possible attributes.
|
||||||
// Hover to view descriptions of existing attributes.
|
// Hover to view descriptions of existing attributes.
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": ".NET Core Launch (console)",
|
"name": ".NET Core Launch (console)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "build",
|
"preLaunchTask": "build",
|
||||||
"program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/File-Folder-Helper.dll",
|
"program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/File-Folder-Helper.dll",
|
||||||
"args": [
|
"args": [
|
||||||
"s",
|
"s",
|
||||||
"X",
|
"X",
|
||||||
"D:/Tmp",
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/PollPath",
|
||||||
"Day-Helper-2025-06-02",
|
"Day-Helper-2025-07-01",
|
||||||
"infineon\\MESPhares",
|
"*.pdsf",
|
||||||
"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",
|
"987654321",
|
||||||
"s",
|
"Time",
|
||||||
"X",
|
".json",
|
||||||
"D:/5-Other-Small/Proxmox/ffnm",
|
"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,vp93~ProcessState,vp154~SystemState,vp78~LL1State,vp83~LL2State,vp176~TotalWaferCount,vp80~LL1Lotid,vp85~LL2Lotid,vp153~PPSTEPNAME,vp221~LeftDefaultRecipe,vp222~RightDefaultRecipe,vp223~RecipeCompleteMsg",
|
||||||
"Day-Helper-2025-05-21",
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/JavaScriptObjectNotation",
|
||||||
"*.pdf",
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/Markdown",
|
||||||
"*.md",
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/KeyValuePairs",
|
||||||
"2",
|
"654321",
|
||||||
"MM-dd-yy",
|
"s",
|
||||||
"Trans Date~Effective Date~Description~Withdrawal Deposit~Balance",
|
"s",
|
||||||
"s",
|
"X",
|
||||||
"X",
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/R55",
|
||||||
"D:/Tmp/phares/VisualStudioCode",
|
"Day-Helper-2023-11-30",
|
||||||
"Day-Helper-2025-05-19",
|
"yyMMddhhmmssfff",
|
||||||
"D:/Tmp/phares/VisualStudioCode/.vscode/input.json",
|
"\"vp154\"",
|
||||||
"s",
|
"s",
|
||||||
"X",
|
"X",
|
||||||
"D:/Tmp/phares/VisualStudioCode",
|
"V:/Tmp/Phares/Pictures/2023 TI2023.6 Fall Samsung",
|
||||||
"Day-Helper-2025-05-19",
|
"Day-Helper-2025-07-05",
|
||||||
"D:/Tmp/phares/VisualStudioCodeLeft",
|
"x-653889110721.jpg~401223300869.jpg",
|
||||||
"z-include-patterns.nsv",
|
"3648,2736,1~3024,4032,6",
|
||||||
"z-exclude-patterns.nsv",
|
"0.341694,0.599963,0.1642,0.279605~0.552357,0.65095,0.195175,0.32383~0.31002,0.42328,0.0379464,0.0459656",
|
||||||
"http://localhost:5004",
|
"0.259594,0.460161,0.1642,0.279605~0.45477,0.489035,0.195175,0.32383~0.328993,0.446263,0.0379464,0.0459656",
|
||||||
"/api/SyncV1/?",
|
"9",
|
||||||
",L",
|
"x-825511723~x-444522128~831410304",
|
||||||
".G",
|
"X",
|
||||||
"+~G~~L~+~Custom-Default",
|
"F:/0-ISO-A",
|
||||||
"",
|
"Day-Helper-2025-06-28",
|
||||||
"+~G~~G~-~Mirror",
|
"*.iso",
|
||||||
"+~G~~~~Update",
|
"F",
|
||||||
"+~G~~L~+~Custom-Default",
|
"s",
|
||||||
"-~G~~G~+~Custom-A",
|
"X",
|
||||||
"-~L~~L~+~Custom-B",
|
"D:/5-Other-Small",
|
||||||
"+~L~~L~-~Custom-C",
|
"Day-Helper-2024-12-17",
|
||||||
"s",
|
".job.json",
|
||||||
"X",
|
"thumbs.db~sync.ffs_db~verify.json~.html",
|
||||||
"\\\\mesfs.infineon.com\\EC_Characterization_Si\\Archive\\BIORAD4\\2025_Week_16\\2025-04-17",
|
"D:/0-ISO-A",
|
||||||
"Day-Helper-2025-02-19",
|
"D:/5-Other-Small/Proxmox/Snap2HTML/Snap2HTML.exe",
|
||||||
"csv-*.pdsf",
|
"s",
|
||||||
"*.pdsf",
|
"M",
|
||||||
"Time,HeaderUniqueId,UniqueId,Date,Wafer,Position,BIORAD4",
|
"D:/5-Other-Small/Notes/EC-Documentation",
|
||||||
",BIORAD4",
|
"-d",
|
||||||
",BIORAD4",
|
"D:/5-Other-Small/Notes/EC-Documentation/.vscode/helper",
|
||||||
"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",
|
"s",
|
||||||
"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",
|
"X",
|
||||||
"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",
|
"D:/5-Other-Small/Proxmox/DiskInfo",
|
||||||
"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",
|
"Day-Helper-2025-06-18",
|
||||||
"s",
|
"*.json",
|
||||||
"X",
|
"D:/5-Other-Small/Proxmox/Disk-Info-Old",
|
||||||
"C:/Users/phares/AppData/Roaming/FreeFileSync",
|
"-2025-",
|
||||||
"Day-Helper-2025-04-21",
|
"1",
|
||||||
"GlobalSettings.xml",
|
"s",
|
||||||
"LastSync|Config",
|
"X",
|
||||||
"s",
|
"D:/Tmp",
|
||||||
"X",
|
"Day-Helper-2025-06-02",
|
||||||
"L:/Tmp/MET08ANLYSDIFAAST230",
|
"infineon\\MESPhares",
|
||||||
"Day-Helper-2025-03-06",
|
"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",
|
||||||
"*.pdsf",
|
"s",
|
||||||
"s",
|
"X",
|
||||||
"X",
|
"D:/5-Other-Small/Proxmox/ffnm",
|
||||||
"D:/ProgramData/VisualStudioCode|D:/6-Other-Large-Z/Linux-Ubuntu-Phares/home/lphares/dorico",
|
"Day-Helper-2025-05-21",
|
||||||
"Day-Helper-2025-04-07",
|
"*.pdf",
|
||||||
"z-include-patterns.nsv",
|
"*.md",
|
||||||
"z-exclude-patterns.nsv",
|
"2",
|
||||||
"https://isccvm57294f1ed/VisualStudioCode|hxttps://dorico.phares.duckdns.org|hxttps://mestsa006.infineon.com/VisualStudioCode",
|
"MM-dd-yy",
|
||||||
"+|G|G|G|-",
|
"Trans Date~Effective Date~Description~Withdrawal Deposit~Balance",
|
||||||
"||||",
|
"s",
|
||||||
"666",
|
"X",
|
||||||
"777",
|
"D:/Tmp/phares/VisualStudioCode",
|
||||||
"888",
|
"Day-Helper-2025-05-19",
|
||||||
"999",
|
"D:/Tmp/phares/VisualStudioCode/.vscode/input.json",
|
||||||
"s",
|
"s",
|
||||||
"X",
|
"X",
|
||||||
"C:/Users/PHARES/AppData/Local/IFXApps/gatus",
|
"D:/Tmp/phares/VisualStudioCode",
|
||||||
"Day-Helper-2025-04-04",
|
"Day-Helper-2025-05-19",
|
||||||
"*.json",
|
"D:/Tmp/phares/VisualStudioCodeLeft",
|
||||||
".metrics",
|
"z-include-patterns.nsv",
|
||||||
"https://messa010ec.infineon.com/metrics",
|
"z-exclude-patterns.nsv",
|
||||||
"gatus_results_endpoint_success",
|
"http://localhost:5004",
|
||||||
"666",
|
"/api/SyncV1/?",
|
||||||
"777",
|
",L",
|
||||||
"888",
|
".G",
|
||||||
"999",
|
"+~G~~L~+~Custom-Default",
|
||||||
""
|
"",
|
||||||
],
|
"+~G~~G~-~Mirror",
|
||||||
"cwd": "${workspaceFolder}",
|
"+~G~~~~Update",
|
||||||
"console": "integratedTerminal",
|
"+~G~~L~+~Custom-Default",
|
||||||
"stopAtEntry": false
|
"-~G~~G~+~Custom-A",
|
||||||
},
|
"-~L~~L~+~Custom-B",
|
||||||
{
|
"+~L~~L~-~Custom-C",
|
||||||
"name": ".NET Core Attach",
|
"s",
|
||||||
"type": "coreclr",
|
"X",
|
||||||
"request": "attach"
|
"\\\\mesfs.infineon.com\\EC_Characterization_Si\\Archive\\BIORAD4\\2025_Week_16\\2025-04-17",
|
||||||
},
|
"Day-Helper-2025-02-19",
|
||||||
{
|
"csv-*.pdsf",
|
||||||
"type": "node",
|
"*.pdsf",
|
||||||
"request": "launch",
|
"Time,HeaderUniqueId,UniqueId,Date,Wafer,Position,BIORAD4",
|
||||||
"name": "node Launch Current Opened File",
|
",BIORAD4",
|
||||||
"program": "${file}"
|
",BIORAD4",
|
||||||
}
|
"Test|EventId,Date|DateTime,Position|Slot,DeltaThicknessSlotsOneAndTwentyFive|Actual Delta Thick Pts 1 and 25,PercentDeltaThicknessSlotsOneAndTwentyFive|% Delta Thick Pts 1 and 25,MID|Cassette,Lot|Batch,Title|Batch,Wafer|Text,Thickness|Site,MeanThickness|GradeMean,|BIORAD4",
|
||||||
]
|
"Time,A_LOGISTICS,B_LOGISTICS,Test,Count,Index,MesEntity,MID,Date,Employee,Lot,PSN,Reactor,Recipe,Cassette,GradeStdDev,HeaderUniqueId,Layer,MeanThickness,PassFail,RDS,Slot,Title,UniqueId,Wafer,Zone,Mean,Position,StdDev,Thickness,ThicknessSlotOne,ThicknessSlotTwentyFive,DeltaThicknessSlotsOneAndTwentyFive,PercentDeltaThicknessSlotsOneAndTwentyFive",
|
||||||
|
"Time,A_LOGISTICS,B_LOGISTICS,Count,Sequence,MesEntity,Index,Batch,Cassette,DateTime,Destination,Mean,PassFail,Recipe,Reference,Site,Slot,Source,StdDev,Text,GradeMean,GradeStdDev,RDS,PSN,Reactor,Layer,Zone,Employee,InferredLot,Thickness First Slot,Thickness Last Slot,Actual Delta Thick Pts 1 and 25,% Delta Thick Pts 1 and 25,EventId",
|
||||||
|
"0,1,2,31,3,6,5,8,9,27,7,23,24,13,8,21,-1,25,20,12,22,16,7,-1,19,26,11,16,18,15,-1,-1,29,30",
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"C:/Users/phares/AppData/Roaming/FreeFileSync",
|
||||||
|
"Day-Helper-2025-04-21",
|
||||||
|
"GlobalSettings.xml",
|
||||||
|
"LastSync|Config",
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"L:/Tmp/MET08ANLYSDIFAAST230",
|
||||||
|
"Day-Helper-2025-03-06",
|
||||||
|
"*.pdsf",
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"D:/ProgramData/VisualStudioCode|D:/6-Other-Large-Z/Linux-Ubuntu-Phares/home/lphares/dorico",
|
||||||
|
"Day-Helper-2025-04-07",
|
||||||
|
"z-include-patterns.nsv",
|
||||||
|
"z-exclude-patterns.nsv",
|
||||||
|
"https://isccvm57294f1ed/VisualStudioCode|hxttps://dorico.phares.duckdns.org|hxttps://mestsa006.infineon.com/VisualStudioCode",
|
||||||
|
"+|G|G|G|-",
|
||||||
|
"||||",
|
||||||
|
"666",
|
||||||
|
"777",
|
||||||
|
"888",
|
||||||
|
"999",
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"C:/Users/PHARES/AppData/Local/IFXApps/gatus",
|
||||||
|
"Day-Helper-2025-04-04",
|
||||||
|
"*.json",
|
||||||
|
".metrics",
|
||||||
|
"https://messa010ec.infineon.com/metrics",
|
||||||
|
"gatus_results_endpoint_success",
|
||||||
|
"666",
|
||||||
|
"777",
|
||||||
|
"888",
|
||||||
|
"999",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"stopAtEntry": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Attach",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "attach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"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"
|
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)
|
```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"
|
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"
|
||||||
|
```
|
||||||
|
@ -24,9 +24,12 @@ internal static partial class Helper20241217
|
|||||||
long Length,
|
long Length,
|
||||||
string RelativePath);
|
string RelativePath);
|
||||||
|
|
||||||
private record Record(string Directory,
|
private record Record(string DestinationDirectory,
|
||||||
|
string DirectoryName,
|
||||||
Job Job,
|
Job Job,
|
||||||
string Path);
|
string Path,
|
||||||
|
string Snap2HyperTextMarkupLanguage,
|
||||||
|
string SourceDirectory);
|
||||||
|
|
||||||
private record Job(string? AlternatePath,
|
private record Job(string? AlternatePath,
|
||||||
string Directory,
|
string Directory,
|
||||||
@ -49,14 +52,17 @@ internal static partial class Helper20241217
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<File> GetFiles(string searchPattern, string[] ignoreFileNames, Record record) =>
|
||||||
|
GetFiles(record.SourceDirectory, searchPattern, ignoreFileNames);
|
||||||
|
|
||||||
internal static void Backup(ILogger<Worker> logger, List<string> args)
|
internal static void Backup(ILogger<Worker> logger, List<string> args)
|
||||||
{
|
{
|
||||||
Job jobNew;
|
Job jobNew;
|
||||||
string path;
|
string path;
|
||||||
string? json;
|
string? json;
|
||||||
string asidePath;
|
string fileName;
|
||||||
bool areTheyTheSame;
|
bool areTheyTheSame;
|
||||||
string directoryName;
|
IEnumerable<Record> records;
|
||||||
logger.LogInformation(args[0]);
|
logger.LogInformation(args[0]);
|
||||||
logger.LogInformation(args[1]);
|
logger.LogInformation(args[1]);
|
||||||
logger.LogInformation(args[2]);
|
logger.LogInformation(args[2]);
|
||||||
@ -64,44 +70,51 @@ internal static partial class Helper20241217
|
|||||||
logger.LogInformation(args[4]);
|
logger.LogInformation(args[4]);
|
||||||
ReadOnlyCollection<File> files;
|
ReadOnlyCollection<File> files;
|
||||||
string searchPattern = args[2];
|
string searchPattern = args[2];
|
||||||
|
IEnumerable<string> searchPatternFiles;
|
||||||
string[] ignoreFileNames = args[3].Split('~');
|
string[] ignoreFileNames = args[3].Split('~');
|
||||||
string destination = Path.GetFullPath(args[4]);
|
string destination = Path.GetFullPath(args[4]);
|
||||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||||
char destinationDriveLetter = destination.Split(':')[0][0];
|
string? snap2HyperTextMarkupLanguage = args.Count < 6 ? null : Path.GetFullPath(args[5]);
|
||||||
logger.LogInformation("Searching <{sourceDirectory}> with search pattern {searchPattern}", args[0], searchPattern);
|
logger.LogInformation("Searching <{sourceDirectory}> with search pattern {searchPattern}", args[0], searchPattern);
|
||||||
if (Debugger.IsAttached)
|
if (Debugger.IsAttached)
|
||||||
Verify(searchPattern, ignoreFileNames);
|
Verify(searchPattern, ignoreFileNames);
|
||||||
IEnumerable<Record> records = GetRecords(sourceDirectory, searchPattern);
|
for (int i = 1; i < 3; i++)
|
||||||
foreach (Record record in records)
|
|
||||||
{
|
{
|
||||||
if (record.Job is null || string.IsNullOrEmpty(record.Job.Extension))
|
if (i == 1)
|
||||||
continue;
|
|
||||||
logger.LogInformation("Searching <{directory}>", record.Directory);
|
|
||||||
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);
|
searchPatternFiles = Directory.EnumerateFiles(sourceDirectory, searchPattern, new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true });
|
||||||
continue;
|
}
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
directoryName = Path.GetFileName(record.Directory);
|
|
||||||
asidePath = Path.Combine(record.Directory, $"{directoryName}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss-fff}{record.Job.Extension}");
|
|
||||||
path = $"{destinationDriveLetter}{asidePath[1..]}";
|
|
||||||
logger.LogInformation("Writing <{path}> extension", path);
|
|
||||||
WritePassedExtension(record, files, directoryName, path);
|
|
||||||
logger.LogInformation("Wrote <{path}> extension", path);
|
|
||||||
MovePassedExtension(destination, path);
|
|
||||||
logger.LogInformation("Moved <{path}> extension", path);
|
|
||||||
WriteAllText(record.Path, json);
|
|
||||||
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, $"{destinationDriveLetter}{record.Directory[1..]}");
|
|
||||||
}
|
|
||||||
if (Debugger.IsAttached && records.Count() == 0)
|
|
||||||
{
|
|
||||||
files = GetFiles(sourceDirectory, searchPattern, ignoreFileNames);
|
|
||||||
json = JsonSerializer.Serialize(files.ToArray(), FilesSourceGenerationContext.Default.FileArray);
|
|
||||||
WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", ".json"), json);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,24 +163,28 @@ internal static partial class Helper20241217
|
|||||||
return results.AsReadOnly();
|
return results.AsReadOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<Record> GetRecords(string directory, string searchPattern)
|
private static IEnumerable<Record> GetRecords(string directory, string destination, IEnumerable<string> files)
|
||||||
{
|
{
|
||||||
Job? job;
|
Job? job;
|
||||||
string json;
|
string json;
|
||||||
Record record;
|
Record record;
|
||||||
string fileName;
|
string fileName;
|
||||||
string directoryName;
|
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)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
fileName = Path.GetFileName(file);
|
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('.'))
|
if (!fileName.StartsWith('.'))
|
||||||
{
|
{
|
||||||
System.IO.File.Move(file, Path.Combine(directoryName, $".{fileName}"));
|
System.IO.File.Move(file, Path.Combine(sourceDirectory, $".{fileName}"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
json = System.IO.File.ReadAllText(file);
|
json = System.IO.File.ReadAllText(file);
|
||||||
|
snap2HyperTextMarkupLanguage = Path.Combine(sourceDirectory, ".html");
|
||||||
if (string.IsNullOrEmpty(json) || json is "{}" or "[]")
|
if (string.IsNullOrEmpty(json) || json is "{}" or "[]")
|
||||||
job = null;
|
job = null;
|
||||||
else
|
else
|
||||||
@ -180,11 +197,36 @@ internal static partial class Helper20241217
|
|||||||
FilesTotalLength: 0,
|
FilesTotalLength: 0,
|
||||||
Keep: 3,
|
Keep: 3,
|
||||||
Targets: []);
|
Targets: []);
|
||||||
record = new(Directory: directoryName, Job: job, Path: file);
|
destinationDirectory = $"{destination}{sourceDirectory[2..]}";
|
||||||
|
if (!Directory.Exists(destinationDirectory))
|
||||||
|
_ = Directory.CreateDirectory(destinationDirectory);
|
||||||
|
record = new(DestinationDirectory: destinationDirectory,
|
||||||
|
DirectoryName: directoryName,
|
||||||
|
Job: job,
|
||||||
|
Path: file,
|
||||||
|
Snap2HyperTextMarkupLanguage: snap2HyperTextMarkupLanguage,
|
||||||
|
SourceDirectory: sourceDirectory);
|
||||||
yield return record;
|
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)
|
private static ReadOnlyCollection<File> GetFiles(string directory, string searchPattern, string[] ignoreFileNames)
|
||||||
{
|
{
|
||||||
List<File> results = [];
|
List<File> results = [];
|
||||||
@ -209,16 +251,13 @@ internal static partial class Helper20241217
|
|||||||
return results.AsReadOnly();
|
return results.AsReadOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ReadOnlyCollection<File> GetFiles(string searchPattern, string[] ignoreFileNames, Record record) =>
|
|
||||||
GetFiles(record.Directory, searchPattern, ignoreFileNames);
|
|
||||||
|
|
||||||
private static Job GetJob(string searchPattern, string[] ignoreFileNames, Record record, ReadOnlyCollection<File> files)
|
private static Job GetJob(string searchPattern, string[] ignoreFileNames, Record record, ReadOnlyCollection<File> files)
|
||||||
{
|
{
|
||||||
Job result;
|
Job result;
|
||||||
ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, files);
|
ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, files);
|
||||||
double filesTotalLengthNew = collection.Select(l => l.Length).Sum();
|
double filesTotalLengthNew = collection.Select(l => l.Length).Sum();
|
||||||
result = new(AlternatePath: record.Job.AlternatePath,
|
result = new(AlternatePath: record.Job.AlternatePath,
|
||||||
Directory: record.Directory,
|
Directory: record.SourceDirectory,
|
||||||
Extension: record.Job.Extension,
|
Extension: record.Job.Extension,
|
||||||
Files: collection.ToArray(),
|
Files: collection.ToArray(),
|
||||||
FilesCount: collection.Count,
|
FilesCount: collection.Count,
|
||||||
@ -237,7 +276,7 @@ internal static partial class Helper20241217
|
|||||||
if (filesCountNew != filesCountOld)
|
if (filesCountNew != filesCountOld)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
logger.LogInformation("<{directory}> file count has changed {filesCountNew} != {filesCountOld}", record.Directory, filesCountNew, filesCountOld);
|
logger.LogInformation("<{directory}> file count has changed {filesCountNew} != {filesCountOld}", record.SourceDirectory, filesCountNew, filesCountOld);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -246,7 +285,7 @@ internal static partial class Helper20241217
|
|||||||
if (filesTotalLengthNew != filesTotalLengthOld)
|
if (filesTotalLengthNew != filesTotalLengthOld)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
logger.LogInformation("<{directory}> file length has changed {filesTotalLengthNew} != {filesTotalLengthOld}", record.Directory, filesTotalLengthNew, filesTotalLengthOld);
|
logger.LogInformation("<{directory}> file length has changed {filesTotalLengthNew} != {filesTotalLengthOld}", record.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -262,7 +301,7 @@ internal static partial class Helper20241217
|
|||||||
WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", "old.json"), jsonOld);
|
WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", "old.json"), jsonOld);
|
||||||
WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", "new.json"), jsonNew);
|
WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", "new.json"), jsonNew);
|
||||||
}
|
}
|
||||||
logger.LogInformation("<{directory}> file serialized are different {filesTotalLengthNew} != {filesTotalLengthOld}", record.Directory, filesTotalLengthNew, filesTotalLengthOld);
|
logger.LogInformation("<{directory}> file serialized are different {filesTotalLengthNew} != {filesTotalLengthOld}", record.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,33 +325,16 @@ internal static partial class Helper20241217
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void MovePassedExtension(string destination, string path)
|
|
||||||
{
|
|
||||||
string checkPath = $"{destination}{path[2..]}";
|
|
||||||
string checkDirectory = Path.GetDirectoryName(checkPath) ?? throw new Exception();
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
if (System.IO.File.Exists(checkPath))
|
|
||||||
throw new NotImplementedException($"<{checkPath}> already exists!");
|
|
||||||
System.IO.File.Move(path, checkPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void WriteISO(Record record, ReadOnlyCollection<File> files, string path, string directoryName)
|
private static void WriteISO(Record record, ReadOnlyCollection<File> files, string path, string directoryName)
|
||||||
{
|
{
|
||||||
string checkDirectory = Path.GetDirectoryName(path) ?? throw new Exception();
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
CDBuilder builder = new() { UseJoliet = true, VolumeIdentifier = directoryName.Length < 25 ? directoryName : directoryName[..25] };
|
CDBuilder builder = new() { UseJoliet = true, VolumeIdentifier = directoryName.Length < 25 ? directoryName : directoryName[..25] };
|
||||||
foreach (File file in files)
|
foreach (File file in files)
|
||||||
_ = builder.AddFile(file.RelativePath, Path.Combine(record.Directory, file.RelativePath));
|
_ = builder.AddFile(file.RelativePath, Path.Combine(record.SourceDirectory, file.RelativePath));
|
||||||
builder.Build(path);
|
builder.Build(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteZIP(Record record, ReadOnlyCollection<File> files, string path)
|
private static void WriteZIP(Record record, ReadOnlyCollection<File> files, string path)
|
||||||
{
|
{
|
||||||
string checkDirectory = Path.GetDirectoryName(path) ?? throw new Exception();
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
using ZipArchive zip = ZipFile.Open(path, ZipArchiveMode.Create);
|
using ZipArchive zip = ZipFile.Open(path, ZipArchiveMode.Create);
|
||||||
string directoryEntry;
|
string directoryEntry;
|
||||||
List<string> directoryEntries = [];
|
List<string> directoryEntries = [];
|
||||||
@ -325,7 +347,16 @@ internal static partial class Helper20241217
|
|||||||
_ = zip.CreateEntry(file.RelativePath);
|
_ = zip.CreateEntry(file.RelativePath);
|
||||||
}
|
}
|
||||||
foreach (File file in files)
|
foreach (File file in files)
|
||||||
_ = zip.CreateEntryFromFile(Path.Combine(record.Directory, file.RelativePath), file.RelativePath);
|
_ = zip.CreateEntryFromFile(Path.Combine(record.SourceDirectory, file.RelativePath), file.RelativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteAllText(Record record, string text, string path)
|
||||||
|
{
|
||||||
|
WriteAllText(record.Path, text);
|
||||||
|
System.IO.File.Copy(record.Path, $"{path}.json");
|
||||||
|
string checkFile = Path.Combine(record.SourceDirectory, ".html");
|
||||||
|
if (System.IO.File.Exists(checkFile))
|
||||||
|
System.IO.File.Copy(checkFile, $"{path}.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -277,12 +277,12 @@ internal static partial class Helper20250219 {
|
|||||||
}
|
}
|
||||||
if (!lookForNumbers) {
|
if (!lookForNumbers) {
|
||||||
for (int c = 0; c < segments.Length; c++) {
|
for (int c = 0; c < segments.Length; c++) {
|
||||||
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
|
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||||
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\",");
|
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\",");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int c = 0; c < segments.Length; c++) {
|
for (int c = 0; c < segments.Length; c++) {
|
||||||
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
|
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||||
if (string.IsNullOrEmpty(value))
|
if (string.IsNullOrEmpty(value))
|
||||||
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,");
|
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,");
|
||||||
else if (value.All(char.IsDigit))
|
else if (value.All(char.IsDigit))
|
||||||
|
@ -71,7 +71,7 @@ internal static partial class Helper20250306 {
|
|||||||
if (segments.Length != columnsLength)
|
if (segments.Length != columnsLength)
|
||||||
continue;
|
continue;
|
||||||
for (int c = 1; c < segments.Length; c++) {
|
for (int c = 1; c < segments.Length; c++) {
|
||||||
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
|
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||||
line += '"' + columns[c].Trim('"') + '"' + ':' + '"' + value + '"' + ',';
|
line += '"' + columns[c].Trim('"') + '"' + ':' + '"' + value + '"' + ',';
|
||||||
}
|
}
|
||||||
line = line.Substring(0, line.Length - 1) + '}' + ',' + '\n';
|
line = line.Substring(0, line.Length - 1) + '}' + ',' + '\n';
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
427
ADO2025/PI6/Helper-2025-07-01.cs
Normal file
427
ADO2025/PI6/Helper-2025-07-01.cs
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
|
||||||
|
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 {
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
|
[JsonSerializable(typeof(ReadOnlyDictionary<string, ReadOnlyDictionary<string, string>>))]
|
||||||
|
internal partial class ReadOnlyDictionaryStringReadOnlyDictionaryStringStringSourceGenerationContext : 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]);
|
||||||
|
logger.LogInformation(args[7]);
|
||||||
|
string[] segments;
|
||||||
|
string extension = args[5];
|
||||||
|
string timeColumn = args[4];
|
||||||
|
string searchPattern = args[2];
|
||||||
|
int sizeFilter = int.Parse(args[3]);
|
||||||
|
string[] columns = args[6].Split(',');
|
||||||
|
Dictionary<string, string> columnMapping = [];
|
||||||
|
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||||
|
string destinationDirectory = Path.GetFullPath(args[7].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, extension, columnMapping, destinationDirectory, directories);
|
||||||
|
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ProcessDataStandardFormatTo(ILogger<Worker> logger, string sourceDirectory, string searchPattern, int sizeFilter, string timeColumn, string extension, Dictionary<string, string> columnMapping, string destinationDirectory, string[] directories) {
|
||||||
|
string text;
|
||||||
|
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 (sizeFilter < 987654321 && 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}{extension}");
|
||||||
|
if (File.Exists(checkFile)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (extension == ".md") {
|
||||||
|
collections = GetMarkdown(logger, timeColumn, columnMapping, file, fileInfo.Name);
|
||||||
|
if (string.IsNullOrEmpty(collections)) {
|
||||||
|
logger.LogWarning("collections is null");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
text = collections;
|
||||||
|
} else if (extension == ".pipe.md") {
|
||||||
|
json = GetJavaScriptObjectNotation(logger, file);
|
||||||
|
if (string.IsNullOrEmpty(json)) {
|
||||||
|
logger.LogWarning("json is null");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pipeTable = GetPipeTable(logger, json);
|
||||||
|
if (string.IsNullOrEmpty(pipeTable)) {
|
||||||
|
logger.LogWarning("pipeTable is null");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
markdown = $"# {fileInfo.Name}{Environment.NewLine}{Environment.NewLine}{pipeTable}{Environment.NewLine}";
|
||||||
|
text = markdown;
|
||||||
|
} else if (extension == ".json") {
|
||||||
|
json = GetJavaScriptObjectNotation(logger, file);
|
||||||
|
if (string.IsNullOrEmpty(json)) {
|
||||||
|
logger.LogWarning("json is null");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
text = json;
|
||||||
|
} else {
|
||||||
|
logger.LogWarning("{extension} is not mapped!", extension);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
File.WriteAllText(checkFile, text);
|
||||||
|
File.SetLastWriteTime(checkFile, 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[] lines) {
|
||||||
|
#pragma warning disable CA1845, IDE0057
|
||||||
|
string result;
|
||||||
|
string record;
|
||||||
|
string value;
|
||||||
|
string[] segments;
|
||||||
|
string? json = null;
|
||||||
|
List<string> records = [];
|
||||||
|
ReadOnlyCollection<string>? footerLines = null;
|
||||||
|
string[] columns = lines[columnTitlesLine].Split('\t');
|
||||||
|
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
|
||||||
|
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
||||||
|
footerLines = GetFooterLines(lines, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
record = "{";
|
||||||
|
segments = lines[i].Split('\t');
|
||||||
|
if (segments.Length > columns.Length) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int c = 0; c < segments.Length; c++) {
|
||||||
|
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||||
|
record += string.Concat('"', columns[c].Trim('"'), '"', ':', '"', value, '"', ',');
|
||||||
|
}
|
||||||
|
record = string.Concat(record.Substring(0, record.Length - 1), '}');
|
||||||
|
records.Add(record);
|
||||||
|
}
|
||||||
|
if (footerLines is not null && footerLines.Count > 0) {
|
||||||
|
ReadOnlyDictionary<string, string> footerKeyValuePairs = GetFooterKeyValuePairs(footerLines);
|
||||||
|
ReadOnlyDictionary<string, ReadOnlyDictionary<string, string>> logisticKeyValuePairs = GetLogisticKeyValuePairs(footerLines, footerKeyValuePairs);
|
||||||
|
json = JsonSerializer.Serialize(logisticKeyValuePairs, ReadOnlyDictionaryStringReadOnlyDictionaryStringStringSourceGenerationContext.Default.ReadOnlyDictionaryStringReadOnlyDictionaryStringString);
|
||||||
|
}
|
||||||
|
string footerText = string.IsNullOrEmpty(json) || json == "{}" ? string.Empty : $",{Environment.NewLine}\"PDSF\":{Environment.NewLine}{json}";
|
||||||
|
result = string.Concat(
|
||||||
|
'{',
|
||||||
|
Environment.NewLine,
|
||||||
|
'"',
|
||||||
|
"Count",
|
||||||
|
'"',
|
||||||
|
": ",
|
||||||
|
records.Count,
|
||||||
|
',',
|
||||||
|
Environment.NewLine,
|
||||||
|
'"',
|
||||||
|
"Records",
|
||||||
|
'"',
|
||||||
|
": ",
|
||||||
|
Environment.NewLine,
|
||||||
|
'[',
|
||||||
|
Environment.NewLine,
|
||||||
|
string.Join($",{Environment.NewLine}", records),
|
||||||
|
Environment.NewLine,
|
||||||
|
']',
|
||||||
|
footerText,
|
||||||
|
'}');
|
||||||
|
return result;
|
||||||
|
#pragma warning restore CA1845, IDE0057
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<string> GetFooterLines(string[] lines, int i) {
|
||||||
|
List<string> results = [];
|
||||||
|
for (int j = i; j < lines.Length; j++) {
|
||||||
|
results.Add(lines[j]);
|
||||||
|
if (lines[j].StartsWith("END_HEADER"))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<string, string> GetFooterKeyValuePairs(ReadOnlyCollection<string> footerLines) {
|
||||||
|
Dictionary<string, string> results = [];
|
||||||
|
string[] segments;
|
||||||
|
foreach (string footerLine in footerLines) {
|
||||||
|
segments = footerLine.Split('\t');
|
||||||
|
if (segments.Length != 2 || string.IsNullOrEmpty(segments[1].Trim())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (segments[1].Contains(';')) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
results.Add(segments[0], segments[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<string, ReadOnlyDictionary<string, string>> GetLogisticKeyValuePairs(ReadOnlyCollection<string> footerLines, ReadOnlyDictionary<string, string> footerKeyValuePairs) {
|
||||||
|
Dictionary<string, ReadOnlyDictionary<string, string>> results = [];
|
||||||
|
string[] segments;
|
||||||
|
string[] subSegments;
|
||||||
|
string[] subSubSegments;
|
||||||
|
Dictionary<string, string>? keyValue;
|
||||||
|
results.Add("Footer", footerKeyValuePairs);
|
||||||
|
Dictionary<string, Dictionary<string, string>> keyValuePairs = [];
|
||||||
|
foreach (string footerLine in footerLines) {
|
||||||
|
segments = footerLine.Split('\t');
|
||||||
|
if (segments.Length != 2 || string.IsNullOrEmpty(segments[1].Trim())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!segments[1].Contains(';') || !segments[1].Contains('=')) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
subSegments = segments[1].Split(';');
|
||||||
|
if (subSegments.Length < 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!keyValuePairs.TryGetValue(segments[0], out keyValue)) {
|
||||||
|
keyValuePairs.Add(segments[0], []);
|
||||||
|
if (!keyValuePairs.TryGetValue(segments[0], out keyValue)) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (string segment in subSegments) {
|
||||||
|
subSubSegments = segment.Split('=');
|
||||||
|
if (subSubSegments.Length != 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
keyValue.Add(subSubSegments[0], subSubSegments[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (KeyValuePair<string, Dictionary<string, string>> keyValuePair in keyValuePairs) {
|
||||||
|
results.Add(keyValuePair.Key, keyValuePair.Value.AsReadOnly());
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -169,6 +169,14 @@ internal static class HelperDay
|
|||||||
ADO2025.PI6.Helper20250601.EquipmentAutomationFrameworkStatus(logger, args);
|
ADO2025.PI6.Helper20250601.EquipmentAutomationFrameworkStatus(logger, args);
|
||||||
else if (args[1] == "Day-Helper-2025-06-02")
|
else if (args[1] == "Day-Helper-2025-06-02")
|
||||||
ADO2025.PI6.Helper20250602.EquipmentAutomationFrameworkCellInstanceStateImageVerbIf(logger, args);
|
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
|
else
|
||||||
throw new Exception(appSettings.Company);
|
throw new Exception(appSettings.Company);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ internal static class Helper20231130
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ReadOnlyCollection<string> GetSystemStateValues(List<string> lines, string[] columns, int keyColumnIndex, ReadOnlyDictionary<string, string> systemStates)
|
private static ReadOnlyCollection<string> GetSystemStateValues(List<string> lines, string[] columns, int keyColumnIndex, ReadOnlyDictionary<string, string> systemStateToNames)
|
||||||
{
|
{
|
||||||
List<string> results = [];
|
List<string> results = [];
|
||||||
string[] values;
|
string[] values;
|
||||||
@ -79,7 +79,7 @@ internal static class Helper20231130
|
|||||||
keyColumnValue = values[keyColumnIndex];
|
keyColumnValue = values[keyColumnIndex];
|
||||||
if (string.IsNullOrEmpty(keyColumnValue))
|
if (string.IsNullOrEmpty(keyColumnValue))
|
||||||
continue;
|
continue;
|
||||||
if (!systemStates.TryGetValue(keyColumnValue, out systemState))
|
if (!systemStateToNames.TryGetValue(keyColumnValue, out systemState))
|
||||||
continue;
|
continue;
|
||||||
if (results.Contains(systemState))
|
if (results.Contains(systemState))
|
||||||
continue;
|
continue;
|
||||||
@ -106,7 +106,7 @@ internal static class Helper20231130
|
|||||||
string missingKeyDirectory = Path.Combine(sourceDirectory, "Missing-Key");
|
string missingKeyDirectory = Path.Combine(sourceDirectory, "Missing-Key");
|
||||||
if (!Directory.Exists(missingKeyDirectory))
|
if (!Directory.Exists(missingKeyDirectory))
|
||||||
_ = Directory.CreateDirectory(missingKeyDirectory);
|
_ = Directory.CreateDirectory(missingKeyDirectory);
|
||||||
ReadOnlyDictionary<string, string> systemStates = GetSystemStates();
|
ReadOnlyDictionary<string, string> systemStateToNames = GetSystemStates();
|
||||||
ReadOnlyCollection<Record> records = GetRecords(sourceDirectory, timestampFormat);
|
ReadOnlyCollection<Record> records = GetRecords(sourceDirectory, timestampFormat);
|
||||||
foreach (Record record in records)
|
foreach (Record record in records)
|
||||||
{
|
{
|
||||||
@ -132,7 +132,7 @@ internal static class Helper20231130
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
logger.LogInformation("{timestamp} triggered", record.TimeStamp);
|
logger.LogInformation("{timestamp} triggered", record.TimeStamp);
|
||||||
systemStateValues = GetSystemStateValues(lines, columns, keyColumnIndex.Value, systemStates);
|
systemStateValues = GetSystemStateValues(lines, columns, keyColumnIndex.Value, systemStateToNames);
|
||||||
if (systemStateValues.Count == 0)
|
if (systemStateValues.Count == 0)
|
||||||
{
|
{
|
||||||
File.Move(record.File, Path.Combine(sourceDirectory, missingKeyDirectory, record.FileName));
|
File.Move(record.File, Path.Combine(sourceDirectory, missingKeyDirectory, record.FileName));
|
||||||
@ -142,7 +142,6 @@ internal static class Helper20231130
|
|||||||
systemState = string.Join('-', systemStateValues);
|
systemState = string.Join('-', systemStateValues);
|
||||||
checkFileName = Path.Combine(Path.GetDirectoryName(record.File) ?? throw new Exception(), $"{record.Equipment}-{record.TimeStamp}-{systemState}.pdsf");
|
checkFileName = Path.Combine(Path.GetDirectoryName(record.File) ?? throw new Exception(), $"{record.Equipment}-{record.TimeStamp}-{systemState}.pdsf");
|
||||||
File.WriteAllLines(checkFileName, lines);
|
File.WriteAllLines(checkFileName, lines);
|
||||||
File.Delete(record.File);
|
|
||||||
if (DateTime.TryParseExact(record.TimeStamp, timestampFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
if (DateTime.TryParseExact(record.TimeStamp, timestampFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
File.SetLastWriteTime(checkFileName, dateTime);
|
File.SetLastWriteTime(checkFileName, dateTime);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
<PackageReference Include="MetadataExtractor" Version="2.8.1" />
|
<PackageReference Include="MetadataExtractor" Version="2.8.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
|
||||||
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.16" />
|
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.17" />
|
||||||
|
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
|
||||||
<PackageReference Include="System.Text.Json" Version="9.0.5" />
|
<PackageReference Include="System.Text.Json" Version="9.0.5" />
|
||||||
<PackageReference Include="TextCopy" Version="6.2.1" />
|
<PackageReference Include="TextCopy" Version="6.2.1" />
|
||||||
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
|
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
|
||||||
|
@ -16,8 +16,20 @@ internal static partial class HelperMarkdown
|
|||||||
|
|
||||||
private record Input(string? Destination,
|
private record Input(string? Destination,
|
||||||
string Source,
|
string Source,
|
||||||
|
string? ReplaceWithTitle,
|
||||||
bool UseProcessStart);
|
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,
|
private record Record(string Directory,
|
||||||
string File,
|
string File,
|
||||||
string[] Lines);
|
string[] Lines);
|
||||||
@ -30,7 +42,7 @@ internal static partial class HelperMarkdown
|
|||||||
string FileNameWithoutExtension,
|
string FileNameWithoutExtension,
|
||||||
ReadOnlyDictionary<string, object> FrontMatterYaml,
|
ReadOnlyDictionary<string, object> FrontMatterYaml,
|
||||||
string H1,
|
string H1,
|
||||||
bool IsGitOthersModifiedAndDeletedExcludingStandard,
|
bool? IsGitOthersModifiedAndDeletedExcludingStandard,
|
||||||
bool IsKanbanIndex,
|
bool IsKanbanIndex,
|
||||||
bool IsKanbanMarkdown,
|
bool IsKanbanMarkdown,
|
||||||
DateTime LastWriteDateTime,
|
DateTime LastWriteDateTime,
|
||||||
@ -49,15 +61,27 @@ internal static partial class HelperMarkdown
|
|||||||
|
|
||||||
private record MarkdownFileH1AndRelativePath(MarkdownFile? MarkdownFile, string[]? Lines, string? H1, string? RelativePath);
|
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)]
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
[JsonSerializable(typeof(Dictionary<string, JsonElement>))]
|
[JsonSerializable(typeof(Dictionary<string, JsonElement>))]
|
||||||
internal partial class DictionaryStringAndJsonElementSourceGenerationContext : JsonSerializerContext
|
internal partial class DictionaryStringAndJsonElementSourceGenerationContext : JsonSerializerContext
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("([A-Z]+(.))")]
|
||||||
|
private static partial Regex UpperCase();
|
||||||
|
|
||||||
[GeneratedRegex("(~~)?(#)([a-zA-Z0-9]{6})(~~)?( )")]
|
[GeneratedRegex("(~~)?(#)([a-zA-Z0-9]{6})(~~)?( )")]
|
||||||
private static partial Regex HtmlColor();
|
private static partial Regex HtmlColor();
|
||||||
|
|
||||||
|
[GeneratedRegex("[\\s!?.,@:;|\\\\/\"'`£$%\\^&*{}[\\]()<>~#+\\-=_¬]+")]
|
||||||
|
private static partial Regex InvalidCharacter();
|
||||||
|
|
||||||
private static MarkdownExtra GetMarkdownExtra(MarkdownFileAndLines markdownFileAndLines)
|
private static MarkdownExtra GetMarkdownExtra(MarkdownFileAndLines markdownFileAndLines)
|
||||||
{
|
{
|
||||||
MarkdownExtra result;
|
MarkdownExtra result;
|
||||||
@ -301,10 +325,10 @@ internal static partial class HelperMarkdown
|
|||||||
if (!directoryInfo.Exists || (!string.IsNullOrEmpty(directoryInfo.LinkTarget) && !Directory.Exists(directoryInfo.LinkTarget)))
|
if (!directoryInfo.Exists || (!string.IsNullOrEmpty(directoryInfo.LinkTarget) && !Directory.Exists(directoryInfo.LinkTarget)))
|
||||||
continue;
|
continue;
|
||||||
collection.AddRange(GetFiles(appSettings, directoryInfo, SearchOption.TopDirectoryOnly));
|
collection.AddRange(GetFiles(appSettings, directoryInfo, SearchOption.TopDirectoryOnly));
|
||||||
foreach (FileInfo file in collection)
|
foreach (FileInfo fileInfo in collection)
|
||||||
results.Add(file);
|
results.Add(fileInfo);
|
||||||
}
|
}
|
||||||
return new(results);
|
return (from l in results orderby l.FullName select l).ToArray().AsReadOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static LineNumber GetLineNumbers(FileInfo fileInfo)
|
internal static LineNumber GetLineNumbers(FileInfo fileInfo)
|
||||||
@ -525,7 +549,7 @@ internal static partial class HelperMarkdown
|
|||||||
h1Check = $"# {h1[2..]}";
|
h1Check = $"# {h1[2..]}";
|
||||||
if (h1Check.Length == h1.Length && h1Check != h1)
|
if (h1Check.Length == h1.Length && h1Check != h1)
|
||||||
{
|
{
|
||||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
lines[markdownFile.LineNumber.H1.Value] = h1Check;
|
lines[markdownFile.LineNumber.H1.Value] = h1Check;
|
||||||
File.WriteAllLines(markdownFile.File, lines);
|
File.WriteAllLines(markdownFile.File, lines);
|
||||||
@ -541,7 +565,7 @@ internal static partial class HelperMarkdown
|
|||||||
checkName = Path.Combine(markdownFile.Directory, checkFileName);
|
checkName = Path.Combine(markdownFile.Directory, checkFileName);
|
||||||
if (checkName == markdownFile.File)
|
if (checkName == markdownFile.File)
|
||||||
continue;
|
continue;
|
||||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
File.Move(markdownFile.File, checkName);
|
File.Move(markdownFile.File, checkName);
|
||||||
result += 1;
|
result += 1;
|
||||||
@ -658,6 +682,7 @@ internal static partial class HelperMarkdown
|
|||||||
Input result;
|
Input result;
|
||||||
string? destination = null;
|
string? destination = null;
|
||||||
bool useProcessStart = false;
|
bool useProcessStart = false;
|
||||||
|
string? replaceWithTitle = null;
|
||||||
string source = Path.GetFullPath(args[0]);
|
string source = Path.GetFullPath(args[0]);
|
||||||
for (int i = 1; i < args.Count; i++)
|
for (int i = 1; i < args.Count; i++)
|
||||||
{
|
{
|
||||||
@ -667,6 +692,8 @@ internal static partial class HelperMarkdown
|
|||||||
useProcessStart = args[i + 1] == "true";
|
useProcessStart = args[i + 1] == "true";
|
||||||
else if (args[i][1] == 'd')
|
else if (args[i][1] == 'd')
|
||||||
destination = Path.GetFullPath(args[i + 1]);
|
destination = Path.GetFullPath(args[i + 1]);
|
||||||
|
else if (args[i][1] == 't')
|
||||||
|
replaceWithTitle = args[i + 1];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -678,11 +705,11 @@ internal static partial class HelperMarkdown
|
|||||||
if (!Directory.Exists(destination))
|
if (!Directory.Exists(destination))
|
||||||
_ = Directory.CreateDirectory(destination);
|
_ = Directory.CreateDirectory(destination);
|
||||||
}
|
}
|
||||||
result = new(destination, source, useProcessStart);
|
result = new(Destination: destination, Source: source, ReplaceWithTitle: replaceWithTitle, UseProcessStart: useProcessStart);
|
||||||
return result;
|
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 = [];
|
Dictionary<string, MarkdownFileAndLines> results = [];
|
||||||
string h1;
|
string h1;
|
||||||
@ -696,17 +723,22 @@ internal static partial class HelperMarkdown
|
|||||||
string fileNameWithoutExtension;
|
string fileNameWithoutExtension;
|
||||||
ReadOnlyCollection<string> lines;
|
ReadOnlyCollection<string> lines;
|
||||||
ReadOnlyDictionary<string, object> frontMatterYaml;
|
ReadOnlyDictionary<string, object> frontMatterYaml;
|
||||||
bool isGitOthersModifiedAndDeletedExcludingStandard;
|
bool? isGitOthersModifiedAndDeletedExcludingStandard;
|
||||||
ReadOnlyCollection<FileInfo> files = GetFiles(appSettings, input);
|
ReadOnlyCollection<FileInfo> files = GetFiles(appSettings, input);
|
||||||
foreach (FileInfo fileInfo in files)
|
foreach (FileInfo fileInfo in files)
|
||||||
{ // cSpell:disable
|
{ // cSpell:disable
|
||||||
if (fileInfo.DirectoryName is null)
|
if (fileInfo.DirectoryName is null)
|
||||||
continue;
|
continue;
|
||||||
key = Path.GetRelativePath(input.Source, fileInfo.FullName);
|
key = Path.GetRelativePath(input.Source, fileInfo.FullName);
|
||||||
isWithinSource = fileInfo.FullName.Contains(input.Source);
|
if (gitOthersModifiedAndDeletedExcludingStandardFiles is null)
|
||||||
isGitOthersModifiedAndDeletedExcludingStandard = gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(fileInfo.FullName);
|
isGitOthersModifiedAndDeletedExcludingStandard = null;
|
||||||
if (!isWithinSource && results.ContainsKey(key))
|
else
|
||||||
continue;
|
{
|
||||||
|
isWithinSource = fileInfo.FullName.Contains(input.Source);
|
||||||
|
isGitOthersModifiedAndDeletedExcludingStandard = gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(fileInfo.FullName);
|
||||||
|
if (!isWithinSource && results.ContainsKey(key))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
lineNumber = GetLineNumbers(fileInfo);
|
lineNumber = GetLineNumbers(fileInfo);
|
||||||
lines = lineNumber.Lines;
|
lines = lineNumber.Lines;
|
||||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
|
||||||
@ -716,7 +748,7 @@ internal static partial class HelperMarkdown
|
|||||||
(type, h1) = GetTypeAndH1(appSettings, h1, lines, lineNumber);
|
(type, h1) = GetTypeAndH1(appSettings, h1, lines, lineNumber);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!isGitOthersModifiedAndDeletedExcludingStandard)
|
if (isGitOthersModifiedAndDeletedExcludingStandard is not null && !isGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
type = appSettings.DefaultNoteType;
|
type = appSettings.DefaultNoteType;
|
||||||
File.WriteAllLines(fileInfo.FullName, ["---", $"type: {type}\"", "---", string.Empty, $"# {h1}"]);
|
File.WriteAllLines(fileInfo.FullName, ["---", $"type: {type}\"", "---", string.Empty, $"# {h1}"]);
|
||||||
@ -724,20 +756,20 @@ internal static partial class HelperMarkdown
|
|||||||
}
|
}
|
||||||
isKanbanMarkdown = fileInfo.Name.EndsWith(".knb.md");
|
isKanbanMarkdown = fileInfo.Name.EndsWith(".knb.md");
|
||||||
isKanbanIndex = fileNameWithoutExtension == "index" && type.StartsWith("kanb", StringComparison.OrdinalIgnoreCase);
|
isKanbanIndex = fileNameWithoutExtension == "index" && type.StartsWith("kanb", StringComparison.OrdinalIgnoreCase);
|
||||||
markdownFile = new(fileInfo.CreationTime,
|
markdownFile = new(CreationDateTime: fileInfo.CreationTime,
|
||||||
fileInfo.DirectoryName,
|
Directory: fileInfo.DirectoryName,
|
||||||
fileInfo.Extension,
|
Extension: fileInfo.Extension,
|
||||||
fileInfo.FullName,
|
File: fileInfo.FullName,
|
||||||
fileInfo.Name,
|
FileName: fileInfo.Name,
|
||||||
fileNameWithoutExtension,
|
FileNameWithoutExtension: fileNameWithoutExtension,
|
||||||
frontMatterYaml,
|
FrontMatterYaml: frontMatterYaml,
|
||||||
h1,
|
H1: h1,
|
||||||
isGitOthersModifiedAndDeletedExcludingStandard,
|
IsGitOthersModifiedAndDeletedExcludingStandard: isGitOthersModifiedAndDeletedExcludingStandard,
|
||||||
isKanbanIndex,
|
IsKanbanIndex: isKanbanIndex,
|
||||||
isKanbanMarkdown,
|
IsKanbanMarkdown: isKanbanMarkdown,
|
||||||
fileInfo.LastWriteTime,
|
LastWriteDateTime: fileInfo.LastWriteTime,
|
||||||
lineNumber,
|
LineNumber: lineNumber,
|
||||||
type);
|
Type: type);
|
||||||
results.Add(key, new(markdownFile, lines.ToArray()));
|
results.Add(key, new(markdownFile, lines.ToArray()));
|
||||||
} // cSpell:restore
|
} // cSpell:restore
|
||||||
return new(results);
|
return new(results);
|
||||||
@ -763,7 +795,7 @@ internal static partial class HelperMarkdown
|
|||||||
markdownFile = relativeTo.Value.MarkdownFile;
|
markdownFile = relativeTo.Value.MarkdownFile;
|
||||||
if (markdownFile.IsKanbanMarkdown)
|
if (markdownFile.IsKanbanMarkdown)
|
||||||
continue;
|
continue;
|
||||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
if (markdownFile.LineNumber.FrontMatterYamlEnd is null)
|
if (markdownFile.LineNumber.FrontMatterYamlEnd is null)
|
||||||
continue;
|
continue;
|
||||||
@ -797,7 +829,7 @@ internal static partial class HelperMarkdown
|
|||||||
circularReference = false;
|
circularReference = false;
|
||||||
lines = relativeTo.Value.Lines;
|
lines = relativeTo.Value.Lines;
|
||||||
markdownFile = relativeTo.Value.MarkdownFile;
|
markdownFile = relativeTo.Value.MarkdownFile;
|
||||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
for (int i = 0; i < lines.Length; i++)
|
for (int i = 0; i < lines.Length; i++)
|
||||||
{
|
{
|
||||||
@ -859,7 +891,7 @@ internal static partial class HelperMarkdown
|
|||||||
found = false;
|
found = false;
|
||||||
lines = relativeTo.Value.Lines;
|
lines = relativeTo.Value.Lines;
|
||||||
markdownFile = relativeTo.Value.MarkdownFile;
|
markdownFile = relativeTo.Value.MarkdownFile;
|
||||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
for (int i = 0; i < lines.Length; i++)
|
for (int i = 0; i < lines.Length; i++)
|
||||||
{
|
{
|
||||||
@ -912,7 +944,7 @@ internal static partial class HelperMarkdown
|
|||||||
write = false;
|
write = false;
|
||||||
lines = relativeTo.Value.Lines;
|
lines = relativeTo.Value.Lines;
|
||||||
markdownFile = relativeTo.Value.MarkdownFile;
|
markdownFile = relativeTo.Value.MarkdownFile;
|
||||||
if (!input.UseProcessStart && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (!input.UseProcessStart && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
for (int i = 0; i < lines.Length; i++)
|
for (int i = 0; i < lines.Length; i++)
|
||||||
{
|
{
|
||||||
@ -940,7 +972,7 @@ internal static partial class HelperMarkdown
|
|||||||
}
|
}
|
||||||
if (!write)
|
if (!write)
|
||||||
continue;
|
continue;
|
||||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
File.WriteAllLines(markdownFile.File, lines);
|
File.WriteAllLines(markdownFile.File, lines);
|
||||||
result += 1;
|
result += 1;
|
||||||
@ -975,7 +1007,7 @@ internal static partial class HelperMarkdown
|
|||||||
markdownFile = relativeTo.Value.MarkdownFile;
|
markdownFile = relativeTo.Value.MarkdownFile;
|
||||||
if (markdownFile.IsKanbanIndex)
|
if (markdownFile.IsKanbanIndex)
|
||||||
continue;
|
continue;
|
||||||
if (!input.UseProcessStart && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (!input.UseProcessStart && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
if (!File.Exists(markdownFile.File))
|
if (!File.Exists(markdownFile.File))
|
||||||
continue;
|
continue;
|
||||||
@ -1040,7 +1072,7 @@ internal static partial class HelperMarkdown
|
|||||||
}
|
}
|
||||||
if (!write)
|
if (!write)
|
||||||
continue;
|
continue;
|
||||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
File.WriteAllLines(markdownFile.File, lines);
|
File.WriteAllLines(markdownFile.File, lines);
|
||||||
result += 1;
|
result += 1;
|
||||||
@ -1057,18 +1089,12 @@ internal static partial class HelperMarkdown
|
|||||||
MarkdownFileAndLines? markdownFileAndLines = GetKanbanIndexMarkdownFileAndLines(relativeToCollection);
|
MarkdownFileAndLines? markdownFileAndLines = GetKanbanIndexMarkdownFileAndLines(relativeToCollection);
|
||||||
if (markdownFileAndLines is not null && File.Exists(markdownFileAndLines.MarkdownFile.File))
|
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");
|
string jsonFile = Path.Combine(input.Destination, $"{nameof(columnsToCards)}.json");
|
||||||
if (File.Exists(jsonFile))
|
string old = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile);
|
||||||
File.Delete(jsonFile);
|
string json = columnsToCards.Count == 0 ? "{}" : JsonSerializer.Serialize(columnsToCards, ColumnsAndCardsSourceGenerationContext.Default.ReadOnlyDictionaryStringListCard);
|
||||||
columnsToCards = GetColumnsToCards(input, relativeToCollection, markdownFileAndLines);
|
if (json != old)
|
||||||
if (columnsToCards.Count == 0)
|
|
||||||
File.WriteAllText(jsonFile, "{}");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string json = JsonSerializer.Serialize(columnsToCards, ColumnsAndCardsSourceGenerationContext.Default.ReadOnlyDictionaryStringListCard);
|
|
||||||
File.WriteAllText(jsonFile, json);
|
File.WriteAllText(jsonFile, json);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1122,7 +1148,7 @@ internal static partial class HelperMarkdown
|
|||||||
results.Insert(0, string.Empty);
|
results.Insert(0, string.Empty);
|
||||||
}
|
}
|
||||||
results.Insert(0, "---");
|
results.Insert(0, "---");
|
||||||
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
{
|
{
|
||||||
results.Insert(0, updatedLine);
|
results.Insert(0, updatedLine);
|
||||||
results.Insert(0, createdLine);
|
results.Insert(0, createdLine);
|
||||||
@ -1140,7 +1166,7 @@ internal static partial class HelperMarkdown
|
|||||||
}
|
}
|
||||||
if (markdownFile.LineNumber.Type is null)
|
if (markdownFile.LineNumber.Type is null)
|
||||||
results.Insert(markdownFile.LineNumber.FrontMatterYamlEnd.Value, typeLine);
|
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)
|
if (markdownFile.LineNumber.Updated is null)
|
||||||
results.Insert(markdownFile.LineNumber.FrontMatterYamlEnd.Value, updatedLine);
|
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))
|
if (results.Count == lines.Length && string.Join('\r', lines) == string.Join('\r', results))
|
||||||
continue;
|
continue;
|
||||||
if (!markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard)
|
if (markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard is not null && !markdownFile.IsGitOthersModifiedAndDeletedExcludingStandard.Value)
|
||||||
continue;
|
continue;
|
||||||
File.WriteAllLines(markdownFile.File, results);
|
File.WriteAllLines(markdownFile.File, results);
|
||||||
File.SetLastWriteTime(markdownFile.File, markdownFile.LastWriteDateTime);
|
File.SetLastWriteTime(markdownFile.File, markdownFile.LastWriteDateTime);
|
||||||
@ -1235,7 +1261,351 @@ internal static partial class HelperMarkdown
|
|||||||
logger.LogInformation("{updated} Markdown file(s) were updated", updated);
|
logger.LogInformation("{updated} Markdown file(s) were updated", updated);
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(input.Destination))
|
if (!string.IsNullOrEmpty(input.Destination))
|
||||||
|
{
|
||||||
SaveColumnToCards(input, relativeToCollection);
|
SaveColumnToCards(input, relativeToCollection);
|
||||||
|
SaveTablesToJson(appSettings, logger, input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SaveTablesToJson(AppSettings appSettings, ILogger<Worker> logger, Input input)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(input.Destination))
|
||||||
|
throw new NotSupportedException();
|
||||||
|
string old;
|
||||||
|
string json;
|
||||||
|
string[] lines;
|
||||||
|
string fileName;
|
||||||
|
List<Block> blocks;
|
||||||
|
string directoryName;
|
||||||
|
List<string>? jsonLines;
|
||||||
|
MarkdownFile markdownFile;
|
||||||
|
List<string> fileNames = [];
|
||||||
|
ReadOnlyCollection<Table> tables;
|
||||||
|
Dictionary<string, List<string>> results = [];
|
||||||
|
ReadOnlyCollection<Block> javaScriptObjectNotationBlocks;
|
||||||
|
ReadOnlyCollection<Block> yetAnotherMarkupLanguageBlocks;
|
||||||
|
ReadOnlyDictionary<string, MarkdownFileAndLines> relativeToCollection = GetRelativeToCollection(appSettings, input, gitOthersModifiedAndDeletedExcludingStandardFiles: null);
|
||||||
|
foreach (KeyValuePair<string, MarkdownFileAndLines> relativeTo in relativeToCollection)
|
||||||
|
{
|
||||||
|
if (relativeTo.Value.Lines.Length == 0)
|
||||||
|
continue;
|
||||||
|
lines = relativeTo.Value.Lines;
|
||||||
|
markdownFile = relativeTo.Value.MarkdownFile;
|
||||||
|
if (markdownFile.IsKanbanIndex)
|
||||||
|
continue;
|
||||||
|
if (markdownFile.IsKanbanMarkdown)
|
||||||
|
continue;
|
||||||
|
if (markdownFile.FileName.StartsWith("index.yml.md"))
|
||||||
|
continue;
|
||||||
|
if (!File.Exists(markdownFile.File))
|
||||||
|
continue;
|
||||||
|
tables = GetTables(lines);
|
||||||
|
javaScriptObjectNotationBlocks = GetJavaScriptObjectNotationBlocks(lines);
|
||||||
|
yetAnotherMarkupLanguageBlocks = GetYetAnotherMarkupLanguageBlocks(lines);
|
||||||
|
if (tables.Count == 0 && javaScriptObjectNotationBlocks.Count == 0 && yetAnotherMarkupLanguageBlocks.Count == 0)
|
||||||
|
continue;
|
||||||
|
fileName = Path.Combine(input.Destination, $"{markdownFile.FileNameWithoutExtension}.json");
|
||||||
|
if (fileNames.Contains(fileName))
|
||||||
|
continue;
|
||||||
|
fileNames.Add(fileName);
|
||||||
|
blocks = [];
|
||||||
|
blocks.AddRange(GetBlocks(tables));
|
||||||
|
blocks.AddRange(javaScriptObjectNotationBlocks);
|
||||||
|
blocks.AddRange(GetBlocks(logger, markdownFile, yetAnotherMarkupLanguageBlocks));
|
||||||
|
if (blocks.Count == 0)
|
||||||
|
continue;
|
||||||
|
directoryName = Path.GetFileName(Path.Combine(input.Destination, markdownFile.Directory));
|
||||||
|
if (!results.TryGetValue(directoryName, out jsonLines))
|
||||||
|
{
|
||||||
|
results.Add(directoryName, []);
|
||||||
|
if (!results.TryGetValue(directoryName, out jsonLines))
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
json = GetJson(input, markdownFile, blocks.AsReadOnly());
|
||||||
|
jsonLines.Add(json);
|
||||||
|
}
|
||||||
|
foreach (KeyValuePair<string, List<string>> keyValuePair in results)
|
||||||
|
{
|
||||||
|
json = string.Concat('[', Environment.NewLine, string.Join($",{Environment.NewLine}", keyValuePair.Value), Environment.NewLine, ']');
|
||||||
|
fileName = Path.Combine(input.Destination, $"{keyValuePair.Key}.json");
|
||||||
|
old = !File.Exists(fileName) ? string.Empty : File.ReadAllText(fileName);
|
||||||
|
if (json != old)
|
||||||
|
{
|
||||||
|
File.WriteAllText(fileName, json);
|
||||||
|
logger.LogInformation("Updated json file for <{fileName}>", fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<Table> GetTables(string[] lines)
|
||||||
|
{
|
||||||
|
List<Table> results = [];
|
||||||
|
Table table;
|
||||||
|
string? title;
|
||||||
|
string[] segments;
|
||||||
|
int? columnsLine = null;
|
||||||
|
List<ReadOnlyCollection<string>> rows = [];
|
||||||
|
string[]? columns = null;
|
||||||
|
for (int i = 0; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
if (columns is null && (!lines[i].StartsWith('|') || !lines[i].EndsWith('|') || i + 3 >= lines.Length))
|
||||||
|
continue;
|
||||||
|
if (columns is null && (lines[i + 1].Length < 3 || lines[i + 1][0] != '|' || (lines[i + 1][1] is not ':' and not '-')))
|
||||||
|
continue;
|
||||||
|
if (columns is null)
|
||||||
|
{
|
||||||
|
columnsLine = i;
|
||||||
|
segments = lines[i][1..^1].Split('|');
|
||||||
|
columns = (from l in segments select l.Trim()).ToArray();
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
segments = lines[i].Length < 3 ? [] : lines[i][1..^1].Split('|');
|
||||||
|
rows.Add((from l in segments select l.Trim()).ToArray().AsReadOnly());
|
||||||
|
if (columns is not null && columnsLine is not null && string.IsNullOrEmpty(lines[i]))
|
||||||
|
{
|
||||||
|
if (columnsLine.Value - 2 > 0 && lines[columnsLine.Value - 2].StartsWith('#'))
|
||||||
|
title = lines[columnsLine.Value - 2];
|
||||||
|
else if (columnsLine.Value - 4 > 0 && lines[columnsLine.Value - 4].StartsWith('#'))
|
||||||
|
title = lines[columnsLine.Value - 4];
|
||||||
|
else
|
||||||
|
title = null;
|
||||||
|
rows.RemoveAt(rows.Count - 1);
|
||||||
|
table = new(columns.AsReadOnly(), columnsLine.Value, rows.AsReadOnly(), title);
|
||||||
|
results.Add(table);
|
||||||
|
columnsLine = null;
|
||||||
|
columns = null;
|
||||||
|
rows = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetParamCase(string value)
|
||||||
|
{
|
||||||
|
string result;
|
||||||
|
StringBuilder stringBuilder = new(value);
|
||||||
|
Match[] matches = UpperCase().Matches(value).ToArray();
|
||||||
|
for (int i = matches.Length - 1; i > -1; i--)
|
||||||
|
_ = stringBuilder.Insert(matches[i].Index, '-');
|
||||||
|
string[] segments = InvalidCharacter().Split(stringBuilder.ToString().ToLower());
|
||||||
|
result = string.Join('-', segments).Trim('-');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<Block> GetBlocks(ReadOnlyCollection<Table> tables)
|
||||||
|
{
|
||||||
|
List<Block> results = [];
|
||||||
|
Block block;
|
||||||
|
string json;
|
||||||
|
foreach (Table table in tables)
|
||||||
|
{
|
||||||
|
if (table.Title is null)
|
||||||
|
continue;
|
||||||
|
if (table.Rows.Count == 0)
|
||||||
|
continue;
|
||||||
|
json = GetJson(table);
|
||||||
|
block = new(Line: table.ColumnsLine, Json: json, RowCount: table.Rows.Count, Rows: null, Title: table.Title);
|
||||||
|
results.Add(block);
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetJson(Table table)
|
||||||
|
{
|
||||||
|
string result;
|
||||||
|
string line;
|
||||||
|
string value;
|
||||||
|
string[] segments;
|
||||||
|
List<string> lines = [];
|
||||||
|
for (int i = 0; i < table.Rows.Count; i++)
|
||||||
|
{
|
||||||
|
line = "{";
|
||||||
|
segments = table.Rows[i].ToArray();
|
||||||
|
if (segments.Length != table.Columns.Count)
|
||||||
|
break;
|
||||||
|
for (int c = 0; c < segments.Length; c++)
|
||||||
|
{
|
||||||
|
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||||
|
line += string.Concat('"', table.Columns[c].Trim('"'), '"', ':', '"', value, '"', ',');
|
||||||
|
}
|
||||||
|
line = string.Concat(line[..^1], '}');
|
||||||
|
lines.Add(line);
|
||||||
|
}
|
||||||
|
result = string.Concat('[', Environment.NewLine, string.Join($",{Environment.NewLine}", lines), Environment.NewLine, ']');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<Block> GetJavaScriptObjectNotationBlocks(string[] lines)
|
||||||
|
{
|
||||||
|
List<Block> results = [];
|
||||||
|
string json;
|
||||||
|
string? title;
|
||||||
|
int? blockLine = null;
|
||||||
|
List<string> rows = [];
|
||||||
|
Block javaScriptObjectNotationBlock;
|
||||||
|
for (int i = 0; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
if (blockLine is null && !lines[i].StartsWith("```json"))
|
||||||
|
continue;
|
||||||
|
if (blockLine is null)
|
||||||
|
{
|
||||||
|
blockLine = i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rows.Add(lines[i]);
|
||||||
|
if (blockLine is not null && lines[i] == "```")
|
||||||
|
{
|
||||||
|
rows.RemoveAt(rows.Count - 1);
|
||||||
|
if (blockLine.Value - 2 > 0 && lines[blockLine.Value - 2].StartsWith('#'))
|
||||||
|
title = lines[blockLine.Value - 2];
|
||||||
|
else if (blockLine.Value - 4 > 0 && lines[blockLine.Value - 4].StartsWith('#'))
|
||||||
|
title = lines[blockLine.Value - 4];
|
||||||
|
else
|
||||||
|
title = null;
|
||||||
|
if (string.IsNullOrEmpty(title))
|
||||||
|
continue;
|
||||||
|
json = string.Join(Environment.NewLine, rows);
|
||||||
|
javaScriptObjectNotationBlock = new(Line: blockLine.Value, Json: json, RowCount: rows.Count, Rows: null, Title: title);
|
||||||
|
results.Add(javaScriptObjectNotationBlock);
|
||||||
|
blockLine = null;
|
||||||
|
rows = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<Block> GetYetAnotherMarkupLanguageBlocks(string[] lines)
|
||||||
|
{
|
||||||
|
List<Block> results = [];
|
||||||
|
string? title = null;
|
||||||
|
int? blockLine = null;
|
||||||
|
List<string> rows = [];
|
||||||
|
Block yetAnotherMarkupLanguageBlock;
|
||||||
|
if (lines[0] == "---")
|
||||||
|
{
|
||||||
|
for (int i = 1; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
rows.Add(lines[i]);
|
||||||
|
if (lines[i] == "---")
|
||||||
|
{
|
||||||
|
rows.RemoveAt(rows.Count - 1);
|
||||||
|
yetAnotherMarkupLanguageBlock = new(Line: 0, Json: null, RowCount: rows.Count, Rows: rows.AsReadOnly(), Title: title);
|
||||||
|
results.Add(yetAnotherMarkupLanguageBlock);
|
||||||
|
rows = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rows = [];
|
||||||
|
for (int i = 0; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
if (blockLine is null && !lines[i].StartsWith("```yml") && !lines[i].StartsWith("```yaml"))
|
||||||
|
continue;
|
||||||
|
if (blockLine is null)
|
||||||
|
{
|
||||||
|
blockLine = i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rows.Add(lines[i]);
|
||||||
|
if (blockLine is not null && lines[i] == "```")
|
||||||
|
{
|
||||||
|
rows.RemoveAt(rows.Count - 1);
|
||||||
|
if (blockLine.Value - 2 > 0 && lines[blockLine.Value - 2].StartsWith('#'))
|
||||||
|
title = lines[blockLine.Value - 2];
|
||||||
|
else if (blockLine.Value - 4 > 0 && lines[blockLine.Value - 4].StartsWith('#'))
|
||||||
|
title = lines[blockLine.Value - 4];
|
||||||
|
else
|
||||||
|
title = null;
|
||||||
|
yetAnotherMarkupLanguageBlock = new(Line: blockLine.Value, Json: null, RowCount: rows.Count, Rows: rows.AsReadOnly(), Title: title);
|
||||||
|
results.Add(yetAnotherMarkupLanguageBlock);
|
||||||
|
blockLine = null;
|
||||||
|
rows = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<Block> GetBlocks(ILogger<Worker> logger, MarkdownFile markdownFile, ReadOnlyCollection<Block> yetAnotherMarkupLanguageBlocks)
|
||||||
|
{
|
||||||
|
List<Block> results = [];
|
||||||
|
string key;
|
||||||
|
Block block;
|
||||||
|
string json;
|
||||||
|
string text;
|
||||||
|
Dictionary<string, object>? keyValuePairs;
|
||||||
|
Dictionary<string, object> keyValuePairsB = [];
|
||||||
|
#pragma warning disable IL3050
|
||||||
|
IDeserializer deserializer = new DeserializerBuilder().Build();
|
||||||
|
#pragma warning restore IL3050
|
||||||
|
foreach (Block yaml in yetAnotherMarkupLanguageBlocks)
|
||||||
|
{
|
||||||
|
if (yaml.Rows is null || yaml.RowCount == 0)
|
||||||
|
continue;
|
||||||
|
if (yaml.Title is null && yaml.Line != 0)
|
||||||
|
continue;
|
||||||
|
text = string.Join(Environment.NewLine, yaml.Rows);
|
||||||
|
try
|
||||||
|
{ keyValuePairs = deserializer.Deserialize<Dictionary<string, object>>(text); }
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
keyValuePairs = null;
|
||||||
|
logger.LogWarning("Invalid yaml file for <{file}>", markdownFile.FileName);
|
||||||
|
}
|
||||||
|
if (keyValuePairs is null)
|
||||||
|
continue;
|
||||||
|
keyValuePairsB.Clear();
|
||||||
|
foreach (KeyValuePair<string, object> keyValuePair in keyValuePairs)
|
||||||
|
{
|
||||||
|
key = GetParamCase(keyValuePair.Key);
|
||||||
|
if (keyValuePairsB.ContainsKey(key))
|
||||||
|
continue;
|
||||||
|
if (keyValuePair.Value is IDictionary<object, object>)
|
||||||
|
{
|
||||||
|
logger.LogWarning("yaml contains a dictionary not allowed in AOT <{file}>", markdownFile.FileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (keyValuePair.Value is not ICollection<object> collection)
|
||||||
|
keyValuePairsB.Add(key, keyValuePair.Value);
|
||||||
|
else
|
||||||
|
keyValuePairsB.Add(key, string.Join(',', collection));
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{ json = JsonSerializer.Serialize(keyValuePairsB, DictionaryStringAndObjectSourceGenerationContext.Default.DictionaryStringObject); }
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
logger.LogWarning("yaml contains special values not allowed in AOT <{file}>", markdownFile.FileName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
block = new(Line: yaml.Line, Json: json, RowCount: yaml.Rows.Count, Rows: null, Title: yaml.Title);
|
||||||
|
results.Add(block);
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetJson(Input input, MarkdownFile markdownFile, ReadOnlyCollection<Block> blocks)
|
||||||
|
{
|
||||||
|
string result;
|
||||||
|
string paramCase;
|
||||||
|
List<string> lines = [];
|
||||||
|
string fileNameParamCase = GetParamCase(markdownFile.FileNameWithoutExtension);
|
||||||
|
foreach (Block block in blocks.OrderBy(l => l.Line))
|
||||||
|
{
|
||||||
|
paramCase = block.Title is null ? $"Line-{block.Line}" : GetParamCase(block.Title);
|
||||||
|
if (!string.IsNullOrEmpty(input.ReplaceWithTitle) && paramCase == input.ReplaceWithTitle)
|
||||||
|
paramCase = $"{fileNameParamCase}-{block.Line}";
|
||||||
|
lines.Add($"\"{paramCase}\": {block.Json}");
|
||||||
|
}
|
||||||
|
result = string.Concat('{',
|
||||||
|
Environment.NewLine,
|
||||||
|
$"\"{fileNameParamCase}\": ",
|
||||||
|
'{',
|
||||||
|
Environment.NewLine,
|
||||||
|
string.Join($",{Environment.NewLine}", lines),
|
||||||
|
Environment.NewLine,
|
||||||
|
'}',
|
||||||
|
Environment.NewLine,
|
||||||
|
'}');
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
7
Scripts/markdown.js
Normal file
7
Scripts/markdown.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// import data from './oi-metrology-viewer-0-Line-yaml.json' with { type: 'json' };
|
||||||
|
// import data from '../.vscode/oi-metrology-viewer-0-Line-yaml.json' with { type: 'json' };
|
||||||
|
import data from '../.vscode/.helper/hosts-legend-table.json' with { type: 'json' };
|
||||||
|
|
||||||
|
data.forEach(element => {
|
||||||
|
console.log(element.Concat);
|
||||||
|
});
|
Reference in New Issue
Block a user