Compare commits

..

4 Commits

Author SHA1 Message Date
84d85094a3 Edits for backup (Day-Helper-2024-12-17) 2025-07-21 17:49:07 -07:00
c3acd17a0e Deleted
immich.js
download-work-items.http
2025-07-21 16:14:51 -07:00
8ecea05fe8 xmp from my face-file after using the digiKam maintenance tool to create xmp files
Alignment with Phares 8.0.118.14751 for Shared and Metadata
2025-07-20 18:46:59 -07:00
d57be048e7 SECS/GEM log-to-trace (Day-Helper-2025-07-10)
java-script-object-notation-to-reactor (Day-Helper-2025-07-09)

Dynamic extension for (Day-Helper-2025-07-01)
2025-07-10 13:07:42 -07:00
42 changed files with 1064 additions and 1441 deletions

View File

@ -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
View File

@ -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
View File

@ -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",

View File

@ -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);
} }
} }
} }

View File

@ -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

View File

@ -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++) {

View File

@ -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]);

View File

@ -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);

View File

@ -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;
} }
} }

View File

@ -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
} }
} }

View 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;
}
}
}
}
}
}
}

View 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;
}
}

View 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
}
}

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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" />

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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
View 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);
}
}
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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
{
}

View File

@ -1,5 +0,0 @@
namespace File_Folder_Helper.Models.Face;
public record OutputResolution(int Height,
int Orientation,
int Width);

View File

@ -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);
// });

View File

@ -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]);
} }