Compare commits
4 Commits
89bb87bd14
...
84d85094a3
Author | SHA1 | Date | |
---|---|---|---|
84d85094a3 | |||
c3acd17a0e | |||
8ecea05fe8 | |||
d57be048e7 |
27
.vscode/download-work-items.http
vendored
27
.vscode/download-work-items.http
vendored
@ -1,27 +0,0 @@
|
|||||||
@host = https://tfs.intra.infineon.com
|
|
||||||
@pat = asdf
|
|
||||||
@ids = 126018, 224543
|
|
||||||
|
|
||||||
GET {{host}}/tfs/FactoryIntegration/_apis/wit/workitems?ids={{ids}}&$expand=Relations
|
|
||||||
Accept: application/json
|
|
||||||
Authorization: Basic {{pat}}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{host}}/tfs/FactoryIntegration/_apis/wit/workitems/{{ids}}/updates
|
|
||||||
Accept: application/json
|
|
||||||
Authorization: Basic {{pat}}
|
|
||||||
|
|
||||||
### Iterations
|
|
||||||
|
|
||||||
GET {{host}}/tfs/FactoryIntegration/ART%20SPS/cea9f426-6fb1-4d65-93d5-dbf471056212/_apis/work/teamsettings/iterations?
|
|
||||||
Accept: application/json
|
|
||||||
Authorization: Basic {{pat}}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
DELETE http://localhost:5004/api/SyncV1/?size=4&ticks=638796666663591762&path=d:\Tmp\phares\VisualStudioCode\z-include-patterns - Copy.nsv
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET http://localhost:5004/api/SyncV1/?size=4&ticks=638796666663591762&path=d:\Tmp\phares\VisualStudioCode\z-include-patterns - Copy.nsv
|
|
66
.vscode/launch.json
vendored
66
.vscode/launch.json
vendored
@ -11,6 +11,60 @@
|
|||||||
"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",
|
||||||
|
"X",
|
||||||
|
"V:/1-Images-A/Images-0b793904",
|
||||||
|
"Day-Helper-2024-12-17",
|
||||||
|
".job.json",
|
||||||
|
"thumbs.db~sync.ffs_db~verify.json~.html",
|
||||||
|
"I:/0-ISO-A",
|
||||||
|
"D:/5-Other-Small/Disk/Snap2HTML/Snap2HTML.exe",
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"V:/Tmp/Phares/Helper-2025-07-20",
|
||||||
|
"Day-Helper-2025-07-20",
|
||||||
|
"871467010009.jpg",
|
||||||
|
"L:/Git/AA/Rename/.vscode/.UserSecrets/secrets.json",
|
||||||
|
"A:/()/638432064000000000.51/1401-08-03_02/2023/X+441981864000000000/871467010009.444090906.jpg.png",
|
||||||
|
"*.png",
|
||||||
|
"D:/{}/DisneyWorld 2019/Magic Kingdom/871467010009.jpg.xmp",
|
||||||
|
"*.xmp",
|
||||||
|
"{}-output",
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/Log",
|
||||||
|
"Day-Helper-2025-07-10",
|
||||||
|
"R*",
|
||||||
|
"EAF_INFO*",
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/JavaScriptObjectNotation",
|
||||||
|
"Day-Helper-2025-07-09",
|
||||||
|
"*.json",
|
||||||
|
"987654321",
|
||||||
|
".agg",
|
||||||
|
"id93,vp93,ProcessState,id154,vp154,SystemState,id78,vp78,LL1State,id83,vp83,LL2State,id176,vp176,TotalWaferCount,id80,vp80,LL1Lotid,id85,vp85,LL2Lotid,id153,vp153,PPSTEPNAME,id221,vp221,LeftDefaultRecipe,id222,vp222,RightDefaultRecipe,id223,vp223,RecipeCompleteMsg",
|
||||||
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/Reactor",
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/PollPath",
|
||||||
|
"Day-Helper-2025-07-01",
|
||||||
|
"*.pdsf",
|
||||||
|
"987654321",
|
||||||
|
"Time",
|
||||||
|
".json",
|
||||||
|
"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",
|
||||||
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/JavaScriptObjectNotation",
|
||||||
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/Markdown",
|
||||||
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/KeyValuePairs",
|
||||||
|
"654321",
|
||||||
|
"s",
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"D:/ProgramData/EC_Characterization_Si/Dummy/DEP08CEPIEPSILON/R55",
|
||||||
|
"Day-Helper-2023-11-30",
|
||||||
|
"yyMMddhhmmssfff",
|
||||||
|
"\"vp154\"",
|
||||||
"s",
|
"s",
|
||||||
"X",
|
"X",
|
||||||
"V:/Tmp/Phares/Pictures/2023 TI2023.6 Fall Samsung",
|
"V:/Tmp/Phares/Pictures/2023 TI2023.6 Fall Samsung",
|
||||||
@ -21,18 +75,6 @@
|
|||||||
"0.259594,0.460161,0.1642,0.279605~0.45477,0.489035,0.195175,0.32383~0.328993,0.446263,0.0379464,0.0459656",
|
"0.259594,0.460161,0.1642,0.279605~0.45477,0.489035,0.195175,0.32383~0.328993,0.446263,0.0379464,0.0459656",
|
||||||
"9",
|
"9",
|
||||||
"x-825511723~x-444522128~831410304",
|
"x-825511723~x-444522128~831410304",
|
||||||
"s",
|
|
||||||
"X",
|
|
||||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\PollPath",
|
|
||||||
"Day-Helper-2025-07-01",
|
|
||||||
"*.pdsf",
|
|
||||||
"654321",
|
|
||||||
"Time",
|
|
||||||
"id12~CenterTemp,id13~CenterSetpt,id15~FrontTemp,id153~PPSTEPNAME,id154~SystemState,id16~FrontSetpt,id172~LVC1Ratio,id173~LVC1Carrier,id176~TotalWaferCount,i-d-1-7-8~TIME,id18~SideTemp,id183~SCRDrive4,id19~SideSetpt,id193~SCRLOAD4,id21~RearTemp,id22~RearSetpt,id221~LeftDefaultRecipe,id222~RightDefaultRecipe,id223~RecipeCompleteMsg,id25~N2H2Setpt,id26~N2H2Flow,id27~HCLSetpt,id28~HCLFlow,id29~HCLHISetpt,id30~HCLHIFlow,id37~NSRCSetpt,id38~NSRCFlow,id39~NDILSetpt,id40~NDILFlow,id41~NINJSetpt,id42~NINJFlow,id57~LVC1Setpt,id58~LVC1Flow,id61~ROTSetpt,id62~ROTSpeed,id78~LL1State,id79~LL1Init,id80~LL1Lotid,id81~LL1WafersIn,id82~LL1WfrCnt,id83~LL2State,id84~LL2Init,id85~LL2Lotid,id86~LL2WafersIn,id87~LL2WfrCnt,id93~ProcessState",
|
|
||||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\Markdown",
|
|
||||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\KeyValuePairs",
|
|
||||||
"\\\\mesfs.infineon.com\\EC_APC\\Production\\Traces\\DEP08CEPIEPSILON\\JavaScriptObjectNotation",
|
|
||||||
"s",
|
|
||||||
"X",
|
"X",
|
||||||
"F:/0-ISO-A",
|
"F:/0-ISO-A",
|
||||||
"Day-Helper-2025-06-28",
|
"Day-Helper-2025-06-28",
|
||||||
|
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
@ -1,4 +1,12 @@
|
|||||||
{
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"*.container": "ini",
|
||||||
|
"*.org": "ini",
|
||||||
|
"*.net": "ini",
|
||||||
|
"*.xmp": "xml",
|
||||||
|
"podman": "ini",
|
||||||
|
"default": "ini"
|
||||||
|
},
|
||||||
"[markdown]": {
|
"[markdown]": {
|
||||||
"editor.wordWrap": "off"
|
"editor.wordWrap": "off"
|
||||||
},
|
},
|
||||||
@ -17,6 +25,7 @@
|
|||||||
"BIRT",
|
"BIRT",
|
||||||
"CHIL",
|
"CHIL",
|
||||||
"DEAT",
|
"DEAT",
|
||||||
|
"digi",
|
||||||
"endianness",
|
"endianness",
|
||||||
"Exif",
|
"Exif",
|
||||||
"FAMC",
|
"FAMC",
|
||||||
@ -32,8 +41,10 @@
|
|||||||
"kanbn",
|
"kanbn",
|
||||||
"Kofax",
|
"Kofax",
|
||||||
"Linc",
|
"Linc",
|
||||||
|
"Makernote",
|
||||||
"mesfs",
|
"mesfs",
|
||||||
"mestsa",
|
"mestsa",
|
||||||
|
"mklink",
|
||||||
"netrm",
|
"netrm",
|
||||||
"NpgSql",
|
"NpgSql",
|
||||||
"NSFX",
|
"NSFX",
|
||||||
|
@ -96,12 +96,15 @@ internal static partial class Helper20241217
|
|||||||
if (record.Job is null || string.IsNullOrEmpty(record.Job.Extension))
|
if (record.Job is null || string.IsNullOrEmpty(record.Job.Extension))
|
||||||
continue;
|
continue;
|
||||||
logger.LogInformation("Searching <{directory}>", record.SourceDirectory);
|
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);
|
files = GetFiles(searchPattern, ignoreFileNames, record);
|
||||||
jobNew = GetJob(searchPattern, ignoreFileNames, record, files);
|
jobNew = GetJob(searchPattern, ignoreFileNames, record, files);
|
||||||
json = JsonSerializer.Serialize(jobNew, JobSourceGenerationContext.Default.Job);
|
json = JsonSerializer.Serialize(jobNew, JobSourceGenerationContext.Default.Job);
|
||||||
areTheyTheSame = GetAreTheyTheSame(logger, searchPattern, ignoreFileNames, record, jobNew);
|
areTheyTheSame = GetAreTheyTheSame(logger, searchPattern, ignoreFileNames, record, jobNew);
|
||||||
|
if (snap2HyperTextMarkupLanguage is not null && System.IO.File.Exists(snap2HyperTextMarkupLanguage))
|
||||||
|
{
|
||||||
|
if (!areTheyTheSame || (areTheyTheSame && !System.IO.File.Exists(record.Snap2HyperTextMarkupLanguage)))
|
||||||
|
WriteSnap2HyperTextMarkupLanguage(logger, snap2HyperTextMarkupLanguage, record);
|
||||||
|
}
|
||||||
if (areTheyTheSame)
|
if (areTheyTheSame)
|
||||||
{
|
{
|
||||||
WriteAllText(record.Path, json);
|
WriteAllText(record.Path, json);
|
||||||
@ -109,10 +112,10 @@ internal static partial class Helper20241217
|
|||||||
}
|
}
|
||||||
fileName = $"{record.DirectoryName}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss-fff}{record.Job.Extension}";
|
fileName = $"{record.DirectoryName}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss-fff}{record.Job.Extension}";
|
||||||
path = Path.Combine(record.DestinationDirectory, fileName);
|
path = Path.Combine(record.DestinationDirectory, fileName);
|
||||||
logger.LogInformation("Writing <{path}> extension", path);
|
logger.LogWarning("Writing <{path}> extension", path);
|
||||||
WritePassedExtension(record, files, record.DirectoryName, path);
|
WritePassedExtension(record, files, record.DirectoryName, path);
|
||||||
logger.LogInformation("Wrote <{path}> extension", path);
|
logger.LogWarning("Wrote <{path}> extension", path);
|
||||||
logger.LogInformation("Moved <{path}> extension", path);
|
logger.LogWarning("Moved <{path}> extension", path);
|
||||||
WriteAllText(record, json, path);
|
WriteAllText(record, json, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,7 +279,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.SourceDirectory, filesCountNew, filesCountOld);
|
logger.LogWarning("<{directory}> file count has changed {filesCountNew} != {filesCountOld}", record.SourceDirectory, filesCountNew, filesCountOld);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -285,7 +288,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.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);
|
logger.LogWarning("<{directory}> file length has changed {filesTotalLengthNew} != {filesTotalLengthOld}", record.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -301,7 +304,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.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);
|
logger.LogWarning("<{directory}> file serialized are different {filesTotalLengthNew} != {filesTotalLengthOld}", record.SourceDirectory, filesTotalLengthNew, filesTotalLengthOld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ dotnet_diagnostic.CA2211.severity = none # Question - Non-constant fields should
|
|||||||
dotnet_diagnostic.CA2249.severity = none # Question - Use
|
dotnet_diagnostic.CA2249.severity = none # Question - Use
|
||||||
dotnet_diagnostic.CA2253.severity = none # Question - Named placeholders should not be numeric values
|
dotnet_diagnostic.CA2253.severity = none # Question - Named placeholders should not be numeric values
|
||||||
dotnet_diagnostic.CS0103.severity = none # Question - The name
|
dotnet_diagnostic.CS0103.severity = none # Question - The name
|
||||||
dotnet_diagnostic.CS0168.severity = none # Question - The variable
|
dotnet_diagnostic.CS0168.severity = warning # Question - The variable
|
||||||
dotnet_diagnostic.CS0219.severity = none # Question - The variable
|
dotnet_diagnostic.CS0219.severity = none # Question - The variable
|
||||||
dotnet_diagnostic.CS0612.severity = none # Question - is obsolete
|
dotnet_diagnostic.CS0612.severity = none # Question - is obsolete
|
||||||
dotnet_diagnostic.CS0618.severity = none # Question - Compiler Warning (level 2)
|
dotnet_diagnostic.CS0618.severity = none # Question - Compiler Warning (level 2)
|
||||||
@ -337,7 +337,7 @@ dotnet_diagnostic.CS8603.severity = none # Question - Possible null reference re
|
|||||||
dotnet_diagnostic.CS8604.severity = none # Question - Possible null reference argument for parameter.
|
dotnet_diagnostic.CS8604.severity = none # Question - Possible null reference argument for parameter.
|
||||||
dotnet_diagnostic.CS8618.severity = none # Question - Non-nullable variable must contain a non-null value when exiting constructor
|
dotnet_diagnostic.CS8618.severity = none # Question - Non-nullable variable must contain a non-null value when exiting constructor
|
||||||
dotnet_diagnostic.CS8625.severity = none # Question - Cannot convert null literal to non-nullable reference type.
|
dotnet_diagnostic.CS8625.severity = none # Question - Cannot convert null literal to non-nullable reference type.
|
||||||
dotnet_diagnostic.CS8629.severity = none # Question - Nullable value type may be null
|
dotnet_diagnostic.CS8629.severity = warning # Question - Nullable value type may be null
|
||||||
dotnet_diagnostic.CS8765.severity = none # Question - Nullability of type of parameter
|
dotnet_diagnostic.CS8765.severity = none # Question - Nullability of type of parameter
|
||||||
dotnet_diagnostic.IDE0005.severity = none # Question - Remove unnecessary using directives
|
dotnet_diagnostic.IDE0005.severity = none # Question - Remove unnecessary using directives
|
||||||
dotnet_diagnostic.IDE0008.severity = warning # Question - Use explicit type instead of
|
dotnet_diagnostic.IDE0008.severity = warning # Question - Use explicit type instead of
|
||||||
@ -361,7 +361,7 @@ dotnet_diagnostic.IDE0055.severity = none # Question - Formatting rule
|
|||||||
dotnet_diagnostic.IDE0057.severity = none # Question - Substring can be simplified
|
dotnet_diagnostic.IDE0057.severity = none # Question - Substring can be simplified
|
||||||
dotnet_diagnostic.IDE0058.severity = none # Question - Remove unnecessary expression value
|
dotnet_diagnostic.IDE0058.severity = none # Question - Remove unnecessary expression value
|
||||||
dotnet_diagnostic.IDE0059.severity = none # Question - Unnecessary assignment of a value to
|
dotnet_diagnostic.IDE0059.severity = none # Question - Unnecessary assignment of a value to
|
||||||
dotnet_diagnostic.IDE0060.severity = none # Question - Remove unused parameter
|
dotnet_diagnostic.IDE0060.severity = warning # Question - Remove unused parameter
|
||||||
dotnet_diagnostic.IDE0063.severity = none # Question - Use simple
|
dotnet_diagnostic.IDE0063.severity = none # Question - Use simple
|
||||||
dotnet_diagnostic.IDE0065.severity = none # Question -
|
dotnet_diagnostic.IDE0065.severity = none # Question -
|
||||||
dotnet_diagnostic.IDE0066.severity = none # Question - Use
|
dotnet_diagnostic.IDE0066.severity = none # Question - Use
|
||||||
|
@ -50,7 +50,12 @@ internal static partial class Helper20250521 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal static void MatchDirectory(ILogger<Worker> logger, List<string> args) {
|
internal static void MatchDirectory(ILogger<Worker> logger, List<string> args) {
|
||||||
Record record;
|
logger.LogInformation(args[0]);
|
||||||
|
logger.LogInformation(args[1]);
|
||||||
|
logger.LogInformation(args[2]);
|
||||||
|
logger.LogInformation(args[3]);
|
||||||
|
logger.LogInformation(args[4]);
|
||||||
|
logger.LogInformation(args[5]);
|
||||||
string datePattern = args[5];
|
string datePattern = args[5];
|
||||||
string searchPattern = args[2];
|
string searchPattern = args[2];
|
||||||
string searchPatternB = args[3];
|
string searchPatternB = args[3];
|
||||||
@ -119,7 +124,6 @@ internal static partial class Helper20250521 {
|
|||||||
private static RecordB? GetRecord(int dateLineSegmentCount, string datePattern, string[] lines, int i, string[] segments, DateTime transactionDate, DateTime effectiveDate) {
|
private static RecordB? GetRecord(int dateLineSegmentCount, string datePattern, string[] lines, int i, string[] segments, DateTime transactionDate, DateTime effectiveDate) {
|
||||||
RecordB? result = null;
|
RecordB? result = null;
|
||||||
string line;
|
string line;
|
||||||
RecordB record;
|
|
||||||
LineCheck lineCheck;
|
LineCheck lineCheck;
|
||||||
List<string> collection = [];
|
List<string> collection = [];
|
||||||
for (int j = i + 1; j < lines.Length; j++) {
|
for (int j = i + 1; j < lines.Length; j++) {
|
||||||
|
@ -36,7 +36,6 @@ internal static partial class Helper20250601 {
|
|||||||
internal static void EquipmentAutomationFrameworkStatus(ILogger<Worker> logger, List<string> args) {
|
internal static void EquipmentAutomationFrameworkStatus(ILogger<Worker> logger, List<string> args) {
|
||||||
Status status;
|
Status status;
|
||||||
Record? record;
|
Record? record;
|
||||||
List<string[]> messages;
|
|
||||||
logger.LogInformation(args[0]);
|
logger.LogInformation(args[0]);
|
||||||
logger.LogInformation(args[1]);
|
logger.LogInformation(args[1]);
|
||||||
logger.LogInformation(args[2]);
|
logger.LogInformation(args[2]);
|
||||||
|
@ -26,7 +26,6 @@ internal static partial class Helper20250628 {
|
|||||||
private static ReadOnlyCollection<Record> GetRecords(string[] searchPatternFiles) {
|
private static ReadOnlyCollection<Record> GetRecords(string[] searchPatternFiles) {
|
||||||
List<Record> results = [];
|
List<Record> results = [];
|
||||||
Record record;
|
Record record;
|
||||||
string[] files;
|
|
||||||
FileInfo fileInfo;
|
FileInfo fileInfo;
|
||||||
foreach (string searchPatternFile in searchPatternFiles) {
|
foreach (string searchPatternFile in searchPatternFiles) {
|
||||||
fileInfo = new(searchPatternFile);
|
fileInfo = new(searchPatternFile);
|
||||||
|
@ -14,6 +14,11 @@ internal static partial class Helper20250701 {
|
|||||||
internal partial class JsonElementSourceGenerationContext : JsonSerializerContext {
|
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) {
|
internal static void ProcessDataStandardFormatTo(ILogger<Worker> logger, List<string> args) {
|
||||||
logger.LogInformation(args[0]);
|
logger.LogInformation(args[0]);
|
||||||
logger.LogInformation(args[1]);
|
logger.LogInformation(args[1]);
|
||||||
@ -22,36 +27,38 @@ internal static partial class Helper20250701 {
|
|||||||
logger.LogInformation(args[4]);
|
logger.LogInformation(args[4]);
|
||||||
logger.LogInformation(args[5]);
|
logger.LogInformation(args[5]);
|
||||||
logger.LogInformation(args[6]);
|
logger.LogInformation(args[6]);
|
||||||
|
logger.LogInformation(args[7]);
|
||||||
string[] segments;
|
string[] segments;
|
||||||
|
string extension = args[5];
|
||||||
string timeColumn = args[4];
|
string timeColumn = args[4];
|
||||||
string searchPattern = args[2];
|
string searchPattern = args[2];
|
||||||
int sizeFilter = int.Parse(args[3]);
|
int sizeFilter = int.Parse(args[3]);
|
||||||
string[] columns = args[5].Split(',');
|
string[] columns = args[6].Split(',');
|
||||||
Dictionary<string, string> columnMapping = [];
|
Dictionary<string, string> columnMapping = [];
|
||||||
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||||
string destinationDirectory = Path.GetFullPath(args[6].Split('~')[0]);
|
string destinationDirectory = Path.GetFullPath(args[7].Split('~')[0]);
|
||||||
foreach (string column in columns) {
|
foreach (string column in columns) {
|
||||||
segments = column.Split('~');
|
segments = column.Split('~');
|
||||||
columnMapping.Add(segments[0], segments[1]);
|
columnMapping.Add(segments[0], segments[1]);
|
||||||
}
|
}
|
||||||
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
|
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
ProcessDataStandardFormatTo(logger, sourceDirectory, searchPattern, sizeFilter, timeColumn, columnMapping, destinationDirectory, directories);
|
ProcessDataStandardFormatTo(logger, sourceDirectory, searchPattern, sizeFilter, timeColumn, extension, columnMapping.AsReadOnly(), destinationDirectory, directories.AsReadOnly());
|
||||||
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
|
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessDataStandardFormatTo(ILogger<Worker> logger, string sourceDirectory, string searchPattern, int sizeFilter, string timeColumn, Dictionary<string, string> columnMapping, string destinationDirectory, string[] directories) {
|
private static void ProcessDataStandardFormatTo(ILogger<Worker> logger, string sourceDirectory, string searchPattern, int sizeFilter, string timeColumn, string extension, ReadOnlyDictionary<string, string> columnMapping, string destinationDirectory, ReadOnlyCollection<string> directories) {
|
||||||
|
string text;
|
||||||
string? json;
|
string? json;
|
||||||
string[] files;
|
string[] files;
|
||||||
string markdown;
|
string markdown;
|
||||||
string checkFile;
|
string checkFile;
|
||||||
string[] matches;
|
|
||||||
FileInfo fileInfo;
|
FileInfo fileInfo;
|
||||||
string? pipeTable;
|
string? pipeTable;
|
||||||
string? collections;
|
string? collections;
|
||||||
string directoryName;
|
string directoryName;
|
||||||
string checkDirectory;
|
string checkDirectory;
|
||||||
foreach (string directory in directories) {
|
foreach (string directory in directories) {
|
||||||
if (Path.GetFileName(directory).Contains('-')) {
|
if (sizeFilter < 987654321 && Path.GetFileName(directory).Contains('-')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||||
@ -77,41 +84,49 @@ internal static partial class Helper20250701 {
|
|||||||
if (!Directory.Exists(checkDirectory)) {
|
if (!Directory.Exists(checkDirectory)) {
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
}
|
}
|
||||||
checkFile = Path.Combine(checkDirectory, $"{fileInfo.Name}.md");
|
checkFile = Path.Combine(checkDirectory, $"{fileInfo.Name}{extension}");
|
||||||
if (File.Exists(checkFile)) {
|
if (File.Exists(checkFile)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
collections = GetMarkdown(logger, timeColumn, columnMapping, file, fileInfo.Name);
|
if (extension == ".md") {
|
||||||
if (string.IsNullOrEmpty(collections)) {
|
collections = GetMarkdown(logger, timeColumn, columnMapping, file, fileInfo.Name);
|
||||||
logger.LogWarning("collections is null");
|
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(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;
|
continue;
|
||||||
}
|
}
|
||||||
File.WriteAllText(checkFile, collections);
|
File.WriteAllText(checkFile, text);
|
||||||
File.SetLastWriteTime(checkFile, fileInfo.LastAccessTime);
|
File.SetLastWriteTime(checkFile, fileInfo.LastWriteTime);
|
||||||
if (!string.IsNullOrEmpty(destinationDirectory)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
json = GetJavaScriptObjectNotation(logger, file);
|
|
||||||
if (string.IsNullOrEmpty(json)) {
|
|
||||||
logger.LogWarning("json is null");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
File.WriteAllText($"{checkFile}.md", json);
|
|
||||||
File.SetLastWriteTime($"{checkFile}.md", fileInfo.LastAccessTime);
|
|
||||||
pipeTable = GetPipeTable(logger, json);
|
|
||||||
if (string.IsNullOrEmpty(pipeTable)) {
|
|
||||||
logger.LogWarning("pipeTable is null");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
markdown = $"# {fileInfo.Name}{Environment.NewLine}{Environment.NewLine}{pipeTable}{Environment.NewLine}";
|
|
||||||
File.WriteAllText($"{checkFile}.md", markdown);
|
|
||||||
File.SetLastWriteTime($"{checkFile}.md", fileInfo.LastAccessTime);
|
|
||||||
logger.LogInformation("<{checkFile}> was written", checkFile);
|
logger.LogInformation("<{checkFile}> was written", checkFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string? GetMarkdown(ILogger<Worker> logger, string timeColumn, Dictionary<string, string> columnMapping, string file, string name) {
|
private static string? GetMarkdown(ILogger<Worker> logger, string timeColumn, ReadOnlyDictionary<string, string> columnMapping, string file, string name) {
|
||||||
string? result = null;
|
string? result = null;
|
||||||
string[] lines = File.ReadAllLines(file);
|
string[] lines = File.ReadAllLines(file);
|
||||||
int? columnTitlesLine = GetProcessDataStandardFormatColumnTitlesLine(lines);
|
int? columnTitlesLine = GetProcessDataStandardFormatColumnTitlesLine(lines);
|
||||||
@ -121,7 +136,7 @@ internal static partial class Helper20250701 {
|
|||||||
if (lines.Length < columnTitlesLine.Value + 1) {
|
if (lines.Length < columnTitlesLine.Value + 1) {
|
||||||
logger.LogWarning("<{lines}>(s)", lines.Length);
|
logger.LogWarning("<{lines}>(s)", lines.Length);
|
||||||
} else {
|
} else {
|
||||||
result = GetMarkdown(timeColumn, columnMapping, name, lines, columnTitlesLine);
|
result = GetMarkdown(timeColumn, columnMapping, name, lines, columnTitlesLine.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -140,7 +155,6 @@ internal static partial class Helper20250701 {
|
|||||||
|
|
||||||
private static ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetKeyValuePairs(int columnTitlesLine, string[] lines) {
|
private static ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetKeyValuePairs(int columnTitlesLine, string[] lines) {
|
||||||
Dictionary<string, ReadOnlyCollection<string>> results = [];
|
Dictionary<string, ReadOnlyCollection<string>> results = [];
|
||||||
string value;
|
|
||||||
string[] segments;
|
string[] segments;
|
||||||
List<List<string>> collections = [];
|
List<List<string>> collections = [];
|
||||||
string[] columns = lines[columnTitlesLine].Split('\t');
|
string[] columns = lines[columnTitlesLine].Split('\t');
|
||||||
@ -173,11 +187,11 @@ internal static partial class Helper20250701 {
|
|||||||
return results.AsReadOnly();
|
return results.AsReadOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string? GetMarkdown(string timeColumn, Dictionary<string, string> columnMapping, string name, string[] lines, int? columnTitlesLine) {
|
private static string? GetMarkdown(string timeColumn, ReadOnlyDictionary<string, string> columnMapping, string name, string[] lines, int columnTitlesLine) {
|
||||||
string? result;
|
string? result;
|
||||||
List<string> charts = [];
|
List<string> charts = [];
|
||||||
List<string> results = [];
|
List<string> results = [];
|
||||||
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs = GetKeyValuePairs(columnTitlesLine.Value, lines);
|
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs = GetKeyValuePairs(columnTitlesLine, lines);
|
||||||
string[] columns = keyValuePairs.Keys.OrderBy(l => l).ToArray();
|
string[] columns = keyValuePairs.Keys.OrderBy(l => l).ToArray();
|
||||||
if (!columns.Contains(timeColumn)) {
|
if (!columns.Contains(timeColumn)) {
|
||||||
result = null;
|
result = null;
|
||||||
@ -211,10 +225,9 @@ internal static partial class Helper20250701 {
|
|||||||
if (results.Count == 0 && charts.Count == 0) {
|
if (results.Count == 0 && charts.Count == 0) {
|
||||||
result = null;
|
result = null;
|
||||||
} else {
|
} else {
|
||||||
string[] segments;
|
|
||||||
results.Add($"## Footer{Environment.NewLine}");
|
results.Add($"## Footer{Environment.NewLine}");
|
||||||
results.Insert(0, $"# {name}{Environment.NewLine}");
|
results.Insert(0, $"# {name}{Environment.NewLine}");
|
||||||
for (int i = columnTitlesLine.Value + 1; i < lines.Length; i++) {
|
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
|
||||||
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
||||||
for (int j = i; j < lines.Length; j++) {
|
for (int j = i; j < lines.Length; j++) {
|
||||||
results.Add($"- {lines[j]}");
|
results.Add($"- {lines[j]}");
|
||||||
@ -239,43 +252,140 @@ internal static partial class Helper20250701 {
|
|||||||
if (lines.Length < columnTitlesLine.Value + 1) {
|
if (lines.Length < columnTitlesLine.Value + 1) {
|
||||||
logger.LogWarning("<{lines}>(s)", lines.Length);
|
logger.LogWarning("<{lines}>(s)", lines.Length);
|
||||||
} else {
|
} else {
|
||||||
result = GetJavaScriptObjectNotation(columnTitlesLine.Value, [], lines);
|
result = GetJavaScriptObjectNotation(columnTitlesLine.Value, lines);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetJavaScriptObjectNotation(int columnTitlesLine, string[] columns, string[] lines) {
|
private static string GetJavaScriptObjectNotation(int columnTitlesLine, string[] lines) {
|
||||||
#pragma warning disable CA1845, IDE0057
|
#pragma warning disable CA1845, IDE0057
|
||||||
string result = "[\n";
|
string result;
|
||||||
string line;
|
string record;
|
||||||
string value;
|
string value;
|
||||||
string[] segments;
|
string[] segments;
|
||||||
if (columns.Length == 0) {
|
string? json = null;
|
||||||
columns = lines[columnTitlesLine].Split('\t');
|
List<string> records = [];
|
||||||
}
|
ReadOnlyCollection<string>? footerLines = null;
|
||||||
|
string[] columns = lines[columnTitlesLine].Split('\t');
|
||||||
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
|
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
|
||||||
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
|
||||||
|
footerLines = GetFooterLines(lines, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
line = "{";
|
record = "{";
|
||||||
segments = lines[i].Split('\t');
|
segments = lines[i].Split('\t');
|
||||||
if (segments.Length > columns.Length) {
|
if (segments.Length > columns.Length) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
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("\"", "\\\"");
|
||||||
line += '"' + columns[c].Trim('"') + '"' + ':' + '"' + value + '"' + ',';
|
record += string.Concat('"', columns[c].Trim('"'), '"', ':', '"', value, '"', ',');
|
||||||
}
|
}
|
||||||
line = line.Substring(0, line.Length - 1) + '}' + ',' + '\n';
|
record = string.Concat(record.Substring(0, record.Length - 1), '}');
|
||||||
result += line;
|
records.Add(record);
|
||||||
}
|
}
|
||||||
result = result.Substring(0, result.Length - 2) + ']';
|
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}\"ProcessDataStandardFormat\":{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;
|
return result;
|
||||||
#pragma warning restore CA1845, IDE0057
|
#pragma warning restore CA1845, IDE0057
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string? GetPipeTable(ILogger<Worker> logger, string json) {
|
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(string json) {
|
||||||
string? result = null;
|
string? result = null;
|
||||||
string? value;
|
string? value;
|
||||||
string[]? columns = null;
|
string[]? columns = null;
|
||||||
@ -310,4 +420,5 @@ internal static partial class Helper20250701 {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@ -94,19 +93,23 @@ internal static partial class Helper20250705 {
|
|||||||
height: rectangleFHeight,
|
height: rectangleFHeight,
|
||||||
left: rectangleFLeft,
|
left: rectangleFLeft,
|
||||||
top: rectangleFTop,
|
top: rectangleFTop,
|
||||||
suffix: $"-{i}whole-percentages.jpg");
|
suffix: $"-{i}-whole-percentages.jpg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Extract(string file, float width, float height, double left, double top, string suffix) {
|
private static void Extract(string file, float width, float height, double left, double top, string suffix) {
|
||||||
|
#if SystemDrawingCommon
|
||||||
RectangleF rectangle = new((float)left, (float)top, width, height);
|
RectangleF rectangle = new((float)left, (float)top, width, height);
|
||||||
using (Bitmap source = new(file)) {
|
using (Bitmap source = new(file)) {
|
||||||
using (Bitmap bitmap = new((int)width, (int)height)) {
|
using (Bitmap bitmap = new((int)width, (int)height)) {
|
||||||
using (Graphics graphics = Graphics.FromImage(bitmap))
|
using (Graphics graphics = Graphics.FromImage(bitmap)) {
|
||||||
graphics.DrawImage(source, new RectangleF(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
graphics.DrawImage(source, new RectangleF(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||||
|
}
|
||||||
bitmap.Save($"{file}{suffix}");
|
bitmap.Save($"{file}{suffix}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
232
ADO2025/PI6/Helper-2025-07-09.cs
Normal file
232
ADO2025/PI6/Helper-2025-07-09.cs
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
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 Helper20250709 {
|
||||||
|
|
||||||
|
// [JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
|
// [JsonSerializable(typeof(JsonElement[]))]
|
||||||
|
// internal partial class Helper20250709JsonElementSourceGenerationContext : JsonSerializerContext {
|
||||||
|
// }
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
|
[JsonSerializable(typeof(Raw))]
|
||||||
|
private partial class RawSourceGenerationContext : JsonSerializerContext {
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Raw(int Count, JsonElement[] Records);
|
||||||
|
|
||||||
|
// cspell::disable
|
||||||
|
private record Reactor([property: JsonPropertyName("id12")] double? Id12,
|
||||||
|
[property: JsonPropertyName("id13")] double? Id13,
|
||||||
|
[property: JsonPropertyName("id15")] double? Id15,
|
||||||
|
[property: JsonPropertyName("id153")] string? Id153,
|
||||||
|
[property: JsonPropertyName("id154")] long? Id154,
|
||||||
|
[property: JsonPropertyName("id16")] double? Id16,
|
||||||
|
[property: JsonPropertyName("id172")] double? Id172,
|
||||||
|
[property: JsonPropertyName("id173")] double? Id173,
|
||||||
|
[property: JsonPropertyName("id176")] double? Id176,
|
||||||
|
[property: JsonPropertyName("id178")] string? Id178,
|
||||||
|
[property: JsonPropertyName("id18")] double? Id18,
|
||||||
|
[property: JsonPropertyName("id183")] double? Id183,
|
||||||
|
[property: JsonPropertyName("id19")] double? Id19,
|
||||||
|
[property: JsonPropertyName("id193")] double? Id193,
|
||||||
|
[property: JsonPropertyName("id21")] double? Id21,
|
||||||
|
[property: JsonPropertyName("id22")] double? Id22,
|
||||||
|
[property: JsonPropertyName("id221")] string? Id221,
|
||||||
|
[property: JsonPropertyName("id222")] string? Id222,
|
||||||
|
[property: JsonPropertyName("id223")] string? Id223,
|
||||||
|
[property: JsonPropertyName("id25")] double? Id25,
|
||||||
|
[property: JsonPropertyName("id26")] double? Id26,
|
||||||
|
[property: JsonPropertyName("id27")] double? Id27,
|
||||||
|
[property: JsonPropertyName("id28")] double? Id28,
|
||||||
|
[property: JsonPropertyName("id29")] double? Id29,
|
||||||
|
[property: JsonPropertyName("id30")] double? Id30,
|
||||||
|
[property: JsonPropertyName("id37")] double? Id37,
|
||||||
|
[property: JsonPropertyName("id38")] double? Id38,
|
||||||
|
[property: JsonPropertyName("id39")] double? Id39,
|
||||||
|
[property: JsonPropertyName("id40")] double? Id40,
|
||||||
|
[property: JsonPropertyName("id41")] double? Id41,
|
||||||
|
[property: JsonPropertyName("id42")] double? Id42,
|
||||||
|
[property: JsonPropertyName("id57")] double? Id57,
|
||||||
|
[property: JsonPropertyName("id58")] double? Id58,
|
||||||
|
[property: JsonPropertyName("id61")] double? Id61,
|
||||||
|
[property: JsonPropertyName("id62")] double? Id62,
|
||||||
|
[property: JsonPropertyName("id78")] long? Id78,
|
||||||
|
[property: JsonPropertyName("id79")] long? Id79,
|
||||||
|
[property: JsonPropertyName("id80")] string? Id80,
|
||||||
|
[property: JsonPropertyName("id81")] long? Id81,
|
||||||
|
[property: JsonPropertyName("id82")] long? Id82,
|
||||||
|
[property: JsonPropertyName("id83")] long? Id83,
|
||||||
|
[property: JsonPropertyName("id84")] long? Id84,
|
||||||
|
[property: JsonPropertyName("id85")] string? Id85,
|
||||||
|
[property: JsonPropertyName("id86")] long? Id86,
|
||||||
|
[property: JsonPropertyName("id87")] long? Id87,
|
||||||
|
[property: JsonPropertyName("id93")] long? Id93,
|
||||||
|
[property: JsonPropertyName("vp93")] long? Vp93,
|
||||||
|
[property: JsonPropertyName("vp154")] long? Vp154,
|
||||||
|
[property: JsonPropertyName("vp78")] long? Vp78,
|
||||||
|
[property: JsonPropertyName("vp83")] long? Vp83,
|
||||||
|
[property: JsonPropertyName("vp176")] double? Vp176,
|
||||||
|
[property: JsonPropertyName("vp80")] string? Vp80,
|
||||||
|
[property: JsonPropertyName("vp85")] string? Vp85,
|
||||||
|
[property: JsonPropertyName("vp153")] string? Vp153,
|
||||||
|
[property: JsonPropertyName("vp221")] string? Vp221,
|
||||||
|
[property: JsonPropertyName("vp222")] string? Vp222,
|
||||||
|
[property: JsonPropertyName("vp223")] string? Vp223,
|
||||||
|
[property: JsonPropertyName("YYYYMMDDhhmmsscc")] string? YYYYMMDDhhmmsscc,
|
||||||
|
[property: JsonPropertyName("CenterTemp")] double? CenterTemp,
|
||||||
|
[property: JsonPropertyName("CenterSetpt")] double? CenterSetpt,
|
||||||
|
[property: JsonPropertyName("FrontTemp")] double? FrontTemp,
|
||||||
|
[property: JsonPropertyName("PPSTEPNAME")] string? PPSTEPNAME,
|
||||||
|
[property: JsonPropertyName("SystemState")] long? SystemState,
|
||||||
|
[property: JsonPropertyName("FrontSetpt")] double? FrontSetpt,
|
||||||
|
[property: JsonPropertyName("LVC1Ratio")] double? LVC1Ratio,
|
||||||
|
[property: JsonPropertyName("LVC1Carrier")] double? LVC1Carrier,
|
||||||
|
[property: JsonPropertyName("TotalWaferCount")] double? TotalWaferCount,
|
||||||
|
[property: JsonPropertyName("TIME")] string? TIME,
|
||||||
|
[property: JsonPropertyName("SideTemp")] double? SideTemp,
|
||||||
|
[property: JsonPropertyName("SCRDrive4")] double? SCRDrive4,
|
||||||
|
[property: JsonPropertyName("SideSetpt")] double? SideSetpt,
|
||||||
|
[property: JsonPropertyName("SCRLOAD4")] double? SCRLOAD4,
|
||||||
|
[property: JsonPropertyName("RearTemp")] double? RearTemp,
|
||||||
|
[property: JsonPropertyName("RearSetpt")] double? RearSetpt,
|
||||||
|
[property: JsonPropertyName("LeftDefaultRecipe")] string? LeftDefaultRecipe,
|
||||||
|
[property: JsonPropertyName("RightDefaultRecipe")] string? RightDefaultRecipe,
|
||||||
|
[property: JsonPropertyName("RecipeCompleteMsg")] string? RecipeCompleteMsg,
|
||||||
|
[property: JsonPropertyName("N2H2Setpt")] double? N2H2Setpt,
|
||||||
|
[property: JsonPropertyName("N2H2Flow")] double? N2H2Flow,
|
||||||
|
[property: JsonPropertyName("HCLSetpt")] double? HCLSetpt,
|
||||||
|
[property: JsonPropertyName("HCLFlow")] double? HCLFlow,
|
||||||
|
[property: JsonPropertyName("HCLHISetpt")] double? HCLHISetpt,
|
||||||
|
[property: JsonPropertyName("HCLHIFlow")] double? HCLHIFlow,
|
||||||
|
[property: JsonPropertyName("NSRCSetpt")] double? NSRCSetpt,
|
||||||
|
[property: JsonPropertyName("NSRCFlow")] double? NSRCFlow,
|
||||||
|
[property: JsonPropertyName("NDILSetpt")] double? NDILSetpt,
|
||||||
|
[property: JsonPropertyName("NDILFlow")] double? NDILFlow,
|
||||||
|
[property: JsonPropertyName("NINJSetpt")] double? NINJSetpt,
|
||||||
|
[property: JsonPropertyName("NINJFlow")] double? NINJFlow,
|
||||||
|
[property: JsonPropertyName("LVC1Setpt")] double? LVC1Setpt,
|
||||||
|
[property: JsonPropertyName("LVC1Flow")] double? LVC1Flow,
|
||||||
|
[property: JsonPropertyName("ROTSetpt")] double? ROTSetpt,
|
||||||
|
[property: JsonPropertyName("ROTSpeed")] double? ROTSpeed,
|
||||||
|
[property: JsonPropertyName("LL1State")] long? LL1State,
|
||||||
|
[property: JsonPropertyName("LL1Init")] long? LL1Init,
|
||||||
|
[property: JsonPropertyName("LL1Lotid")] string? LL1Lotid,
|
||||||
|
[property: JsonPropertyName("LL1WafersIn")] long? LL1WafersIn,
|
||||||
|
[property: JsonPropertyName("LL1WfrCnt")] long? LL1WfrCnt,
|
||||||
|
[property: JsonPropertyName("LL2State")] long? LL2State,
|
||||||
|
[property: JsonPropertyName("LL2Init")] long? LL2Init,
|
||||||
|
[property: JsonPropertyName("LL2Lotid")] string? LL2Lotid,
|
||||||
|
[property: JsonPropertyName("LL2WafersIn")] long? LL2WafersIn,
|
||||||
|
[property: JsonPropertyName("LL2WfrCnt")] long? LL2WfrCnt,
|
||||||
|
[property: JsonPropertyName("ProcessState")] long? ProcessState);
|
||||||
|
// [property: JsonPropertyName("A_BASIC_TYPE")] string? ABasicType,
|
||||||
|
// [property: JsonPropertyName("A_INFO")] string? AInfo,
|
||||||
|
// [property: JsonPropertyName("A_INFO2")] string? AInfo2,
|
||||||
|
// [property: JsonPropertyName("A_JOBID")] string? AJobid,
|
||||||
|
// [property: JsonPropertyName("A_LAYER")] string? ALayer,
|
||||||
|
// [property: JsonPropertyName("A_LAYER2")] string? ALayer2,
|
||||||
|
// [property: JsonPropertyName("A_MES_ENTITY")] string? AMesEntity,
|
||||||
|
// [property: JsonPropertyName("A_MID")] string? AMID,
|
||||||
|
// [property: JsonPropertyName("A_NULL_DATA")] string? ANullData,
|
||||||
|
// [property: JsonPropertyName("A_PPID")] string? APPID,
|
||||||
|
// [property: JsonPropertyName("A_PROCESS_JOBID")] string? AProcessJobid,
|
||||||
|
// [property: JsonPropertyName("A_PRODUCT")] string? AProduct,
|
||||||
|
// [property: JsonPropertyName("A_SEQUENCE")] string? ASequence,
|
||||||
|
// [property: JsonPropertyName("A_WAFER_ID")] string? AWaferId,
|
||||||
|
// [property: JsonPropertyName("A_WAFER_POS")] string? AWaferPos
|
||||||
|
// cspell::enable,
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, NumberHandling = JsonNumberHandling.AllowReadingFromString)]
|
||||||
|
[JsonSerializable(typeof(Reactor))]
|
||||||
|
private partial class ReactorSourceGenerationContext : JsonSerializerContext {
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void JavaScriptObjectNotationToReactor(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]);
|
||||||
|
string extension = args[4];
|
||||||
|
string searchPattern = args[2];
|
||||||
|
int sizeFilter = int.Parse(args[3]);
|
||||||
|
string[] columns = args[5].Split(',');
|
||||||
|
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||||
|
string destinationDirectory = Path.GetFullPath(args[6].Split('~')[0]);
|
||||||
|
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
JavaScriptObjectNotationTo(sourceDirectory, searchPattern, sizeFilter, extension, destinationDirectory, directories.AsReadOnly());
|
||||||
|
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void JavaScriptObjectNotationTo(string sourceDirectory, string searchPattern, int sizeFilter, string extension, string destinationDirectory, ReadOnlyCollection<string> directories) {
|
||||||
|
Raw? raw;
|
||||||
|
string json;
|
||||||
|
string[] files;
|
||||||
|
string checkFile;
|
||||||
|
Reactor? reactor;
|
||||||
|
FileInfo fileInfo;
|
||||||
|
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 == ".agg") {
|
||||||
|
json = File.ReadAllText(fileInfo.FullName);
|
||||||
|
raw = JsonSerializer.Deserialize(json, RawSourceGenerationContext.Default.Raw);
|
||||||
|
if (raw is null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach (JsonElement jsonElement in raw.Records) {
|
||||||
|
try {
|
||||||
|
reactor = JsonSerializer.Deserialize(jsonElement.ToString().Replace("\"\"", "null"), ReactorSourceGenerationContext.Default.Reactor);
|
||||||
|
} catch (Exception) {
|
||||||
|
reactor = null;
|
||||||
|
}
|
||||||
|
if (reactor is null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (reactor is null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
95
ADO2025/PI6/Helper-2025-07-10.cs
Normal file
95
ADO2025/PI6/Helper-2025-07-10.cs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.ADO2025.PI6;
|
||||||
|
|
||||||
|
internal static partial class Helper20250710 {
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^(?<stream>S[0-9]{1,2})(?<function>F[0-9]{1,2}) W-Bit=(?<wait>[01])")]
|
||||||
|
private static partial Regex StreamFunction();
|
||||||
|
|
||||||
|
internal static void StripLog(ILogger<Worker> logger, List<string> args) {
|
||||||
|
logger.LogInformation(args[0]);
|
||||||
|
logger.LogInformation(args[1]);
|
||||||
|
logger.LogInformation(args[2]);
|
||||||
|
logger.LogInformation(args[3]);
|
||||||
|
string searchPattern = args[3];
|
||||||
|
string directoryPattern = args[2];
|
||||||
|
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||||
|
string[] directories = Directory.GetDirectories(sourceDirectory, directoryPattern, SearchOption.TopDirectoryOnly);
|
||||||
|
LogToTrace(logger, searchPattern, directories.AsReadOnly());
|
||||||
|
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LogToTrace(ILogger<Worker> logger, string searchPattern, ReadOnlyCollection<string> directories) {
|
||||||
|
string[] lines;
|
||||||
|
string[] files;
|
||||||
|
string checkFile;
|
||||||
|
FileInfo fileInfo;
|
||||||
|
string directoryName;
|
||||||
|
const string extension = ".trc";
|
||||||
|
foreach (string directory in directories) {
|
||||||
|
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (string file in files) {
|
||||||
|
fileInfo = new(file);
|
||||||
|
if (fileInfo.LastWriteTime > DateTime.Now.AddSeconds(-5)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
directoryName = Path.GetFileName(fileInfo.DirectoryName);
|
||||||
|
checkFile = Path.Combine(directoryName, $"{fileInfo.Name}{extension}");
|
||||||
|
if (File.Exists(checkFile)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lines = File.ReadAllLines(fileInfo.FullName);
|
||||||
|
LogToTrace(logger, fileInfo, lines, checkFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LogToTrace(ILogger<Worker> logger, FileInfo fileInfo, string[] lines, string checkFile) {
|
||||||
|
string line;
|
||||||
|
Match match;
|
||||||
|
string body;
|
||||||
|
string[] segments;
|
||||||
|
List<string> log = [];
|
||||||
|
for (int i = 1; i < lines.Length - 1; i++) {
|
||||||
|
line = lines[i];
|
||||||
|
if (!line.StartsWith('S')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
match = StreamFunction().Match(line);
|
||||||
|
if (!match.Success) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
segments = lines[i - 1].Split(" ");
|
||||||
|
if (segments.Length < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!segments[0].Contains(' ')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
body = GetBody(lines, i, segments[0].Split(' '));
|
||||||
|
log.Add($"{segments[0]} {line} ~ {body}");
|
||||||
|
}
|
||||||
|
if (log.Count > 0) {
|
||||||
|
File.WriteAllText(checkFile, string.Join(Environment.NewLine, log));
|
||||||
|
File.SetLastWriteTime(checkFile, fileInfo.LastWriteTime);
|
||||||
|
logger.LogInformation("<{checkFile}> was written", checkFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetBody(string[] lines, int i, string[] segments) {
|
||||||
|
string result;
|
||||||
|
List<string> results = [];
|
||||||
|
for (int j = i + 1; j < lines.Length; j++) {
|
||||||
|
if (lines[j].StartsWith(segments[0]))
|
||||||
|
break;
|
||||||
|
results.Add(lines[j].Trim());
|
||||||
|
}
|
||||||
|
result = string.Join('_', results);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
427
ADO2025/PI6/Helper-2025-07-20.cs
Normal file
427
ADO2025/PI6/Helper-2025-07-20.cs
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
using Phares.Metadata.Models.Stateless;
|
||||||
|
using Phares.Shared.Models;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.ADO2025.PI6;
|
||||||
|
|
||||||
|
internal static partial class Helper20250720 {
|
||||||
|
|
||||||
|
internal static void WriteFaceData(ILogger<Worker> logger, List<string> args) {
|
||||||
|
logger.LogInformation(args[0]);
|
||||||
|
logger.LogInformation(args[1]);
|
||||||
|
logger.LogInformation(args[2]);
|
||||||
|
logger.LogInformation(args[3]);
|
||||||
|
logger.LogInformation(args[4]);
|
||||||
|
logger.LogInformation(args[5]);
|
||||||
|
logger.LogInformation(args[6]);
|
||||||
|
logger.LogInformation(args[6]);
|
||||||
|
logger.LogInformation(args[7]);
|
||||||
|
logger.LogInformation(args[8]);
|
||||||
|
string searchPattern = args[5];
|
||||||
|
string searchPatternXMP = args[7];
|
||||||
|
string outputDirectoryName = args[8];
|
||||||
|
string jsonFile = Path.GetFullPath(args[3]);
|
||||||
|
string digiKamFile = Path.GetFullPath(args[6]);
|
||||||
|
FileInfo faceFileInfo = new(Path.GetFullPath(args[4]));
|
||||||
|
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
|
||||||
|
string pathRoot = Path.GetPathRoot(faceFileInfo.FullName) ?? throw new Exception();
|
||||||
|
string? checkDirectory = Path.GetDirectoryName(digiKamFile.Replace("{}", outputDirectoryName));
|
||||||
|
string originalFile = Path.Combine(sourceDirectory, args[2]);
|
||||||
|
string pathRootXMP = digiKamFile[..5];
|
||||||
|
if (!File.Exists(jsonFile)) {
|
||||||
|
logger.LogError("json file doesn't exist! <{jsonFile}>", jsonFile);
|
||||||
|
} else if (!File.Exists(digiKamFile)) {
|
||||||
|
logger.LogError("digiKam file doesn't exist! <{digiKamFile}>", digiKamFile);
|
||||||
|
} else if (!File.Exists(originalFile)) {
|
||||||
|
logger.LogError("Original file doesn't exist! <{checkFile}>", originalFile);
|
||||||
|
} else if (!Directory.Exists(checkDirectory)) {
|
||||||
|
logger.LogError("checkDirectory doesn't exist! <{checkDirectory}>", checkDirectory);
|
||||||
|
} else if (!faceFileInfo.Exists) {
|
||||||
|
logger.LogError("Face file doesn't exist! <{faceFileInfo}>", faceFileInfo.FullName);
|
||||||
|
} else {
|
||||||
|
string json = File.ReadAllText(jsonFile);
|
||||||
|
ResultSettings? resultSettings = JsonSerializer.Deserialize(json, ResultSettingsSourceGenerationContext.Default.ResultSettings);
|
||||||
|
MetadataSettings? metadataSettings = JsonSerializer.Deserialize(json, MetadataSettingsSourceGenerationContext.Default.MetadataSettings);
|
||||||
|
if (resultSettings is null) {
|
||||||
|
logger.LogError(nameof(ResultSettings));
|
||||||
|
} else if (metadataSettings is null) {
|
||||||
|
logger.LogError(nameof(MetadataSettings));
|
||||||
|
} else {
|
||||||
|
WriteFaceData(logger, outputDirectoryName, originalFile, faceFileInfo, digiKamFile, resultSettings, metadataSettings);
|
||||||
|
ReadOnlyDictionary<long, ReadOnlyCollection<string>> keyValuePairsXMP = GetKeyValuePairs(searchPatternXMP, pathRootXMP);
|
||||||
|
ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> keyValuePairs = GetKeyValuePairs(searchPattern, pathRoot, resultSettings, metadataSettings);
|
||||||
|
if (keyValuePairs.Count == 0) {
|
||||||
|
logger.LogError("Didn't find any valid file(s)!");
|
||||||
|
} else {
|
||||||
|
WriteFaceData(logger, outputDirectoryName, keyValuePairs, keyValuePairsXMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteFaceData(ILogger<Worker> logger, string outputDirectoryName, string originalFile, FileInfo faceFileInfo, string digiKamFile, ResultSettings resultSettings, MetadataSettings metadataSettings) {
|
||||||
|
ExifDirectory? exifDirectory = IMetadata.GetExifDirectory(resultSettings, metadataSettings, faceFileInfo);
|
||||||
|
if (exifDirectory is null) {
|
||||||
|
logger.LogError("exifDirectory is null!");
|
||||||
|
} else {
|
||||||
|
long id;
|
||||||
|
string fileNameWithoutExtension;
|
||||||
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(faceFileInfo.FullName);
|
||||||
|
if (!long.TryParse(fileNameWithoutExtension.Split('.')[0], out id)) {
|
||||||
|
id = -1;
|
||||||
|
}
|
||||||
|
long? fileNameFirstSegment = id == -1 ? null : id;
|
||||||
|
ReadOnlyCollection<string> digiKamFiles = new([digiKamFile]);
|
||||||
|
ReadOnlyCollection<ExifDirectory> exifDirectories = new([exifDirectory]);
|
||||||
|
WriteFaceData(logger, outputDirectoryName, originalFile, fileNameFirstSegment, exifDirectories, digiKamFiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteFaceData(ILogger<Worker> logger, string outputDirectoryName, string? originalFile, long? fileNameFirstSegment, ReadOnlyCollection<ExifDirectory> exifDirectories, ReadOnlyCollection<string> digiKamFiles) {
|
||||||
|
ReadOnlyDictionary<string, FaceFile> keyValuePairs = GetKeyValuePairs(logger, exifDirectories);
|
||||||
|
if (keyValuePairs.Count > 0) {
|
||||||
|
WriteFaceData(logger, outputDirectoryName, originalFile, fileNameFirstSegment, digiKamFiles, keyValuePairs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int? GetMatchingLine(string digiKamLine, ReadOnlyCollection<string> lines) {
|
||||||
|
int? result = null;
|
||||||
|
for (int i = 0; i < lines.Count; i++) {
|
||||||
|
if (lines[i] == digiKamLine) {
|
||||||
|
result = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteFaceData(string outputDirectoryName, string? originalFile, ReadOnlyDictionary<string, FaceFile> keyValuePairs, string digiKamFile, List<string> trimmed, int rdfLine) {
|
||||||
|
if (keyValuePairs.Count == 0) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
double h;
|
||||||
|
double w;
|
||||||
|
double mpTop;
|
||||||
|
double width;
|
||||||
|
double height;
|
||||||
|
double mpLeft;
|
||||||
|
double mwgTop;
|
||||||
|
double mwgLeft;
|
||||||
|
string personKey;
|
||||||
|
FaceFile faceFile;
|
||||||
|
string descriptionLine = "</rdf:Description>";
|
||||||
|
faceFile = keyValuePairs.ElementAt(0).Value;
|
||||||
|
List<string> regionLines = [
|
||||||
|
"<MP:RegionInfo rdf:parseType=\"Resource\">",
|
||||||
|
"<MPRI:Regions>",
|
||||||
|
"<rdf:Bag>"
|
||||||
|
];
|
||||||
|
List<string> regionsLinesB = [
|
||||||
|
"<mwg-rs:Regions rdf:parseType=\"Resource\">",
|
||||||
|
"<mwg-rs:AppliedToDimensions",
|
||||||
|
$"stDim:w=\"{faceFile.OutputResolution.Width}\"",
|
||||||
|
$"stDim:h=\"{faceFile.OutputResolution.Height}\"",
|
||||||
|
"stDim:unit=\"pixel\"/>",
|
||||||
|
"<mwg-rs:RegionList>",
|
||||||
|
"<rdf:Bag>"
|
||||||
|
];
|
||||||
|
List<string> digiKamLines = ["<digiKam:TagsList>", "<rdf:Seq>"];
|
||||||
|
List<string> microsoftPhotoLines = ["<MicrosoftPhoto:LastKeywordXMP>", "<rdf:Bag>"];
|
||||||
|
List<string> hierarchicalSubjectLines = ["<lr:hierarchicalSubject>", "<rdf:Bag>"];
|
||||||
|
List<string> catalogSetLines = ["<mediapro:CatalogSets>", "<rdf:Bag>"];
|
||||||
|
List<string> subjectLines = ["<dc:subject>", "<rdf:Bag>"];
|
||||||
|
foreach (KeyValuePair<string, FaceFile> keyValuePair in keyValuePairs) {
|
||||||
|
personKey = keyValuePair.Key;
|
||||||
|
faceFile = keyValuePair.Value;
|
||||||
|
width = faceFile.Location.Right - faceFile.Location.Left;
|
||||||
|
height = faceFile.Location.Bottom - faceFile.Location.Top;
|
||||||
|
if (!string.IsNullOrEmpty(originalFile) && File.Exists(originalFile)) {
|
||||||
|
Extract(file: originalFile,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
left: faceFile.Location.Left,
|
||||||
|
top: faceFile.Location.Top,
|
||||||
|
suffix: $"-{keyValuePair.Key}-whole-percentages.jpg");
|
||||||
|
}
|
||||||
|
w = width / faceFile.OutputResolution.Width;
|
||||||
|
h = height / faceFile.OutputResolution.Height;
|
||||||
|
if (w == 0 || h == 0)
|
||||||
|
throw new NotImplementedException();
|
||||||
|
mpLeft = (double)faceFile.Location.Left / faceFile.OutputResolution.Width;
|
||||||
|
mpTop = (double)faceFile.Location.Top / faceFile.OutputResolution.Height;
|
||||||
|
mwgLeft = (faceFile.Location.Left + (width * .5)) / faceFile.OutputResolution.Width;
|
||||||
|
mwgTop = (faceFile.Location.Top + (height * .5)) / faceFile.OutputResolution.Height;
|
||||||
|
// <MP:RegionInfo rdf:parseType="Resource">
|
||||||
|
// <MPRI:Regions>
|
||||||
|
// <rdf:Bag>
|
||||||
|
// <rdf:li
|
||||||
|
// MPReg:PersonDisplayName="{personKey}"
|
||||||
|
// MPReg:Rectangle="{mpLeft:0.000000}, {mpTop:0.000000}, {w:0.000000}, {h:0.000000}"/>
|
||||||
|
// </rdf:Bag>
|
||||||
|
// </MPRI:Regions>
|
||||||
|
// </MP:RegionInfo>
|
||||||
|
regionLines.Add("<rdf:li");
|
||||||
|
regionLines.Add($"MPReg:PersonDisplayName=\"{personKey}\"");
|
||||||
|
regionLines.Add($"MPReg:Rectangle=\"{mpLeft:0.000000}, {mpTop:0.000000}, {w:0.000000}, {h:0.000000}\"/>");
|
||||||
|
// <mwg-rs:Regions rdf:parseType="Resource">
|
||||||
|
// <mwg-rs:AppliedToDimensions
|
||||||
|
// stDim:w="{faceFile.OutputResolution.Width}"
|
||||||
|
// stDim:h="{faceFile.OutputResolution.Height}"
|
||||||
|
// stDim:unit="pixel"/>
|
||||||
|
// <mwg-rs:RegionList>
|
||||||
|
// <rdf:Bag>
|
||||||
|
// <rdf:li>
|
||||||
|
// <rdf:Description
|
||||||
|
// mwg-rs:Name="{personKey}"
|
||||||
|
// mwg-rs:Type="Face">
|
||||||
|
// <mwg-rs:Area
|
||||||
|
// stArea:x="{mwgLeft:0.000000}"
|
||||||
|
// stArea:y="{mwgTop:0.000000}"
|
||||||
|
// stArea:w="{w:0.000000}"
|
||||||
|
// stArea:h="{h:0.000000}"
|
||||||
|
// stArea:unit="normalized"/>
|
||||||
|
// </rdf:Description>
|
||||||
|
// </rdf:li>
|
||||||
|
// </rdf:Bag>
|
||||||
|
// </mwg-rs:RegionList>
|
||||||
|
// </mwg-rs:Regions>
|
||||||
|
regionsLinesB.Add("<rdf:li>");
|
||||||
|
regionsLinesB.Add("<rdf:Description");
|
||||||
|
regionsLinesB.Add($"mwg-rs:Name=\"{personKey}\"");
|
||||||
|
regionsLinesB.Add("mwg-rs:Type=\"Face\">");
|
||||||
|
regionsLinesB.Add("<mwg-rs:Area");
|
||||||
|
regionsLinesB.Add($"stArea:x=\"{mwgLeft:0.000000}\"");
|
||||||
|
regionsLinesB.Add($"stArea:y=\"{mwgTop:0.000000}\"");
|
||||||
|
regionsLinesB.Add($"stArea:w=\"{w:0.000000}\"");
|
||||||
|
regionsLinesB.Add($"stArea:h=\"{h:0.000000}\"");
|
||||||
|
regionsLinesB.Add("stArea:unit=\"normalized\"/>");
|
||||||
|
regionsLinesB.Add("</rdf:Description>");
|
||||||
|
regionsLinesB.Add("</rdf:li>");
|
||||||
|
// <digiKam:TagsList>
|
||||||
|
// <rdf:Seq>
|
||||||
|
// <rdf:li>People/{personKey}</rdf:li>
|
||||||
|
// </rdf:Seq>
|
||||||
|
// </digiKam:TagsList>
|
||||||
|
digiKamLines.Add($"<rdf:li>People/{personKey}</rdf:li>");
|
||||||
|
// <MicrosoftPhoto:LastKeywordXMP>
|
||||||
|
// <rdf:Bag>
|
||||||
|
// <rdf:li>People/{personKey}</rdf:li>
|
||||||
|
// </rdf:Bag>
|
||||||
|
// </MicrosoftPhoto:LastKeywordXMP>
|
||||||
|
microsoftPhotoLines.Add($"<rdf:li>People/{personKey}</rdf:li>");
|
||||||
|
// <lr:hierarchicalSubject>
|
||||||
|
// <rdf:Bag>
|
||||||
|
// <rdf:li>People|{personKey}</rdf:li>
|
||||||
|
// </rdf:Bag>
|
||||||
|
// </lr:hierarchicalSubject>
|
||||||
|
hierarchicalSubjectLines.Add($"<rdf:li>People|{personKey}</rdf:li>");
|
||||||
|
// <mediapro:CatalogSets>
|
||||||
|
// <rdf:Bag>
|
||||||
|
// <rdf:li>People|{personKey}</rdf:li>
|
||||||
|
// </rdf:Bag>
|
||||||
|
// </mediapro:CatalogSets>
|
||||||
|
catalogSetLines.Add($"<rdf:li>People|{personKey}</rdf:li>");
|
||||||
|
// <dc:subject>
|
||||||
|
// <rdf:Bag>
|
||||||
|
// <rdf:li>{personKey}</rdf:li>
|
||||||
|
// </rdf:Bag>
|
||||||
|
// </dc:subject>
|
||||||
|
subjectLines.Add($"<rdf:li>{personKey}</rdf:li>");
|
||||||
|
}
|
||||||
|
regionLines.AddRange(["</rdf:Bag>","</MPRI:Regions>","</MP:RegionInfo>"]);
|
||||||
|
regionsLinesB.AddRange(["</rdf:Bag>", "</mwg-rs:RegionList>","</mwg-rs:Regions>"]);
|
||||||
|
digiKamLines.AddRange(["</rdf:Seq>", "</digiKam:TagsList>"]);
|
||||||
|
microsoftPhotoLines.AddRange(["</rdf:Bag>", "</MicrosoftPhoto:LastKeywordXMP>"]);
|
||||||
|
hierarchicalSubjectLines.AddRange(["</rdf:Bag>", "</lr:hierarchicalSubject>"]);
|
||||||
|
catalogSetLines.AddRange(["</rdf:Bag>", "</mediapro:CatalogSets>"]);
|
||||||
|
subjectLines.AddRange(["</rdf:Bag>", "</dc:subject>"]);
|
||||||
|
List<string> lines = [];
|
||||||
|
lines.AddRange(regionLines);
|
||||||
|
lines.AddRange(regionsLinesB);
|
||||||
|
lines.AddRange(digiKamLines);
|
||||||
|
lines.AddRange(microsoftPhotoLines);
|
||||||
|
lines.AddRange(hierarchicalSubjectLines);
|
||||||
|
lines.AddRange(catalogSetLines);
|
||||||
|
lines.AddRange(subjectLines);
|
||||||
|
string text = string.Join(Environment.NewLine, lines);
|
||||||
|
if (trimmed[rdfLine - 1] != descriptionLine) {
|
||||||
|
trimmed[rdfLine - 1] = $"{trimmed[rdfLine - 1][..^2]}>";
|
||||||
|
trimmed.Insert(rdfLine, descriptionLine);
|
||||||
|
rdfLine++;
|
||||||
|
}
|
||||||
|
trimmed.Insert(rdfLine - 1, text);
|
||||||
|
string allText = string.Join(Environment.NewLine, trimmed);
|
||||||
|
File.WriteAllText(digiKamFile.Replace("{}", outputDirectoryName), allText);
|
||||||
|
if (!string.IsNullOrEmpty(originalFile)) {
|
||||||
|
if (Debugger.IsAttached) {
|
||||||
|
File.WriteAllText(".xml", allText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<long, ReadOnlyCollection<string>> GetKeyValuePairs(string searchPattern, string pathRoot) {
|
||||||
|
Dictionary<long, ReadOnlyCollection<string>> results = [];
|
||||||
|
long fileNameFirstSegment;
|
||||||
|
List<string>? collection;
|
||||||
|
string fileNameWithoutExtension;
|
||||||
|
Dictionary<long, List<string>> keyValuePairs = [];
|
||||||
|
string[] files = Directory.GetFiles(pathRoot, searchPattern, SearchOption.AllDirectories);
|
||||||
|
foreach (string file in files) {
|
||||||
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
|
||||||
|
if (!long.TryParse(fileNameWithoutExtension.Split('.')[0], out fileNameFirstSegment)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!keyValuePairs.TryGetValue(fileNameFirstSegment, out collection)) {
|
||||||
|
keyValuePairs.Add(fileNameFirstSegment, []);
|
||||||
|
if (!keyValuePairs.TryGetValue(fileNameFirstSegment, out collection)) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
collection.Add(file);
|
||||||
|
}
|
||||||
|
foreach (KeyValuePair<long, List<string>> keyValuePair in keyValuePairs) {
|
||||||
|
results.Add(keyValuePair.Key, keyValuePair.Value.AsReadOnly());
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<string, FaceFile> GetKeyValuePairs(ILogger<Worker> logger, ReadOnlyCollection<ExifDirectory> exifDirectories) {
|
||||||
|
Dictionary<string, FaceFile> results = [];
|
||||||
|
string personKey;
|
||||||
|
FaceFile? faceFile;
|
||||||
|
foreach (ExifDirectory exifDirectory in exifDirectories) {
|
||||||
|
faceFile = IMetadata.GetFaceFile(exifDirectory);
|
||||||
|
if (faceFile is null) {
|
||||||
|
logger.LogError("faceFile is null!");
|
||||||
|
} else if (faceFile.Location is null) {
|
||||||
|
logger.LogError("faceFile location is null!");
|
||||||
|
} else if (faceFile.OutputResolution?.Orientation is not 0 and not 1) {
|
||||||
|
logger.LogWarning("faceFile output-resolution orientation is not aloud!");
|
||||||
|
} else {
|
||||||
|
personKey = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(exifDirectory.FilePath.FullName))));
|
||||||
|
if (results.ContainsKey(personKey)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
results.Add(personKey, faceFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> GetKeyValuePairs(string searchPattern, string pathRoot, ResultSettings resultSettings, MetadataSettings metadataSettings) {
|
||||||
|
Dictionary<long, ReadOnlyCollection<ExifDirectory>> results = [];
|
||||||
|
FileInfo faceFileInfo;
|
||||||
|
long fileNameFirstSegment;
|
||||||
|
ExifDirectory? exifDirectory;
|
||||||
|
List<ExifDirectory>? collection;
|
||||||
|
string fileNameWithoutExtension;
|
||||||
|
Dictionary<long, List<ExifDirectory>> keyValuePairs = [];
|
||||||
|
string[] files = Directory.GetFiles(pathRoot, searchPattern, SearchOption.AllDirectories);
|
||||||
|
foreach (string file in files) {
|
||||||
|
faceFileInfo = new(file);
|
||||||
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(faceFileInfo.FullName);
|
||||||
|
if (!long.TryParse(fileNameWithoutExtension.Split('.')[0], out fileNameFirstSegment)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
exifDirectory = IMetadata.GetExifDirectory(resultSettings, metadataSettings, faceFileInfo);
|
||||||
|
if (exifDirectory is null)
|
||||||
|
continue;
|
||||||
|
if (!keyValuePairs.TryGetValue(fileNameFirstSegment, out collection)) {
|
||||||
|
keyValuePairs.Add(fileNameFirstSegment, []);
|
||||||
|
if (!keyValuePairs.TryGetValue(fileNameFirstSegment, out collection))
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
collection.Add(exifDirectory);
|
||||||
|
}
|
||||||
|
foreach (KeyValuePair<long, List<ExifDirectory>> keyValuePair in keyValuePairs) {
|
||||||
|
results.Add(keyValuePair.Key, keyValuePair.Value.AsReadOnly());
|
||||||
|
}
|
||||||
|
return results.AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteFaceData(ILogger<Worker> logger, string outputDirectoryName, ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> keyValuePairs, ReadOnlyDictionary<long, ReadOnlyCollection<string>> keyValuePairsXMP) {
|
||||||
|
ReadOnlyCollection<string>? digiKamFiles;
|
||||||
|
foreach (KeyValuePair<long, ReadOnlyCollection<ExifDirectory>> keyValuePair in keyValuePairs) {
|
||||||
|
if (!keyValuePairsXMP.TryGetValue(keyValuePair.Key, out digiKamFiles)) {
|
||||||
|
logger.LogWarning("{fileNameFirstSegment}) Didn't find a matching file!", keyValuePair.Key);
|
||||||
|
} else {
|
||||||
|
string? originalFile = null;
|
||||||
|
WriteFaceData(logger, outputDirectoryName, originalFile, keyValuePair.Key, keyValuePair.Value, digiKamFiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteFaceData(ILogger<Worker> logger, string outputDirectoryName, string? originalFile, long? fileNameFirstSegment, ReadOnlyCollection<string> digiKamFiles, ReadOnlyDictionary<string, FaceFile> keyValuePairs) {
|
||||||
|
#if xmp
|
||||||
|
IXmpMeta xmp;
|
||||||
|
using FileStream stream = File.OpenRead(digiKamFile);
|
||||||
|
xmp = XmpMetaFactory.Parse(stream);
|
||||||
|
foreach (var property in xmp.Properties) {
|
||||||
|
logger.LogDebug("Path={property.Path} Namespace={property.Namespace} Value={property.Value}", property.Path, property.Namespace, property.Value);
|
||||||
|
}
|
||||||
|
xmp.Sort();
|
||||||
|
SerializeOptions serializeOptions = new(SerializeOptions.EncodeUtf8);
|
||||||
|
string check = XmpMetaFactory.SerializeToString(xmp, serializeOptions);
|
||||||
|
File.WriteAllText(".xmp", check);
|
||||||
|
#endif
|
||||||
|
string[] requiredLines = [
|
||||||
|
"xmlns:digiKam=\"http://www.digikam.org/ns/1.0/\"",
|
||||||
|
"xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"",
|
||||||
|
"xmlns:exif=\"http://ns.adobe.com/exif/1.0/\"",
|
||||||
|
"xmlns:tiff=\"http://ns.adobe.com/tiff/1.0/\"",
|
||||||
|
"xmlns:dc=\"http://purl.org/dc/elements/1.1/\"",
|
||||||
|
"xmlns:acdsee=\"http://ns.acdsee.com/iptc/1.0/\"",
|
||||||
|
"xmlns:lr=\"http://ns.adobe.com/lightroom/1.0/\"",
|
||||||
|
"xmlns:MP=\"http://ns.microsoft.com/photo/1.2/\"",
|
||||||
|
"xmlns:stArea=\"http://ns.adobe.com/xmp/sType/Area#\"",
|
||||||
|
"xmlns:photoshop=\"http://ns.adobe.com/photoshop/1.0/\"",
|
||||||
|
"xmlns:MicrosoftPhoto=\"http://ns.microsoft.com/photo/1.0/\"",
|
||||||
|
"xmlns:MPReg=\"http://ns.microsoft.com/photo/1.2/t/Region#\"",
|
||||||
|
"xmlns:stDim=\"http://ns.adobe.com/xap/1.0/sType/Dimensions#\"",
|
||||||
|
"xmlns:MPRI=\"http://ns.microsoft.com/photo/1.2/t/RegionInfo#\"",
|
||||||
|
"xmlns:mediapro=\"http://ns.iview-multimedia.com/mediapro/1.0/\"",
|
||||||
|
"xmlns:mwg-rs=\"http://www.metadataworkinggroup.com/schemas/regions/\"",
|
||||||
|
"</rdf:RDF>"
|
||||||
|
];
|
||||||
|
foreach (string digiKamFile in digiKamFiles) {
|
||||||
|
string[] lines = File.ReadAllLines(digiKamFile);
|
||||||
|
List<string> trimmed = lines.Select(l => l.Trim()).ToList();
|
||||||
|
int? digiKamLine = GetMatchingLine(requiredLines[0], trimmed.AsReadOnly());
|
||||||
|
if (digiKamLine is null) {
|
||||||
|
logger.LogError("{fileNameFirstSegment}) Didn't fine digiKam line!", fileNameFirstSegment);
|
||||||
|
} else {
|
||||||
|
foreach (string requiredLine in requiredLines) {
|
||||||
|
if (!trimmed.Contains(requiredLine)) {
|
||||||
|
trimmed.Insert(digiKamLine.Value + 1, requiredLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int? rdfLine = GetMatchingLine(requiredLines[^1], trimmed.AsReadOnly());
|
||||||
|
if (rdfLine is null) {
|
||||||
|
logger.LogError("{fileNameFirstSegment}) Didn't fine description line!", fileNameFirstSegment);
|
||||||
|
} else {
|
||||||
|
WriteFaceData(outputDirectoryName, originalFile, keyValuePairs, digiKamFile, trimmed, rdfLine.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Extract(string file, double width, double height, int left, int top, string suffix) {
|
||||||
|
#if SystemDrawingCommon
|
||||||
|
Rectangle rectangle = new(left, top, width, height);
|
||||||
|
using (Bitmap source = new(file)) {
|
||||||
|
using (Bitmap bitmap = new(width, height)) {
|
||||||
|
using (Graphics graphics = Graphics.FromImage(bitmap)) {
|
||||||
|
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||||
|
}
|
||||||
|
bitmap.Save($"{file}{suffix}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -177,6 +177,12 @@ internal static class HelperDay
|
|||||||
ADO2025.PI6.Helper20250701.ProcessDataStandardFormatTo(logger, args);
|
ADO2025.PI6.Helper20250701.ProcessDataStandardFormatTo(logger, args);
|
||||||
else if (args[1] == "Day-Helper-2025-07-05")
|
else if (args[1] == "Day-Helper-2025-07-05")
|
||||||
ADO2025.PI6.Helper20250705.ExportFaces(logger, args);
|
ADO2025.PI6.Helper20250705.ExportFaces(logger, args);
|
||||||
|
else if (args[1] == "Day-Helper-2025-07-09")
|
||||||
|
ADO2025.PI6.Helper20250709.JavaScriptObjectNotationToReactor(logger, args);
|
||||||
|
else if (args[1] == "Day-Helper-2025-07-10")
|
||||||
|
ADO2025.PI6.Helper20250710.StripLog(logger, args);
|
||||||
|
else if (args[1] == "Day-Helper-2025-07-20")
|
||||||
|
ADO2025.PI6.Helper20250720.WriteFaceData(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);
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DiscUtils.Iso9660" Version="0.16.13" />
|
<PackageReference Include="DiscUtils.Iso9660" Version="0.16.13" />
|
||||||
<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.17" />
|
<PackageReference Include="Phares.Metadata" Version="8.0.118.14751" />
|
||||||
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
|
<PackageReference Include="Phares.Shared" Version="8.0.118.14751" />
|
||||||
<PackageReference Include="System.Text.Json" Version="9.0.5" />
|
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.18" />
|
||||||
|
<PackageReference Include="System.Text.Json" Version="9.0.7" />
|
||||||
<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" />
|
||||||
<PackageReference Include="YamlDotNet" Version="16.3.0" />
|
<PackageReference Include="YamlDotNet" Version="16.3.0" />
|
||||||
|
@ -1,126 +0,0 @@
|
|||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Helpers.Exif;
|
|
||||||
|
|
||||||
internal static class Dimensions
|
|
||||||
{
|
|
||||||
|
|
||||||
#pragma warning disable IDE0230
|
|
||||||
private static readonly Dictionary<byte[], Func<BinaryReader, Size?>> _ImageFormatDecoders = new()
|
|
||||||
{
|
|
||||||
{ new byte[] { 0x42, 0x4D }, DecodeBitmap },
|
|
||||||
{ new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif },
|
|
||||||
{ new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif },
|
|
||||||
{ new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng },
|
|
||||||
{ new byte[] { 0xff, 0xd8 }, DecodeJfif },
|
|
||||||
{ new byte[] { 0x52, 0x49, 0x46, 0x46 }, DecodeWebP },
|
|
||||||
};
|
|
||||||
#pragma warning restore IDE0230
|
|
||||||
|
|
||||||
private static bool StartsWith(byte[] thisBytes, byte[] thatBytes)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < thatBytes.Length; i += 1)
|
|
||||||
{
|
|
||||||
if (thisBytes[i] == thatBytes[i])
|
|
||||||
continue;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static short ReadLittleEndianInt16(BinaryReader binaryReader)
|
|
||||||
{
|
|
||||||
byte[] bytes = new byte[sizeof(short)];
|
|
||||||
for (int i = 0; i < sizeof(short); i += 1)
|
|
||||||
bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte();
|
|
||||||
return BitConverter.ToInt16(bytes, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int ReadLittleEndianInt32(BinaryReader binaryReader)
|
|
||||||
{
|
|
||||||
byte[] bytes = new byte[sizeof(int)];
|
|
||||||
for (int i = 0; i < sizeof(int); i += 1)
|
|
||||||
bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte();
|
|
||||||
return BitConverter.ToInt32(bytes, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Size? DecodeBitmap(BinaryReader binaryReader)
|
|
||||||
{
|
|
||||||
_ = binaryReader.ReadBytes(16);
|
|
||||||
int width = binaryReader.ReadInt32();
|
|
||||||
int height = binaryReader.ReadInt32();
|
|
||||||
return new Size(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Size? DecodeGif(BinaryReader binaryReader)
|
|
||||||
{
|
|
||||||
int width = binaryReader.ReadInt16();
|
|
||||||
int height = binaryReader.ReadInt16();
|
|
||||||
return new Size(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Size? DecodePng(BinaryReader binaryReader)
|
|
||||||
{
|
|
||||||
_ = binaryReader.ReadBytes(8);
|
|
||||||
int width = ReadLittleEndianInt32(binaryReader);
|
|
||||||
int height = ReadLittleEndianInt32(binaryReader);
|
|
||||||
return new Size(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Size? DecodeJfif(BinaryReader binaryReader)
|
|
||||||
{
|
|
||||||
while (binaryReader.ReadByte() == 0xff)
|
|
||||||
{
|
|
||||||
byte marker = binaryReader.ReadByte();
|
|
||||||
short chunkLength = ReadLittleEndianInt16(binaryReader);
|
|
||||||
if (marker == 0xc0)
|
|
||||||
{
|
|
||||||
_ = binaryReader.ReadByte();
|
|
||||||
int height = ReadLittleEndianInt16(binaryReader);
|
|
||||||
int width = ReadLittleEndianInt16(binaryReader);
|
|
||||||
return new Size(width, height);
|
|
||||||
}
|
|
||||||
if (chunkLength >= 0)
|
|
||||||
_ = binaryReader.ReadBytes(chunkLength - 2);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ushort uChunkLength = (ushort)chunkLength;
|
|
||||||
_ = binaryReader.ReadBytes(uChunkLength - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Size? DecodeWebP(BinaryReader binaryReader)
|
|
||||||
{
|
|
||||||
_ = binaryReader.ReadUInt32(); // Size
|
|
||||||
_ = binaryReader.ReadBytes(15); // WEBP, VP8 + more
|
|
||||||
_ = binaryReader.ReadBytes(3); // SYNC
|
|
||||||
int width = binaryReader.ReadUInt16() & 0b00_11111111111111; // 14 bits width
|
|
||||||
int height = binaryReader.ReadUInt16() & 0b00_11111111111111; // 14 bits height
|
|
||||||
return new Size(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static Size? GetDimensions(BinaryReader binaryReader)
|
|
||||||
{
|
|
||||||
int maxMagicBytesLength = _ImageFormatDecoders.Keys.OrderByDescending(x => x.Length).First().Length;
|
|
||||||
byte[] magicBytes = new byte[maxMagicBytesLength];
|
|
||||||
for (int i = 0; i < maxMagicBytesLength; i += 1)
|
|
||||||
{
|
|
||||||
magicBytes[i] = binaryReader.ReadByte();
|
|
||||||
foreach (KeyValuePair<byte[], Func<BinaryReader, Size?>> kvPair in _ImageFormatDecoders)
|
|
||||||
{
|
|
||||||
if (StartsWith(magicBytes, kvPair.Key))
|
|
||||||
return kvPair.Value(binaryReader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static Size? GetDimensions(string path)
|
|
||||||
{
|
|
||||||
using BinaryReader binaryReader = new(File.OpenRead(path));
|
|
||||||
return GetDimensions(binaryReader);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,534 +0,0 @@
|
|||||||
using MetadataExtractor;
|
|
||||||
using MetadataExtractor.Formats.Exif;
|
|
||||||
using MetadataExtractor.Formats.Exif.Makernotes;
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Helpers.Exif;
|
|
||||||
|
|
||||||
internal abstract class Exif
|
|
||||||
{
|
|
||||||
|
|
||||||
private static DateTime? GetDateTime(string? value)
|
|
||||||
{
|
|
||||||
DateTime? result;
|
|
||||||
string dateTimeFormat = "yyyy:MM:dd HH:mm:ss";
|
|
||||||
string alternateFormat = "ddd MMM dd HH:mm:ss yyyy";
|
|
||||||
if (value is not null && DateTime.TryParse(value, out DateTime dateTime))
|
|
||||||
result = dateTime;
|
|
||||||
else if (value is not null && value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
|
||||||
result = dateTime;
|
|
||||||
else if (value is not null && value.Length == alternateFormat.Length && DateTime.TryParseExact(value, alternateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
|
||||||
result = dateTime;
|
|
||||||
else
|
|
||||||
result = null;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.AviDirectory[] GetAviDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.AviDirectory> results = [];
|
|
||||||
IEnumerable<MetadataExtractor.Formats.Avi.AviDirectory> aviDirectories = directories.OfType<MetadataExtractor.Formats.Avi.AviDirectory>();
|
|
||||||
foreach (MetadataExtractor.Formats.Avi.AviDirectory aviDirectory in aviDirectories)
|
|
||||||
{
|
|
||||||
if (aviDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
DateTime? dateTimeOriginal;
|
|
||||||
string? duration = aviDirectory.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagDuration);
|
|
||||||
string? height = aviDirectory.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagHeight);
|
|
||||||
string? width = aviDirectory.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagWidth);
|
|
||||||
if (aviDirectory.TryGetDateTime(MetadataExtractor.Formats.Avi.AviDirectory.TagDateTimeOriginal, out DateTime checkDateTime))
|
|
||||||
dateTimeOriginal = checkDateTime;
|
|
||||||
else
|
|
||||||
dateTimeOriginal = GetDateTime(aviDirectory.GetString(MetadataExtractor.Formats.Avi.AviDirectory.TagDateTimeOriginal));
|
|
||||||
if (dateTimeOriginal is null && duration is null && height is null && width is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(dateTimeOriginal, duration, height, width));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.ExifDirectoryBase[] GetExifBaseDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.ExifDirectoryBase> results = [];
|
|
||||||
IEnumerable<ExifDirectoryBase> exifBaseDirectories = directories.OfType<ExifDirectoryBase>();
|
|
||||||
foreach (ExifDirectoryBase exifDirectoryBase in exifBaseDirectories)
|
|
||||||
{
|
|
||||||
if (exifDirectoryBase.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
DateTime? dateTime;
|
|
||||||
DateTime checkDateTime;
|
|
||||||
DateTime? dateTimeOriginal;
|
|
||||||
DateTime? dateTimeDigitized;
|
|
||||||
string? aperture = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagAperture);
|
|
||||||
string? applicationNotes = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagApplicationNotes);
|
|
||||||
string? artist = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagArtist);
|
|
||||||
string? bitsPerSample = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagBitsPerSample);
|
|
||||||
string? bodySerialNumber = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagBodySerialNumber);
|
|
||||||
string? cameraOwnerName = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCameraOwnerName);
|
|
||||||
string? compressedAverageBitsPerPixel = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCompressedAverageBitsPerPixel);
|
|
||||||
string? compression = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCompression);
|
|
||||||
string? copyright = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCopyright);
|
|
||||||
string? documentName = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagDocumentName);
|
|
||||||
string? exifVersion = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagExifVersion);
|
|
||||||
string? exposureTime = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagExposureTime);
|
|
||||||
string? fileSource = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagFileSource);
|
|
||||||
string? imageDescription = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageDescription);
|
|
||||||
string? imageHeight = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageHeight);
|
|
||||||
string? imageNumber = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageNumber);
|
|
||||||
string? imageUniqueId = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageUniqueId);
|
|
||||||
string? imageWidth = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageWidth);
|
|
||||||
string? isoSpeed = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagIsoSpeed);
|
|
||||||
string? lensMake = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagLensMake);
|
|
||||||
string? lensModel = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagLensModel);
|
|
||||||
string? lensSerialNumber = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagLensSerialNumber);
|
|
||||||
string? make = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagMake);
|
|
||||||
string? makerNote = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagMakernote);
|
|
||||||
string? model = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagModel);
|
|
||||||
string? orientation = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagOrientation);
|
|
||||||
int? orientationValue = orientation is null ? null : exifDirectoryBase.GetInt32(ExifDirectoryBase.TagOrientation);
|
|
||||||
string? rating = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagRating);
|
|
||||||
string? ratingPercent = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagRatingPercent);
|
|
||||||
string? securityClassification = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagSecurityClassification);
|
|
||||||
string? shutterSpeed = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagShutterSpeed);
|
|
||||||
string? software = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagSoftware);
|
|
||||||
string? timeZone = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagTimeZone);
|
|
||||||
string? timeZoneDigitized = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagTimeZoneDigitized);
|
|
||||||
string? timeZoneOriginal = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagTimeZoneOriginal);
|
|
||||||
string? userComment = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagUserComment);
|
|
||||||
string? winAuthor = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinAuthor);
|
|
||||||
string? winComment = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinComment);
|
|
||||||
string? winKeywords = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinKeywords);
|
|
||||||
string? winSubject = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinSubject);
|
|
||||||
string? winTitle = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinTitle);
|
|
||||||
string? xResolution = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagXResolution);
|
|
||||||
string? yResolution = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagYResolution);
|
|
||||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTime, out checkDateTime))
|
|
||||||
dateTime = checkDateTime;
|
|
||||||
else
|
|
||||||
dateTime = GetDateTime(exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTime));
|
|
||||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTimeOriginal, out checkDateTime))
|
|
||||||
dateTimeOriginal = checkDateTime;
|
|
||||||
else
|
|
||||||
dateTimeOriginal = GetDateTime(exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTimeOriginal));
|
|
||||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTimeDigitized, out checkDateTime))
|
|
||||||
dateTimeDigitized = checkDateTime;
|
|
||||||
else
|
|
||||||
dateTimeDigitized = GetDateTime(exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTimeDigitized));
|
|
||||||
if (userComment is not null && userComment.Length > 255)
|
|
||||||
userComment = "...";
|
|
||||||
if (aperture is null
|
|
||||||
&& applicationNotes is null
|
|
||||||
&& artist is null
|
|
||||||
&& bitsPerSample is null
|
|
||||||
&& bodySerialNumber is null
|
|
||||||
&& cameraOwnerName is null
|
|
||||||
&& compressedAverageBitsPerPixel is null
|
|
||||||
&& compression is null
|
|
||||||
&& copyright is null
|
|
||||||
&& dateTime is null
|
|
||||||
&& dateTimeDigitized is null
|
|
||||||
&& dateTimeOriginal is null
|
|
||||||
&& documentName is null
|
|
||||||
&& exifVersion is null
|
|
||||||
&& exposureTime is null
|
|
||||||
&& fileSource is null
|
|
||||||
&& imageDescription is null
|
|
||||||
&& imageHeight is null
|
|
||||||
&& imageNumber is null
|
|
||||||
&& imageUniqueId is null
|
|
||||||
&& imageWidth is null
|
|
||||||
&& isoSpeed is null
|
|
||||||
&& lensMake is null
|
|
||||||
&& lensModel is null
|
|
||||||
&& lensSerialNumber is null
|
|
||||||
&& make is null
|
|
||||||
&& makerNote is null
|
|
||||||
&& model is null
|
|
||||||
&& orientation is null
|
|
||||||
&& orientationValue is null
|
|
||||||
&& rating is null
|
|
||||||
&& ratingPercent is null
|
|
||||||
&& securityClassification is null
|
|
||||||
&& shutterSpeed is null
|
|
||||||
&& software is null
|
|
||||||
&& timeZone is null
|
|
||||||
&& timeZoneDigitized is null
|
|
||||||
&& timeZoneOriginal is null
|
|
||||||
&& userComment is null
|
|
||||||
&& winAuthor is null
|
|
||||||
&& winComment is null
|
|
||||||
&& winKeywords is null
|
|
||||||
&& winSubject is null
|
|
||||||
&& winTitle is null
|
|
||||||
&& xResolution is not null
|
|
||||||
&& yResolution is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(aperture,
|
|
||||||
applicationNotes,
|
|
||||||
artist,
|
|
||||||
bitsPerSample,
|
|
||||||
bodySerialNumber,
|
|
||||||
cameraOwnerName,
|
|
||||||
compressedAverageBitsPerPixel,
|
|
||||||
compression,
|
|
||||||
copyright,
|
|
||||||
dateTime,
|
|
||||||
dateTimeDigitized,
|
|
||||||
dateTimeOriginal,
|
|
||||||
documentName,
|
|
||||||
exifVersion,
|
|
||||||
exposureTime,
|
|
||||||
fileSource,
|
|
||||||
imageDescription,
|
|
||||||
imageHeight,
|
|
||||||
imageNumber,
|
|
||||||
imageUniqueId,
|
|
||||||
imageWidth,
|
|
||||||
isoSpeed,
|
|
||||||
lensMake,
|
|
||||||
lensModel,
|
|
||||||
lensSerialNumber,
|
|
||||||
make,
|
|
||||||
makerNote,
|
|
||||||
model,
|
|
||||||
orientation,
|
|
||||||
orientationValue,
|
|
||||||
rating,
|
|
||||||
ratingPercent,
|
|
||||||
securityClassification,
|
|
||||||
shutterSpeed,
|
|
||||||
software,
|
|
||||||
timeZone,
|
|
||||||
timeZoneDigitized,
|
|
||||||
timeZoneOriginal,
|
|
||||||
userComment,
|
|
||||||
winAuthor,
|
|
||||||
winComment,
|
|
||||||
winKeywords,
|
|
||||||
winSubject,
|
|
||||||
winTitle,
|
|
||||||
xResolution,
|
|
||||||
yResolution));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.FileMetadataDirectory[] GetFileMetadataDirectories(string file, IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.FileMetadataDirectory> results = [];
|
|
||||||
IEnumerable<MetadataExtractor.Formats.FileSystem.FileMetadataDirectory> fileMetadataDirectories = directories.OfType<MetadataExtractor.Formats.FileSystem.FileMetadataDirectory>();
|
|
||||||
foreach (MetadataExtractor.Formats.FileSystem.FileMetadataDirectory fileMetadataDirectory in fileMetadataDirectories)
|
|
||||||
{
|
|
||||||
if (fileMetadataDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
DateTime? fileModifiedDate;
|
|
||||||
string? fileName = fileMetadataDirectory.GetDescription(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileName);
|
|
||||||
string? fileSize = fileMetadataDirectory.GetDescription(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileSize);
|
|
||||||
if (fileMetadataDirectory.TryGetDateTime(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileModifiedDate, out DateTime checkDateTime))
|
|
||||||
fileModifiedDate = checkDateTime;
|
|
||||||
else
|
|
||||||
fileModifiedDate = GetDateTime(fileMetadataDirectory.GetString(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileModifiedDate));
|
|
||||||
if (fileName is null || !file.EndsWith(fileName))
|
|
||||||
throw new NotSupportedException($"!{file}.EndsWith({fileName})");
|
|
||||||
if (fileModifiedDate is null && fileName is null && fileSize is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(fileModifiedDate, fileName, fileSize));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.GifHeaderDirectory[] GetGifHeaderDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.GifHeaderDirectory> results = [];
|
|
||||||
IEnumerable<MetadataExtractor.Formats.Gif.GifHeaderDirectory> gifHeaderDirectories = directories.OfType<MetadataExtractor.Formats.Gif.GifHeaderDirectory>();
|
|
||||||
foreach (MetadataExtractor.Formats.Gif.GifHeaderDirectory gifHeaderDirectory in gifHeaderDirectories)
|
|
||||||
{
|
|
||||||
if (gifHeaderDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? imageHeight = gifHeaderDirectory.GetDescription(MetadataExtractor.Formats.Gif.GifHeaderDirectory.TagImageHeight);
|
|
||||||
string? imageWidth = gifHeaderDirectory.GetDescription(MetadataExtractor.Formats.Gif.GifHeaderDirectory.TagImageWidth);
|
|
||||||
if (imageHeight is null && imageWidth is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(imageHeight, imageWidth));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.GpsDirectory[] GetGpsDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.GpsDirectory> results = [];
|
|
||||||
IEnumerable<GpsDirectory> gpsDirectories = directories.OfType<GpsDirectory>();
|
|
||||||
foreach (GpsDirectory gpsDirectory in gpsDirectories)
|
|
||||||
{
|
|
||||||
if (gpsDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
DateTime? timeStamp;
|
|
||||||
string? altitude = gpsDirectory.GetDescription(GpsDirectory.TagAltitude);
|
|
||||||
string? latitude = gpsDirectory.GetDescription(GpsDirectory.TagLatitude);
|
|
||||||
string? latitudeRef = gpsDirectory.GetDescription(GpsDirectory.TagLatitudeRef);
|
|
||||||
string? longitude = gpsDirectory.GetDescription(GpsDirectory.TagLongitude);
|
|
||||||
string? longitudeRef = gpsDirectory.GetDescription(GpsDirectory.TagLongitudeRef);
|
|
||||||
if (gpsDirectory.TryGetDateTime(GpsDirectory.TagTimeStamp, out DateTime checkDateTime))
|
|
||||||
timeStamp = checkDateTime;
|
|
||||||
else
|
|
||||||
timeStamp = GetDateTime(gpsDirectory.GetString(GpsDirectory.TagTimeStamp));
|
|
||||||
if (altitude is null && latitude is null && latitudeRef is null && longitude is null && longitudeRef is null && timeStamp is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(altitude,
|
|
||||||
latitude,
|
|
||||||
latitudeRef,
|
|
||||||
longitude,
|
|
||||||
longitudeRef,
|
|
||||||
timeStamp));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.JpegDirectory[] GetJpegDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.JpegDirectory> results = [];
|
|
||||||
IEnumerable<MetadataExtractor.Formats.Jpeg.JpegDirectory> jpegDirectories = directories.OfType<MetadataExtractor.Formats.Jpeg.JpegDirectory>();
|
|
||||||
foreach (MetadataExtractor.Formats.Jpeg.JpegDirectory jpegDirectory in jpegDirectories)
|
|
||||||
{
|
|
||||||
if (jpegDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? imageHeight = jpegDirectory.GetDescription(MetadataExtractor.Formats.Jpeg.JpegDirectory.TagImageHeight);
|
|
||||||
string? imageWidth = jpegDirectory.GetDescription(MetadataExtractor.Formats.Jpeg.JpegDirectory.TagImageWidth);
|
|
||||||
if (imageHeight is null && imageWidth is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(imageHeight, imageWidth));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.MakernoteDirectory[] GetMakernoteDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.MakernoteDirectory> results = [];
|
|
||||||
IEnumerable<AppleMakernoteDirectory> appleMakernoteDirectories = directories.OfType<AppleMakernoteDirectory>();
|
|
||||||
foreach (AppleMakernoteDirectory appleMakernoteDirectory in appleMakernoteDirectories)
|
|
||||||
{
|
|
||||||
if (appleMakernoteDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? cameraSerialNumber = null;
|
|
||||||
string? firmwareVersion = null;
|
|
||||||
string? qualityAndFileFormat = null;
|
|
||||||
if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat));
|
|
||||||
}
|
|
||||||
IEnumerable<CanonMakernoteDirectory> canonMakernoteDirectories = directories.OfType<CanonMakernoteDirectory>();
|
|
||||||
foreach (CanonMakernoteDirectory canonMakernoteDirectory in canonMakernoteDirectories)
|
|
||||||
{
|
|
||||||
if (canonMakernoteDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? cameraSerialNumber = canonMakernoteDirectory.GetDescription(CanonMakernoteDirectory.TagModelId);
|
|
||||||
string? firmwareVersion = canonMakernoteDirectory.GetDescription(CanonMakernoteDirectory.TagCanonFirmwareVersion);
|
|
||||||
string? qualityAndFileFormat = canonMakernoteDirectory.GetDescription(CanonMakernoteDirectory.CameraSettings.TagQuality);
|
|
||||||
if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat));
|
|
||||||
}
|
|
||||||
IEnumerable<NikonType2MakernoteDirectory> nikonType2MakernoteDirectories = directories.OfType<NikonType2MakernoteDirectory>();
|
|
||||||
foreach (NikonType2MakernoteDirectory nikonType2MakernoteDirectory in nikonType2MakernoteDirectories)
|
|
||||||
{
|
|
||||||
if (nikonType2MakernoteDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? cameraSerialNumber = nikonType2MakernoteDirectory.GetDescription(NikonType2MakernoteDirectory.TagCameraSerialNumber);
|
|
||||||
string? firmwareVersion = nikonType2MakernoteDirectory.GetDescription(NikonType2MakernoteDirectory.TagFirmwareVersion);
|
|
||||||
string? qualityAndFileFormat = nikonType2MakernoteDirectory.GetDescription(NikonType2MakernoteDirectory.TagQualityAndFileFormat);
|
|
||||||
if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat));
|
|
||||||
}
|
|
||||||
IEnumerable<OlympusMakernoteDirectory> olympusMakernoteDirectories = directories.OfType<OlympusMakernoteDirectory>();
|
|
||||||
foreach (OlympusMakernoteDirectory olympusMakernoteDirectory in olympusMakernoteDirectories)
|
|
||||||
{
|
|
||||||
if (olympusMakernoteDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? cameraSerialNumber = olympusMakernoteDirectory.GetDescription(OlympusMakernoteDirectory.TagSerialNumber1);
|
|
||||||
string? firmwareVersion = olympusMakernoteDirectory.GetDescription(OlympusMakernoteDirectory.TagBodyFirmwareVersion);
|
|
||||||
string? qualityAndFileFormat = olympusMakernoteDirectory.GetDescription(OlympusMakernoteDirectory.TagJpegQuality);
|
|
||||||
if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat));
|
|
||||||
}
|
|
||||||
IEnumerable<PanasonicMakernoteDirectory> panasonicMakernoteDirectories = directories.OfType<PanasonicMakernoteDirectory>();
|
|
||||||
foreach (PanasonicMakernoteDirectory panasonicMakernoteDirectory in panasonicMakernoteDirectories)
|
|
||||||
{
|
|
||||||
if (panasonicMakernoteDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? cameraSerialNumber = panasonicMakernoteDirectory.GetDescription(PanasonicMakernoteDirectory.TagInternalSerialNumber);
|
|
||||||
string? firmwareVersion = panasonicMakernoteDirectory.GetDescription(PanasonicMakernoteDirectory.TagFirmwareVersion);
|
|
||||||
string? qualityAndFileFormat = panasonicMakernoteDirectory.GetDescription(PanasonicMakernoteDirectory.TagQualityMode);
|
|
||||||
if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat));
|
|
||||||
}
|
|
||||||
IEnumerable<SamsungType2MakernoteDirectory> samsungType2MakernoteDirectories = directories.OfType<SamsungType2MakernoteDirectory>();
|
|
||||||
foreach (SamsungType2MakernoteDirectory samsungType2MakernoteDirectory in samsungType2MakernoteDirectories)
|
|
||||||
{
|
|
||||||
if (samsungType2MakernoteDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? cameraSerialNumber = samsungType2MakernoteDirectory.GetDescription(SamsungType2MakernoteDirectory.TagSerialNumber);
|
|
||||||
string? firmwareVersion = samsungType2MakernoteDirectory.GetDescription(SamsungType2MakernoteDirectory.TagFirmwareName);
|
|
||||||
string? qualityAndFileFormat = null;
|
|
||||||
if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat));
|
|
||||||
}
|
|
||||||
IEnumerable<SonyType6MakernoteDirectory> sonyType6MakernoteDirectories = directories.OfType<SonyType6MakernoteDirectory>();
|
|
||||||
foreach (SonyType6MakernoteDirectory sonyType6MakernoteDirectory in sonyType6MakernoteDirectories)
|
|
||||||
{
|
|
||||||
if (sonyType6MakernoteDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? cameraSerialNumber = null;
|
|
||||||
string? firmwareVersion = null;
|
|
||||||
string? qualityAndFileFormat = null;
|
|
||||||
if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.PhotoshopDirectory[] GetPhotoshopDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.PhotoshopDirectory> results = [];
|
|
||||||
IEnumerable<MetadataExtractor.Formats.Photoshop.PhotoshopDirectory> photoshopDirectories = directories.OfType<MetadataExtractor.Formats.Photoshop.PhotoshopDirectory>();
|
|
||||||
foreach (MetadataExtractor.Formats.Photoshop.PhotoshopDirectory photoshopDirectory in photoshopDirectories)
|
|
||||||
{
|
|
||||||
if (photoshopDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? jpegQuality = photoshopDirectory.GetDescription(MetadataExtractor.Formats.Photoshop.PhotoshopDirectory.TagJpegQuality);
|
|
||||||
string? url = photoshopDirectory.GetDescription(MetadataExtractor.Formats.Photoshop.PhotoshopDirectory.TagUrl);
|
|
||||||
if (jpegQuality is null && url is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(jpegQuality, url));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.PngDirectory[] GetPngDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.PngDirectory> results = [];
|
|
||||||
IEnumerable<MetadataExtractor.Formats.Png.PngDirectory> pngDirectories = directories.OfType<MetadataExtractor.Formats.Png.PngDirectory>();
|
|
||||||
foreach (MetadataExtractor.Formats.Png.PngDirectory pngDirectory in pngDirectories)
|
|
||||||
{
|
|
||||||
if (pngDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? imageHeight = pngDirectory.GetDescription(MetadataExtractor.Formats.Png.PngDirectory.TagImageHeight);
|
|
||||||
string? imageWidth = pngDirectory.GetDescription(MetadataExtractor.Formats.Png.PngDirectory.TagImageWidth);
|
|
||||||
string? textualData = pngDirectory.GetDescription(MetadataExtractor.Formats.Png.PngDirectory.TagTextualData);
|
|
||||||
if (imageHeight is null && imageWidth is null && textualData is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(imageHeight, imageWidth, textualData));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.QuickTimeMovieHeaderDirectory[] GetQuickTimeMovieHeaderDirectoryDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.QuickTimeMovieHeaderDirectory> results = [];
|
|
||||||
IEnumerable<MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory> quickTimeMovieHeaderDirectories = directories.OfType<MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory>();
|
|
||||||
foreach (MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory quickTimeMovieHeaderDirectory in quickTimeMovieHeaderDirectories)
|
|
||||||
{
|
|
||||||
if (quickTimeMovieHeaderDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
DateTime? created;
|
|
||||||
if (quickTimeMovieHeaderDirectory.TryGetDateTime(MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory.TagCreated, out DateTime checkDateTime))
|
|
||||||
created = checkDateTime;
|
|
||||||
else
|
|
||||||
created = GetDateTime(quickTimeMovieHeaderDirectory.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory.TagCreated));
|
|
||||||
if (created is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(created));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.QuickTimeTrackHeaderDirectory[] GetQuickTimeTrackHeaderDirectoryDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.QuickTimeTrackHeaderDirectory> results = [];
|
|
||||||
IEnumerable<MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory> quickTimeTrackHeaderDirectories = directories.OfType<MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory>();
|
|
||||||
foreach (MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory quickTimeTrackHeaderDirectory in quickTimeTrackHeaderDirectories)
|
|
||||||
{
|
|
||||||
if (quickTimeTrackHeaderDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
DateTime? created;
|
|
||||||
if (quickTimeTrackHeaderDirectory.TryGetDateTime(MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory.TagCreated, out DateTime checkDateTime))
|
|
||||||
created = checkDateTime;
|
|
||||||
else
|
|
||||||
created = GetDateTime(quickTimeTrackHeaderDirectory.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory.TagCreated));
|
|
||||||
if (created is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(created));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.WebPDirectory[] GetWebPDirectories(IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
List<Models.Exif.WebPDirectory> results = [];
|
|
||||||
IEnumerable<MetadataExtractor.Formats.WebP.WebPDirectory> webPDirectories = directories.OfType<MetadataExtractor.Formats.WebP.WebPDirectory>();
|
|
||||||
foreach (MetadataExtractor.Formats.WebP.WebPDirectory webPDirectory in webPDirectories)
|
|
||||||
{
|
|
||||||
if (webPDirectory.Tags.Count == 0)
|
|
||||||
continue;
|
|
||||||
string? imageHeight = webPDirectory.GetDescription(MetadataExtractor.Formats.WebP.WebPDirectory.TagImageHeight);
|
|
||||||
string? imageWidth = webPDirectory.GetDescription(MetadataExtractor.Formats.WebP.WebPDirectory.TagImageWidth);
|
|
||||||
if (imageHeight is null && imageWidth is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(imageHeight, imageWidth));
|
|
||||||
}
|
|
||||||
return results.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Models.Exif.ExifDirectory Covert(FileInfo fileInfo, System.Drawing.Size? size, int id, IReadOnlyList<MetadataExtractor.Directory> directories)
|
|
||||||
{
|
|
||||||
Models.Exif.ExifDirectory result;
|
|
||||||
Models.Exif.AviDirectory[] aviDirectories = GetAviDirectories(directories);
|
|
||||||
Models.Exif.GpsDirectory[] gpsDirectories = GetGpsDirectories(directories);
|
|
||||||
Models.Exif.PngDirectory[] pngDirectories = GetPngDirectories(directories);
|
|
||||||
Models.Exif.JpegDirectory[] jpegDirectories = GetJpegDirectories(directories);
|
|
||||||
Models.Exif.WebPDirectory[] webPDirectories = GetWebPDirectories(directories);
|
|
||||||
Models.Exif.ExifDirectoryBase[] exifBaseDirectories = GetExifBaseDirectories(directories);
|
|
||||||
Models.Exif.GifHeaderDirectory[] gifHeaderDirectories = GetGifHeaderDirectories(directories);
|
|
||||||
Models.Exif.MakernoteDirectory[] MakernoteDirectories = GetMakernoteDirectories(directories);
|
|
||||||
Models.Exif.PhotoshopDirectory[] photoshopDirectories = GetPhotoshopDirectories(directories);
|
|
||||||
Models.Exif.FileMetadataDirectory[] fileMetadataDirectories = GetFileMetadataDirectories(fileInfo.FullName, directories);
|
|
||||||
Models.Exif.QuickTimeMovieHeaderDirectory[] quickTimeMovieHeaderDirectories = GetQuickTimeMovieHeaderDirectoryDirectories(directories);
|
|
||||||
Models.Exif.QuickTimeTrackHeaderDirectory[] quickTimeTrackHeaderDirectories = GetQuickTimeTrackHeaderDirectoryDirectories(directories);
|
|
||||||
result = new(aviDirectories,
|
|
||||||
exifBaseDirectories,
|
|
||||||
fileMetadataDirectories,
|
|
||||||
gifHeaderDirectories,
|
|
||||||
gpsDirectories,
|
|
||||||
size?.Height,
|
|
||||||
id,
|
|
||||||
jpegDirectories,
|
|
||||||
MakernoteDirectories,
|
|
||||||
fileInfo.Name,
|
|
||||||
photoshopDirectories,
|
|
||||||
pngDirectories,
|
|
||||||
quickTimeMovieHeaderDirectories,
|
|
||||||
quickTimeTrackHeaderDirectories,
|
|
||||||
webPDirectories,
|
|
||||||
size?.Width);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static Models.Exif.ExifDirectory GetExifDirectory(FileInfo fileInfo)
|
|
||||||
{
|
|
||||||
Models.Exif.ExifDirectory result;
|
|
||||||
int id = 1;
|
|
||||||
System.Drawing.Size? size;
|
|
||||||
try
|
|
||||||
{ size = Dimensions.GetDimensions(fileInfo.FullName); }
|
|
||||||
catch (Exception)
|
|
||||||
{ size = null; }
|
|
||||||
IReadOnlyList<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(fileInfo.FullName);
|
|
||||||
result = Covert(fileInfo, size, id, directories);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
using File_Folder_Helper.Models;
|
|
||||||
using File_Folder_Helper.Models.Exif;
|
|
||||||
using File_Folder_Helper.Models.Face;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Helpers.Exif;
|
|
||||||
|
|
||||||
internal static class HelperExif
|
|
||||||
{
|
|
||||||
|
|
||||||
private static ReadOnlyCollection<FaceFile> GetCollection(ExifDirectoryBase[]? exifDirectoryBases)
|
|
||||||
{
|
|
||||||
List<FaceFile> results = [];
|
|
||||||
if (exifDirectoryBases is not null)
|
|
||||||
{
|
|
||||||
string? json;
|
|
||||||
FaceFile[]? collection;
|
|
||||||
foreach (ExifDirectoryBase exifDirectoryBase in exifDirectoryBases)
|
|
||||||
{
|
|
||||||
json = exifDirectoryBase.Artist;
|
|
||||||
if (string.IsNullOrEmpty(json))
|
|
||||||
continue;
|
|
||||||
collection = JsonSerializer.Deserialize(json, FaceFileCollectionGenerationContext.Default.FaceFileArray);
|
|
||||||
if (collection is null)
|
|
||||||
continue;
|
|
||||||
results.AddRange(collection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new(results);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void DragAndDrop(ILogger<Worker> logger, string argZero)
|
|
||||||
{
|
|
||||||
FileInfo fileInfo = new(argZero);
|
|
||||||
logger.LogInformation("<{argZero}> exists", argZero);
|
|
||||||
ExifDirectory exifDirectory = Exif.GetExifDirectory(fileInfo);
|
|
||||||
string directory = Path.GetDirectoryName(argZero) ?? throw new Exception();
|
|
||||||
string[] files = Directory.GetFiles(directory, "*.json", SearchOption.TopDirectoryOnly);
|
|
||||||
string? json = files.Length != 1 ? string.Empty : File.ReadAllText(files[0]);
|
|
||||||
ReadOnlyCollection<FaceFile> collection = GetCollection(exifDirectory.ExifBaseDirectories);
|
|
||||||
logger.LogInformation("<{collection}> value", collection.Count);
|
|
||||||
Dictionary<long, Person>? people = string.IsNullOrEmpty(json) ? [] : JsonSerializer.Deserialize(json, PeopleSourceGenerationContext.Default.DictionaryInt64Person) ?? throw new NullReferenceException();
|
|
||||||
logger.LogInformation("<{people}> value", people?.Count);
|
|
||||||
foreach (FaceFile faceFile in collection)
|
|
||||||
{
|
|
||||||
if (faceFile.MappingFromPerson is null)
|
|
||||||
logger.LogInformation("<{Confidence}> value", faceFile.Location?.Confidence);
|
|
||||||
else
|
|
||||||
logger.LogInformation("<{DisplayDirectoryName}> value", faceFile.MappingFromPerson.DisplayDirectoryName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
43
Helpers/ExifHelper.cs
Normal file
43
Helpers/ExifHelper.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using File_Folder_Helper.Models;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Phares.Metadata.Models.Stateless;
|
||||||
|
using Phares.Shared.Models;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Helpers;
|
||||||
|
|
||||||
|
internal static partial class ExifHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static void DragAndDrop(ILogger<Worker> logger, string argZero)
|
||||||
|
{
|
||||||
|
string? json;
|
||||||
|
string secrets = "L:/Git/AA/Rename/.vscode/.UserSecrets/secrets.json";
|
||||||
|
json = !File.Exists(secrets) ? null : File.ReadAllText(secrets);
|
||||||
|
if (string.IsNullOrEmpty(json))
|
||||||
|
throw new Exception($"Use mklink to map user secrets for rename!");
|
||||||
|
ResultSettings? resultSettings = JsonSerializer.Deserialize(json, ResultSettingsSourceGenerationContext.Default.ResultSettings) ??
|
||||||
|
throw new Exception(nameof(ResultSettings));
|
||||||
|
MetadataSettings? metadataSettings = JsonSerializer.Deserialize(json, MetadataSettingsSourceGenerationContext.Default.MetadataSettings) ??
|
||||||
|
throw new Exception(nameof(MetadataSettings));
|
||||||
|
FileInfo fileInfo = new(argZero);
|
||||||
|
logger.LogInformation("<{argZero}> exists", argZero);
|
||||||
|
if (!string.IsNullOrEmpty(fileInfo.Directory?.FullName))
|
||||||
|
{
|
||||||
|
string[] files = Directory.GetFiles(fileInfo.Directory.FullName, "*.json", SearchOption.TopDirectoryOnly);
|
||||||
|
json = files.Length != 1 ? string.Empty : File.ReadAllText(files[0]);
|
||||||
|
Dictionary<long, Person>? people = string.IsNullOrEmpty(json) ? [] : JsonSerializer.Deserialize(json, PeopleSourceGenerationContext.Default.DictionaryInt64Person) ?? throw new NullReferenceException();
|
||||||
|
logger.LogInformation("<{people}> value", people?.Count);
|
||||||
|
}
|
||||||
|
ExifDirectory? exifDirectory = IMetadata.GetExifDirectory(resultSettings, metadataSettings, fileInfo);
|
||||||
|
FaceFile? faceFile = IMetadata.GetFaceFile(exifDirectory);
|
||||||
|
if (faceFile is not null)
|
||||||
|
{
|
||||||
|
if (faceFile.MappingFromPerson is null)
|
||||||
|
logger.LogInformation("<{Confidence}> value", faceFile.Location?.Confidence);
|
||||||
|
else
|
||||||
|
logger.LogInformation("<{DisplayDirectoryName}> value", faceFile.MappingFromPerson.DisplayDirectoryName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,24 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record AviDirectory(DateTime? DateTimeOriginal,
|
|
||||||
string? Duration,
|
|
||||||
string? Height,
|
|
||||||
string? Width)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, AviDirectorySourceGenerationContext.Default.AviDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(AviDirectory))]
|
|
||||||
public partial class AviDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record ExifDirectory(AviDirectory[] AviDirectories,
|
|
||||||
ExifDirectoryBase[] ExifBaseDirectories,
|
|
||||||
FileMetadataDirectory[] FileMetadataDirectories,
|
|
||||||
GifHeaderDirectory[] GifHeaderDirectories,
|
|
||||||
GpsDirectory[] GpsDirectories,
|
|
||||||
int? Height,
|
|
||||||
int? Id,
|
|
||||||
JpegDirectory[] JpegDirectories,
|
|
||||||
MakernoteDirectory[] MakernoteDirectories,
|
|
||||||
string OriginalFileName,
|
|
||||||
PhotoshopDirectory[] PhotoshopDirectories,
|
|
||||||
PngDirectory[] PngDirectories,
|
|
||||||
QuickTimeMovieHeaderDirectory[] QuickTimeMovieHeaderDirectories,
|
|
||||||
QuickTimeTrackHeaderDirectory[] QuickTimeTrackHeaderDirectories,
|
|
||||||
WebPDirectory[] WebPDirectories,
|
|
||||||
int? Width)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, ExifDirectorySourceGenerationContext.Default.ExifDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
|
||||||
[JsonSerializable(typeof(ExifDirectory))]
|
|
||||||
public partial class ExifDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record ExifDirectoryBase(string? Aperture,
|
|
||||||
string? ApplicationNotes,
|
|
||||||
string? Artist,
|
|
||||||
string? BitsPerSample,
|
|
||||||
string? BodySerialNumber,
|
|
||||||
string? CameraOwnerName,
|
|
||||||
string? CompressedAverageBitsPerPixel,
|
|
||||||
string? Compression,
|
|
||||||
string? Copyright,
|
|
||||||
DateTime? DateTime,
|
|
||||||
DateTime? DateTimeDigitized,
|
|
||||||
DateTime? DateTimeOriginal,
|
|
||||||
string? DocumentName,
|
|
||||||
string? ExifVersion,
|
|
||||||
string? ExposureTime,
|
|
||||||
string? FileSource,
|
|
||||||
string? ImageDescription,
|
|
||||||
string? ImageHeight,
|
|
||||||
string? ImageNumber,
|
|
||||||
string? ImageUniqueId,
|
|
||||||
string? ImageWidth,
|
|
||||||
string? IsoSpeed,
|
|
||||||
string? LensMake,
|
|
||||||
string? LensModel,
|
|
||||||
string? LensSerialNumber,
|
|
||||||
string? Make,
|
|
||||||
string? MakerNote,
|
|
||||||
string? Model,
|
|
||||||
string? Orientation,
|
|
||||||
int? OrientationValue,
|
|
||||||
string? Rating,
|
|
||||||
string? RatingPercent,
|
|
||||||
string? SecurityClassification,
|
|
||||||
string? ShutterSpeed,
|
|
||||||
string? Software,
|
|
||||||
string? TimeZone,
|
|
||||||
string? TimeZoneDigitized,
|
|
||||||
string? TimeZoneOriginal,
|
|
||||||
string? UserComment,
|
|
||||||
string? WinAuthor,
|
|
||||||
string? WinComment,
|
|
||||||
string? WinKeywords,
|
|
||||||
string? WinSubject,
|
|
||||||
string? WinTitle,
|
|
||||||
string? XResolution,
|
|
||||||
string? YResolution)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, ExifDirectoryBaseSourceGenerationContext.Default.ExifDirectoryBase);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(ExifDirectoryBase))]
|
|
||||||
public partial class ExifDirectoryBaseSourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record FileMetadataDirectory(DateTime? FileModifiedDate,
|
|
||||||
string? FileName,
|
|
||||||
string? FileSize)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, FileMetadataDirectorySourceGenerationContext.Default.FileMetadataDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(FileMetadataDirectory))]
|
|
||||||
public partial class FileMetadataDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record GifHeaderDirectory(string? ImageHeight,
|
|
||||||
string? ImageWidth)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, GifHeaderDirectorySourceGenerationContext.Default.GifHeaderDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(GifHeaderDirectory))]
|
|
||||||
public partial class GifHeaderDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record GpsDirectory(string? Altitude,
|
|
||||||
string? Latitude,
|
|
||||||
string? LatitudeRef,
|
|
||||||
string? Longitude,
|
|
||||||
string? LongitudeRef,
|
|
||||||
DateTime? TimeStamp)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, GpsDirectorySourceGenerationContext.Default.GpsDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(GpsDirectory))]
|
|
||||||
public partial class GpsDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record JpegDirectory(string? ImageHeight,
|
|
||||||
string? ImageWidth)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, JpegDirectorySourceGenerationContext.Default.JpegDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(JpegDirectory))]
|
|
||||||
public partial class JpegDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record MakernoteDirectory(string? CameraSerialNumber,
|
|
||||||
string? FirmwareVersion,
|
|
||||||
string? QualityAndFileFormat)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, MakernoteDirectorySourceGenerationContext.Default.MakernoteDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(MakernoteDirectory))]
|
|
||||||
public partial class MakernoteDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record PhotoshopDirectory(string? JpegQuality,
|
|
||||||
string? Url)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, PhotoshopDirectorySourceGenerationContext.Default.PhotoshopDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(PhotoshopDirectory))]
|
|
||||||
public partial class PhotoshopDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record PngDirectory(string? ImageHeight,
|
|
||||||
string? ImageWidth,
|
|
||||||
string? TextualData)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, PngDirectorySourceGenerationContext.Default.PngDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(PngDirectory))]
|
|
||||||
public partial class PngDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record QuickTimeMovieHeaderDirectory(DateTime? Created)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, QuickTimeMovieHeaderDirectorySourceGenerationContext.Default.QuickTimeMovieHeaderDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(QuickTimeMovieHeaderDirectory))]
|
|
||||||
public partial class QuickTimeMovieHeaderDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record QuickTimeTrackHeaderDirectory(DateTime? Created)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, QuickTimeTrackHeaderDirectorySourceGenerationContext.Default.QuickTimeTrackHeaderDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(QuickTimeTrackHeaderDirectory))]
|
|
||||||
public partial class QuickTimeTrackHeaderDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Exif;
|
|
||||||
|
|
||||||
public record WebPDirectory(string? ImageHeight,
|
|
||||||
string? ImageWidth)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, WebPDirectorySourceGenerationContext.Default.WebPDirectory);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(WebPDirectory))]
|
|
||||||
public partial class WebPDirectorySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Face;
|
|
||||||
|
|
||||||
public record FaceEncoding(double[] RawEncoding, int Size);
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = false)]
|
|
||||||
[JsonSerializable(typeof(FaceEncoding))]
|
|
||||||
public partial class FaceEncodingGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Face;
|
|
||||||
|
|
||||||
public record FaceFile(int? AreaPermyriad,
|
|
||||||
int? ConfidencePercent,
|
|
||||||
string? DMS,
|
|
||||||
DateTime DateTime,
|
|
||||||
FaceEncoding? FaceEncoding,
|
|
||||||
Dictionary<FacePart, FacePoint[]>? FaceParts,
|
|
||||||
Location? Location,
|
|
||||||
string? Maker,
|
|
||||||
MappingFromPerson? MappingFromPerson,
|
|
||||||
string? Model,
|
|
||||||
OutputResolution? OutputResolution);
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = false)]
|
|
||||||
[JsonSerializable(typeof(FaceFile))]
|
|
||||||
public partial class FaceFileGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
|
||||||
[JsonSerializable(typeof(FaceFile[]))]
|
|
||||||
public partial class FaceFileCollectionGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
|
||||||
[JsonSerializable(typeof(FaceFile[]))]
|
|
||||||
public partial class FaceFileCollectionWriteIndentedGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
namespace File_Folder_Helper.Models.Face;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the part of face.
|
|
||||||
/// </summary>
|
|
||||||
public enum FacePart
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the chin.
|
|
||||||
/// </summary>
|
|
||||||
Chin = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the left eyebrow.
|
|
||||||
/// </summary>
|
|
||||||
LeftEyebrow = 17,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the right eyebrow.
|
|
||||||
/// </summary>
|
|
||||||
RightEyebrow = 22,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the nose bridge.
|
|
||||||
/// </summary>
|
|
||||||
NoseBridge = 27,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the nose tip.
|
|
||||||
/// </summary>
|
|
||||||
NoseTip = 31,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the left eye.
|
|
||||||
/// </summary>
|
|
||||||
LeftEye = 36,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the right eye.
|
|
||||||
/// </summary>
|
|
||||||
RightEye = 42,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the top lip.
|
|
||||||
/// </summary>
|
|
||||||
TopLip = 48,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the bottom lip.
|
|
||||||
/// </summary>
|
|
||||||
BottomLip = 55
|
|
||||||
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
using System.Drawing;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Face;
|
|
||||||
|
|
||||||
[method: JsonConstructor]
|
|
||||||
public class FacePoint(int index, int x, int y)
|
|
||||||
{
|
|
||||||
public int Index { get; } = index;
|
|
||||||
public int X { get; } = x;
|
|
||||||
public int Y { get; } = y;
|
|
||||||
|
|
||||||
private readonly Point _Point = new(x, y);
|
|
||||||
|
|
||||||
public override bool Equals(object? obj) => obj is FacePoint point && Equals(point);
|
|
||||||
|
|
||||||
#pragma warning disable IDE0070
|
|
||||||
public override int GetHashCode()
|
|
||||||
#pragma warning restore IDE0070
|
|
||||||
{
|
|
||||||
int hashCode = 1861411795;
|
|
||||||
hashCode = (hashCode * -1521134295) + _Point.GetHashCode();
|
|
||||||
hashCode = (hashCode * -1521134295) + Index.GetHashCode();
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(FacePoint? facePoint)
|
|
||||||
{
|
|
||||||
return facePoint is not null
|
|
||||||
&& X == facePoint.X
|
|
||||||
&& Y == facePoint.Y
|
|
||||||
&& Index == facePoint.Index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator ==(FacePoint point1, FacePoint point2) => point1.Equals(point2);
|
|
||||||
|
|
||||||
public static bool operator !=(FacePoint point1, FacePoint point2) => !(point1 == point2);
|
|
||||||
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Face;
|
|
||||||
|
|
||||||
[method: JsonConstructor]
|
|
||||||
public class Location(int bottom, double confidence, int left, int right, int top) : IEquatable<Location>
|
|
||||||
{
|
|
||||||
|
|
||||||
public int Bottom { init; get; } = bottom;
|
|
||||||
public double Confidence { init; get; } = confidence;
|
|
||||||
public int Left { init; get; } = left;
|
|
||||||
public int Right { init; get; } = right;
|
|
||||||
public int Top { init; get; } = top;
|
|
||||||
|
|
||||||
public override bool Equals(object? obj) => Equals(obj as Location);
|
|
||||||
|
|
||||||
#pragma warning disable IDE0070
|
|
||||||
public override int GetHashCode()
|
|
||||||
#pragma warning restore IDE0070
|
|
||||||
{
|
|
||||||
int hashCode = -773114317;
|
|
||||||
hashCode = (hashCode * -1521134295) + Bottom.GetHashCode();
|
|
||||||
hashCode = (hashCode * -1521134295) + Left.GetHashCode();
|
|
||||||
hashCode = (hashCode * -1521134295) + Right.GetHashCode();
|
|
||||||
hashCode = (hashCode * -1521134295) + Top.GetHashCode();
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(Location? location)
|
|
||||||
{
|
|
||||||
return location is not null
|
|
||||||
&& Bottom == location.Bottom
|
|
||||||
&& Left == location.Left
|
|
||||||
&& Right == location.Right
|
|
||||||
&& Top == location.Top;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator ==(Location location1, Location location2) => EqualityComparer<Location>.Default.Equals(location1, location2);
|
|
||||||
|
|
||||||
public static bool operator !=(Location location1, Location location2) => !(location1 == location2);
|
|
||||||
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models.Face;
|
|
||||||
|
|
||||||
public record MappingFromPerson(int? ApproximateYears,
|
|
||||||
string DisplayDirectoryName,
|
|
||||||
long PersonKey,
|
|
||||||
string SegmentB)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, MappingFromPersonGenerationContext.Default.MappingFromPerson);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(MappingFromPerson))]
|
|
||||||
public partial class MappingFromPersonGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
namespace File_Folder_Helper.Models.Face;
|
|
||||||
|
|
||||||
public record OutputResolution(int Height,
|
|
||||||
int Orientation,
|
|
||||||
int Width);
|
|
@ -1,50 +0,0 @@
|
|||||||
const axios = require('axios');
|
|
||||||
|
|
||||||
const url = 'https://immich.bchs.duckdns.org';
|
|
||||||
|
|
||||||
let config = {
|
|
||||||
method: 'get',
|
|
||||||
maxBodyLength: Infinity,
|
|
||||||
// url: url + '/api/users',
|
|
||||||
url: url + '/api/assets/f89d0de1-2762-4f9e-b60e-c7eeec93c4e9',
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'x-api-key': 'Pm2CbhJvgStEPAFKRVclW88qrOAy79OeIEcfj3k'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
axios.request(config)
|
|
||||||
.then((response) => {
|
|
||||||
console.log(JSON.stringify(response.data));
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
// let data = JSON.stringify({
|
|
||||||
// "avatar": {
|
|
||||||
// "color": "green"
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let configB = {
|
|
||||||
// method: 'put',
|
|
||||||
// maxBodyLength: Infinity,
|
|
||||||
// url: url + '/api/users/me/preferences',
|
|
||||||
// headers: {
|
|
||||||
// 'Content-Type': 'application/json',
|
|
||||||
// 'Accept': 'application/json',
|
|
||||||
// 'x-api-key': 'Pm2CbhJvgStEPAFKRVclW88qrOAy79OeIEcfj3k'
|
|
||||||
// },
|
|
||||||
// data: data
|
|
||||||
// };
|
|
||||||
|
|
||||||
// axios.request(configB)
|
|
||||||
// .then((response) => {
|
|
||||||
// console.log(JSON.stringify(response.data));
|
|
||||||
// })
|
|
||||||
// .catch((error) => {
|
|
||||||
// console.log(error);
|
|
||||||
// });
|
|
||||||
|
|
@ -235,7 +235,7 @@ public class Worker : BackgroundService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_AppSettings.ValidImageFormatExtensions.Contains(extension) && File.Exists(_Args[0]))
|
else if (_AppSettings.ValidImageFormatExtensions.Contains(extension) && File.Exists(_Args[0]))
|
||||||
Helpers.Exif.HelperExif.DragAndDrop(_Logger, _Args[0]);
|
Helpers.ExifHelper.DragAndDrop(_Logger, _Args[0]);
|
||||||
else
|
else
|
||||||
throw new Exception(_Args[0]);
|
throw new Exception(_Args[0]);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user