Dynamic extension for (Day-Helper-2025-07-01)

This commit is contained in:
2025-07-09 13:03:16 -07:00
parent 89bb87bd14
commit 342af4a210
3 changed files with 178 additions and 57 deletions

32
.vscode/launch.json vendored
View File

@ -11,6 +11,26 @@
"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",
"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 +41,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",

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,24 +27,27 @@ 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, destinationDirectory, directories);
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, Dictionary<string, string> columnMapping, string destinationDirectory, string[] directories) {
string text;
string? json; string? json;
string[] files; string[] files;
string markdown; string markdown;
@ -51,7 +59,7 @@ internal static partial class Helper20250701 {
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,35 +85,43 @@ 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(logger, json);
if (string.IsNullOrEmpty(pipeTable)) {
logger.LogWarning("pipeTable is null");
continue;
}
markdown = $"# {fileInfo.Name}{Environment.NewLine}{Environment.NewLine}{pipeTable}{Environment.NewLine}";
text = markdown;
} else if (extension == ".json") {
json = GetJavaScriptObjectNotation(logger, file);
if (string.IsNullOrEmpty(json)) {
logger.LogWarning("json is null");
continue;
}
text = json;
} else {
logger.LogWarning("{extension} is not mapped!", extension);
continue; continue;
} }
File.WriteAllText(checkFile, collections); File.WriteAllText(checkFile, text);
File.SetLastWriteTime(checkFile, fileInfo.LastAccessTime); File.SetLastWriteTime(checkFile, fileInfo.LastAccessTime);
if (!string.IsNullOrEmpty(destinationDirectory)) {
continue;
}
json = GetJavaScriptObjectNotation(logger, file);
if (string.IsNullOrEmpty(json)) {
logger.LogWarning("json is null");
continue;
}
File.WriteAllText($"{checkFile}.md", json);
File.SetLastWriteTime($"{checkFile}.md", fileInfo.LastAccessTime);
pipeTable = GetPipeTable(logger, json);
if (string.IsNullOrEmpty(pipeTable)) {
logger.LogWarning("pipeTable is null");
continue;
}
markdown = $"# {fileInfo.Name}{Environment.NewLine}{Environment.NewLine}{pipeTable}{Environment.NewLine}";
File.WriteAllText($"{checkFile}.md", markdown);
File.SetLastWriteTime($"{checkFile}.md", fileInfo.LastAccessTime);
logger.LogInformation("<{checkFile}> was written", checkFile); logger.LogInformation("<{checkFile}> was written", checkFile);
} }
} }
@ -239,42 +255,139 @@ 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}\"PDSF\":{Environment.NewLine}{json}";
result = string.Concat(
'{',
Environment.NewLine,
'"',
"Count",
'"',
": ",
records.Count,
',',
Environment.NewLine,
'"',
"Records",
'"',
": ",
Environment.NewLine,
'[',
Environment.NewLine,
string.Join($",{Environment.NewLine}", records),
Environment.NewLine,
']',
footerText,
'}');
return result; return result;
#pragma warning restore CA1845, IDE0057 #pragma warning restore CA1845, IDE0057
} }
private static ReadOnlyCollection<string> GetFooterLines(string[] lines, int i) {
List<string> results = [];
for (int j = i; j < lines.Length; j++) {
results.Add(lines[j]);
if (lines[j].StartsWith("END_HEADER"))
break;
}
return results.AsReadOnly();
}
private static ReadOnlyDictionary<string, string> GetFooterKeyValuePairs(ReadOnlyCollection<string> footerLines) {
Dictionary<string, string> results = [];
string[] segments;
foreach (string footerLine in footerLines) {
segments = footerLine.Split('\t');
if (segments.Length != 2 || string.IsNullOrEmpty(segments[1].Trim())) {
continue;
}
if (segments[1].Contains(';')) {
continue;
} else {
results.Add(segments[0], segments[1]);
}
}
return results.AsReadOnly();
}
private static ReadOnlyDictionary<string, ReadOnlyDictionary<string, string>> GetLogisticKeyValuePairs(ReadOnlyCollection<string> footerLines, ReadOnlyDictionary<string, string> footerKeyValuePairs) {
Dictionary<string, ReadOnlyDictionary<string, string>> results = [];
string[] segments;
string[] subSegments;
string[] subSubSegments;
Dictionary<string, string>? keyValue;
results.Add("Footer", footerKeyValuePairs);
Dictionary<string, Dictionary<string, string>> keyValuePairs = [];
foreach (string footerLine in footerLines) {
segments = footerLine.Split('\t');
if (segments.Length != 2 || string.IsNullOrEmpty(segments[1].Trim())) {
continue;
}
if (!segments[1].Contains(';') || !segments[1].Contains('=')) {
continue;
} else {
subSegments = segments[1].Split(';');
if (subSegments.Length < 1) {
continue;
}
if (!keyValuePairs.TryGetValue(segments[0], out keyValue)) {
keyValuePairs.Add(segments[0], []);
if (!keyValuePairs.TryGetValue(segments[0], out keyValue)) {
throw new Exception();
}
}
foreach (string segment in subSegments) {
subSubSegments = segment.Split('=');
if (subSubSegments.Length != 2) {
continue;
}
keyValue.Add(subSubSegments[0], subSubSegments[1]);
}
}
}
foreach (KeyValuePair<string, Dictionary<string, string>> keyValuePair in keyValuePairs) {
results.Add(keyValuePair.Key, keyValuePair.Value.AsReadOnly());
}
return results.AsReadOnly();
}
private static string? GetPipeTable(ILogger<Worker> logger, string json) { private static string? GetPipeTable(ILogger<Worker> logger, string json) {
string? result = null; string? result = null;
string? value; string? value;
@ -310,4 +423,5 @@ internal static partial class Helper20250701 {
} }
return result; return result;
} }
} }

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