Add logging functionality for equipment availability tracking (Day-Helper-2025-12-03)

This commit is contained in:
2025-12-03 09:37:57 -07:00
parent e4a3e0a64b
commit 6ce555a08a
4 changed files with 232 additions and 99 deletions

19
.vscode/launch.json vendored
View File

@ -11,6 +11,25 @@
"preLaunchTask": "Build",
"program": "${workspaceFolder}/bin/Debug/net10.0/win-x64/File-Folder-Helper.dll",
"args": [
"s",
"X",
"\\\\mesfs.infineon.com\\EC_EAFLog\\Production\\Logs\\EAF-Info-Warn-002-061-001-Trace",
"Day-Helper-2025-12-03",
"*.trc",
"102400",
"s",
"X",
"D:/Tmp/Phares",
"Day-Helper-2025-07-20",
"871467010009.jpg",
"L:/Git/AA/Rename/.vscode/.UserSecrets/secrets.json",
"P:/6-Other-Large-Z/Current-Results/E)Distance/0b793904/()/638432064000000000.51/1401-08-03_02/2023/X+441981864000000000/871467010009.444090906.jpg.png",
"*.png",
"P:/{}/DisneyWorld 2019/Magic Kingdom/871467010009.jpg.xmp",
"*.xmp",
"{}-output",
"P:/5-Other-Small/(helper)",
"true",
"s",
"M",
"J:/5-Other-Small/Notes/Infineon",

View File

@ -17,17 +17,87 @@ internal static partial class Helper20250720 {
private partial class Helper20250720SettingsSourceGenerationContext : JsonSerializerContext {
}
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);
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]);
logger.LogInformation(args[9]);
logger.LogInformation(args[10]);
string searchPattern = args[5];
bool replace = args[10] == "true";
string outputDirectoryName = args[8];
string jsonFile = Path.GetFullPath(args[3]);
FileInfo faceFileInfo = new(Path.GetFullPath(args[4]));
string searchPatternExtensibleMetadataPlatform = args[7];
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string extensibleMetadataPlatformFile = Path.GetFullPath(args[6]);
string pathRoot = Path.GetPathRoot(faceFileInfo.FullName) ?? throw new Exception();
string rootExtensibleMetadataPlatformPath = Path.GetFullPath(args[9].Split('~')[0]);
string? checkDirectory = Path.GetDirectoryName(extensibleMetadataPlatformFile.Replace("{}", outputDirectoryName));
string originalFile = Path.Combine(sourceDirectory, args[2]);
ReadOnlyDictionary<long, ReadOnlyCollection<string>> keyToExtensibleMetadataPlatformFiles = GetExtensibleMetadataPlatformFiles(searchPatternExtensibleMetadataPlatform, rootExtensibleMetadataPlatformPath, replace);
if (!File.Exists(jsonFile)) {
logger.LogError("json file doesn't exist! <{jsonFile}>", jsonFile);
} else if (!File.Exists(extensibleMetadataPlatformFile)) {
logger.LogError("digiKam file doesn't exist! <{extensibleMetadataPlatformFile}>", extensibleMetadataPlatformFile);
} 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);
Helper20250720Settings? settings = JsonSerializer.Deserialize(json, Helper20250720SettingsSourceGenerationContext.Default.Helper20250720Settings);
if (settings?.ResultSettings is null || settings.ResultSettings.ResultAllInOneSubdirectoryLength < 1 || settings.MetadataSettings is null) {
throw new Exception(nameof(Helper20250720Settings));
}
WriteFaceData69(logger, outputDirectoryName, originalFile, faceFileInfo, extensibleMetadataPlatformFile, settings.ResultSettings, settings.MetadataSettings);
ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> keyToExifDirectories = GetExifDirectories(searchPattern, pathRoot, settings.ResultSettings, settings.MetadataSettings);
if (keyToExifDirectories.Count == 0) {
logger.LogError("Didn't find any valid file(s)!");
} else {
WriteFaceData415(logger, outputDirectoryName, keyToExifDirectories, keyToExtensibleMetadataPlatformFiles);
}
}
}
private static void WriteFaceData(ILogger<Worker> logger, string outputDirectoryName, string? originalFile, long? fileNameFirstSegment, ReadOnlyCollection<string> digiKamFiles, ReadOnlyDictionary<string, FaceFile> keyValuePairs) {
private static void WriteFaceData69(ILogger<Worker> logger, string outputDirectoryName, string originalFile, FileInfo faceFileInfo, string extensibleMetadataPlatformFile, 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<ExifDirectory> exifDirectories = new([exifDirectory]);
ReadOnlyCollection<string> extensibleMetadataPlatformFiles = new([extensibleMetadataPlatformFile]);
WriteFaceData87(logger, outputDirectoryName, originalFile, fileNameFirstSegment, exifDirectories, extensibleMetadataPlatformFiles);
}
}
private static void WriteFaceData87(ILogger<Worker> logger, string outputDirectoryName, string? originalFile, long? fileNameFirstSegment, ReadOnlyCollection<ExifDirectory> exifDirectories, ReadOnlyCollection<string> extensibleMetadataPlatformFiles) {
ReadOnlyDictionary<string, FaceFile> faceFiles = GetFaceFiles(logger, exifDirectories);
if (faceFiles.Count > 0) {
WriteFaceData94(logger, outputDirectoryName, originalFile, fileNameFirstSegment, extensibleMetadataPlatformFiles, faceFiles);
}
}
private static void WriteFaceData94(ILogger<Worker> logger, string outputDirectoryName, string? originalFile, long? fileNameFirstSegment, ReadOnlyCollection<string> extensibleMetadataPlatformFiles, ReadOnlyDictionary<string, FaceFile> faceFiles) {
#if xmp
IXmpMeta xmp;
using FileStream stream = File.OpenRead(digiKamFile);
using FileStream stream = File.OpenRead(extensibleMetadataPlatformFile);
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);
@ -56,12 +126,12 @@ internal static partial class Helper20250720 {
"xmlns:mwg-rs=\"http://www.metadataworkinggroup.com/schemas/regions/\"",
"</rdf:RDF>"
];
foreach (string digiKamFile in digiKamFiles) {
string[] lines = File.ReadAllLines(digiKamFile);
foreach (string extensibleMetadataPlatformFile in extensibleMetadataPlatformFiles) {
string[] lines = File.ReadAllLines(extensibleMetadataPlatformFile);
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);
logger.LogError("{fileNameFirstSegment}) Didn't find digiKam line!", fileNameFirstSegment);
} else {
foreach (string requiredLine in requiredLines) {
if (!trimmed.Contains(requiredLine)) {
@ -70,83 +140,27 @@ internal static partial class Helper20250720 {
}
int? rdfLine = GetMatchingLine(requiredLines[^1], trimmed.AsReadOnly());
if (rdfLine is null) {
logger.LogError("{fileNameFirstSegment}) Didn't fine description line!", fileNameFirstSegment);
logger.LogError("{fileNameFirstSegment}) Didn't find description line!", fileNameFirstSegment);
} else {
WriteFaceData(outputDirectoryName, originalFile, keyValuePairs, digiKamFile, trimmed, rdfLine.Value);
WriteFaceData159(outputDirectoryName, originalFile, faceFiles, extensibleMetadataPlatformFile, trimmed, rdfLine.Value);
}
}
}
}
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);
Helper20250720Settings? settings = JsonSerializer.Deserialize(json, Helper20250720SettingsSourceGenerationContext.Default.Helper20250720Settings);
if (settings?.ResultSettings is null || settings.ResultSettings.ResultAllInOneSubdirectoryLength < 1 || settings.MetadataSettings is null) {
throw new Exception(nameof(Helper20250720Settings));
}
WriteFaceData(logger, outputDirectoryName, originalFile, faceFileInfo, digiKamFile, settings.ResultSettings, settings.MetadataSettings);
ReadOnlyDictionary<long, ReadOnlyCollection<string>> keyValuePairsXMP = GetKeyValuePairs(searchPatternXMP, pathRootXMP);
ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> keyValuePairs = GetKeyValuePairs(searchPattern, pathRoot, settings.ResultSettings, settings.MetadataSettings);
if (keyValuePairs.Count == 0) {
logger.LogError("Didn't find any valid file(s)!");
} else {
WriteFaceData(logger, outputDirectoryName, keyValuePairs, keyValuePairsXMP);
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(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(string outputDirectoryName, string? originalFile, ReadOnlyDictionary<string, FaceFile> keyValuePairs, string digiKamFile, List<string> trimmed, int rdfLine) {
if (keyValuePairs.Count == 0) {
private static void WriteFaceData159(string outputDirectoryName, string? originalFile, ReadOnlyDictionary<string, FaceFile> faceFiles, string extensibleMetadataPlatformFile, List<string> trimmed, int rdfLine) {
if (faceFiles.Count == 0) {
throw new Exception();
}
double h;
@ -160,7 +174,7 @@ internal static partial class Helper20250720 {
string personKey;
FaceFile faceFile;
string descriptionLine = "</rdf:Description>";
faceFile = keyValuePairs.ElementAt(0).Value;
faceFile = faceFiles.ElementAt(0).Value;
if (faceFile.Location is null || faceFile.OutputResolution is null) {
throw new Exception();
}
@ -183,7 +197,7 @@ internal static partial class Helper20250720 {
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) {
foreach (KeyValuePair<string, FaceFile> keyValuePair in faceFiles) {
personKey = keyValuePair.Key;
faceFile = keyValuePair.Value;
if (faceFile.Location is null || faceFile.OutputResolution is null) {
@ -308,7 +322,7 @@ internal static partial class Helper20250720 {
}
trimmed.Insert(rdfLine - 1, text);
string allText = string.Join(Environment.NewLine, trimmed);
File.WriteAllText(digiKamFile.Replace("{}", outputDirectoryName), allText);
File.WriteAllText(extensibleMetadataPlatformFile.Replace("{}", outputDirectoryName), allText);
if (!string.IsNullOrEmpty(originalFile)) {
if (Debugger.IsAttached) {
File.WriteAllText(".xml", allText);
@ -316,13 +330,36 @@ internal static partial class Helper20250720 {
}
}
private static ReadOnlyDictionary<long, ReadOnlyCollection<string>> GetKeyValuePairs(string searchPattern, string pathRoot) {
private static ReadOnlyDictionary<long, ReadOnlyCollection<string>> GetExtensibleMetadataPlatformFiles(string searchPattern, string pathRoot, bool replace) {
Dictionary<long, ReadOnlyCollection<string>> results = [];
long fileNameFirstSegment;
string text;
string oldText;
string newText;
string[] segments;
List<string>? collection;
long fileNameFirstSegment;
string fileNameWithoutExtension;
Dictionary<long, List<string>> keyValuePairs = [];
string[] files = Directory.GetFiles(pathRoot, searchPattern, SearchOption.AllDirectories);
if (replace) {
string split = "<digiKam:";
foreach (string file in files) {
oldText = File.ReadAllText(file);
segments = oldText.Split(split);
if (segments.Length != 2) {
continue;
}
text = segments[1].Replace(" /", " ").Replace("/<", "<").Replace("/\"", "\"").
Replace(" |", " ").Replace("|<", "<").Replace("|\"", "\"").
Replace("Phares/", "Phares").Replace("Phares|", "Phares").
Replace("Clifton/", "Clifton").Replace("Clifton|", "Clifton");
newText = $"{segments[0]}{split}{text}";
if (oldText == newText) {
continue;
}
File.WriteAllText(file, newText);
}
}
foreach (string file in files) {
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
if (!long.TryParse(fileNameWithoutExtension.Split('.')[0], out fileNameFirstSegment)) {
@ -342,7 +379,7 @@ internal static partial class Helper20250720 {
return results.AsReadOnly();
}
private static ReadOnlyDictionary<string, FaceFile> GetKeyValuePairs(ILogger<Worker> logger, ReadOnlyCollection<ExifDirectory> exifDirectories) {
private static ReadOnlyDictionary<string, FaceFile> GetFaceFiles(ILogger<Worker> logger, ReadOnlyCollection<ExifDirectory> exifDirectories) {
Dictionary<string, FaceFile> results = [];
string? personKey;
FaceFile? faceFile;
@ -368,7 +405,7 @@ internal static partial class Helper20250720 {
return results.AsReadOnly();
}
private static ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> GetKeyValuePairs(string searchPattern, string pathRoot, ResultSettings resultSettings, MetadataSettings metadataSettings) {
private static ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> GetExifDirectories(string searchPattern, string pathRoot, ResultSettings resultSettings, MetadataSettings metadataSettings) {
Dictionary<long, ReadOnlyCollection<ExifDirectory>> results = [];
FileInfo faceFileInfo;
long fileNameFirstSegment;
@ -401,29 +438,18 @@ internal static partial class Helper20250720 {
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)) {
private static void WriteFaceData415(ILogger<Worker> logger, string outputDirectoryName, ReadOnlyDictionary<long, ReadOnlyCollection<ExifDirectory>> keyToExifDirectories, ReadOnlyDictionary<long, ReadOnlyCollection<string>> keyToExtensibleMetadataPlatformFiles) {
ReadOnlyCollection<string>? extensibleMetadataPlatformFiles;
foreach (KeyValuePair<long, ReadOnlyCollection<ExifDirectory>> keyValuePair in keyToExifDirectories) {
if (!keyToExtensibleMetadataPlatformFiles.TryGetValue(keyValuePair.Key, out extensibleMetadataPlatformFiles)) {
logger.LogWarning("{fileNameFirstSegment}) Didn't find a matching file!", keyValuePair.Key);
} else {
string? originalFile = null;
WriteFaceData(logger, outputDirectoryName, originalFile, keyValuePair.Key, keyValuePair.Value, digiKamFiles);
WriteFaceData87(logger, outputDirectoryName, originalFile, keyValuePair.Key, keyValuePair.Value, extensibleMetadataPlatformFiles);
}
}
}
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 Extract(string file, double width, double height, int left, int top, string suffix) {
#if SystemDrawingCommon
Rectangle rectangle = new(left, top, width, height);

View File

@ -0,0 +1,86 @@
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI8;
internal static partial class Helper20251203 {
internal static void TraceToMarkdown(ILogger<Worker> logger, List<string> args) {
logger.LogInformation(args[0]);
logger.LogInformation(args[1]);
logger.LogInformation(args[2]);
logger.LogInformation(args[3]);
string newText;
string[] files;
string? oldText;
FileInfo fileInfo;
string destinationPath;
List<string> hours = [];
List<string> lines = [];
List<string> values = [];
string weekDirectoryName;
string[] weekDirectories;
string equipmentDirectoryName;
string searchPattern = args[2];
long size = long.Parse(args[3]);
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string[] equipmentDirectories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string equipmentDirectory in equipmentDirectories) {
equipmentDirectoryName = Path.GetFileName(equipmentDirectory);
weekDirectories = Directory.GetDirectories(equipmentDirectory, "*", SearchOption.TopDirectoryOnly);
lines.Clear();
foreach (string weekDirectory in weekDirectories.OrderByDescending(f => f)) {
hours.Clear();
values.Clear();
weekDirectoryName = Path.GetFileName(weekDirectory);
files = Directory.GetFiles(weekDirectory, searchPattern, SearchOption.TopDirectoryOnly);
logger.LogInformation("Equipment: {equipmentDirectoryName}, Week: {weekDirectoryName}, Files found: {fileCount}", equipmentDirectoryName, weekDirectoryName, files.Length);
foreach (string file in files) {
fileInfo = new(file);
hours.Add(fileInfo.Name[..^3]);
if (fileInfo.Length < size) {
values.Add("0");
} else {
logger.LogInformation("File: {file}, Size: {size}", file, fileInfo.Length);
values.Add("1");
}
}
if (hours.Count == 0 || values.Count == 0) {
logger.LogWarning("No data found for Equipment: {equipmentDirectoryName}, Week: {weekDirectoryName}", equipmentDirectoryName, weekDirectoryName);
} else {
lines.Add($"## Equipment: {equipmentDirectoryName}, Week: {weekDirectoryName}");
lines.Add(string.Empty);
lines.Add("```chart");
lines.Add("{\"type\": \"line\", \"data\": {\"datasets\": [{");
lines.Add($"\"label\": \"Availability - {equipmentDirectoryName} - {weekDirectoryName}\",");
lines.Add("\"data\": [");
lines.Add(string.Join(',', values));
lines.Add("],");
lines.Add("\"borderColor\": \"rgb(75, 192, 192)\"");
lines.Add("}],");
lines.Add("\"labels\": [");
lines.Add(string.Join(',', hours.Select(h => $"\"{h}\"")));
lines.Add("]");
lines.Add("}}");
lines.Add("```");
lines.Add(string.Empty);
}
}
if (lines.Count == 0) {
logger.LogWarning("No data to write for equipment {equipmentDirectoryName}", equipmentDirectoryName);
continue;
}
lines.Insert(0, string.Empty);
lines.Insert(0, $"# Equipment: {equipmentDirectoryName}");
destinationPath = Path.Combine(sourceDirectory, $"{equipmentDirectoryName}_Availability.md");
newText = string.Join(Environment.NewLine, lines);
oldText = File.Exists(destinationPath) ? File.ReadAllText(destinationPath) : null;
if (newText == oldText) {
logger.LogInformation("No changes for availability chart at {destinationPath}", destinationPath);
continue;
}
File.WriteAllLines(destinationPath, lines);
logger.LogInformation("Written availability chart to {destinationPath}", destinationPath);
}
}
}

View File

@ -203,6 +203,8 @@ internal static class HelperDay
ADO2025.PI8.Helper20251122.MoveBack(logger, args);
else if (args[1] == "Day-Helper-2025-11-23")
ADO2025.PI8.Helper20251123.LogToTrace(logger, args);
else if (args[1] == "Day-Helper-2025-12-03")
ADO2025.PI8.Helper20251203.TraceToMarkdown(logger, args);
else
throw new Exception(appSettings.Company);
}