From 3f7b95c91608012ffced64122e96f12fd1465115 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Thu, 16 Nov 2023 15:15:58 -0700 Subject: [PATCH] Separate configuration settings Added EAFLog Testing Stratus file --- .editorconfig | 30 ++- .vscode/launch.json | 19 +- .vscode/tasks.json | 28 +- File-Watcher.csproj | 17 +- Helpers/HelperCreateNoteFiles.cs | 287 --------------------- Helpers/HelperEAFLog.cs | 27 ++ Helpers/HelperStratus.cs | 46 ++++ Helpers/HelperWaferCounter.cs | 43 +++ Models/AppSettings.cs | 8 +- Models/Binder/AppSettings.cs | 55 +++- Models/Binder/EAFLogConfiguration.cs | 67 +++++ Models/Binder/StratusConfiguration.cs | 73 ++++++ Models/Binder/WaferCounterConfiguration.cs | 70 +++++ Models/EAFLogConfiguration.cs | 21 ++ Models/StratusConfiguration.cs | 23 ++ Models/WaferCounterConfiguration.cs | 22 ++ Program.cs | 7 +- Worker.cs | 37 +-- package-lock.json | 2 +- 19 files changed, 494 insertions(+), 388 deletions(-) delete mode 100644 Helpers/HelperCreateNoteFiles.cs create mode 100644 Helpers/HelperEAFLog.cs create mode 100644 Helpers/HelperStratus.cs create mode 100644 Helpers/HelperWaferCounter.cs create mode 100644 Models/Binder/EAFLogConfiguration.cs create mode 100644 Models/Binder/StratusConfiguration.cs create mode 100644 Models/Binder/WaferCounterConfiguration.cs create mode 100644 Models/EAFLogConfiguration.cs create mode 100644 Models/StratusConfiguration.cs create mode 100644 Models/WaferCounterConfiguration.cs diff --git a/.editorconfig b/.editorconfig index 046ef9f..3806628 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,19 @@ +[*.csproj] +end_of_line = crlf +file_header_template = unset +indent_size = 2 +indent_style = space +insert_final_newline = false +root = true +tab_width = 2 +[*.md] +end_of_line = crlf +file_header_template = unset +indent_size = 2 +indent_style = space +insert_final_newline = false +root = true +tab_width = 2 [*.cs] csharp_indent_block_contents = true csharp_indent_braces = false @@ -13,6 +29,7 @@ csharp_new_line_before_members_in_object_initializers = true csharp_new_line_before_open_brace = all csharp_new_line_between_query_expression_clauses = true csharp_prefer_braces = false +csharp_prefer_qualified_reference = true:error csharp_prefer_simple_default_expression = true:warning csharp_prefer_simple_using_statement = true:warning csharp_prefer_static_local_function = true:warning @@ -79,11 +96,22 @@ dotnet_code_quality.CAXXXX.api_surface = private, internal dotnet_diagnostic.CA1825.severity = warning # CA1823: Avoid zero-length array allocations dotnet_diagnostic.CA1829.severity = warning # CA1829: Use Length/Count property instead of Count() when available dotnet_diagnostic.CA1834.severity = warning # CA1834: Consider using 'StringBuilder.Append(char)' when applicable +dotnet_diagnostic.CA1860.severity = error # CA1860: Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance +dotnet_diagnostic.CA1869.severity = none # CA1869: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. +dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template should not vary between calls to 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2"); +dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant. dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary +dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified +dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031) dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be removed +dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049) dotnet_diagnostic.IDE0060.severity = warning # IDE0060: Remove unused parameter +dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]csharp(IDE0290) +dotnet_diagnostic.IDE0300.severity = error # IDE0300: Collection initialization can be simplified +dotnet_diagnostic.IDE0301.severity = error #IDE0301: Collection initialization can be simplified +dotnet_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method @@ -215,7 +243,7 @@ dotnet_style_parentheses_in_other_binary_operators = always_for_clarity dotnet_style_parentheses_in_other_operators = never_if_unnecessary dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity dotnet_style_predefined_type_for_locals_parameters_members = true -dotnet_style_predefined_type_for_member_access = true +dotnet_style_predefined_type_for_member_access = true:warning dotnet_style_prefer_auto_properties = true:warning dotnet_style_prefer_compound_assignment = true:warning dotnet_style_prefer_conditional_expression_over_assignment = false diff --git a/.vscode/launch.json b/.vscode/launch.json index db9b413..775aade 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,10 +9,9 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build", - "program": "${workspaceFolder}/bin/Debug/net7.0/win-x64/File-Folder-Helper.dll", + "program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/File-Watcher.dll", "args": [ - "s", - "\\\\messv02ecc1.ec.local\\EC_EDA\\Staging\\Traces\\HTR-PLC\\R72-PLC\\PollPath" + "s" ], "cwd": "${workspaceFolder}", "console": "integratedTerminal", @@ -25,17 +24,3 @@ } ] } -// dotnet build -// dotnet run "s" "\\messv02ecc1.ec.local\EC_EDA\Staging\Traces\HTR-PLC\R45-PLC\PollPath" -// dotnet run "s" "\\messv02ecc1.ec.local\EC_EDA\Staging\Traces\HTR-PLC\R47-PLC\PollPath" -// dotnet run "s" "\\messv02ecc1.ec.local\EC_EDA\Staging\Traces\HTR-PLC\R49-PLC\PollPath" -// dotnet run "s" "\\messv02ecc1.ec.local\EC_EDA\Staging\Traces\HTR-PLC\R51-PLC\PollPath" -// dotnet run "s" "\\messv02ecc1.ec.local\EC_EDA\Staging\Traces\HTR-PLC\R70-PLC\PollPath" -// dotnet run "s" "\\messv02ecc1.ec.local\EC_EDA\Staging\Traces\HTR-PLC\R72-PLC\PollPath" -// dotnet run "s" "\\messv02ecc1.ec.local\EC_EDA\Staging\Traces\HTR-PLC\R73-PLC\PollPath" -// dotnet run "s" "\\messv02ecc1.ec.local\EC_EDA\Staging\Traces\HTR-PLC\R74-PLC\PollPath" -// dotnet run "s" "C:/Users/phares/.nuget/packages" -// dotnet run "s" "D:/ProgramData/EC_EAFRepository/nupkg" -// dotnet run "s" "D:/Baget/packages" -// dotnet run "s" "\\messdv002.na.infineon.com\Candela\BaGet\packages" -// dotnet run "s" "T:/MESAFIBACKLOG/06_SourceCode/MESAFIBACKLOG/Adaptation/.kanbn" \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 45cab2e..c39c8b9 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -54,30 +54,6 @@ ], "problemMatcher": "$msCompile" }, - { - "label": "publish", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "${workspaceFolder}/File-Watcher.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "watch", - "command": "dotnet", - "type": "process", - "args": [ - "watch", - "run", - "--project", - "${workspaceFolder}/File-Watcher.csproj" - ], - "problemMatcher": "$msCompile" - }, { "label": "Publish AOT", "command": "dotnet", @@ -89,8 +65,6 @@ "-c", "Release", "-p:PublishAot=true", - "--source", - "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json", "${workspaceFolder}/File-Watcher.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" @@ -100,7 +74,7 @@ { "label": "File-Watcher AOT s V Helpers", "type": "shell", - "command": "& L:/DevOps/Mesa_FI/File-Watcher/bin/Release/net7.0/win-x64/publish/File-Watcher.exe s V Helpers", + "command": "& L:/DevOps/Mesa_FI/File-Watcher/bin/Release/net8.0/win-x64/publish/File-Watcher.exe s V Helpers", "problemMatcher": [] } ] diff --git a/File-Watcher.csproj b/File-Watcher.csproj index a4ca5e6..010a6c3 100644 --- a/File-Watcher.csproj +++ b/File-Watcher.csproj @@ -3,16 +3,17 @@ enable enable Exe - net7.0 + win-x64 + net8.0 b6f34b8e-5026-41d4-9c28-6516d19d6569 - - - - - - - + + + + + + + \ No newline at end of file diff --git a/Helpers/HelperCreateNoteFiles.cs b/Helpers/HelperCreateNoteFiles.cs deleted file mode 100644 index 5ffd2c0..0000000 --- a/Helpers/HelperCreateNoteFiles.cs +++ /dev/null @@ -1,287 +0,0 @@ -using System.Globalization; -using System.Text; -using System.Text.RegularExpressions; - -namespace File_Watcher.Helpers; - -internal static partial class HelperCreateNoteFiles -{ - - [GeneratedRegex("[^a-z0-9-]")] - private static partial Regex AlphaNumOnly(); - - private static string? GetTags(string tagsText) - { - string? result; - StringBuilder stringBuilder = new(); - if (string.IsNullOrEmpty(tagsText)) - result = null; - else - { - string[] segments; - _ = stringBuilder.AppendLine("tags:"); - string[] tags = tagsText.Split(';', StringSplitOptions.RemoveEmptyEntries); - foreach (string tag in tags) - { - segments = tag.Split(':'); - _ = stringBuilder.AppendLine($"- '{segments.First()}'"); - } - result = stringBuilder.ToString().Trim(); - } - return result; - } - - private static string? GetLinks(string type, string linksText) - { - string? result; - StringBuilder stringBuilder = new(); - if (!string.IsNullOrEmpty(linksText)) - result = null; - else - { - string linkLower; - string[] segments; - string[] links = linksText.Split(';', StringSplitOptions.RemoveEmptyEntries); - foreach (string link in links) - { - segments = link.Split(':'); - linkLower = AlphaNumOnly().Replace(segments.First().Trim().ToLower(), "-").Replace("--", "-"); - if (segments.Length == 1) - _ = stringBuilder.AppendLine($"- [[{type}/{linkLower}]]"); - else if (segments.Length == 2) - _ = stringBuilder.AppendLine($"- [{type}/{linkLower}]({segments.Last()})"); - else - continue; - } - result = stringBuilder.ToString().Trim(); - } - return result; - } - - private static string? GetAttributes(string[] columns, string[]? headerColumns, int expectedCount) - { - string? result; - if (headerColumns is null || columns.Length <= expectedCount) - result = null; - else - { - StringBuilder stringBuilder = new(); - for (int j = expectedCount; j < columns.Length; j++) - { - if (headerColumns.Length <= j) - continue; - _ = stringBuilder.AppendLine($"{headerColumns[j].Trim()}: '{columns[j].Trim()}'"); - } - result = stringBuilder.ToString().Trim(); - } - return result; - } - - private static void CleanExistingFiles(string directory, long ticks) - { - string check; - string[] lines; - string checkFile; - string? fileDirectory; - string checkDirectory; - bool circularReference; - string fileNameWithoutExtension; - char altDrive = directory[0] is 'c' or 'C' ? 'D' : 'C'; - string[] files = Directory.GetFiles(directory, "*.md", SearchOption.AllDirectories); - string match = ",*** *** *** *** *** *** *** *** ***,*** *** *** *** *** *** *** *** ***,*** *** *** *** *** *** *** *** ***,,TODO:,*** *** *** *** *** *** *** *** ***,*** *** *** *** *** *** *** *** ***,,Notes:,*** *** *** *** *** *** *** *** ***,*** *** *** *** *** *** *** *** ***"; - foreach (string file in files) - { - lines = File.ReadAllLines(file); - if (lines.Length < 1) - continue; - circularReference = false; - fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file); - for (int i = 0; i < lines.Length; i++) - { - if (!lines[i].Contains($"[[{fileNameWithoutExtension}]]")) - continue; - lines[i] = lines[i].Replace("[[", "__").Replace("]]", "__"); - if (!circularReference) - circularReference = true; - } - if (circularReference) - File.WriteAllLines(file, lines); - lines[0] = string.Empty; - check = string.Join(',', lines); - if (check != match) - continue; - fileDirectory = Path.GetDirectoryName(file); - if (string.IsNullOrEmpty(fileDirectory)) - continue; - checkDirectory = $"{altDrive}:/{ticks}/{fileDirectory[3..]}"; - if (!Directory.Exists(checkDirectory)) - _ = Directory.CreateDirectory(checkDirectory); - checkFile = $"{altDrive}:/{ticks}/{file[3..]}"; - if (File.Exists(checkFile)) - continue; - File.Move(file, checkFile); - } - } - - private static void CreateDailyNotes(string argsZero, long ticks) - { - string file; - string directory; - string weekOfYear; - DateTime dateTime; - string lastDirectory = string.Empty; - DateTime startDateTime = DateTime.Now.AddDays(1); - Calendar calendar = new CultureInfo("en-US").Calendar; - double totalDays = new TimeSpan(DateTime.Now.AddDays(1000).Ticks - startDateTime.Ticks).TotalDays; - int days = (int)Math.Ceiling(totalDays); - for (int i = 0; i < days; i++) - { - dateTime = startDateTime.AddDays(i); - weekOfYear = calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); - directory = Path.Combine(argsZero, ticks.ToString(), dateTime.ToString("yyyy"), $"Week_{weekOfYear}"); - if (!Directory.Exists(directory)) - _ = Directory.CreateDirectory(directory); - file = string.Concat(Path.Combine(directory, $"{dateTime:yyyy-MM-dd}.md")); - if (File.Exists(file)) - continue; - File.WriteAllLines(file, new string[] - { - "---", - "type: daily-note", - $"created: {dateTime:yyyy-MM-dd}", - "---", - string.Empty, - $"# {dateTime:yyyy-MM-dd dddd}", - string.Empty, - "```bash", - string.Empty, - "```", - }); - if (directory != lastDirectory) - { - Directory.SetCreationTime(directory, dateTime); - Directory.SetLastWriteTime(directory, dateTime); - } - lastDirectory = directory; - } - } - - private static void CreateImportFiles(long ticks, List importFiles) - { - bool csv; - bool tsv; - string file; - string text; - string type; - string title; - string? tags; - string? links; - string[] lines; - int bodyKey = 5; - int tagsKey = 3; - int typeKey = 0; - string fileName; - string tagsText; - int linksKey = 4; - int titleKey = 1; - string linksText; - string[] columns; - string? directory; - string? attributes; - int descriptionKey = 2; - string[]? headerColumns; - string destinationDirectory; - List allLines = new(); - DateTime dateTime = new(ticks); - string csvHeader = "type,title,description,tags,links,body"; - string tsvHeader = "type\ttitle\tdescription\ttags\tlinks\tbody"; - int expectedCount = csvHeader.Length - csvHeader.Replace(",", string.Empty).Length + 1; - foreach (string importFile in importFiles) - { - csv = false; - tsv = false; - headerColumns = null; - directory = Path.GetDirectoryName(importFile); - if (directory is null) - continue; - lines = File.ReadAllLines(importFile); - for (int i = 0; i < lines.Length; i++) - { - if (i == 0) - { - if (lines[i].StartsWith(csvHeader)) - { - (csv, tsv) = (true, false); - headerColumns = lines[i].Split(','); - } - else if (lines[i].StartsWith(tsvHeader)) - { - (csv, tsv) = (false, true); - headerColumns = lines[i].Split('\t'); - } - else - break; - continue; - } - if (csv) - columns = lines[i].Split(','); - else if (tsv) - columns = lines[i].Split('\t'); - else - continue; - if (columns.Length < expectedCount) - continue; - title = columns[titleKey].Trim(); - tagsText = columns[tagsKey].Trim(); - linksText = columns[linksKey].Trim(); - fileName = AlphaNumOnly().Replace(title.ToLower(), "-").Replace("--", "-"); - type = AlphaNumOnly().Replace(columns[typeKey].Trim().ToLower(), "-").Replace("--", "-"); - tags = GetTags(tagsText); - links = GetLinks(type, linksText); - attributes = GetAttributes(columns, headerColumns, expectedCount); - destinationDirectory = Path.Combine(directory, type); - if (!Directory.Exists(destinationDirectory)) - _ = Directory.CreateDirectory(destinationDirectory); - file = Path.Combine(destinationDirectory, $"{fileName}.md"); - allLines.Clear(); - allLines.Add("---"); - allLines.Add($"type: \"{type}\""); - allLines.Add($"title: \"{title}\""); - allLines.Add($"description: \"{columns[descriptionKey].Trim()}\""); - allLines.Add($"created: \"{dateTime:yyyy-MM-ddTHH:mm:ss.fffZ}\""); - allLines.Add($"updated: \"{dateTime:yyyy-MM-ddTHH:mm:ss.fffZ}\""); - if (!string.IsNullOrEmpty(tags)) - allLines.Add(tags); - if (!string.IsNullOrEmpty(attributes)) - allLines.Add(attributes); - allLines.Add("---"); - allLines.Add(string.Empty); - allLines.Add($"# {title}"); - allLines.Add(string.Empty); - if (!string.IsNullOrEmpty(links)) - allLines.Add(links); - allLines.Add(string.Empty); - allLines.Add($"## Comment {dateTime:yyyy-MM-dd}"); - allLines.Add(string.Empty); - allLines.Add(columns[bodyKey].Trim()); - allLines.Add(string.Empty); - text = string.Join(Environment.NewLine, allLines); - File.WriteAllText(file, text); - } - } - } - - internal static void CreateNoteFiles(string argsZero) - { - long ticks = DateTime.Now.Ticks; - List importFiles = new(); - CleanExistingFiles(argsZero, ticks); - importFiles.AddRange(Directory.GetFiles(argsZero, "*.csv", SearchOption.TopDirectoryOnly)); - importFiles.AddRange(Directory.GetFiles(argsZero, "*.tsv", SearchOption.TopDirectoryOnly)); - if (!importFiles.Any()) - CreateDailyNotes(argsZero, ticks); - else - CreateImportFiles(ticks, importFiles); - } - -} \ No newline at end of file diff --git a/Helpers/HelperEAFLog.cs b/Helpers/HelperEAFLog.cs new file mode 100644 index 0000000..52f6af2 --- /dev/null +++ b/Helpers/HelperEAFLog.cs @@ -0,0 +1,27 @@ +using File_Watcher.Models; + +namespace File_Watcher.Helpers; + +internal static partial class HelperEAFLog +{ + + internal static bool DeleteFiles(AppSettings appSettings, ILogger logger) + { + IEnumerable files = Directory.EnumerateFiles(appSettings.WatchDirectory, appSettings.EAFLogConfiguration.SearchPattern, SearchOption.AllDirectories); + foreach (string file in files) + { + if (file.EndsWith(".dll")) + continue; + if (file.EndsWith(".pdb")) + continue; + if (file.EndsWith(".xml")) + continue; + try + { File.Delete(file); } + catch (Exception ex) + { logger.LogError(ex, "Inner loop error!"); } + } + return true; + } + +} \ No newline at end of file diff --git a/Helpers/HelperStratus.cs b/Helpers/HelperStratus.cs new file mode 100644 index 0000000..93f6753 --- /dev/null +++ b/Helpers/HelperStratus.cs @@ -0,0 +1,46 @@ +using File_Watcher.Models; +using System.Text.RegularExpressions; + +namespace File_Watcher.Helpers; + +internal static partial class HelperStratus +{ + // Batch FINAL QA_28_00_12 finished at 10/28/23 00:14. Elapsed time 00:01:34. + // Cassette 1T614291 finished. + // Mean 9.091, STDD 0.0091 + + private static void TryMoveFile(AppSettings appSettings, string checkFile) + { + string line; + List collection = []; + char start = appSettings.StratusConfiguration.FileDelimiterPattern[0]; + string[] lines = !File.Exists(checkFile) ? [] : File.ReadAllLines(checkFile); + for (int i = 0; i < lines.Length; i++) + { + line = lines[i]; + collection.Add(line); + if (line.Length < 1 || line[0] != start) + continue; + if (!Regex.Match(line, appSettings.StratusConfiguration.FileDelimiterPattern).Success) + continue; + File.WriteAllLines(Path.Combine(appSettings.WatchDirectory, $"{DateTime.Now.Ticks}.txt"), collection); + collection.Clear(); + for (int j = i + 1; j < lines.Length; j++) + collection.Add(lines[j]); + File.WriteAllLines(checkFile, collection); + collection.Clear(); + break; + } + } + + internal static bool MoveFile(AppSettings appSettings, ILogger logger) + { + string file = Path.Combine(appSettings.WatchDirectory, appSettings.StratusConfiguration.WatchFile); + try + { TryMoveFile(appSettings, file); } + catch (Exception ex) + { logger.LogError(ex, "Inner loop error!"); } + return true; + } + +} \ No newline at end of file diff --git a/Helpers/HelperWaferCounter.cs b/Helpers/HelperWaferCounter.cs new file mode 100644 index 0000000..545933c --- /dev/null +++ b/Helpers/HelperWaferCounter.cs @@ -0,0 +1,43 @@ +using File_Watcher.Models; + +namespace File_Watcher.Helpers; + +internal static partial class HelperWaferCounter +{ + + internal static bool MoveFile(AppSettings appSettings, ILogger logger) + { + string[] files; + string checkFile; + FileInfo fileInfo; + string checkDirectory; + string[] directories = Directory.GetDirectories(appSettings.WatchDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string directory in directories) + { + checkDirectory = !appSettings.WaferCounterConfiguration.MatchPath ? appSettings.WaferCounterConfiguration.Destination : Path.Combine(appSettings.WaferCounterConfiguration.Destination, Path.GetFileName(directory)); + try + { + if (!Directory.Exists(checkDirectory)) + _ = Directory.CreateDirectory(checkDirectory); + files = Directory.GetFiles(directory, "*", SearchOption.TopDirectoryOnly); + foreach (string file in files) + { + fileInfo = new(file); + if (new TimeSpan(DateTime.Now.Ticks - fileInfo.LastWriteTime.Ticks).TotalMilliseconds < appSettings.MillisecondsDelay) + continue; + checkFile = Path.Combine(checkDirectory, Path.GetFileName(file)); + if (File.Exists(checkFile)) + continue; + try + { File.Move(file, checkFile); } + catch (Exception ex) + { logger.LogError(ex, "Inner loop error!"); } + } + } + catch (Exception ex) + { logger.LogError(ex, "Loop error!"); } + } + return true; + } + +} \ No newline at end of file diff --git a/Models/AppSettings.cs b/Models/AppSettings.cs index b069f0a..0b1bde4 100644 --- a/Models/AppSettings.cs +++ b/Models/AppSettings.cs @@ -3,11 +3,13 @@ using System.Text.Json.Serialization; namespace File_Watcher.Models; -public record AppSettings(string BuildNumber, +public record AppSettings(EAFLogConfiguration EAFLogConfiguration, + StratusConfiguration StratusConfiguration, + WaferCounterConfiguration WaferCounterConfiguration, + string BuildNumber, string Company, - string Destination, string GitCommitSeven, - bool MatchPath, + string Helper, int MillisecondsDelay, string WatchDirectory) { diff --git a/Models/Binder/AppSettings.cs b/Models/Binder/AppSettings.cs index 529da4b..a466c08 100644 --- a/Models/Binder/AppSettings.cs +++ b/Models/Binder/AppSettings.cs @@ -8,9 +8,8 @@ public class AppSettings public string? BuildNumber { get; set; } public string? Company { get; set; } - public string? Destination { get; set; } public string? GitCommitSeven { get; set; } - public bool? MatchPath { get; set; } + public string? Helper { get; set; } public int? MillisecondsDelay { get; set; } public string? WatchDirectory { get; set; } @@ -20,34 +19,68 @@ public class AppSettings return result; } - private static Models.AppSettings Get(AppSettings? appSettings) + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.BuildNumber is null) + { + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + if (!physicalFileProvider.Root.Contains("UserSecrets")) + continue; + throw new NotSupportedException(physicalFileProvider.Root); + } + throw new NotSupportedException("Not Found!"); + } + } + + private static void Verify(AppSettings _) + { + } + + private static Models.AppSettings Get(AppSettings? appSettings, + Models.EAFLogConfiguration eafLogConfiguration, + Models.StratusConfiguration stratusConfiguration, + Models.WaferCounterConfiguration waferCounterConfiguration) { Models.AppSettings result; if (appSettings is null) throw new NullReferenceException(nameof(appSettings)); if (appSettings.BuildNumber is null) throw new NullReferenceException(nameof(BuildNumber)); if (appSettings.Company is null) throw new NullReferenceException(nameof(Company)); - if (appSettings.Destination is null) throw new NullReferenceException(nameof(Destination)); if (appSettings.GitCommitSeven is null) throw new NullReferenceException(nameof(GitCommitSeven)); - if (appSettings.MatchPath is null) throw new NullReferenceException(nameof(MatchPath)); + if (appSettings.Helper is null) throw new NullReferenceException(nameof(Helper)); if (appSettings.MillisecondsDelay is null) throw new NullReferenceException(nameof(MillisecondsDelay)); if (appSettings.WatchDirectory is null) throw new NullReferenceException(nameof(WatchDirectory)); - result = new(appSettings.BuildNumber, + Verify(appSettings); + result = new(eafLogConfiguration, + stratusConfiguration, + waferCounterConfiguration, + appSettings.BuildNumber, appSettings.Company, - appSettings.Destination, appSettings.GitCommitSeven, - appSettings.MatchPath.Value, + appSettings.Helper, appSettings.MillisecondsDelay.Value, appSettings.WatchDirectory); return result; } - public static Models.AppSettings Get(IConfiguration configuration) + public static Models.AppSettings Get(IConfigurationRoot configurationRoot, + Models.EAFLogConfiguration eafLogConfiguration, + Models.StratusConfiguration stratusConfiguration, + Models.WaferCounterConfiguration waferCounterConfiguration) { Models.AppSettings result; #pragma warning disable IL3050, IL2026 - AppSettings? appSettings = configuration.Get(); + AppSettings? appSettings = configurationRoot.Get(); #pragma warning restore IL3050, IL2026 - result = Get(appSettings); + PreVerify(configurationRoot, appSettings); + result = Get(appSettings, + eafLogConfiguration, + stratusConfiguration, + waferCounterConfiguration); return result; } diff --git a/Models/Binder/EAFLogConfiguration.cs b/Models/Binder/EAFLogConfiguration.cs new file mode 100644 index 0000000..725f42b --- /dev/null +++ b/Models/Binder/EAFLogConfiguration.cs @@ -0,0 +1,67 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace File_Watcher.Models.Binder; + +public class EAFLogConfiguration +{ + + public string? SearchPattern { get; set; } + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, BinderEAFLogConfigurationSourceGenerationContext.Default.EAFLogConfiguration); + return result; + } + + private static void PreVerify(IConfigurationRoot configurationRoot, EAFLogConfiguration? configuration) + { + if (configuration?.SearchPattern is null) + { + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + if (!physicalFileProvider.Root.Contains("UserSecrets")) + continue; + throw new NotSupportedException(physicalFileProvider.Root); + } + throw new NotSupportedException("Not Found!"); + } + } + + private static void Verify(EAFLogConfiguration _) + { + } + + private static Models.EAFLogConfiguration Get(EAFLogConfiguration? configuration) + { + Models.EAFLogConfiguration result; + if (configuration is null) throw new NullReferenceException(nameof(configuration)); + if (configuration.SearchPattern is null) throw new NullReferenceException(nameof(configuration.SearchPattern)); + Verify(configuration); + result = new(configuration.SearchPattern); + return result; + } + + public static Models.EAFLogConfiguration Get(IConfigurationRoot configurationRoot) + { + Models.EAFLogConfiguration result; + IConfigurationSection configurationSection = configurationRoot.GetSection(nameof(Models.EAFLogConfiguration)); +#pragma warning disable IL3050, IL2026 + EAFLogConfiguration? configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, configuration); + result = Get(configuration); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(EAFLogConfiguration))] +internal partial class BinderEAFLogConfigurationSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Models/Binder/StratusConfiguration.cs b/Models/Binder/StratusConfiguration.cs new file mode 100644 index 0000000..7af2e8c --- /dev/null +++ b/Models/Binder/StratusConfiguration.cs @@ -0,0 +1,73 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace File_Watcher.Models.Binder; + +public class StratusConfiguration +{ + + public string? Destination { get; set; } + public string? FileDelimiterPattern { get; set; } + public string? WatchFile { get; set; } + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, BinderStratusConfigurationSourceGenerationContext.Default.StratusConfiguration); + return result; + } + + private static void PreVerify(IConfigurationRoot configurationRoot, StratusConfiguration? configuration) + { + if (configuration?.Destination is null) + { + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + if (!physicalFileProvider.Root.Contains("UserSecrets")) + continue; + throw new NotSupportedException(physicalFileProvider.Root); + } + throw new NotSupportedException("Not Found!"); + } + } + + private static void Verify(StratusConfiguration _) + { + } + + private static Models.StratusConfiguration Get(StratusConfiguration? configuration) + { + Models.StratusConfiguration result; + if (configuration is null) throw new NullReferenceException(nameof(configuration)); + if (configuration.Destination is null) throw new NullReferenceException(nameof(configuration.Destination)); + if (configuration.FileDelimiterPattern is null) throw new NullReferenceException(nameof(configuration.FileDelimiterPattern)); + if (configuration.WatchFile is null) throw new NullReferenceException(nameof(configuration.WatchFile)); + Verify(configuration); + result = new(configuration.Destination, + configuration.FileDelimiterPattern, + configuration.WatchFile); + return result; + } + + public static Models.StratusConfiguration Get(IConfigurationRoot configurationRoot) + { + Models.StratusConfiguration result; + IConfigurationSection configurationSection = configurationRoot.GetSection(nameof(Models.StratusConfiguration)); +#pragma warning disable IL3050, IL2026 + StratusConfiguration? configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, configuration); + result = Get(configuration); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(StratusConfiguration))] +internal partial class BinderStratusConfigurationSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Models/Binder/WaferCounterConfiguration.cs b/Models/Binder/WaferCounterConfiguration.cs new file mode 100644 index 0000000..1e5a07f --- /dev/null +++ b/Models/Binder/WaferCounterConfiguration.cs @@ -0,0 +1,70 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace File_Watcher.Models.Binder; + +public class WaferCounterConfiguration +{ + + public string? Destination { get; set; } + public bool? MatchPath { get; set; } + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, BinderWaferCounterConfigurationSourceGenerationContext.Default.WaferCounterConfiguration); + return result; + } + + private static void PreVerify(IConfigurationRoot configurationRoot, WaferCounterConfiguration? configuration) + { + if (configuration?.Destination is null) + { + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + if (!physicalFileProvider.Root.Contains("UserSecrets")) + continue; + throw new NotSupportedException(physicalFileProvider.Root); + } + throw new NotSupportedException("Not Found!"); + } + } + + private static void Verify(WaferCounterConfiguration _) + { + } + + private static Models.WaferCounterConfiguration Get(WaferCounterConfiguration? configuration) + { + Models.WaferCounterConfiguration result; + if (configuration is null) throw new NullReferenceException(nameof(configuration)); + if (configuration.Destination is null) throw new NullReferenceException(nameof(configuration.Destination)); + if (configuration.MatchPath is null) throw new NullReferenceException(nameof(configuration.MatchPath)); + Verify(configuration); + result = new(configuration.Destination, + configuration.MatchPath.Value); + return result; + } + + public static Models.WaferCounterConfiguration Get(IConfigurationRoot configurationRoot) + { + Models.WaferCounterConfiguration result; + IConfigurationSection configurationSection = configurationRoot.GetSection(nameof(Models.WaferCounterConfiguration)); +#pragma warning disable IL3050, IL2026 + WaferCounterConfiguration? configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, configuration); + result = Get(configuration); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(WaferCounterConfiguration))] +internal partial class BinderWaferCounterConfigurationSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Models/EAFLogConfiguration.cs b/Models/EAFLogConfiguration.cs new file mode 100644 index 0000000..a650f66 --- /dev/null +++ b/Models/EAFLogConfiguration.cs @@ -0,0 +1,21 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace File_Watcher.Models; + +public record EAFLogConfiguration(string SearchPattern) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, EAFLogConfigurationSourceGenerationContext.Default.EAFLogConfiguration); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(EAFLogConfiguration))] +internal partial class EAFLogConfigurationSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Models/StratusConfiguration.cs b/Models/StratusConfiguration.cs new file mode 100644 index 0000000..41bdeb2 --- /dev/null +++ b/Models/StratusConfiguration.cs @@ -0,0 +1,23 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace File_Watcher.Models; + +public record StratusConfiguration(string Destination, + string FileDelimiterPattern, + string WatchFile) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, StratusConfigurationSourceGenerationContext.Default.StratusConfiguration); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(StratusConfiguration))] +internal partial class StratusConfigurationSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Models/WaferCounterConfiguration.cs b/Models/WaferCounterConfiguration.cs new file mode 100644 index 0000000..eb0a5e9 --- /dev/null +++ b/Models/WaferCounterConfiguration.cs @@ -0,0 +1,22 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace File_Watcher.Models; + +public record WaferCounterConfiguration(string Destination, + bool MatchPath) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, WaferCounterConfigurationSourceGenerationContext.Default.WaferCounterConfiguration); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(WaferCounterConfiguration))] +internal partial class WaferCounterConfigurationSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Program.cs b/Program.cs index c0f0ba9..b39e50a 100644 --- a/Program.cs +++ b/Program.cs @@ -14,12 +14,15 @@ public class Program WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args); #pragma warning restore IL3050 _ = webApplicationBuilder.Configuration.AddUserSecrets(); - AppSettings appSettings = Models.Binder.AppSettings.Get(webApplicationBuilder.Configuration); + EAFLogConfiguration eafLogConfiguration = Models.Binder.EAFLogConfiguration.Get(webApplicationBuilder.Configuration); + StratusConfiguration stratusConfiguration = Models.Binder.StratusConfiguration.Get(webApplicationBuilder.Configuration); + WaferCounterConfiguration waferCounterConfiguration = Models.Binder.WaferCounterConfiguration.Get(webApplicationBuilder.Configuration); + AppSettings appSettings = Models.Binder.AppSettings.Get(webApplicationBuilder.Configuration, eafLogConfiguration, stratusConfiguration, waferCounterConfiguration); if (string.IsNullOrEmpty(appSettings.Company)) throw new Exception("Company name must have a value!"); try { - List collection = new(); + List collection = []; _ = webApplicationBuilder.Services.AddHostedService(); _ = webApplicationBuilder.Services.AddSingleton(collection); _ = webApplicationBuilder.Services.AddSingleton(appSettings); diff --git a/Worker.cs b/Worker.cs index a2c38cb..4faa553 100644 --- a/Worker.cs +++ b/Worker.cs @@ -26,40 +26,15 @@ public partial class Worker : BackgroundService _Logger.LogInformation("A) Next execute will be at {date}", DateTime.Now.AddMilliseconds(_AppSettings.MillisecondsDelay).ToString("yyyy-MM-dd hh:mm:ss.fff tt")); if (!Directory.Exists(_AppSettings.WatchDirectory)) _ = Directory.CreateDirectory(_AppSettings.WatchDirectory); - if (!Directory.Exists(Path.GetPathRoot(_AppSettings.Destination)) || !Directory.Exists(_AppSettings.Destination)) - _Logger.LogCritical("<{Destination}> Doesn't exist!", _AppSettings.Destination); else { - string[] files; - string checkFile; - FileInfo fileInfo; - string checkDirectory; - string[] directories = Directory.GetDirectories(_AppSettings.WatchDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string directory in directories) + _ = _AppSettings.Helper switch { - checkDirectory = !_AppSettings.MatchPath ? _AppSettings.Destination : Path.Combine(_AppSettings.Destination, Path.GetFileName(directory)); - try - { - if (!Directory.Exists(checkDirectory)) - _ = Directory.CreateDirectory(checkDirectory); - files = Directory.GetFiles(directory, "*", SearchOption.TopDirectoryOnly); - foreach (string file in files) - { - fileInfo = new(file); - if (new TimeSpan(DateTime.Now.Ticks - fileInfo.LastWriteTime.Ticks).TotalMilliseconds < _AppSettings.MillisecondsDelay) - continue; - checkFile = Path.Combine(checkDirectory, Path.GetFileName(file)); - if (File.Exists(checkFile)) - continue; - try - { File.Move(file, checkFile); } - catch (Exception ex) - { _Logger.LogError(ex, "Inner loop error!"); } - } - } - catch (Exception ex) - { _Logger.LogError(ex, "Loop error!"); } - } + nameof(Helpers.HelperEAFLog) => Helpers.HelperEAFLog.DeleteFiles(_AppSettings, _Logger), + nameof(Helpers.HelperStratus) => Helpers.HelperStratus.MoveFile(_AppSettings, _Logger), + nameof(Helpers.HelperWaferCounter) => Helpers.HelperWaferCounter.MoveFile(_AppSettings, _Logger), + _ => throw new NotSupportedException() + }; } _Logger.LogInformation("B) Next execute will be at {date}", DateTime.Now.AddMilliseconds(_AppSettings.MillisecondsDelay).ToString("yyyy-MM-dd hh:mm:ss.fff tt")); } diff --git a/package-lock.json b/package-lock.json index aed116c..1380eab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "File-Folder-Helper", + "name": "File-Watcher", "lockfileVersion": 2, "requires": true, "packages": {