Compare commits

...

5 Commits

61 changed files with 3441 additions and 2449 deletions

View File

@ -120,7 +120,7 @@ dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name 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.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.IDE0004.severity = warning # IDE0004: Cast is redundant.
dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary dotnet_diagnostic.IDE0005.severity = none # Using directive is unnecessary
dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement (IDE0010) dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement (IDE0010)
dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031) dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)

27
.vscode/launch.json vendored
View File

@ -8,12 +8,31 @@
"name": ".NET Core Launch (console)", "name": ".NET Core Launch (console)",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"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", "s",
"X", "X",
"V:/1-Images-A/Images-0b793904", "P:/6-Other-Large-Z/Current-Results/A2)People/c9dbce3b/([])/File-Folder-Helper/638443643487798783/638443643487798783",
"Day-Helper-2024-05-18",
"people.json",
"person",
"ownerId,name,birthDate",
"c76905af-c06a-4a78-a9a7-c32f5b58e793",
"yyyy-MM-dd",
"1900-01-01",
"s",
"X",
"P:/1-Images-A/Images-0b793904",
"Day-Helper-2025-07-26",
"4e+9",
"L:/Git/AA/Rename/.vscode/.UserSecrets/secrets.json",
".avif~.bmp~.gif~.heic~.insp~.jp2~.jpe~.jpeg~.jpg~.jxl~.png~.psd~.raw~.rw2~.svg~.tif~.tiff~.webp~.3gp~.3gpp~.avi~.dvr-ms~.flv~.insv~.m2t~.m2ts~.m4v~.mkv~.mov~.mp4~.mpe~.mpeg~.mpg~.mts~.ts~.webm~.wmv",
"P:/6-Other-Large-Z/Current-Results/C)Resize/0b793904/Original",
"(helper)",
"s",
"X",
"P:/1-Images-A/Images-0b793904",
"Day-Helper-2024-12-17", "Day-Helper-2024-12-17",
".job.json", ".job.json",
"thumbs.db~sync.ffs_db~verify.json~.html", "thumbs.db~sync.ffs_db~verify.json~.html",
@ -21,7 +40,7 @@
"D:/5-Other-Small/Disk/Snap2HTML/Snap2HTML.exe", "D:/5-Other-Small/Disk/Snap2HTML/Snap2HTML.exe",
"s", "s",
"X", "X",
"V:/Tmp/Phares/Helper-2025-07-20", "P:/Tmp/Phares/Helper-2025-07-20",
"Day-Helper-2025-07-20", "Day-Helper-2025-07-20",
"871467010009.jpg", "871467010009.jpg",
"L:/Git/AA/Rename/.vscode/.UserSecrets/secrets.json", "L:/Git/AA/Rename/.vscode/.UserSecrets/secrets.json",
@ -67,7 +86,7 @@
"\"vp154\"", "\"vp154\"",
"s", "s",
"X", "X",
"V:/Tmp/Phares/Pictures/2023 TI2023.6 Fall Samsung", "P:/Tmp/Phares/Pictures/2023 TI2023.6 Fall Samsung",
"Day-Helper-2025-07-05", "Day-Helper-2025-07-05",
"x-653889110721.jpg~401223300869.jpg", "x-653889110721.jpg~401223300869.jpg",
"3648,2736,1~3024,4032,6", "3648,2736,1~3024,4032,6",

297
.vscode/tasks.json vendored
View File

@ -1,22 +1,135 @@
{ {
"version": "2.0.0", "inputs": [
{
"default": "Development",
"description": "Which ASP Net Core Environment?",
"id": "ASPNETCORE_ENVIRONMENT",
"options": [
"Development",
"Production"
],
"type": "pickString"
},
{
"default": "{AssemblyTitle}",
"description": "What Assembly Title?",
"id": "AssemblyTitle",
"type": "promptString"
},
{
"default": "{Build.BuildId}",
"description": "Which Build BuildId?",
"id": "Build.BuildId",
"type": "promptString"
},
{
"default": "{Build.Reason}",
"description": "Which Build Reason?",
"id": "Build.Reason",
"type": "promptString"
},
{
"default": "{Build.Repository.Id}",
"description": "Which Build Repository Id?",
"id": "Build.Repository.Id",
"type": "promptString"
},
{
"default": "{Build.Repository.Name}",
"description": "Which Build Repository Name?",
"id": "Build.Repository.Name",
"type": "promptString"
},
{
"default": "{Build.SourceVersion}",
"description": "Which Build Source Version?",
"id": "Build.SourceVersion",
"type": "promptString"
},
{
"default": "Debug",
"description": "Which Configuration?",
"id": "Configuration",
"options": [
"Debug",
"Release"
],
"type": "pickString"
},
{
"default": "net8.0",
"description": "Which Core Version?",
"id": "CoreVersion",
"options": [
"net8.0"
],
"type": "pickString"
},
{
"default": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe",
"description": "Which MS Build?",
"id": "MSBuild",
"type": "promptString"
},
{
"default": "https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/",
"description": "Which Nuget Source?",
"id": "NugetSource",
"type": "promptString"
},
{
"default": "win-x64",
"description": "Which Runtime?",
"id": "Runtime",
"options": [
"win-x64",
"win-x32",
"linux-x64",
"linux-x32"
],
"type": "pickString"
},
{
"default": "L:/",
"description": "Which System DefaultWorkingDirectory?",
"id": "System.DefaultWorkingDirectory",
"options": [
"L:/",
"D:/",
"C:/"
],
"type": "pickString"
},
{
"default": "v4.8",
"description": "Which Core Target Framework Version?",
"id": "TargetFrameworkVersion",
"options": [
"v4.8"
],
"type": "pickString"
},
{
"default": "{UserSecretsId}",
"description": "Which Core User Secrets Id?",
"id": "UserSecretsId",
"type": "promptString"
}
],
"tasks": [ "tasks": [
{ {
"label": "User Secrets Init",
"command": "dotnet",
"type": "process",
"args": [ "args": [
"user-secrets", "user-secrets",
"-p", "-p",
"${workspaceFolder}/File-Folder-Helper.csproj", "${workspaceFolder}/File-Folder-Helper.csproj",
"init" "init"
], ],
"problemMatcher": "$msCompile" "command": "dotnet",
"label": "User Secrets Init",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "User Secrets Set",
"command": "dotnet",
"type": "process",
"args": [ "args": [
"user-secrets", "user-secrets",
"-p", "-p",
@ -25,12 +138,12 @@
"_UserSecretsId", "_UserSecretsId",
"0c43f9aa-96e9-4298-967c-ed069d79e262" "0c43f9aa-96e9-4298-967c-ed069d79e262"
], ],
"problemMatcher": "$msCompile" "command": "dotnet",
"label": "User Secrets Set",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "Format",
"command": "dotnet",
"type": "process",
"args": [ "args": [
"format", "format",
"--report", "--report",
@ -40,82 +153,78 @@
"--severity", "--severity",
"warn" "warn"
], ],
"problemMatcher": "$msCompile" "command": "dotnet",
"label": "Format",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "Format-Whitespaces",
"command": "dotnet",
"type": "process",
"args": [ "args": [
"format", "format",
"whitespace" "whitespace"
], ],
"problemMatcher": "$msCompile" "command": "dotnet",
"label": "Format Whitespaces",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "build",
"command": "dotnet",
"type": "process",
"args": [ "args": [
"build", "build",
"-r", "-r",
"win-x64", "win-x64",
"${workspaceFolder}/File-Folder-Helper.csproj", "${workspaceFolder}/File-Folder-Helper.csproj"
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
], ],
"problemMatcher": "$msCompile" "command": "dotnet",
"label": "Build",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "build Linux",
"command": "dotnet",
"type": "process",
"args": [ "args": [
"build", "build",
"-r", "-r",
"linux-x64", "linux-x64",
"${workspaceFolder}/File-Folder-Helper.csproj", "${workspaceFolder}/File-Folder-Helper.csproj"
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
], ],
"problemMatcher": "$msCompile" "command": "dotnet",
"label": "Build Linux",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "podmanLogin",
"command": "podman",
"type": "process",
"args": [ "args": [
"login", "login",
"gitea.phares.duckdns.org:443" "gitea.phares.duckdns.org:443"
], ],
"problemMatcher": "$msCompile" "command": "podman",
"label": "Podman Login",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "podmanBuild",
"command": "podman",
"type": "process",
"args": [ "args": [
"build", "build",
"-t", "-t",
"file-folder-helper", "file-folder-helper",
"." "."
], ],
"problemMatcher": "$msCompile" "command": "podman",
"label": "Podman Build",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "podmanImageList",
"command": "podman",
"type": "process",
"args": [ "args": [
"image", "image",
"ls" "ls"
], ],
"problemMatcher": "$msCompile" "command": "podman",
"label": "Podman Image List",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "podmanRun",
"command": "podman",
"type": "process",
"args": [ "args": [
"run", "run",
"-p", "-p",
@ -124,57 +233,55 @@
"file-folder-helper-001", "file-folder-helper-001",
"a3de856b5731" "a3de856b5731"
], ],
"problemMatcher": "$msCompile" "command": "podman",
"label": "Podman Run",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "podmanTag",
"command": "podman",
"type": "process",
"args": [ "args": [
"tag", "tag",
"a3de856b5731", "a3de856b5731",
"gitea.phares.duckdns.org:443/phares3757/file-folder-helper:latest" "gitea.phares.duckdns.org:443/phares3757/file-folder-helper:latest"
], ],
"problemMatcher": "$msCompile" "command": "podman",
"label": "Podman Tag",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "podmanPush",
"command": "podman",
"type": "process",
"args": [ "args": [
"push", "push",
"gitea.phares.duckdns.org:443/phares3757/file-folder-helper:latest" "gitea.phares.duckdns.org:443/phares3757/file-folder-helper:latest"
], ],
"problemMatcher": "$msCompile" "command": "podman",
"label": "Podman Push",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [ "args": [
"publish", "publish",
"${workspaceFolder}/File-Folder-Helper.csproj", "${workspaceFolder}/File-Folder-Helper.csproj"
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
], ],
"problemMatcher": "$msCompile" "command": "dotnet",
"label": "Publish",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [ "args": [
"watch", "watch",
"run", "run",
"--project", "--project",
"${workspaceFolder}/File-Folder-Helper.csproj" "${workspaceFolder}/File-Folder-Helper.csproj"
], ],
"problemMatcher": "$msCompile" "command": "dotnet",
"label": "Watch",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "Publish AOT",
"command": "dotnet",
"type": "process",
"args": [ "args": [
"publish", "publish",
"-r", "-r",
@ -182,16 +289,14 @@
"-c", "-c",
"Release", "Release",
"-p:PublishAot=true", "-p:PublishAot=true",
"${workspaceFolder}/File-Folder-Helper.csproj", "${workspaceFolder}/File-Folder-Helper.csproj"
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
], ],
"problemMatcher": "$msCompile" "command": "dotnet",
"label": "Publish AOT",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "Publish AOT Linux",
"command": "dotnet",
"type": "process",
"args": [ "args": [
"publish", "publish",
"-r", "-r",
@ -199,40 +304,38 @@
"-c", "-c",
"Release", "Release",
"-p:PublishAot=true", "-p:PublishAot=true",
"${workspaceFolder}/File-Folder-Helper.csproj", "${workspaceFolder}/File-Folder-Helper.csproj"
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
], ],
"problemMatcher": "$msCompile" "command": "dotnet",
"label": "Publish AOT Linux",
"problemMatcher": "$msCompile",
"type": "process"
}, },
{ {
"label": "Kanbn Console", "label": "Kanbn Console",
"type": "npm", "problemMatcher": [],
"script": "kanbn.board", "script": "kanbn.board",
"problemMatcher": [] "type": "npm"
}, },
{ {
"label": "Kanbn Write Boad",
"type": "shell",
"command": "& kanbn board -j | L:/Git/kanbn2md/kanbn2md.exe >.kanbn/board.md", "command": "& kanbn board -j | L:/Git/kanbn2md/kanbn2md.exe >.kanbn/board.md",
"problemMatcher": [] "label": "Kanbn Write Boad",
"problemMatcher": [],
"type": "shell"
}, },
{ {
"label": "Kanbn Write json", "label": "Kanbn Write json",
"type": "npm", "problemMatcher": [],
"script": "kanbn.board.json", "script": "kanbn.board.json",
"problemMatcher": [] "type": "npm"
}, },
{ {
"label": "Jest",
"type": "shell",
"command": "npx jest", "command": "npx jest",
"problemMatcher": [] "label": "Jest",
"problemMatcher": [],
"type": "shell"
}, },
{ {
"label": "File-Folder-Helper AOT s X Day-Helper-2025-03-20",
"type": "shell",
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe",
"args": [ "args": [
"s", "s",
"X", "X",
@ -241,7 +344,11 @@
"false", "false",
"4" "4"
], ],
"problemMatcher": [] "command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe",
"label": "File-Folder-Helper AOT s X Day-Helper-2025-03-20",
"problemMatcher": [],
"type": "shell"
} }
] ],
"version": "2.0.0"
} }

296
ADO2024/PI2/.editorconfig Normal file
View File

@ -0,0 +1,296 @@
[*.md]
end_of_line = crlf
file_header_template = unset
indent_size = 2
indent_style = space
insert_final_newline = false
root = true
tab_width = 2
[*.csproj]
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
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true
csharp_prefer_braces = true
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
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = false
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
csharp_style_allow_embedded_statements_on_same_line_experimental = true
csharp_style_conditional_delegate_call = true
csharp_style_deconstructed_variable_declaration = false
csharp_style_expression_bodied_accessors = when_on_single_line:warning
csharp_style_expression_bodied_constructors = when_on_single_line:warning
csharp_style_expression_bodied_indexers = when_on_single_line:warning
csharp_style_expression_bodied_lambdas = when_on_single_line:warning
csharp_style_expression_bodied_local_functions = when_on_single_line:warning
csharp_style_expression_bodied_methods = when_on_single_line:warning
csharp_style_expression_bodied_operators = when_on_single_line:warning
csharp_style_expression_bodied_properties = when_on_single_line:warning
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
csharp_style_inlined_variable_declaration = false
csharp_style_namespace_declarations = file_scoped:warning
csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_not_pattern = true:warning
csharp_style_prefer_null_check_over_type_check = true
csharp_style_prefer_pattern_matching = true:warning
csharp_style_prefer_range_operator = true:warning
csharp_style_prefer_switch_expression = true:warning
csharp_style_throw_expression = true
csharp_style_unused_value_assignment_preference = discard_variable:warning
csharp_style_unused_value_expression_statement_preference = discard_variable:warning
csharp_style_var_elsewhere = false:warning
csharp_style_var_for_built_in_types = false:warning
csharp_style_var_when_type_is_apparent = false:warning
csharp_using_directive_placement = outside_namespace
dotnet_analyzer_diagnostic.category-Design.severity = error
dotnet_analyzer_diagnostic.category-Documentation.severity = error
dotnet_analyzer_diagnostic.category-Globalization.severity = none
dotnet_analyzer_diagnostic.category-Interoperability.severity = error
dotnet_analyzer_diagnostic.category-Maintainability.severity = error
dotnet_analyzer_diagnostic.category-Naming.severity = none
dotnet_analyzer_diagnostic.category-Performance.severity = none
dotnet_analyzer_diagnostic.category-Reliability.severity = error
dotnet_analyzer_diagnostic.category-Security.severity = error
dotnet_analyzer_diagnostic.category-SingleFile.severity = error
dotnet_analyzer_diagnostic.category-Style.severity = error
dotnet_analyzer_diagnostic.category-Usage.severity = error
dotnet_code_quality_unused_parameters = all
dotnet_code_quality_unused_parameters = non_public
dotnet_code_quality.CAXXXX.api_surface = private, internal
dotnet_diagnostic.CA1001.severity = error # CA1001: Types that own disposable fields should be disposable
dotnet_diagnostic.CA1051.severity = error # CA1051: Do not declare visible instance fields
dotnet_diagnostic.CA1511.severity = warning # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1513.severity = warning # Use 'ObjectDisposedException.ThrowIf' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1825.severity = warning # CA1825: 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.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'
dotnet_diagnostic.CA1869.severity = none # CA1869: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead.
dotnet_diagnostic.CA2201.severity = none # CA2201: Exception type System.NullReferenceException is reserved by the runtime
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.IDE0010.severity = none # Add missing cases to switch statement (IDE0010)
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.IDE0048.severity = none # Parentheses preferences (IDE0047 and IDE0048)
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
dotnet_diagnostic.IDE0051.severity = error # Private member '' is unused [, ]
dotnet_diagnostic.IDE0058.severity = warning # IDE0058: Expression value is never used
dotnet_diagnostic.IDE0060.severity = error # IDE0060: Remove unused parameter
dotnet_diagnostic.IDE0074.severity = warning # IDE0074: Use compound assignment
dotnet_diagnostic.IDE0130.severity = none # Namespace does not match folder structure (IDE0130)
dotnet_diagnostic.IDE0270.severity = warning # IDE0270: Null check can be simplified
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
dotnet_naming_rule.class_should_be_pascal_case.severity = warning
dotnet_naming_rule.class_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.class_should_be_pascal_case.symbols = class
dotnet_naming_rule.delegate_should_be_pascal_case.severity = warning
dotnet_naming_rule.delegate_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.delegate_should_be_pascal_case.symbols = delegate
dotnet_naming_rule.enum_should_be_pascal_case.severity = warning
dotnet_naming_rule.enum_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.enum_should_be_pascal_case.symbols = enum
dotnet_naming_rule.event_should_be_pascal_case.severity = warning
dotnet_naming_rule.event_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.event_should_be_pascal_case.symbols = event
dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.method_should_be_pascal_case.severity = warning
dotnet_naming_rule.method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.method_should_be_pascal_case.symbols = method
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.private_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.private_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.private_method_should_be_pascal_case.symbols = private_method
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.symbols = private_or_internal_field
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.symbols = private_or_internal_static_field
dotnet_naming_rule.property_should_be_pascal_case.severity = warning
dotnet_naming_rule.property_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.property_should_be_pascal_case.symbols = property
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.symbols = public_or_protected_field
dotnet_naming_rule.static_field_should_be_pascal_case.severity = warning
dotnet_naming_rule.static_field_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_field_should_be_pascal_case.symbols = static_field
dotnet_naming_rule.static_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.static_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_method_should_be_pascal_case.symbols = static_method
dotnet_naming_rule.struct_should_be_pascal_case.severity = warning
dotnet_naming_rule.struct_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.struct_should_be_pascal_case.symbols = struct
dotnet_naming_rule.types_should_be_pascal_case.severity = warning
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.private_of_internal_field.capitalization = pascal_case
dotnet_naming_style.private_of_internal_field.required_prefix = _
dotnet_naming_style.private_of_internal_field.required_suffix =
dotnet_naming_style.private_of_internal_field.word_separator =
dotnet_naming_symbols.abstract_method.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.abstract_method.applicable_kinds = method
dotnet_naming_symbols.abstract_method.required_modifiers = abstract
dotnet_naming_symbols.class.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.class.applicable_kinds = class
dotnet_naming_symbols.class.required_modifiers =
dotnet_naming_symbols.delegate.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.delegate.applicable_kinds = delegate
dotnet_naming_symbols.delegate.required_modifiers =
dotnet_naming_symbols.enum.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.enum.applicable_kinds = enum
dotnet_naming_symbols.enum.required_modifiers =
dotnet_naming_symbols.event.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.event.applicable_kinds = event
dotnet_naming_symbols.event.required_modifiers =
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.method.applicable_accessibilities = public
dotnet_naming_symbols.method.applicable_kinds = method
dotnet_naming_symbols.method.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_symbols.private_method.applicable_accessibilities = private
dotnet_naming_symbols.private_method.applicable_kinds = method
dotnet_naming_symbols.private_method.required_modifiers =
dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected
dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_field.required_modifiers =
dotnet_naming_symbols.private_or_internal_static_field.applicable_accessibilities = internal, private, private_protected
dotnet_naming_symbols.private_or_internal_static_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_static_field.required_modifiers = static
dotnet_naming_symbols.property.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.property.applicable_kinds = property
dotnet_naming_symbols.property.required_modifiers =
dotnet_naming_symbols.public_or_protected_field.applicable_accessibilities = public, protected
dotnet_naming_symbols.public_or_protected_field.applicable_kinds = field
dotnet_naming_symbols.public_or_protected_field.required_modifiers =
dotnet_naming_symbols.static_field.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.static_field.applicable_kinds = field
dotnet_naming_symbols.static_field.required_modifiers = static
dotnet_naming_symbols.static_method.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.static_method.applicable_kinds = method
dotnet_naming_symbols.static_method.required_modifiers = static
dotnet_naming_symbols.struct.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.struct.applicable_kinds = struct
dotnet_naming_symbols.struct.required_modifiers =
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.required_modifiers =
dotnet_remove_unnecessary_suppression_exclusions = 0
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
dotnet_style_allow_multiple_blank_lines_experimental = false:warning
dotnet_style_allow_statement_immediately_after_block_experimental = true
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true:warning
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_namespace_match_folder = true
dotnet_style_null_propagation = true:warning
dotnet_style_object_initializer = true:warning
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
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:warning
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_compound_assignment = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = false
dotnet_style_prefer_conditional_expression_over_return = false
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
dotnet_style_prefer_simplified_boolean_expressions = true:warning
dotnet_style_prefer_simplified_interpolation = true
dotnet_style_qualification_for_event = false:error
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false:error
dotnet_style_qualification_for_property = false:error
dotnet_style_readonly_field = true:warning
dotnet_style_require_accessibility_modifiers = for_non_interface_members
end_of_line = crlf
file_header_template = unset
indent_size = 4
indent_style = space
insert_final_newline = false
root = true
tab_width = 4
# https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1822
# https://github.com/dotnet/aspnetcore/blob/main/.editorconfig
# https://github.com/dotnet/project-system/blob/main/.editorconfig

View File

@ -3,11 +3,9 @@ using System.Diagnostics;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240429 internal static partial class Helper20240429 {
{
internal static void GitConfigCleanUp(ILogger<Worker> logger, List<string> args) internal static void GitConfigCleanUp(ILogger<Worker> logger, List<string> args) {
{
string[] files; string[] files;
Process? process; Process? process;
string? directory; string? directory;
@ -19,34 +17,34 @@ internal static partial class Helper20240429
string[] removeRemotes = args[4].Split(','); string[] removeRemotes = args[4].Split(',');
string systemVolumeInformation = Path.Combine(root, args[2]); string systemVolumeInformation = Path.Combine(root, args[2]);
string[] subDirectories = Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly); string[] subDirectories = Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly);
foreach (string subDirectory in subDirectories) foreach (string subDirectory in subDirectories) {
{ if (subDirectory == systemVolumeInformation) {
if (subDirectory == systemVolumeInformation)
continue; continue;
}
files = Directory.GetFiles(subDirectory, searchPattern, SearchOption.AllDirectories); files = Directory.GetFiles(subDirectory, searchPattern, SearchOption.AllDirectories);
foreach (string file in files) foreach (string file in files) {
{
directory = Path.GetDirectoryName(file); directory = Path.GetDirectoryName(file);
if (directory is null) if (directory is null) {
continue; continue;
foreach (string removeRemote in removeRemotes) }
{ foreach (string removeRemote in removeRemotes) {
processStartInfo = new() processStartInfo = new() {
{
FileName = "git", FileName = "git",
WorkingDirectory = directory, WorkingDirectory = directory,
Arguments = $"remote rm {removeRemote}", Arguments = $"remote rm {removeRemote}",
RedirectStandardError = true RedirectStandardError = true
}; };
process = Process.Start(processStartInfo); process = Process.Start(processStartInfo);
if (process is null) if (process is null) {
continue; continue;
}
#pragma warning disable IDE0058 #pragma warning disable IDE0058
process.WaitForExit(7000); process.WaitForExit(7000);
#pragma warning restore IDE0058 #pragma warning restore IDE0058
standardError = process.StandardError.ReadToEnd(); standardError = process.StandardError.ReadToEnd();
if (!standardError.Contains(ignoreError)) if (!standardError.Contains(ignoreError)) {
logger.LogInformation(standardError); logger.LogInformation(standardError);
}
logger.LogInformation("for <{directoryName}> remote rm {removeRemote}", directory, removeRemote); logger.LogInformation("for <{directoryName}> remote rm {removeRemote}", directory, removeRemote);
} }
} }

View File

@ -2,33 +2,33 @@ using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240510 internal static partial class Helper20240510 {
{
internal static void PullIconsForBLM(ILogger<Worker> logger, List<string> args) internal static void PullIconsForBLM(ILogger<Worker> logger, List<string> args) {
{
string fileName; string fileName;
FileInfo fileInfo; FileInfo fileInfo;
string searchPattern = args[4]; string searchPattern = args[4];
string sourceDirectory = args[3]; string sourceDirectory = args[3];
string root = Path.GetFullPath(args[0]); string root = Path.GetFullPath(args[0]);
string createDirectory = Path.Combine(root, args[2]); string createDirectory = Path.Combine(root, args[2]);
if (!Directory.Exists(createDirectory)) if (!Directory.Exists(createDirectory)) {
_ = Directory.CreateDirectory(createDirectory); _ = Directory.CreateDirectory(createDirectory);
}
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
foreach (string file in files) foreach (string file in files) {
{
fileName = Path.GetFileName(file); fileName = Path.GetFileName(file);
fileInfo = new(Path.Combine(createDirectory, fileName)); fileInfo = new(Path.Combine(createDirectory, fileName));
if (fileInfo.Exists && fileInfo.LastWriteTime == new FileInfo(file).LastWriteTime) if (fileInfo.Exists && fileInfo.LastWriteTime == new FileInfo(file).LastWriteTime) {
continue; continue;
}
File.Copy(file, fileInfo.FullName, overwrite: true); File.Copy(file, fileInfo.FullName, overwrite: true);
logger.LogInformation("<{fileName}> copied", fileName); logger.LogInformation("<{fileName}> copied", fileName);
} }
logger.LogWarning("What reactor is this near?"); logger.LogWarning("What reactor is this near?");
string? reactor = Console.ReadLine(); string? reactor = Console.ReadLine();
if (!string.IsNullOrEmpty(reactor)) if (!string.IsNullOrEmpty(reactor)) {
_ = Directory.CreateDirectory(Path.Combine(sourceDirectory, Environment.MachineName, reactor)); _ = Directory.CreateDirectory(Path.Combine(sourceDirectory, Environment.MachineName, reactor));
}
} }
} }

View File

@ -4,11 +4,9 @@ using System.Text.Json;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240513 internal static partial class Helper20240513 {
{
internal static void PersonKeyToName(ILogger<Worker> logger, List<string> args) internal static void PersonKeyToName(ILogger<Worker> logger, List<string> args) {
{
Person? person; Person? person;
string directoryName; string directoryName;
string checkDirectory; string checkDirectory;
@ -17,20 +15,21 @@ internal static partial class Helper20240513
Dictionary<string, Person> keyValuePairs = []; Dictionary<string, Person> keyValuePairs = [];
string[] directories = Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly); string[] directories = Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly);
Dictionary<long, Person> people = JsonSerializer.Deserialize(json, PeopleSourceGenerationContext.Default.DictionaryInt64Person) ?? throw new NullReferenceException(); Dictionary<long, Person> people = JsonSerializer.Deserialize(json, PeopleSourceGenerationContext.Default.DictionaryInt64Person) ?? throw new NullReferenceException();
foreach (KeyValuePair<long, Person> keyValuePair in people) foreach (KeyValuePair<long, Person> keyValuePair in people) {
{ if (keyValuePair.Value.Birth?.Note is null) {
if (keyValuePair.Value.Birth?.Note is null)
continue; continue;
}
keyValuePairs.Add(keyValuePair.Value.Birth.Note, keyValuePair.Value); keyValuePairs.Add(keyValuePair.Value.Birth.Note, keyValuePair.Value);
} }
foreach (string directory in directories) foreach (string directory in directories) {
{
directoryName = Path.GetFileName(directory); directoryName = Path.GetFileName(directory);
if (!keyValuePairs.TryGetValue(directoryName, out person) || person.Name?.ForwardSlashFull is null) if (!keyValuePairs.TryGetValue(directoryName, out person) || person.Name?.ForwardSlashFull is null) {
continue; continue;
}
checkDirectory = Path.Combine(root, $"{person.Name.ForwardSlashFull.Replace('/', '-')}{directoryName}-{person.Id}"); checkDirectory = Path.Combine(root, $"{person.Name.ForwardSlashFull.Replace('/', '-')}{directoryName}-{person.Id}");
if (Directory.Exists(checkDirectory)) if (Directory.Exists(checkDirectory)) {
continue; continue;
}
Directory.Move(directory, checkDirectory); Directory.Move(directory, checkDirectory);
logger.LogInformation("<{directory}> was moved", directory); logger.LogInformation("<{directory}> was moved", directory);
} }

View File

@ -5,16 +5,14 @@ using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240517 internal static partial class Helper20240517 {
{
private record ContentSignature([property: JsonPropertyName("contentSignature")] string Value, private record ContentSignature([property: JsonPropertyName("contentSignature")] string Value,
[property: JsonPropertyName("contentSignatureType")] string ContentSignatureType); [property: JsonPropertyName("contentSignatureType")] string ContentSignatureType);
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ContentSignature))] [JsonSerializable(typeof(ContentSignature))]
private partial class ContentSignatureGenerationContext : JsonSerializerContext private partial class ContentSignatureGenerationContext : JsonSerializerContext {
{
} }
private record Type([property: JsonPropertyName("count")] int Count, private record Type([property: JsonPropertyName("count")] int Count,
@ -23,8 +21,7 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Type))] [JsonSerializable(typeof(Type))]
private partial class TypeGenerationContext : JsonSerializerContext private partial class TypeGenerationContext : JsonSerializerContext {
{
} }
private record ImageAmazon([property: JsonPropertyName("colorSpace")] string ColorSpace, private record ImageAmazon([property: JsonPropertyName("colorSpace")] string ColorSpace,
@ -54,8 +51,7 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ImageAmazon))] [JsonSerializable(typeof(ImageAmazon))]
private partial class ImageAmazonGenerationContext : JsonSerializerContext private partial class ImageAmazonGenerationContext : JsonSerializerContext {
{
} }
private record ContentProperties([property: JsonPropertyName("contentDate")] DateTime ContentDate, private record ContentProperties([property: JsonPropertyName("contentDate")] DateTime ContentDate,
@ -69,16 +65,14 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ContentProperties))] [JsonSerializable(typeof(ContentProperties))]
private partial class ContentPropertiesGenerationContext : JsonSerializerContext private partial class ContentPropertiesGenerationContext : JsonSerializerContext {
{
} }
private record XAccntParentMap(); private record XAccntParentMap();
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(XAccntParentMap))] [JsonSerializable(typeof(XAccntParentMap))]
private partial class XAccntParentMapGenerationContext : JsonSerializerContext private partial class XAccntParentMapGenerationContext : JsonSerializerContext {
{
} }
private record Datum([property: JsonPropertyName("accessRuleIds")] IReadOnlyList<object> AccessRuleIds, private record Datum([property: JsonPropertyName("accessRuleIds")] IReadOnlyList<object> AccessRuleIds,
@ -111,14 +105,12 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Datum))] [JsonSerializable(typeof(Datum))]
private partial class DatumGenerationContext : JsonSerializerContext private partial class DatumGenerationContext : JsonSerializerContext {
{
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Dictionary<string, Datum>))] [JsonSerializable(typeof(Dictionary<string, Datum>))]
private partial class DictionaryDatumGenerationContext : JsonSerializerContext private partial class DictionaryDatumGenerationContext : JsonSerializerContext {
{
} }
private record LocationAmazon([property: JsonPropertyName("count")] int Count, private record LocationAmazon([property: JsonPropertyName("count")] int Count,
@ -127,8 +119,7 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(LocationAmazon))] [JsonSerializable(typeof(LocationAmazon))]
private partial class LocationAmazonGenerationContext : JsonSerializerContext private partial class LocationAmazonGenerationContext : JsonSerializerContext {
{
} }
private record LocationInfo([property: JsonPropertyName("city")] string City, private record LocationInfo([property: JsonPropertyName("city")] string City,
@ -139,8 +130,7 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(LocationInfo))] [JsonSerializable(typeof(LocationInfo))]
private partial class LocationInfoGenerationContext : JsonSerializerContext private partial class LocationInfoGenerationContext : JsonSerializerContext {
{
} }
private record SearchData([property: JsonPropertyName("clusterName")] string ClusterName, private record SearchData([property: JsonPropertyName("clusterName")] string ClusterName,
@ -150,8 +140,7 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(SearchData))] [JsonSerializable(typeof(SearchData))]
private partial class SearchDataGenerationContext : JsonSerializerContext private partial class SearchDataGenerationContext : JsonSerializerContext {
{
} }
private record AllPerson([property: JsonPropertyName("count")] int Count, private record AllPerson([property: JsonPropertyName("count")] int Count,
@ -160,8 +149,7 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(AllPerson))] [JsonSerializable(typeof(AllPerson))]
private partial class AllPersonGenerationContext : JsonSerializerContext private partial class AllPersonGenerationContext : JsonSerializerContext {
{
} }
private record PersonAmazon([property: JsonPropertyName("count")] int Count, private record PersonAmazon([property: JsonPropertyName("count")] int Count,
@ -170,8 +158,7 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(PersonAmazon))] [JsonSerializable(typeof(PersonAmazon))]
private partial class PersonAmazonGenerationContext : JsonSerializerContext private partial class PersonAmazonGenerationContext : JsonSerializerContext {
{
} }
private record ClusterId([property: JsonPropertyName("count")] int Count, private record ClusterId([property: JsonPropertyName("count")] int Count,
@ -180,8 +167,7 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ClusterId))] [JsonSerializable(typeof(ClusterId))]
private partial class ClusterIdGenerationContext : JsonSerializerContext private partial class ClusterIdGenerationContext : JsonSerializerContext {
{
} }
private record Thing([property: JsonPropertyName("count")] int Count, private record Thing([property: JsonPropertyName("count")] int Count,
@ -190,8 +176,7 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Thing))] [JsonSerializable(typeof(Thing))]
private partial class ThingGenerationContext : JsonSerializerContext private partial class ThingGenerationContext : JsonSerializerContext {
{
} }
private record Time([property: JsonPropertyName("count")] int Count, private record Time([property: JsonPropertyName("count")] int Count,
@ -200,8 +185,7 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Time))] [JsonSerializable(typeof(Time))]
private partial class TimeGenerationContext : JsonSerializerContext private partial class TimeGenerationContext : JsonSerializerContext {
{
} }
private record ParentMap([property: JsonPropertyName("FOLDER")] IReadOnlyList<string> FOLDER); private record ParentMap([property: JsonPropertyName("FOLDER")] IReadOnlyList<string> FOLDER);
@ -216,14 +200,12 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Aggregations))] [JsonSerializable(typeof(Aggregations))]
private partial class AggregationsGenerationContext : JsonSerializerContext private partial class AggregationsGenerationContext : JsonSerializerContext {
{
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ParentMap))] [JsonSerializable(typeof(ParentMap))]
private partial class ParentMapGenerationContext : JsonSerializerContext private partial class ParentMapGenerationContext : JsonSerializerContext {
{
} }
private record RootAmazon([property: JsonPropertyName("aggregations")] Aggregations Aggregations, private record RootAmazon([property: JsonPropertyName("aggregations")] Aggregations Aggregations,
@ -232,12 +214,23 @@ internal static partial class Helper20240517
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(RootAmazon))] [JsonSerializable(typeof(RootAmazon))]
private partial class RootAmazonGenerationContext : JsonSerializerContext private partial class RootAmazonGenerationContext : JsonSerializerContext {
{
} }
private static void SaveAmazon(string destination, string harFile) internal static void SaveAmazon(ILogger<Worker> logger, List<string> args) {
{ string root = Path.GetFullPath(args[0]);
string destination = Path.GetFullPath(args[2]);
if (string.IsNullOrEmpty(root)) {
throw new NullReferenceException(nameof(root));
}
string[] harFiles = Directory.GetFiles(root, "*.har", SearchOption.TopDirectoryOnly);
foreach (string harFile in harFiles) {
SaveAmazon(destination, harFile);
}
logger?.LogInformation("{harFiles} count", harFiles.Length);
}
private static void SaveAmazon(string destination, string harFile) {
string offset; string offset;
string personId; string personId;
RootAmazon amazon; RootAmazon amazon;
@ -247,37 +240,43 @@ internal static partial class Helper20240517
PersonAmazon personAmazon; PersonAmazon personAmazon;
Dictionary<string, string> keyValuePairs = []; Dictionary<string, string> keyValuePairs = [];
ReadOnlyCollection<(string Url, string AggregationLine)> aggregationLines = GetAggregationLines(harFile); ReadOnlyCollection<(string Url, string AggregationLine)> aggregationLines = GetAggregationLines(harFile);
foreach ((string url, string aggregationLine) in aggregationLines) foreach ((string url, string aggregationLine) in aggregationLines) {
{ if (aggregationLine.Contains(",\"category\":\"allPeople\"}")) {
if (aggregationLine.Contains(",\"category\":\"allPeople\"}"))
continue; continue;
}
amazon = JsonSerializer.Deserialize(aggregationLine, RootAmazonGenerationContext.Default.RootAmazon) ?? throw new Exception(); amazon = JsonSerializer.Deserialize(aggregationLine, RootAmazonGenerationContext.Default.RootAmazon) ?? throw new Exception();
if (amazon.Aggregations?.People is null || amazon.Aggregations.People.Count < 1) if (amazon.Aggregations?.People is null || amazon.Aggregations.People.Count < 1) {
continue; continue;
}
personAmazon = amazon.Aggregations.People[0]; personAmazon = amazon.Aggregations.People[0];
if (!url.Contains(personAmazon.Match)) if (!url.Contains(personAmazon.Match)) {
continue; continue;
}
personDirectory = Path.Combine(destination, personAmazon.SearchData.ClusterName); personDirectory = Path.Combine(destination, personAmazon.SearchData.ClusterName);
_ = Directory.CreateDirectory(personDirectory); _ = Directory.CreateDirectory(personDirectory);
personIdFile = Path.Combine(personDirectory, $"000) {personAmazon.Match}.json"); personIdFile = Path.Combine(personDirectory, $"000) {personAmazon.Match}.json");
_ = keyValuePairs.TryAdd(personAmazon.Match, personAmazon.SearchData.ClusterName); _ = keyValuePairs.TryAdd(personAmazon.Match, personAmazon.SearchData.ClusterName);
SaveAmazon(amazon.Data, personIdFile); SaveAmazon(amazon.Data, personIdFile);
} }
foreach ((string url, string aggregationLine) in aggregationLines) foreach ((string url, string aggregationLine) in aggregationLines) {
{ if (aggregationLine.Contains(",\"category\":\"allPeople\"}")) {
if (aggregationLine.Contains(",\"category\":\"allPeople\"}"))
continue; continue;
}
amazon = JsonSerializer.Deserialize(aggregationLine, RootAmazonGenerationContext.Default.RootAmazon) ?? throw new Exception(); amazon = JsonSerializer.Deserialize(aggregationLine, RootAmazonGenerationContext.Default.RootAmazon) ?? throw new Exception();
if (amazon.Aggregations?.People is not null && amazon.Aggregations.People.Count > 0) if (amazon.Aggregations?.People is not null && amazon.Aggregations.People.Count > 0) {
continue; continue;
if (!url.Contains("offset=")) }
if (!url.Contains("offset=")) {
continue; continue;
}
offset = url.Split("offset=")[1]; offset = url.Split("offset=")[1];
if (!url.Contains("people%3A(")) if (!url.Contains("people%3A(")) {
continue; continue;
}
personId = url.Split("people%3A(")[1].Split(')')[0]; personId = url.Split("people%3A(")[1].Split(')')[0];
if (!keyValuePairs.TryGetValue(personId, out personName)) if (!keyValuePairs.TryGetValue(personId, out personName)) {
continue; continue;
}
personDirectory = Path.Combine(destination, personName); personDirectory = Path.Combine(destination, personName);
_ = Directory.CreateDirectory(personDirectory); _ = Directory.CreateDirectory(personDirectory);
personIdFile = Path.Combine(personDirectory, $"{offset.Split('&')[0]}) {personId}.json"); personIdFile = Path.Combine(personDirectory, $"{offset.Split('&')[0]}) {personId}.json");
@ -285,46 +284,37 @@ internal static partial class Helper20240517
} }
} }
internal static void SaveAmazon(ILogger<Worker> logger, List<string> args) private static void SaveAmazon(IReadOnlyList<Datum> data, string personIdFile) {
{
string root = Path.GetFullPath(args[0]);
string destination = Path.GetFullPath(args[2]);
if (string.IsNullOrEmpty(root))
throw new NullReferenceException(nameof(root));
string[] harFiles = Directory.GetFiles(root, "*.har", SearchOption.TopDirectoryOnly);
foreach (string harFile in harFiles)
SaveAmazon(destination, harFile);
logger?.LogInformation("{harFiles} count", harFiles.Length);
}
private static void SaveAmazon(IReadOnlyList<Datum> data, string personIdFile)
{
string json; string json;
Dictionary<string, Datum> keyValuePairs = []; Dictionary<string, Datum> keyValuePairs = [];
foreach (Datum datum in data) foreach (Datum datum in data) {
_ = keyValuePairs.TryAdd(datum.Name.Split('.')[0], datum); _ = keyValuePairs.TryAdd(datum.Name.Split('.')[0], datum);
}
json = JsonSerializer.Serialize(keyValuePairs, DictionaryDatumGenerationContext.Default.DictionaryStringDatum); json = JsonSerializer.Serialize(keyValuePairs, DictionaryDatumGenerationContext.Default.DictionaryStringDatum);
File.WriteAllText(personIdFile, json); File.WriteAllText(personIdFile, json);
} }
private static ReadOnlyCollection<(string, string)> GetAggregationLines(string harFile) private static ReadOnlyCollection<(string, string)> GetAggregationLines(string harFile) {
{
List<(string, string)> results = []; List<(string, string)> results = [];
if (!File.Exists(harFile)) if (!File.Exists(harFile)) {
throw new Exception(); throw new Exception();
}
string lastUrl = string.Empty; string lastUrl = string.Empty;
string text = "\"text\": \"{"; string text = "\"text\": \"{";
string[] lines = File.ReadAllLines(harFile); string[] lines = File.ReadAllLines(harFile);
foreach (string line in lines) foreach (string line in lines) {
{ if (line.Contains("\"url\": \"")) {
if (line.Contains("\"url\": \""))
lastUrl = line; lastUrl = line;
if (!line.Contains(text)) }
if (!line.Contains(text)) {
continue; continue;
if (!line.Contains("aggregations")) }
if (!line.Contains("aggregations")) {
continue; continue;
if (lastUrl.Contains("search?asset=NONE")) }
if (lastUrl.Contains("search?asset=NONE")) {
continue; continue;
}
results.Add(new(lastUrl, line.Trim()[(text.Length - 1)..^1].Replace("\\\"", "\""))); results.Add(new(lastUrl, line.Trim()[(text.Length - 1)..^1].Replace("\\\"", "\"")));
lastUrl = string.Empty; lastUrl = string.Empty;
} }

View File

@ -1,35 +1,58 @@
using File_Folder_Helper.Models; using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Globalization;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240518 internal static partial class Helper20240518 {
{
internal static void PersonKeyToImmichImport(ILogger<Worker> logger, List<string> args) internal static void PersonKeyToImmichImport(ILogger<Worker> logger, List<string> args) {
{ string json;
string name; string name;
Person person;
string birthDate; string birthDate;
string ownerId = args[5]; string ownerId = args[5];
List<string> inserts = []; List<string> inserts = [];
string tableName = args[3]; string tableName = args[3];
string birthDateFormat = args[6]; string birthDateFormat = args[6];
string[] columns = args[4].Split(','); string[] columns = args[4].Split(',');
string json = File.ReadAllText(args[2]);
string root = Path.GetFullPath(args[0]); string root = Path.GetFullPath(args[0]);
Dictionary<long, Person> people = JsonSerializer.Deserialize(json, PeopleSourceGenerationContext.Default.DictionaryInt64Person) ?? throw new NullReferenceException(); Dictionary<string, string> keyValuePairs = [];
foreach (KeyValuePair<long, Person> keyValuePair in people) json = File.ReadAllText(Path.Combine(root, args[2]));
{ DateOnly minimumBirthDate = DateOnly.ParseExact(args[7], birthDateFormat, CultureInfo.InvariantCulture);
if (keyValuePair.Value.Birth?.Note is null || keyValuePair.Value.Name?.ForwardSlashFull is null || keyValuePair.Value.Birth?.Date is null) Dictionary<long, Person> people = JsonSerializer.Deserialize(json, PeopleSourceGenerationContext.Default.DictionaryInt64Person) ??
throw new NullReferenceException();
foreach (KeyValuePair<long, Person> keyValuePair in people) {
person = keyValuePair.Value;
if (string.IsNullOrEmpty(person.Birth?.Note) || string.IsNullOrEmpty(person.Name?.ForwardSlashFull) || person.Birth.Date < minimumBirthDate) {
continue; continue;
birthDate = keyValuePair.Value.Birth.Date.Value.ToString(birthDateFormat); }
name = keyValuePair.Value.Name.ForwardSlashFull.Replace("/", string.Empty); name = string.IsNullOrEmpty(person.Name.Suffix) ? person.Name.ForwardSlashFull : $"{person.Name.ForwardSlashFull} {person.Name.Suffix}";
keyValuePairs.Add(person.Birth.Note, name);
}
json = JsonSerializer.Serialize(keyValuePairs, DictionaryStringStringSourceGenerationContext.Default.DictionaryStringString);
string jsonFile = Path.Combine(root, $"{DateTime.Now.Ticks}.json");
logger.LogInformation("<{file}> saved", jsonFile);
File.WriteAllText(jsonFile, json);
foreach (KeyValuePair<long, Person> keyValuePair in people) {
person = keyValuePair.Value;
if (string.IsNullOrEmpty(person.Birth?.Note) || string.IsNullOrEmpty(person.Name?.ForwardSlashFull) || person.Birth?.Date is null) {
continue;
}
birthDate = person.Birth.Date.Value.ToString(birthDateFormat);
name = person.Name.ForwardSlashFull.Replace("/", string.Empty);
inserts.Add($"insert into \"{tableName}\" (\"{string.Join("\", \"", columns)}\") values ('{ownerId}', '{name}', '{birthDate}');"); inserts.Add($"insert into \"{tableName}\" (\"{string.Join("\", \"", columns)}\") values ('{ownerId}', '{name}', '{birthDate}');");
} }
string file = Path.Combine(root, $"{DateTime.Now.Ticks}.sql"); string sqlFile = Path.Combine(root, $"{DateTime.Now.Ticks}.sql");
logger.LogInformation("<{file}> saved", file); logger.LogInformation("<{file}> saved", sqlFile);
File.WriteAllLines(file, inserts); File.WriteAllLines(sqlFile, inserts);
} }
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Dictionary<string, string>))]
internal partial class DictionaryStringStringSourceGenerationContext : JsonSerializerContext {
} }

View File

@ -4,45 +4,27 @@ using System.Collections.ObjectModel;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240519 internal static partial class Helper20240519 {
{
private record Record(long Length, long Ticks); private record Record(long Length, long Ticks);
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(string source, string[] sourceFiles) internal static void FindReplaceDirectoryName(ILogger<Worker> logger, List<string> args) {
{
Dictionary<string, Record> results = [];
string key;
Record? record;
FileInfo fileInfo;
int sourceLength = source.Length;
foreach (string sourceFile in sourceFiles)
{
fileInfo = new(sourceFile);
key = sourceFile[sourceLength..];
if (results.TryGetValue(key, out record))
throw new NotSupportedException();
results.Add(key, new(fileInfo.Length, fileInfo.LastWriteTime.Ticks));
}
return new(results);
}
internal static void FindReplaceDirectoryName(ILogger<Worker> logger, List<string> args)
{
string checkDirectory; string checkDirectory;
string replaceText = args[3]; string replaceText = args[3];
string[] findTexts = args[2].Split(','); string[] findTexts = args[2].Split(',');
string root = Path.GetFullPath(args[0]); string root = Path.GetFullPath(args[0]);
string[] directories = Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly); string[] directories = Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories) foreach (string directory in directories) {
{
checkDirectory = directory; checkDirectory = directory;
foreach (string findText in findTexts) foreach (string findText in findTexts) {
checkDirectory = checkDirectory.Replace(findText, replaceText); checkDirectory = checkDirectory.Replace(findText, replaceText);
if (checkDirectory == directory) }
if (checkDirectory == directory) {
continue; continue;
if (Directory.Exists(checkDirectory)) }
if (Directory.Exists(checkDirectory)) {
continue; continue;
}
logger.LogInformation("<{directory}> to <{checkDirectory}>", directory, checkDirectory); logger.LogInformation("<{directory}> to <{checkDirectory}>", directory, checkDirectory);
Directory.Move(directory, checkDirectory); Directory.Move(directory, checkDirectory);
} }
@ -57,24 +39,44 @@ internal static partial class Helper20240519
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(source, sourceFiles); ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(source, sourceFiles);
string[] compareFiles = Directory.GetFiles(compare, "*", SearchOption.AllDirectories); string[] compareFiles = Directory.GetFiles(compare, "*", SearchOption.AllDirectories);
int compareLength = compare.Length; int compareLength = compare.Length;
foreach (string compareFile in compareFiles) foreach (string compareFile in compareFiles) {
{
fileInfo = new(compareFile); fileInfo = new(compareFile);
key = compareFile[compareLength..]; key = compareFile[compareLength..];
if (!keyValuePairs.TryGetValue(key, out record)) if (!keyValuePairs.TryGetValue(key, out record)) {
continue; continue;
if (fileInfo.Length != record.Length || fileInfo.LastWriteTime.Ticks != record.Ticks) }
if (fileInfo.Length != record.Length || fileInfo.LastWriteTime.Ticks != record.Ticks) {
continue; continue;
}
checkFile = $"{target}{key}"; checkFile = $"{target}{key}";
checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new NotSupportedException(); checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new NotSupportedException();
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
if (File.Exists(checkFile)) }
if (File.Exists(checkFile)) {
continue; continue;
}
logger.LogInformation("<{compareFile}> to <{checkFile}>", compareFile, checkFile); logger.LogInformation("<{compareFile}> to <{checkFile}>", compareFile, checkFile);
File.Move(compareFile, checkFile); File.Move(compareFile, checkFile);
} }
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, compare); HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, compare);
} }
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(string source, string[] sourceFiles) {
Dictionary<string, Record> results = [];
string key;
Record? record;
FileInfo fileInfo;
int sourceLength = source.Length;
foreach (string sourceFile in sourceFiles) {
fileInfo = new(sourceFile);
key = sourceFile[sourceLength..];
if (results.TryGetValue(key, out record)) {
throw new NotSupportedException();
}
results.Add(key, new(fileInfo.Length, fileInfo.LastWriteTime.Ticks));
}
return new(results);
}
} }

View File

@ -6,66 +6,23 @@ using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240520 internal static partial class Helper20240520 {
{
private record RecordA(string Directory, string Extension, string SourceFile, Identifier Identifier); private record RecordA(string Directory, string Extension, string SourceFile, Identifier Identifier);
private record RecordB(ReadOnlyDictionary<int, Identifier> IdTo, ReadOnlyDictionary<long, Identifier> LengthTo, ReadOnlyDictionary<string, Identifier> PaddedTo); private record RecordB(ReadOnlyDictionary<int, Identifier> IdTo, ReadOnlyDictionary<long, Identifier> LengthTo, ReadOnlyDictionary<string, Identifier> PaddedTo);
internal sealed record Identifier(int Id, long Length, string PaddedId, long Ticks)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, IdentifierSourceGenerationContext.Default.Identifier);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Identifier))] [JsonSerializable(typeof(Identifier))]
internal partial class IdentifierSourceGenerationContext : JsonSerializerContext internal partial class IdentifierSourceGenerationContext : JsonSerializerContext {
{
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Identifier[]))] [JsonSerializable(typeof(Identifier[]))]
internal partial class IdentifierCollectionSourceGenerationContext : JsonSerializerContext internal partial class IdentifierCollectionSourceGenerationContext : JsonSerializerContext {
{
} }
private static RecordB GetRecordB(string jsonFile) internal static void IdentifierRename(ILogger<Worker> logger, List<string> args) {
{
RecordB result;
Dictionary<int, Identifier> idTo = [];
Dictionary<long, Identifier> lengthTo = [];
Dictionary<string, Identifier> paddedTo = [];
string? json = !File.Exists(jsonFile) ? null : File.ReadAllText(jsonFile);
Identifier[]? identifiers = json is null ? null : JsonSerializer.Deserialize(json, IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
if (identifiers is null && !string.IsNullOrEmpty(jsonFile))
throw new Exception($"Invalid {nameof(jsonFile)}");
if (identifiers is not null)
{
foreach (Identifier identifier in identifiers)
{
idTo.Add(identifier.Id, identifier);
paddedTo.Add(identifier.PaddedId, identifier);
if (lengthTo.ContainsKey(identifier.Length))
{
_ = lengthTo.Remove(identifier.Length);
continue;
}
lengthTo.Add(identifier.Length, identifier);
}
}
result = new(new(idTo), new(lengthTo), new(paddedTo));
return result;
}
internal static void IdentifierRename(ILogger<Worker> logger, List<string> args)
{
int id; int id;
string key; string key;
RecordA recordA; RecordA recordA;
@ -87,50 +44,48 @@ internal static partial class Helper20240520
string[] sourceFiles = Directory.GetFiles(source, "*", SearchOption.AllDirectories); string[] sourceFiles = Directory.GetFiles(source, "*", SearchOption.AllDirectories);
logger.LogInformation("Found {files}(s)", sourceFiles.Length); logger.LogInformation("Found {files}(s)", sourceFiles.Length);
int sourceLength = source.Length; int sourceLength = source.Length;
foreach (string sourceFile in sourceFiles) foreach (string sourceFile in sourceFiles) {
{
fileInfo = new(sourceFile); fileInfo = new(sourceFile);
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName); fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
if (fileInfo.Directory is null) if (fileInfo.Directory is null) {
throw new NotSupportedException(); throw new NotSupportedException();
if (option == "Padded") }
{ if (option == "Padded") {
if (fileNameWithoutExtension.Length < intMinValueLength) if (fileNameWithoutExtension.Length < intMinValueLength) {
continue; continue;
}
key = fileNameWithoutExtension; key = fileNameWithoutExtension;
if (recordB.PaddedTo.TryGetValue(key, out identifier)) if (recordB.PaddedTo.TryGetValue(key, out identifier)) {
{
recordACollection.Add(new($"{destination}{fileInfo.Directory.FullName[sourceLength..]}", fileInfo.Extension, fileInfo.FullName, identifier)); recordACollection.Add(new($"{destination}{fileInfo.Directory.FullName[sourceLength..]}", fileInfo.Extension, fileInfo.FullName, identifier));
continue; continue;
} }
} }
if (option == "Length") if (option == "Length") {
{ if (recordB.LengthTo.TryGetValue(fileInfo.Length, out identifier)) {
if (recordB.LengthTo.TryGetValue(fileInfo.Length, out identifier))
{
checkDirectory = $"{destination}{fileInfo.Directory.FullName[sourceLength..]}"; checkDirectory = $"{destination}{fileInfo.Directory.FullName[sourceLength..]}";
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
}
checkFile = Path.Combine(checkDirectory, $"{identifier.PaddedId}{fileInfo.Extension}"); checkFile = Path.Combine(checkDirectory, $"{identifier.PaddedId}{fileInfo.Extension}");
if (File.Exists(checkFile)) if (File.Exists(checkFile)) {
continue; continue;
}
File.Copy(fileInfo.FullName, checkFile); File.Copy(fileInfo.FullName, checkFile);
logger.LogInformation("<{fileInfo.FullName}> was moved to <{checkFile}>", fileInfo.FullName, checkFile); logger.LogInformation("<{fileInfo.FullName}> was moved to <{checkFile}>", fileInfo.FullName, checkFile);
continue; continue;
} }
} }
if (option == "Id") if (option == "Id") {
{ if (int.TryParse(fileNameWithoutExtension, out id)) {
if (int.TryParse(fileNameWithoutExtension, out id)) if (recordB.IdTo.TryGetValue(id, out identifier)) {
{
if (recordB.IdTo.TryGetValue(id, out identifier))
{
checkDirectory = $"{destination}{fileInfo.Directory.FullName[sourceLength..]}"; checkDirectory = $"{destination}{fileInfo.Directory.FullName[sourceLength..]}";
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
}
checkFile = Path.Combine(checkDirectory, $"{identifier.PaddedId}{fileInfo.Extension}"); checkFile = Path.Combine(checkDirectory, $"{identifier.PaddedId}{fileInfo.Extension}");
if (File.Exists(checkFile)) if (File.Exists(checkFile)) {
continue; continue;
}
File.Move(fileInfo.FullName, checkFile); File.Move(fileInfo.FullName, checkFile);
logger.LogInformation("<{fileInfo.FullName}> was moved to <{checkFile}>", fileInfo.FullName, checkFile); logger.LogInformation("<{fileInfo.FullName}> was moved to <{checkFile}>", fileInfo.FullName, checkFile);
continue; continue;
@ -138,18 +93,19 @@ internal static partial class Helper20240520
} }
} }
} }
if (option == "Padded") if (option == "Padded") {
{ if (!isOffsetDeterministicHashCode) {
if (!isOffsetDeterministicHashCode)
recordACollection = (from l in recordACollection orderby l.Identifier.Ticks select l).ToList(); recordACollection = (from l in recordACollection orderby l.Identifier.Ticks select l).ToList();
for (int i = 0; i < recordACollection.Count; i++) }
{ for (int i = 0; i < recordACollection.Count; i++) {
recordA = recordACollection[i]; recordA = recordACollection[i];
if (!Directory.Exists(recordA.Directory)) if (!Directory.Exists(recordA.Directory)) {
_ = Directory.CreateDirectory(recordA.Directory); _ = Directory.CreateDirectory(recordA.Directory);
}
checkFile = Path.Combine(recordA.Directory, isOffsetDeterministicHashCode ? $"{recordA.Identifier.PaddedId}{recordA.Extension}" : $"{offset + i}{recordA.Identifier.PaddedId}{recordA.Extension}"); checkFile = Path.Combine(recordA.Directory, isOffsetDeterministicHashCode ? $"{recordA.Identifier.PaddedId}{recordA.Extension}" : $"{offset + i}{recordA.Identifier.PaddedId}{recordA.Extension}");
if (File.Exists(checkFile)) if (File.Exists(checkFile)) {
continue; continue;
}
File.Move(recordA.SourceFile, checkFile); File.Move(recordA.SourceFile, checkFile);
logger.LogInformation("<{recordA.SourceFile}> was moved to <{checkFile}>", recordA.SourceFile, checkFile); logger.LogInformation("<{recordA.SourceFile}> was moved to <{checkFile}>", recordA.SourceFile, checkFile);
} }
@ -157,4 +113,37 @@ internal static partial class Helper20240520
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, source); HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, source);
} }
private static RecordB GetRecordB(string jsonFile) {
RecordB result;
Dictionary<int, Identifier> idTo = [];
Dictionary<long, Identifier> lengthTo = [];
Dictionary<string, Identifier> paddedTo = [];
string? json = !File.Exists(jsonFile) ? null : File.ReadAllText(jsonFile);
Identifier[]? identifiers = json is null ? null : JsonSerializer.Deserialize(json, IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
if (identifiers is null && !string.IsNullOrEmpty(jsonFile)) {
throw new Exception($"Invalid {nameof(jsonFile)}");
}
if (identifiers is not null) {
foreach (Identifier identifier in identifiers) {
idTo.Add(identifier.Id, identifier);
paddedTo.Add(identifier.PaddedId, identifier);
if (lengthTo.ContainsKey(identifier.Length)) {
_ = lengthTo.Remove(identifier.Length);
continue;
}
lengthTo.Add(identifier.Length, identifier);
}
}
result = new(new(idTo), new(lengthTo), new(paddedTo));
return result;
}
internal sealed record Identifier(int Id, long Length, string PaddedId, long Ticks) {
public override string ToString() {
string result = JsonSerializer.Serialize(this, IdentifierSourceGenerationContext.Default.Identifier);
return result;
}
}
} }

View File

@ -10,8 +10,7 @@ using System.Text.RegularExpressions;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240623 internal static partial class Helper20240623 {
{
[GeneratedRegex("([A-Z]+(.))")] [GeneratedRegex("([A-Z]+(.))")]
private static partial Regex UpperCase(); private static partial Regex UpperCase();
@ -36,34 +35,34 @@ internal static partial class Helper20240623
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Input))] [JsonSerializable(typeof(Input))]
private partial class InputSourceGenerationContext : JsonSerializerContext private partial class InputSourceGenerationContext : JsonSerializerContext {
{
} }
private static Record GetRecord(Input input, FileInfo fileInfo) private static Record GetRecord(Input input, FileInfo fileInfo) {
{
Record result; Record result;
string line; string line;
int? stopLine = null; int? stopLine = null;
int? subTasksLine = null; int? subTasksLine = null;
int? codeInsidersLine = null; int? codeInsidersLine = null;
LineNumber lineNumber = HelperMarkdown.GetLineNumbers(fileInfo); LineNumber lineNumber = HelperMarkdown.GetLineNumbers(fileInfo);
for (int i = 0; i < lineNumber.Lines.Count; i++) for (int i = 0; i < lineNumber.Lines.Count; i++) {
{
line = lineNumber.Lines[i]; line = lineNumber.Lines[i];
if (line.StartsWith(input.CodeInsiders) && line[^1] == ')') if (line.StartsWith(input.CodeInsiders) && line[^1] == ')') {
codeInsidersLine = i; codeInsidersLine = i;
if (line != input.SubTasks) }
if (line != input.SubTasks) {
continue; continue;
}
subTasksLine = i; subTasksLine = i;
if (codeInsidersLine is null) if (codeInsidersLine is null) {
break; break;
if (lineNumber.Lines.Count > i) }
{
for (int j = i + 1; j < lineNumber.Lines.Count; j++) if (lineNumber.Lines.Count > i) {
{ for (int j = i + 1; j < lineNumber.Lines.Count; j++) {
if (lineNumber.Lines[j].Length > 0 && lineNumber.Lines[j][0] == '#') if (lineNumber.Lines[j].Length > 0 && lineNumber.Lines[j][0] == '#') {
{
stopLine = j; stopLine = j;
break; break;
} }
@ -76,22 +75,18 @@ internal static partial class Helper20240623
return result; return result;
} }
private static List<Record> GetRecords(Input input) private static List<Record> GetRecords(Input input) {
{
List<Record> results = []; List<Record> results = [];
Record record; Record record;
FileInfo fileInfo; FileInfo fileInfo;
string sourceDirectory = input.SourceDirectory; string sourceDirectory = input.SourceDirectory;
ReadOnlyCollection<string> directoryNames = HelperDirectory.GetDirectoryNames(input.SourceDirectory); ReadOnlyCollection<string> directoryNames = HelperDirectory.GetDirectoryNames(input.SourceDirectory);
if (!directoryNames.Any(l => l.StartsWith(input.DirectoryFilter, StringComparison.CurrentCultureIgnoreCase))) if (!directoryNames.Any(l => l.StartsWith(input.DirectoryFilter, StringComparison.CurrentCultureIgnoreCase))) {
{
string directoryName; string directoryName;
string[] checkDirectories = Directory.GetDirectories(input.SourceDirectory, "*", SearchOption.TopDirectoryOnly); string[] checkDirectories = Directory.GetDirectories(input.SourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string checkDirectory in checkDirectories) foreach (string checkDirectory in checkDirectories) {
{
directoryName = Path.GetFileName(checkDirectory); directoryName = Path.GetFileName(checkDirectory);
if (directoryName.StartsWith(input.DirectoryFilter, StringComparison.CurrentCultureIgnoreCase)) if (directoryName.StartsWith(input.DirectoryFilter, StringComparison.CurrentCultureIgnoreCase)) {
{
sourceDirectory = checkDirectory; sourceDirectory = checkDirectory;
break; break;
} }
@ -99,10 +94,10 @@ internal static partial class Helper20240623
} }
string[] subDirectories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly); string[] subDirectories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
List<string> files = Directory.GetFiles(sourceDirectory, input.SearchPattern, SearchOption.TopDirectoryOnly).ToList(); List<string> files = Directory.GetFiles(sourceDirectory, input.SearchPattern, SearchOption.TopDirectoryOnly).ToList();
foreach (string subDirectory in subDirectories) foreach (string subDirectory in subDirectories) {
files.AddRange(Directory.GetFiles(subDirectory, input.SearchPattern, SearchOption.TopDirectoryOnly)); files.AddRange(Directory.GetFiles(subDirectory, input.SearchPattern, SearchOption.TopDirectoryOnly));
foreach (string file in files) }
{ foreach (string file in files) {
fileInfo = new(file); fileInfo = new(file);
record = GetRecord(input, fileInfo); record = GetRecord(input, fileInfo);
results.Add(record); results.Add(record);
@ -110,20 +105,19 @@ internal static partial class Helper20240623
return results; return results;
} }
private static string GetParamCase(string value) private static string GetParamCase(string value) {
{
string result; string result;
StringBuilder stringBuilder = new(value); StringBuilder stringBuilder = new(value);
Match[] matches = UpperCase().Matches(value).ToArray(); Match[] matches = UpperCase().Matches(value).ToArray();
for (int i = matches.Length - 1; i > -1; i--) for (int i = matches.Length - 1; i > -1; i--) {
_ = stringBuilder.Insert(matches[i].Index, '-'); _ = stringBuilder.Insert(matches[i].Index, '-');
}
string[] segments = InvalidCharacter().Split(stringBuilder.ToString().ToLower()); string[] segments = InvalidCharacter().Split(stringBuilder.ToString().ToLower());
result = string.Join('-', segments).Trim('-'); result = string.Join('-', segments).Trim('-');
return result; return result;
} }
private static ReadOnlyCollection<SubTaskLine> GetSubTaskLines(Input input, bool? foundStarted, bool? foundCompleted, string fallbackLine, Record record) private static ReadOnlyCollection<SubTaskLine> GetSubTaskLines(Input input, bool? foundStarted, bool? foundCompleted, string fallbackLine, Record record) {
{
List<SubTaskLine> results = []; List<SubTaskLine> results = [];
char done; char done;
string line; string line;
@ -134,15 +128,17 @@ internal static partial class Helper20240623
bool foundSubTasks = false; bool foundSubTasks = false;
int tasksZeroLength = input.Tasks[0].Length; int tasksZeroLength = input.Tasks[0].Length;
long ticks = record.FileInfo.LastWriteTime.Ticks; long ticks = record.FileInfo.LastWriteTime.Ticks;
for (int i = 0; i < record.LineNumber.Lines.Count; i++) for (int i = 0; i < record.LineNumber.Lines.Count; i++) {
{
line = record.LineNumber.Lines[i]; line = record.LineNumber.Lines[i];
if (!foundSubTasks && line == input.SubTasks) if (!foundSubTasks && line == input.SubTasks) {
foundSubTasks = true; foundSubTasks = true;
if (!foundSubTasks) }
if (!foundSubTasks) {
continue; continue;
if (line.Length <= tasksZeroLength || !line.StartsWith(input.Tasks[0]) || line[tasksZeroLength] is not ' ' and not 'x' || line[tasksZeroLength + 1] != ']') }
if (line.Length <= tasksZeroLength || !line.StartsWith(input.Tasks[0]) || line[tasksZeroLength] is not ' ' and not 'x' || line[tasksZeroLength + 1] != ']') {
continue; continue;
}
startedValue = foundStarted is not null && foundStarted.Value; startedValue = foundStarted is not null && foundStarted.Value;
completedValue = foundCompleted is not null && foundCompleted.Value; completedValue = foundCompleted is not null && foundCompleted.Value;
subTaskLine = new(Text: $" {line}", Started: startedValue, Completed: completedValue, Ticks: ticks, Line: i); subTaskLine = new(Text: $" {line}", Started: startedValue, Completed: completedValue, Ticks: ticks, Line: i);
@ -150,10 +146,9 @@ internal static partial class Helper20240623
} }
startedValue = foundStarted is not null && foundStarted.Value; startedValue = foundStarted is not null && foundStarted.Value;
completedValue = foundCompleted is not null && foundCompleted.Value; completedValue = foundCompleted is not null && foundCompleted.Value;
if (record.LineNumber.H1 is null) if (record.LineNumber.H1 is null) {
subTaskLine = new(Text: fallbackLine, Started: startedValue, Completed: completedValue, Ticks: ticks, Line: null); subTaskLine = new(Text: fallbackLine, Started: startedValue, Completed: completedValue, Ticks: ticks, Line: null);
else } else {
{
done = foundCompleted is null || !foundCompleted.Value ? ' ' : 'x'; done = foundCompleted is null || !foundCompleted.Value ? ' ' : 'x';
string codeInsidersLine = record.CodeInsidersLine is null ? string.Empty : $" ~~{record.LineNumber.Lines[record.CodeInsidersLine.Value]}~~"; string codeInsidersLine = record.CodeInsidersLine is null ? string.Empty : $" ~~{record.LineNumber.Lines[record.CodeInsidersLine.Value]}~~";
text = $"- [{done}] {ticks} {record.LineNumber.Lines[record.LineNumber.H1.Value]}{codeInsidersLine}"; text = $"- [{done}] {ticks} {record.LineNumber.Lines[record.LineNumber.H1.Value]}{codeInsidersLine}";
@ -163,10 +158,8 @@ internal static partial class Helper20240623
return new(results); return new(results);
} }
private static string GetSeasonName(int dayOfYear) private static string GetSeasonName(int dayOfYear) {
{ string result = dayOfYear switch {
string result = dayOfYear switch
{
< 78 => "0.Winter", < 78 => "0.Winter",
< 124 => "1.Spring", < 124 => "1.Spring",
< 171 => "2.Spring", < 171 => "2.Spring",
@ -259,21 +252,20 @@ internal static partial class Helper20240623
} }
""".Replace("{}", directory.Replace('\\', '/')); """.Replace("{}", directory.Replace('\\', '/'));
private static void FileWriteAllText(string path, string contents) private static void FileWriteAllText(string path, string contents) {
{
// string checkJson = Regex.Replace(File.ReadAllText(path), @"\s+", " ", RegexOptions.Multiline); // string checkJson = Regex.Replace(File.ReadAllText(path), @"\s+", " ", RegexOptions.Multiline);
// if (Regex.Replace(singletonJson, @"\s+", " ", RegexOptions.Multiline) != checkJson) // if (Regex.Replace(singletonJson, @"\s+", " ", RegexOptions.Multiline) != checkJson)
// File.WriteAllText(path, singletonJson); // File.WriteAllText(path, singletonJson);
string old = !File.Exists(path) ? string.Empty : File.ReadAllText(path); string old = !File.Exists(path) ? string.Empty : File.ReadAllText(path);
if (old != contents) if (old != contents) {
File.WriteAllText(path, contents); File.WriteAllText(path, contents);
}
} }
private static void FileWriteAllText(string path, string[] contents) => private static void FileWriteAllText(string path, string[] contents) =>
FileWriteAllText(path, string.Join(Environment.NewLine, contents)); FileWriteAllText(path, string.Join(Environment.NewLine, contents));
private static ReadOnlyCollection<H1AndParamCase> GetH1ParamCaseCollection(Input input, ReadOnlyCollection<string> lines) private static ReadOnlyCollection<H1AndParamCase> GetH1ParamCaseCollection(Input input, ReadOnlyCollection<string> lines) {
{
List<H1AndParamCase> results = []; List<H1AndParamCase> results = [];
string h1; string h1;
string line; string line;
@ -281,18 +273,21 @@ internal static partial class Helper20240623
bool foundSubTasks = false; bool foundSubTasks = false;
H1AndParamCase h1AndParamCase; H1AndParamCase h1AndParamCase;
int tasksZeroLength = input.Tasks[0].Length; int tasksZeroLength = input.Tasks[0].Length;
for (int i = 0; i < lines.Count; i++) for (int i = 0; i < lines.Count; i++) {
{
line = lines[i]; line = lines[i];
if (!foundSubTasks && line == input.SubTasks) if (!foundSubTasks && line == input.SubTasks) {
foundSubTasks = true; foundSubTasks = true;
if (!foundSubTasks) }
if (!foundSubTasks) {
continue; continue;
if (line.Length <= tasksZeroLength || !line.StartsWith(input.Tasks[0]) || line[tasksZeroLength] is not ' ' and not 'x' || line[tasksZeroLength + 1] != ']') }
if (line.Length <= tasksZeroLength || !line.StartsWith(input.Tasks[0]) || line[tasksZeroLength] is not ' ' and not 'x' || line[tasksZeroLength + 1] != ']') {
continue; continue;
}
h1 = line[(tasksZeroLength + 3)..]; h1 = line[(tasksZeroLength + 3)..];
if (string.IsNullOrEmpty(h1)) if (string.IsNullOrEmpty(h1)) {
continue; continue;
}
paramCase = GetParamCase(h1); paramCase = GetParamCase(h1);
h1AndParamCase = new(h1, paramCase); h1AndParamCase = new(h1, paramCase);
results.Add(h1AndParamCase); results.Add(h1AndParamCase);
@ -300,23 +295,24 @@ internal static partial class Helper20240623
return results.AsReadOnly(); return results.AsReadOnly();
} }
private static void CreateFiles(string directory, ReadOnlyCollection<H1AndParamCase> h1ParamCaseCollection) private static void CreateFiles(string directory, ReadOnlyCollection<H1AndParamCase> h1ParamCaseCollection) {
{ foreach (H1AndParamCase h1ParamCase in h1ParamCaseCollection) {
foreach (H1AndParamCase h1ParamCase in h1ParamCaseCollection)
FileWriteAllText(Path.Combine(directory, $"{h1ParamCase.ParamCase}.md"), $"# {h1ParamCase.H1}"); FileWriteAllText(Path.Combine(directory, $"{h1ParamCase.ParamCase}.md"), $"# {h1ParamCase.H1}");
}
} }
private static string WriteAndGetIndexFile(string h1, string verifiedDirectory, ReadOnlyCollection<H1AndParamCase> h1ParamCaseCollection) private static string WriteAndGetIndexFile(string h1, string verifiedDirectory, ReadOnlyCollection<H1AndParamCase> h1ParamCaseCollection) {
{
string result; string result;
string[] indexLines = GetIndexLines(h1, h1ParamCaseCollection); string[] indexLines = GetIndexLines(h1, h1ParamCaseCollection);
string kanbanDirectory = Path.Combine(verifiedDirectory, ".kanbn"); string kanbanDirectory = Path.Combine(verifiedDirectory, ".kanbn");
string tasksKanbanDirectory = Path.Combine(kanbanDirectory, "tasks"); string tasksKanbanDirectory = Path.Combine(kanbanDirectory, "tasks");
if (!Directory.Exists(tasksKanbanDirectory)) if (!Directory.Exists(tasksKanbanDirectory)) {
_ = Directory.CreateDirectory(tasksKanbanDirectory); _ = Directory.CreateDirectory(tasksKanbanDirectory);
}
string verifiedVisualStudioCodeDirectory = Path.Combine(verifiedDirectory, ".vscode"); string verifiedVisualStudioCodeDirectory = Path.Combine(verifiedDirectory, ".vscode");
if (!Directory.Exists(verifiedVisualStudioCodeDirectory)) if (!Directory.Exists(verifiedVisualStudioCodeDirectory)) {
_ = Directory.CreateDirectory(verifiedVisualStudioCodeDirectory); _ = Directory.CreateDirectory(verifiedVisualStudioCodeDirectory);
}
result = Path.Combine(kanbanDirectory, "index.md"); result = Path.Combine(kanbanDirectory, "index.md");
CreateFiles(tasksKanbanDirectory, h1ParamCaseCollection); CreateFiles(tasksKanbanDirectory, h1ParamCaseCollection);
FileWriteAllText(result, indexLines); FileWriteAllText(result, indexLines);
@ -326,48 +322,49 @@ internal static partial class Helper20240623
return result; return result;
} }
private static ReadOnlyCollection<string> GetXColumns(Input input, int frontMatterYamlEnd, int value, ReadOnlyCollection<string> lines) private static ReadOnlyCollection<string> GetXColumns(Input input, int frontMatterYamlEnd, int value, ReadOnlyCollection<string> lines) {
{
List<string> results = []; List<string> results = [];
string[] segments; string[] segments;
for (int i = value + 1; i < frontMatterYamlEnd; i++) for (int i = value + 1; i < frontMatterYamlEnd; i++) {
{
segments = lines[i].Replace("\t", " ").Split(" - "); segments = lines[i].Replace("\t", " ").Split(" - ");
if (segments.Length != 2) if (segments.Length != 2) {
break; break;
}
results.Add($"## {segments[1].Replace("'", string.Empty)}"); results.Add($"## {segments[1].Replace("'", string.Empty)}");
} }
if (results.Count == 0) if (results.Count == 0) {
results.Add(input.Done); results.Add(input.Done);
}
return results.AsReadOnly(); return results.AsReadOnly();
} }
private static ReadOnlyCollection<string> GetCompletedColumns(Input input, LineNumber lineNumber) private static ReadOnlyCollection<string> GetCompletedColumns(Input input, LineNumber lineNumber) {
{
List<string> results; List<string> results;
if (lineNumber.FrontMatterYamlEnd is null || lineNumber.CompletedColumns is null) if (lineNumber.FrontMatterYamlEnd is null || lineNumber.CompletedColumns is null) {
results = []; results = [];
else } else {
results = GetXColumns(input, lineNumber.FrontMatterYamlEnd.Value, lineNumber.CompletedColumns.Value, lineNumber.Lines).ToList(); results = GetXColumns(input, lineNumber.FrontMatterYamlEnd.Value, lineNumber.CompletedColumns.Value, lineNumber.Lines).ToList();
if (results.Count == 0) }
if (results.Count == 0) {
results.Add(input.Done); results.Add(input.Done);
}
return results.AsReadOnly(); return results.AsReadOnly();
} }
private static ReadOnlyCollection<string> GetStartedColumns(Input input, LineNumber lineNumber) private static ReadOnlyCollection<string> GetStartedColumns(Input input, LineNumber lineNumber) {
{
List<string> results; List<string> results;
if (lineNumber.FrontMatterYamlEnd is null || lineNumber.StartedColumns is null) if (lineNumber.FrontMatterYamlEnd is null || lineNumber.StartedColumns is null) {
results = []; results = [];
else } else {
results = GetXColumns(input, lineNumber.FrontMatterYamlEnd.Value, lineNumber.StartedColumns.Value, lineNumber.Lines).ToList(); results = GetXColumns(input, lineNumber.FrontMatterYamlEnd.Value, lineNumber.StartedColumns.Value, lineNumber.Lines).ToList();
if (results.Count == 0) }
if (results.Count == 0) {
results.Add(input.Done); results.Add(input.Done);
}
return results.AsReadOnly(); return results.AsReadOnly();
} }
private static ReadOnlyCollection<SubTaskLine> GetSubTaskLines(Input input, FileInfo fileInfo, LineNumber lineNumber) private static ReadOnlyCollection<SubTaskLine> GetSubTaskLines(Input input, FileInfo fileInfo, LineNumber lineNumber) {
{
List<SubTaskLine> results = []; List<SubTaskLine> results = [];
FileInfo f; FileInfo f;
Record record; Record record;
@ -382,37 +379,39 @@ internal static partial class Helper20240623
ReadOnlyCollection<string> startedColumns = GetStartedColumns(input, lineNumber); ReadOnlyCollection<string> startedColumns = GetStartedColumns(input, lineNumber);
ReadOnlyCollection<string> completedColumns = GetCompletedColumns(input, lineNumber); ReadOnlyCollection<string> completedColumns = GetCompletedColumns(input, lineNumber);
int start = lineNumber.FrontMatterYamlEnd is null ? 0 : lineNumber.FrontMatterYamlEnd.Value + 1; int start = lineNumber.FrontMatterYamlEnd is null ? 0 : lineNumber.FrontMatterYamlEnd.Value + 1;
for (int i = start; i < lineNumber.Lines.Count; i++) for (int i = start; i < lineNumber.Lines.Count; i++) {
{ if ((foundStarted is null || !foundStarted.Value) && startedColumns.Any(lineNumber.Lines[i].StartsWith)) {
if ((foundStarted is null || !foundStarted.Value) && startedColumns.Any(lineNumber.Lines[i].StartsWith))
foundStarted = true; foundStarted = true;
if ((foundCompleted is null || !foundCompleted.Value) && completedColumns.Any(lineNumber.Lines[i].StartsWith)) }
if ((foundCompleted is null || !foundCompleted.Value) && completedColumns.Any(lineNumber.Lines[i].StartsWith)) {
foundCompleted = true; foundCompleted = true;
}
segments = lineNumber.Lines[i].Split(input.Tasks[1]); segments = lineNumber.Lines[i].Split(input.Tasks[1]);
startedValue = foundStarted is not null && foundStarted.Value; startedValue = foundStarted is not null && foundStarted.Value;
completedValue = foundCompleted is not null && foundCompleted.Value; completedValue = foundCompleted is not null && foundCompleted.Value;
if (segments.Length > 2 || !segments[0].StartsWith(input.Tasks[0])) if (segments.Length > 2 || !segments[0].StartsWith(input.Tasks[0])) {
continue; continue;
}
completed = foundCompleted is null || !foundCompleted.Value ? ' ' : 'x'; completed = foundCompleted is null || !foundCompleted.Value ? ' ' : 'x';
fallbackLine = $"- [{completed}] {segments[0][input.Tasks[0].Length..]} ~~FallbackLine~~"; fallbackLine = $"- [{completed}] {segments[0][input.Tasks[0].Length..]} ~~FallbackLine~~";
if (string.IsNullOrEmpty(fileInfo.DirectoryName)) if (string.IsNullOrEmpty(fileInfo.DirectoryName)) {
continue; continue;
}
f = new(Path.GetFullPath(Path.Combine(fileInfo.DirectoryName, segments[1][..^1]))); f = new(Path.GetFullPath(Path.Combine(fileInfo.DirectoryName, segments[1][..^1])));
if (!f.Exists) if (!f.Exists) {
{
results.Add(new(Text: fallbackLine, Started: startedValue, Completed: completedValue, Ticks: null, Line: null)); results.Add(new(Text: fallbackLine, Started: startedValue, Completed: completedValue, Ticks: null, Line: null));
continue; continue;
} }
record = GetRecord(input, f); record = GetRecord(input, f);
subTaskLines = GetSubTaskLines(input, startedValue, completedValue, fallbackLine, record); subTaskLines = GetSubTaskLines(input, startedValue, completedValue, fallbackLine, record);
for (int j = subTaskLines.Count - 1; j >= 0; j--) for (int j = subTaskLines.Count - 1; j >= 0; j--) {
results.Add(subTaskLines[j]); results.Add(subTaskLines[j]);
}
} }
return results.AsReadOnly(); return results.AsReadOnly();
} }
private static Input GetInput(List<string> args) private static Input GetInput(List<string> args) {
{
string indexFile = args[5]; string indexFile = args[5];
string searchPattern = args[2]; string searchPattern = args[2];
string directoryFilter = args[8]; string directoryFilter = args[8];
@ -433,46 +432,42 @@ internal static partial class Helper20240623
SubTasks: subTasks, SubTasks: subTasks,
SourceDirectory: sourceDirectory, SourceDirectory: sourceDirectory,
Tasks: tasks.AsReadOnly()); Tasks: tasks.AsReadOnly());
if (input.Tasks[0] != "- [" || input.Tasks[1] != "](") if (input.Tasks[0] != "- [" || input.Tasks[1] != "](") {
throw new Exception(JsonSerializer.Serialize(input, InputSourceGenerationContext.Default.Input)); throw new Exception(JsonSerializer.Serialize(input, InputSourceGenerationContext.Default.Input));
}
return input; return input;
} }
private static string? MaybeWriteAndGetIndexFile(Input input, Record record, string? checkDirectory) private static string? MaybeWriteAndGetIndexFile(Input input, Record record, string? checkDirectory) {
{
string? result; string? result;
if (string.IsNullOrEmpty(checkDirectory) || input.AfterEpochTotalMilliseconds is null || input.DestinationDirectories.Count == 0) if (string.IsNullOrEmpty(checkDirectory) || input.AfterEpochTotalMilliseconds is null || input.DestinationDirectories.Count == 0) {
result = null; result = null;
else } else {
{ if (!input.DestinationDirectories.Any(checkDirectory.Contains)) {
if (!input.DestinationDirectories.Any(checkDirectory.Contains))
result = null; result = null;
else } else {
{ if (record.LineNumber.H1 is null) {
if (record.LineNumber.H1 is null)
result = null; result = null;
else } else {
{
string segment = Path.GetFileName(checkDirectory); string segment = Path.GetFileName(checkDirectory);
string h1 = record.LineNumber.Lines[record.LineNumber.H1.Value]; string h1 = record.LineNumber.Lines[record.LineNumber.H1.Value];
DateTime utcEpochDateTime = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); DateTime utcEpochDateTime = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long utcEpochTotalMilliseconds = (long)Math.Floor(DateTime.UtcNow.Subtract(utcEpochDateTime).TotalMilliseconds); long utcEpochTotalMilliseconds = (long)Math.Floor(DateTime.UtcNow.Subtract(utcEpochDateTime).TotalMilliseconds);
if (!long.TryParse(segment, out long check) || check < input.AfterEpochTotalMilliseconds || check > utcEpochTotalMilliseconds) if (!long.TryParse(segment, out long check) || check < input.AfterEpochTotalMilliseconds || check > utcEpochTotalMilliseconds) {
result = null; result = null;
else } else {
{
ReadOnlyCollection<H1AndParamCase> h1ParamCaseCollection = GetH1ParamCaseCollection(input, record.LineNumber.Lines); ReadOnlyCollection<H1AndParamCase> h1ParamCaseCollection = GetH1ParamCaseCollection(input, record.LineNumber.Lines);
if (h1ParamCaseCollection.Count == 0) if (h1ParamCaseCollection.Count == 0) {
result = null; result = null;
else } else {
{
DateTime dateTime = utcEpochDateTime.AddMilliseconds(check).ToLocalTime(); DateTime dateTime = utcEpochDateTime.AddMilliseconds(check).ToLocalTime();
string seasonName = GetSeasonName(dateTime.DayOfYear); string seasonName = GetSeasonName(dateTime.DayOfYear);
ReadOnlyCollection<string> directoryNames = HelperDirectory.GetDirectoryNames(checkDirectory); ReadOnlyCollection<string> directoryNames = HelperDirectory.GetDirectoryNames(checkDirectory);
if (!directoryNames.Contains(dateTime.Year.ToString()) || !directoryNames.Contains($"{dateTime.Year}-{seasonName}") || !directoryNames.Contains(check.ToString())) if (!directoryNames.Contains(dateTime.Year.ToString()) || !directoryNames.Contains($"{dateTime.Year}-{seasonName}") || !directoryNames.Contains(check.ToString())) {
result = null; result = null;
else } else {
result = WriteAndGetIndexFile(h1, checkDirectory, h1ParamCaseCollection); result = WriteAndGetIndexFile(h1, checkDirectory, h1ParamCaseCollection);
}
} }
} }
} }
@ -481,53 +476,50 @@ internal static partial class Helper20240623
return result; return result;
} }
private static bool FileWrite(long ticks, Record record, List<string> newLines, double percent) private static bool FileWrite(long ticks, Record record, List<string> newLines, double percent) {
{
bool result = false; bool result = false;
if (record.StopLine is not null && record.SubTasksLine is not null) if (record.StopLine is not null && record.SubTasksLine is not null) {
{
string contents; string contents;
string progressLine; string progressLine;
List<string> resultLines; List<string> resultLines;
if (record.FileInfo.LastWriteTime.Ticks <= ticks) if (record.FileInfo.LastWriteTime.Ticks <= ticks) {
resultLines = record.LineNumber.Lines.ToList(); resultLines = record.LineNumber.Lines.ToList();
else } else {
resultLines = File.ReadAllLines(record.FileInfo.FullName).ToList(); resultLines = File.ReadAllLines(record.FileInfo.FullName).ToList();
if (record.LineNumber.FrontMatterYamlEnd is not null) }
{ if (record.LineNumber.FrontMatterYamlEnd is not null) {
progressLine = $"progress: {percent}"; progressLine = $"progress: {percent}";
if (record.LineNumber.Progress is not null) if (record.LineNumber.Progress is not null) {
resultLines[record.LineNumber.Progress.Value] = progressLine; resultLines[record.LineNumber.Progress.Value] = progressLine;
else } else {
{
resultLines.Insert(record.LineNumber.FrontMatterYamlEnd.Value, progressLine); resultLines.Insert(record.LineNumber.FrontMatterYamlEnd.Value, progressLine);
contents = string.Join(Environment.NewLine, resultLines); contents = string.Join(Environment.NewLine, resultLines);
FileWriteAllText(record.FileInfo.FullName, contents); FileWriteAllText(record.FileInfo.FullName, contents);
result = true; result = true;
} }
if (!result && record.LineNumber.Completed is null && percent > 99.9) if (!result && record.LineNumber.Completed is null && percent > 99.9) {
{
resultLines.Insert(record.LineNumber.FrontMatterYamlEnd.Value, $"completed: {DateTime.Now:yyyy-MM-dd}"); resultLines.Insert(record.LineNumber.FrontMatterYamlEnd.Value, $"completed: {DateTime.Now:yyyy-MM-dd}");
contents = string.Join(Environment.NewLine, resultLines); contents = string.Join(Environment.NewLine, resultLines);
FileWriteAllText(record.FileInfo.FullName, contents); FileWriteAllText(record.FileInfo.FullName, contents);
result = true; result = true;
} }
if (!result && record.LineNumber.Completed is not null && percent < 99.9) if (!result && record.LineNumber.Completed is not null && percent < 99.9) {
{
resultLines.RemoveAt(record.LineNumber.Completed.Value); resultLines.RemoveAt(record.LineNumber.Completed.Value);
contents = string.Join(Environment.NewLine, resultLines); contents = string.Join(Environment.NewLine, resultLines);
FileWriteAllText(record.FileInfo.FullName, contents); FileWriteAllText(record.FileInfo.FullName, contents);
result = true; result = true;
} }
} }
if (!result) if (!result) {
{ for (int i = record.StopLine.Value - 1; i > record.SubTasksLine.Value + 1; i--) {
for (int i = record.StopLine.Value - 1; i > record.SubTasksLine.Value + 1; i--)
resultLines.RemoveAt(i); resultLines.RemoveAt(i);
if (record.StopLine.Value == record.LineNumber.Lines.Count && resultLines[^1].Length == 0) }
if (record.StopLine.Value == record.LineNumber.Lines.Count && resultLines[^1].Length == 0) {
resultLines.RemoveAt(resultLines.Count - 1); resultLines.RemoveAt(resultLines.Count - 1);
for (int i = 0; i < newLines.Count; i++) }
for (int i = 0; i < newLines.Count; i++) {
resultLines.Insert(record.SubTasksLine.Value + 1 + i, newLines[i]); resultLines.Insert(record.SubTasksLine.Value + 1 + i, newLines[i]);
}
resultLines.Insert(record.SubTasksLine.Value + 1, string.Empty); resultLines.Insert(record.SubTasksLine.Value + 1, string.Empty);
contents = string.Join(Environment.NewLine, resultLines); contents = string.Join(Environment.NewLine, resultLines);
FileWriteAllText(record.FileInfo.FullName, contents); FileWriteAllText(record.FileInfo.FullName, contents);
@ -536,102 +528,95 @@ internal static partial class Helper20240623
return result; return result;
} }
private static string? GetInferredCheckDirectory(string directory) private static string? GetInferredCheckDirectory(string directory) {
{
string? result = null; string? result = null;
List<string> directoryNames = []; List<string> directoryNames = [];
DirectoryInfo directoryInfo; DirectoryInfo directoryInfo;
string? checkDirectory = directory; string? checkDirectory = directory;
directoryNames.Add(Path.GetFileName(checkDirectory)); directoryNames.Add(Path.GetFileName(checkDirectory));
string pathRoot = Path.GetPathRoot(directory) ?? throw new Exception(); string pathRoot = Path.GetPathRoot(directory) ?? throw new Exception();
for (int i = 0; i < directory.Length; i++) for (int i = 0; i < directory.Length; i++) {
{
checkDirectory = Path.GetDirectoryName(checkDirectory); checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot) if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot) {
break; break;
}
directoryInfo = new(checkDirectory); directoryInfo = new(checkDirectory);
if (!directoryInfo.Exists) if (!directoryInfo.Exists) {
directoryNames.Add(directoryInfo.Name); directoryNames.Add(directoryInfo.Name);
else } else {
{
directoryNames.Reverse(); directoryNames.Reverse();
result = string.IsNullOrEmpty(directoryInfo.LinkTarget) ? checkDirectory : directoryInfo.LinkTarget; result = string.IsNullOrEmpty(directoryInfo.LinkTarget) ? checkDirectory : directoryInfo.LinkTarget;
for (int j = 0; j < directoryNames.Count; j++) for (int j = 0; j < directoryNames.Count; j++) {
result = Path.GetDirectoryName(result) ?? throw new Exception(); result = Path.GetDirectoryName(result) ?? throw new Exception();
foreach (string directoryName in directoryNames) }
foreach (string directoryName in directoryNames) {
result = Path.Combine(result, directoryName); result = Path.Combine(result, directoryName);
}
break; break;
} }
} }
return result; return result;
} }
private static void UpdateFileAndStartNewProcess(ILogger<Worker> logger, Input input, Record record, string inferredCheckDirectory) private static void UpdateFileAndStartNewProcess(ILogger<Worker> logger, Input input, Record record, string inferredCheckDirectory) {
{ if (record.CodeInsidersLine is null) {
if (record.CodeInsidersLine is null)
throw new Exception(); throw new Exception();
}
List<string> lines = record.LineNumber.Lines.ToList(); List<string> lines = record.LineNumber.Lines.ToList();
lines[record.CodeInsidersLine.Value] = $"{input.CodeInsiders}{inferredCheckDirectory})"; lines[record.CodeInsidersLine.Value] = $"{input.CodeInsiders}{inferredCheckDirectory})";
string text = string.Join(Environment.NewLine, lines); string text = string.Join(Environment.NewLine, lines);
File.WriteAllText(record.FileInfo.FullName, text); File.WriteAllText(record.FileInfo.FullName, text);
record.FileInfo.Refresh(); record.FileInfo.Refresh();
string file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Programs", "Microsoft VS Code Insiders", "Code - Insiders.exe"); string file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Programs", "Microsoft VS Code Insiders", "Code - Insiders.exe");
try try { _ = Process.Start(file, $"\"{inferredCheckDirectory}\""); } catch (Exception) { logger.LogWarning("Failed to start code-insiders!"); }
{ _ = Process.Start(file, $"\"{inferredCheckDirectory}\""); }
catch (Exception) { logger.LogWarning("Failed to start code-insiders!"); }
} }
private static FileInfo GetIndexFileInfo(ILogger<Worker> logger, Input input, Record record) private static FileInfo GetIndexFileInfo(ILogger<Worker> logger, Input input, Record record) {
{
FileInfo result; FileInfo result;
string? indexFile; string? indexFile;
List<string> results; List<string> results;
if (record.CodeInsidersLine is null) if (record.CodeInsidersLine is null) {
throw new Exception(); throw new Exception();
}
string codeInsidersLine = record.LineNumber.Lines[record.CodeInsidersLine.Value]; string codeInsidersLine = record.LineNumber.Lines[record.CodeInsidersLine.Value];
string raw = codeInsidersLine[input.CodeInsiders.Length..^1]; string raw = codeInsidersLine[input.CodeInsiders.Length..^1];
string checkDirectory = $"{raw[..2].ToUpper()}{raw[2..]}"; string checkDirectory = $"{raw[..2].ToUpper()}{raw[2..]}";
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory)) {
{ if (input.DestinationDirectories.Count > 0 && input.DestinationDirectories.Any(checkDirectory.Contains)) {
if (input.DestinationDirectories.Count > 0 && input.DestinationDirectories.Any(checkDirectory.Contains))
{
string? inferredCheckDirectory = GetInferredCheckDirectory(checkDirectory); string? inferredCheckDirectory = GetInferredCheckDirectory(checkDirectory);
if (!string.IsNullOrEmpty(inferredCheckDirectory)) if (!string.IsNullOrEmpty(inferredCheckDirectory)) {
{
checkDirectory = inferredCheckDirectory; checkDirectory = inferredCheckDirectory;
_ = Directory.CreateDirectory(inferredCheckDirectory); _ = Directory.CreateDirectory(inferredCheckDirectory);
UpdateFileAndStartNewProcess(logger, input, record, inferredCheckDirectory); UpdateFileAndStartNewProcess(logger, input, record, inferredCheckDirectory);
} }
} }
} }
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory)) {
results = []; results = [];
else } else {
{
results = Directory.GetFiles(checkDirectory, input.IndexFile, SearchOption.AllDirectories).ToList(); results = Directory.GetFiles(checkDirectory, input.IndexFile, SearchOption.AllDirectories).ToList();
if (results.Count != 1) if (results.Count != 1) {
{ for (int i = results.Count - 1; i > -1; i--) {
for (int i = results.Count - 1; i > -1; i--) if (!results[i].Contains(input.DirectoryFilter, StringComparison.CurrentCultureIgnoreCase)) {
{
if (!results[i].Contains(input.DirectoryFilter, StringComparison.CurrentCultureIgnoreCase))
results.RemoveAt(i); results.RemoveAt(i);
}
} }
} }
if (results.Count == 0) if (results.Count == 0) {
{
indexFile = MaybeWriteAndGetIndexFile(input, record, checkDirectory); indexFile = MaybeWriteAndGetIndexFile(input, record, checkDirectory);
if (!string.IsNullOrEmpty(indexFile)) if (!string.IsNullOrEmpty(indexFile)) {
results.Add(indexFile); results.Add(indexFile);
else } else {
logger.LogInformation("<{checkDirectory}>", checkDirectory); logger.LogInformation("<{checkDirectory}>", checkDirectory);
}
} }
} }
result = results.Count == 0 ? new(Path.Combine(checkDirectory, input.IndexFile)) : new(results[0]); result = results.Count == 0 ? new(Path.Combine(checkDirectory, input.IndexFile)) : new(results[0]);
return result; return result;
} }
internal static void UpdateSubTasksInMarkdownFiles(ILogger<Worker> logger, List<string> args) internal static void UpdateSubTasksInMarkdownFiles(ILogger<Worker> logger, List<string> args) {
{
bool reload; bool reload;
int allCount; int allCount;
int lineCheck; int lineCheck;
@ -650,26 +635,24 @@ internal static partial class Helper20240623
string fileNameWithoutExtension; string fileNameWithoutExtension;
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
ReadOnlyCollection<SubTaskLine> subTaskLines; ReadOnlyCollection<SubTaskLine> subTaskLines;
for (int z = 0; z < 9; z++) for (int z = 0; z < 9; z++) {
{
records = GetRecords(input); records = GetRecords(input);
foreach (Record record in from l in records orderby l.SubTasksLine is null, l.CodeInsidersLine is null select l) foreach (Record record in from l in records orderby l.SubTasksLine is null, l.CodeInsidersLine is null select l) {
{ if (record.SubTasksLine is null) {
if (record.SubTasksLine is null)
continue; continue;
}
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(record.FileInfo.FullName); fileNameWithoutExtension = Path.GetFileNameWithoutExtension(record.FileInfo.FullName);
if (record.CodeInsidersLine is not null) if (record.CodeInsidersLine is not null) {
logger.LogInformation("<{file}> has [{subTasks}]", fileNameWithoutExtension, input.SubTasks); logger.LogInformation("<{file}> has [{subTasks}]", fileNameWithoutExtension, input.SubTasks);
else } else {
{
logger.LogWarning("<{file}> has [{subTasks}] but doesn't have [{codeInsiders}]!", fileNameWithoutExtension, input.SubTasks, input.CodeInsiders); logger.LogWarning("<{file}> has [{subTasks}] but doesn't have [{codeInsiders}]!", fileNameWithoutExtension, input.SubTasks, input.CodeInsiders);
continue; continue;
} }
if (record.StopLine is null) if (record.StopLine is null) {
continue; continue;
}
fileInfo = GetIndexFileInfo(logger, input, record); fileInfo = GetIndexFileInfo(logger, input, record);
if (!fileInfo.Exists) if (!fileInfo.Exists) {
{
logger.LogError("<{checkDirectory}> doesn't have a [{indexFile}]", fileInfo.DirectoryName, input.IndexFile); logger.LogError("<{checkDirectory}> doesn't have a [{indexFile}]", fileInfo.DirectoryName, input.IndexFile);
continue; continue;
} }
@ -677,18 +660,17 @@ internal static partial class Helper20240623
checkDirectory = fileInfo.DirectoryName; checkDirectory = fileInfo.DirectoryName;
lineNumber = HelperMarkdown.GetLineNumbers(fileInfo); lineNumber = HelperMarkdown.GetLineNumbers(fileInfo);
subTaskLines = GetSubTaskLines(input, fileInfo, lineNumber); subTaskLines = GetSubTaskLines(input, fileInfo, lineNumber);
if (subTaskLines.Count == 0) if (subTaskLines.Count == 0) {
continue; continue;
}
lineCheck = 0; lineCheck = 0;
for (int i = record.SubTasksLine.Value + 1; i < record.StopLine.Value - 1; i++) for (int i = record.SubTasksLine.Value + 1; i < record.StopLine.Value - 1; i++) {
oldLines.Add(record.LineNumber.Lines[i]); oldLines.Add(record.LineNumber.Lines[i]);
if (subTaskLines.Count == 0) }
{ if (subTaskLines.Count == 0) {
percent = 0; percent = 0;
replace = "0"; replace = "0";
} } else {
else
{
allCount = (from l in subTaskLines where l.Line is not null && l.Line.Value == 0 select 1).Count(); allCount = (from l in subTaskLines where l.Line is not null && l.Line.Value == 0 select 1).Count();
completedCount = (from l in subTaskLines where l.Line is not null && l.Line.Value == 0 && l.Completed select 1).Count(); completedCount = (from l in subTaskLines where l.Line is not null && l.Line.Value == 0 && l.Completed select 1).Count();
startedCount = (from l in subTaskLines where l.Line is not null && l.Line.Value == 0 && l.Started && !l.Completed select 1).Count(); startedCount = (from l in subTaskLines where l.Line is not null && l.Line.Value == 0 && l.Started && !l.Completed select 1).Count();
@ -696,38 +678,40 @@ internal static partial class Helper20240623
// newLines.Insert(0, $"- [{done}] Sub-tasks {doneCount} of {allCount} [{percent * 100}%]"); // newLines.Insert(0, $"- [{done}] Sub-tasks {doneCount} of {allCount} [{percent * 100}%]");
replace = $"{allCount} » {startedCount} ✓ {completedCount} {Math.Floor(percent * 100)}%".Replace(" ✓ 0 0%", string.Empty).Replace(" 100%", string.Empty).Replace(" » 0", string.Empty); replace = $"{allCount} » {startedCount} ✓ {completedCount} {Math.Floor(percent * 100)}%".Replace(" ✓ 0 0%", string.Empty).Replace(" 100%", string.Empty).Replace(" » 0", string.Empty);
} }
if (subTaskLines.Any(l => l.Ticks is null)) if (subTaskLines.Any(l => l.Ticks is null)) {
newLines = (from l in subTaskLines newLines = (from l in subTaskLines
select l.Text).ToList(); select l.Text).ToList();
else } else {
{
newLines = (from l in subTaskLines newLines = (from l in subTaskLines
orderby l.Completed descending, l.Started descending, l.Ticks, l.Line orderby l.Completed descending, l.Started descending, l.Ticks, l.Line
select l.Text.Replace($"{l.Ticks}", replace)).ToList(); select l.Text.Replace($"{l.Ticks}", replace)).ToList();
} }
if (newLines.Count == oldLines.Count) if (newLines.Count == oldLines.Count) {
{ for (int i = 0; i < newLines.Count; i++) {
for (int i = 0; i < newLines.Count; i++) if (newLines[i] != record.LineNumber.Lines[record.SubTasksLine.Value + 1 + i]) {
{
if (newLines[i] != record.LineNumber.Lines[record.SubTasksLine.Value + 1 + i])
continue; continue;
}
lineCheck++; lineCheck++;
} }
if (lineCheck == newLines.Count) if (lineCheck == newLines.Count) {
continue; continue;
}
} }
if (string.IsNullOrEmpty(checkDirectory)) if (string.IsNullOrEmpty(checkDirectory)) {
continue; continue;
}
checkDirectory = Path.Combine(checkDirectory, DateTime.Now.Ticks.ToString()); checkDirectory = Path.Combine(checkDirectory, DateTime.Now.Ticks.ToString());
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
Thread.Sleep(500); Thread.Sleep(500);
Directory.Delete(checkDirectory); Directory.Delete(checkDirectory);
reload = FileWrite(ticks, record, newLines, percent); reload = FileWrite(ticks, record, newLines, percent);
if (!reloadAny && reload) if (!reloadAny && reload) {
reloadAny = true; reloadAny = true;
}
} }
if (!reloadAny) if (!reloadAny) {
break; break;
}
} }
} }

View File

@ -2,11 +2,21 @@ using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240624 internal static partial class Helper20240624 {
{
private static void MoveUpOndDirectory(ILogger<Worker> logger, string sourceDirectory, string[] files) internal static void MoveUpOneDirectory(ILogger<Worker> logger, List<string> args) {
{ string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0]);
string[] deleteMatchingIdsDirectoryNames = args[3].Split(',');
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
if (deleteMatchingIdsDirectoryNames.Length == 0) {
MoveUpOndDirectory(logger, sourceDirectory, files);
} else {
Distinct(args, sourceDirectory, deleteMatchingIdsDirectoryNames, files);
}
}
private static void MoveUpOndDirectory(ILogger<Worker> logger, string sourceDirectory, string[] files) {
string? match; string? match;
string checkFile; string checkFile;
FileInfo fileInfoA; FileInfo fileInfoA;
@ -14,75 +24,64 @@ internal static partial class Helper20240624
string? checkDirectory; string? checkDirectory;
List<string> deleteFiles = []; List<string> deleteFiles = [];
Dictionary<string, string> keyValuePairs = []; Dictionary<string, string> keyValuePairs = [];
foreach (string file in files) foreach (string file in files) {
{
checkDirectory = Path.GetDirectoryName(Path.GetDirectoryName(file)) ?? throw new NotSupportedException(); checkDirectory = Path.GetDirectoryName(Path.GetDirectoryName(file)) ?? throw new NotSupportedException();
checkFile = Path.Combine(checkDirectory, Path.GetFileName(file)); checkFile = Path.Combine(checkDirectory, Path.GetFileName(file));
if (File.Exists(checkFile)) if (File.Exists(checkFile)) {
throw new NotSupportedException(); throw new NotSupportedException();
if (keyValuePairs.TryGetValue(checkFile, out match)) }
{ if (keyValuePairs.TryGetValue(checkFile, out match)) {
fileInfoA = new(file); fileInfoA = new(file);
fileInfoB = new(match); fileInfoB = new(match);
if (fileInfoA.Length != fileInfoB.Length) if (fileInfoA.Length != fileInfoB.Length) {
throw new NotSupportedException("Files don't match!"); throw new NotSupportedException("Files don't match!");
}
logger.LogWarning("<{file}> already exists!", file); logger.LogWarning("<{file}> already exists!", file);
deleteFiles.Add(file); deleteFiles.Add(file);
continue; continue;
} }
keyValuePairs.Add(checkFile, file); keyValuePairs.Add(checkFile, file);
} }
foreach (string file in deleteFiles) foreach (string file in deleteFiles) {
File.Delete(file); File.Delete(file);
foreach (KeyValuePair<string, string> keyValuePair in keyValuePairs) }
foreach (KeyValuePair<string, string> keyValuePair in keyValuePairs) {
File.Move(keyValuePair.Value, keyValuePair.Key); File.Move(keyValuePair.Value, keyValuePair.Key);
}
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory); Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
} }
private static void Distinct(List<string> args, string sourceDirectory, string[] deleteMatchingIdsDirectoryNames, string[] files) private static void Distinct(List<string> args, string sourceDirectory, string[] deleteMatchingIdsDirectoryNames, string[] files) {
{
string fileName; string fileName;
string directory; string directory;
List<string> distinct = []; List<string> distinct = [];
List<string> duplicate = []; List<string> duplicate = [];
string[] keepMatchingIdsDirectoryNames = args[4].Split(','); string[] keepMatchingIdsDirectoryNames = args[4].Split(',');
if (deleteMatchingIdsDirectoryNames.Length != keepMatchingIdsDirectoryNames.Length) if (deleteMatchingIdsDirectoryNames.Length != keepMatchingIdsDirectoryNames.Length) {
throw new NotSupportedException("Check arg lengths!"); throw new NotSupportedException("Check arg lengths!");
}
string[] keepMatchingIdsDirectories = keepMatchingIdsDirectoryNames.Select(l => Path.Combine(sourceDirectory, l)).ToArray(); string[] keepMatchingIdsDirectories = keepMatchingIdsDirectoryNames.Select(l => Path.Combine(sourceDirectory, l)).ToArray();
string[] deleteMatchingIdsDirectories = deleteMatchingIdsDirectoryNames.Select(l => Path.Combine(sourceDirectory, l)).ToArray(); string[] deleteMatchingIdsDirectories = deleteMatchingIdsDirectoryNames.Select(l => Path.Combine(sourceDirectory, l)).ToArray();
foreach (string file in files) foreach (string file in files) {
{
fileName = Path.GetFileName(file); fileName = Path.GetFileName(file);
if (distinct.Contains(fileName)) if (distinct.Contains(fileName)) {
{
duplicate.Add(fileName); duplicate.Add(fileName);
continue; continue;
} }
distinct.Add(Path.GetFileName(file)); distinct.Add(Path.GetFileName(file));
} }
foreach (string file in files) foreach (string file in files) {
{
fileName = Path.GetFileName(file); fileName = Path.GetFileName(file);
directory = Path.GetDirectoryName(file) ?? throw new NotSupportedException(); directory = Path.GetDirectoryName(file) ?? throw new NotSupportedException();
if (!duplicate.Contains(fileName)) if (!duplicate.Contains(fileName)) {
continue; continue;
if (deleteMatchingIdsDirectories.Contains(directory)) }
if (deleteMatchingIdsDirectories.Contains(directory)) {
File.Move(file, $"{file}.del"); File.Move(file, $"{file}.del");
else if (!keepMatchingIdsDirectories.Contains(directory)) } else if (!keepMatchingIdsDirectories.Contains(directory)) {
throw new NotSupportedException($"Missing <{Path.GetFileName(directory)}> as a directory for {fileName}"); throw new NotSupportedException($"Missing <{Path.GetFileName(directory)}> as a directory for {fileName}");
}
} }
} }
internal static void MoveUpOneDirectory(ILogger<Worker> logger, List<string> args)
{
string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0]);
string[] deleteMatchingIdsDirectoryNames = args[3].Split(',');
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
if (deleteMatchingIdsDirectoryNames.Length == 0)
MoveUpOndDirectory(logger, sourceDirectory, files);
else
Distinct(args, sourceDirectory, deleteMatchingIdsDirectoryNames, files);
}
} }

View File

@ -3,11 +3,9 @@ using System.Collections.ObjectModel;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240711 internal static partial class Helper20240711 {
{
internal static void GitRemoteRemove(ILogger<Worker> logger, List<string> args) internal static void GitRemoteRemove(ILogger<Worker> logger, List<string> args) {
{
string line; string line;
string[] lines; string[] lines;
bool branchCheck; bool branchCheck;
@ -27,52 +25,56 @@ internal static partial class Helper20240711
string extension = args[7].Length > 2 ? args[7] : string.Empty; string extension = args[7].Length > 2 ? args[7] : string.Empty;
string[] files = Directory.EnumerateFiles(sourceDirectory, searchPattern, new EnumerationOptions() { IgnoreInaccessible = true, RecurseSubdirectories = true, AttributesToSkip = FileAttributes.None }).ToArray(); string[] files = Directory.EnumerateFiles(sourceDirectory, searchPattern, new EnumerationOptions() { IgnoreInaccessible = true, RecurseSubdirectories = true, AttributesToSkip = FileAttributes.None }).ToArray();
logger.LogInformation("Found {files} file(s)", files.Length); logger.LogInformation("Found {files} file(s)", files.Length);
foreach (string file in files) foreach (string file in files) {
{
branchCheck = false; branchCheck = false;
remoteCheck = false; remoteCheck = false;
lines = File.ReadAllLines(file); lines = File.ReadAllLines(file);
for (int i = 0; i < lines.Length; i++) for (int i = 0; i < lines.Length; i++) {
{
line = lines[i]; line = lines[i];
if (!line.Contains(remoteToRemove)) if (!line.Contains(remoteToRemove)) {
continue; continue;
if (!lines[i - 1].Contains(remoteToRemoveFilter)) }
if (!lines[i - 1].Contains(remoteToRemoveFilter)) {
continue; continue;
}
remoteCheck = true; remoteCheck = true;
break; break;
} }
for (int i = 0; i < lines.Length; i++) for (int i = 0; i < lines.Length; i++) {
{
line = lines[i]; line = lines[i];
if (!line.Contains(branchName)) if (!line.Contains(branchName)) {
continue; continue;
}
branchCheck = true; branchCheck = true;
break; break;
} }
if (!remoteCheck) if (!remoteCheck) {
continue; continue;
}
directory = Path.GetDirectoryName(file); directory = Path.GetDirectoryName(file);
if (directory is null) if (directory is null) {
continue; continue;
}
parentDirectory = Path.GetDirectoryName(directory); parentDirectory = Path.GetDirectoryName(directory);
if (parentDirectory is null) if (parentDirectory is null) {
continue; continue;
}
parentDirectoryName = Path.GetFileName(parentDirectory).ToLower(); parentDirectoryName = Path.GetFileName(parentDirectory).ToLower();
messages = Helpers.HelperGit.RemoteRemove(parentDirectory, lastRemoteSegment, CancellationToken.None); messages = Helpers.HelperGit.RemoteRemove(parentDirectory, lastRemoteSegment, CancellationToken.None);
foreach (string message in messages) foreach (string message in messages) {
logger.LogInformation("{function} => {parentDirectoryName}: [{message}]", nameof(Helpers.HelperGit.RemoteRemove), parentDirectoryName, message); logger.LogInformation("{function} => {parentDirectoryName}: [{message}]", nameof(Helpers.HelperGit.RemoteRemove), parentDirectoryName, message);
}
messages = Helpers.HelperGit.RemoteAdd(parentDirectory, remoteToAddName, $"{remoteToAddUrl}{parentDirectoryName}{extension}", CancellationToken.None); messages = Helpers.HelperGit.RemoteAdd(parentDirectory, remoteToAddName, $"{remoteToAddUrl}{parentDirectoryName}{extension}", CancellationToken.None);
foreach (string message in messages) foreach (string message in messages) {
logger.LogInformation("{function} => {parentDirectoryName}: [{message}]", nameof(Helpers.HelperGit.RemoteAdd), parentDirectoryName, message); logger.LogInformation("{function} => {parentDirectoryName}: [{message}]", nameof(Helpers.HelperGit.RemoteAdd), parentDirectoryName, message);
if (!branchCheck) }
if (!branchCheck) {
continue; continue;
try }
{ messages = Helpers.HelperGit.PushBranch(parentDirectory, remoteToAddName, branchName, CancellationToken.None); } try { messages = Helpers.HelperGit.PushBranch(parentDirectory, remoteToAddName, branchName, CancellationToken.None); } catch (Exception ex) { messages = new([ex.Message]); }
catch (Exception ex) foreach (string message in messages) {
{ messages = new([ex.Message]); }
foreach (string message in messages)
logger.LogInformation("{function} => {parentDirectoryName}: [{message}]", nameof(Helpers.HelperGit.PushBranch), parentDirectoryName, message); logger.LogInformation("{function} => {parentDirectoryName}: [{message}]", nameof(Helpers.HelperGit.PushBranch), parentDirectoryName, message);
}
} }
} }

View File

@ -5,8 +5,7 @@ using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240718 internal static partial class Helper20240718 {
{
private record Host([property: JsonPropertyName("a")] string? Id, private record Host([property: JsonPropertyName("a")] string? Id,
[property: JsonPropertyName("b")] string? Colon, [property: JsonPropertyName("b")] string? Colon,
@ -21,67 +20,10 @@ internal static partial class Helper20240718
[JsonSourceGenerationOptions(WriteIndented = true, AllowTrailingCommas = true)] [JsonSourceGenerationOptions(WriteIndented = true, AllowTrailingCommas = true)]
[JsonSerializable(typeof(Host[]))] [JsonSerializable(typeof(Host[]))]
private partial class HostsSourceGenerationContext : JsonSerializerContext private partial class HostsSourceGenerationContext : JsonSerializerContext {
{
} }
private static Host[] GetHosts(ILogger<Worker> logger, string file) internal static void JsonToMarkdown(ILogger<Worker> logger, List<string> args) {
{
Host[] results;
string lines = File.ReadAllText(file);
string json = $"[{lines.Replace("\r\n", ",")}]";
logger.LogDebug(lines);
results = JsonSerializer.Deserialize(json, HostsSourceGenerationContext.Default.HostArray) ?? throw new NullReferenceException();
return results;
}
private static ReadOnlyCollection<string> GetLines(Host[] hosts, string title, string wired)
{
List<string> results = [$"# {title}", string.Empty, "```mermaid", "flowchart TB", $" subgraph {title}"];
int id;
string check;
List<int> distinct = [];
string newLine = $"{Environment.NewLine} ";
foreach (Host host in hosts)
{
if (host.Id is null || host.Hyphen is null || host.Device is null || host.Name is null || host.Hyphen.Length != 17)
continue;
if (!int.TryParse(host.Id, out id))
throw new NotSupportedException($"{host.Id} is not a number");
if (distinct.Contains(id))
throw new NotSupportedException($"{id} is not distinct!");
distinct.Add(id);
results.Add($" {id}(fa:{host.Type}{newLine}{host.Colon}{newLine}{host.Hyphen}{newLine}{host.Device}{newLine}https://{host.Name}/)");
}
results.Add(" end");
results.Add($" subgraph {title}");
foreach (Host host in from l in hosts orderby l.Location, l.Type, l.Line select l)
{
if (host.Id is null || host.Hyphen is null || host.Device is null || host.Name is null || host.Hyphen.Length != 17)
continue;
if (!int.TryParse(host.Id, out id))
throw new NotSupportedException($"{host.Id} is not a number");
check = host.Type == wired ? "-->" : "-.->";
results.Add($" {id} {check} |{id}| {host.Location}{host.Type}{host.Line}");
}
results.Add(" end");
results.Add($" subgraph {title}");
foreach (Host host in from l in hosts orderby l.Line, l.Location, l.Type select l)
{
if (host.Id is null || host.Hyphen is null || host.Device is null || host.Name is null || host.Line is null || host.Hyphen.Length != 17)
continue;
if (!int.TryParse(host.Id, out id))
throw new NotSupportedException($"{host.Id} is not a number");
check = host.Type == wired ? "-->" : "-.->";
results.Add($" {host.Location}{host.Type}{host.Line} {check} Line{host.Line}");
}
results.Add(" end");
results.Add("```");
return results.AsReadOnly();
}
internal static void JsonToMarkdown(ILogger<Worker> logger, List<string> args)
{
Host[] hosts; Host[] hosts;
string title = args[3]; string title = args[3];
string wired = args[4]; string wired = args[4];
@ -90,12 +32,68 @@ internal static partial class Helper20240718
ReadOnlyCollection<string> lines; ReadOnlyCollection<string> lines;
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
foreach (string file in files) foreach (string file in files) {
{
hosts = GetHosts(logger, file); hosts = GetHosts(logger, file);
lines = GetLines(hosts, title, wired); lines = GetLines(hosts, title, wired);
File.WriteAllText($"{file}{extension}", string.Join(Environment.NewLine, lines)); File.WriteAllText($"{file}{extension}", string.Join(Environment.NewLine, lines));
} }
} }
private static Host[] GetHosts(ILogger<Worker> logger, string file) {
Host[] results;
string lines = File.ReadAllText(file);
string json = $"[{lines.Replace("\r\n", ",")}]";
logger.LogDebug(lines);
results = JsonSerializer.Deserialize(json, HostsSourceGenerationContext.Default.HostArray) ?? throw new NullReferenceException();
return results;
}
private static ReadOnlyCollection<string> GetLines(Host[] hosts, string title, string wired) {
List<string> results = [$"# {title}", string.Empty, "```mermaid", "flowchart TB", $" subgraph {title}"];
int id;
string check;
List<int> distinct = [];
string newLine = $"{Environment.NewLine} ";
foreach (Host host in hosts) {
if (host.Id is null || host.Hyphen is null || host.Device is null || host.Name is null || host.Hyphen.Length != 17) {
continue;
}
if (!int.TryParse(host.Id, out id)) {
throw new NotSupportedException($"{host.Id} is not a number");
}
if (distinct.Contains(id)) {
throw new NotSupportedException($"{id} is not distinct!");
}
distinct.Add(id);
results.Add($" {id}(fa:{host.Type}{newLine}{host.Colon}{newLine}{host.Hyphen}{newLine}{host.Device}{newLine}https://{host.Name}/)");
}
results.Add(" end");
results.Add($" subgraph {title}");
foreach (Host host in from l in hosts orderby l.Location, l.Type, l.Line select l) {
if (host.Id is null || host.Hyphen is null || host.Device is null || host.Name is null || host.Hyphen.Length != 17) {
continue;
}
if (!int.TryParse(host.Id, out id)) {
throw new NotSupportedException($"{host.Id} is not a number");
}
check = host.Type == wired ? "-->" : "-.->";
results.Add($" {id} {check} |{id}| {host.Location}{host.Type}{host.Line}");
}
results.Add(" end");
results.Add($" subgraph {title}");
foreach (Host host in from l in hosts orderby l.Line, l.Location, l.Type select l) {
if (host.Id is null || host.Hyphen is null || host.Device is null || host.Name is null || host.Line is null || host.Hyphen.Length != 17) {
continue;
}
if (!int.TryParse(host.Id, out id)) {
throw new NotSupportedException($"{host.Id} is not a number");
}
check = host.Type == wired ? "-->" : "-.->";
results.Add($" {host.Location}{host.Type}{host.Line} {check} Line{host.Line}");
}
results.Add(" end");
results.Add("```");
return results.AsReadOnly();
}
} }

View File

@ -3,11 +3,9 @@ using System.Diagnostics;
namespace File_Folder_Helper.ADO2024.PI2; namespace File_Folder_Helper.ADO2024.PI2;
internal static partial class Helper20240728 internal static partial class Helper20240728 {
{
internal static void DownloadSslCertificates(ILogger<Worker> logger, List<string> args) internal static void DownloadSslCertificates(ILogger<Worker> logger, List<string> args) {
{
string file; string file;
Process? process; Process? process;
string[] segments; string[] segments;
@ -23,8 +21,7 @@ internal static partial class Helper20240728
int waitForExit = int.Parse(args[5]); int waitForExit = int.Parse(args[5]);
string[] subdomains = args[3].Split(','); string[] subdomains = args[3].Split(',');
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
ProcessStartInfo processStartInfo = new() ProcessStartInfo processStartInfo = new() {
{
CreateNoWindow = true, CreateNoWindow = true,
RedirectStandardError = true, RedirectStandardError = true,
RedirectStandardOutput = true, RedirectStandardOutput = true,
@ -32,28 +29,29 @@ internal static partial class Helper20240728
FileName = args[4], FileName = args[4],
WorkingDirectory = sourceDirectory WorkingDirectory = sourceDirectory
}; };
foreach (string subdomain in subdomains) foreach (string subdomain in subdomains) {
{
argumentSegment = $"{subdomain}.{domain}:443 -servername {subdomain}.{domain}"; argumentSegment = $"{subdomain}.{domain}:443 -servername {subdomain}.{domain}";
processStartInfo.Arguments = $"s_client -connect {subdomain}.{domain}:443 -servername {subdomain}.{domain}"; processStartInfo.Arguments = $"s_client -connect {subdomain}.{domain}:443 -servername {subdomain}.{domain}";
process = Process.Start(processStartInfo); process = Process.Start(processStartInfo);
if (process is null) if (process is null) {
continue; continue;
}
_ = process.WaitForExit(waitForExit); _ = process.WaitForExit(waitForExit);
process.Kill(entireProcessTree: true); process.Kill(entireProcessTree: true);
standardOutput = process.StandardOutput.ReadToEnd(); standardOutput = process.StandardOutput.ReadToEnd();
if (!standardOutput.Contains(beginCertificate) || !standardOutput.Contains(endCertificate)) if (!standardOutput.Contains(beginCertificate) || !standardOutput.Contains(endCertificate)) {
{
standardError = process.StandardError.ReadToEnd(); standardError = process.StandardError.ReadToEnd();
logger.LogWarning($"Error: {subdomain}{Environment.NewLine}{standardOutput}{Environment.NewLine}{standardError}"); logger.LogWarning($"Error: {subdomain}{Environment.NewLine}{standardOutput}{Environment.NewLine}{standardError}");
continue; continue;
} }
segments = standardOutput.Split(beginCertificate); segments = standardOutput.Split(beginCertificate);
if (segments.Length != 2) if (segments.Length != 2) {
break; break;
}
segments = segments[1].Split(endCertificate); segments = segments[1].Split(endCertificate);
if (segments.Length != 2) if (segments.Length != 2) {
break; break;
}
lines.Add($"{logSegment} \"{store}\" {subdomain}.{domain}.cert"); lines.Add($"{logSegment} \"{store}\" {subdomain}.{domain}.cert");
file = Path.Combine(sourceDirectory, $"{subdomain}.{domain}.cert"); file = Path.Combine(sourceDirectory, $"{subdomain}.{domain}.cert");
File.WriteAllText(file, $"{beginCertificate}{segments[0]}{endCertificate}{Environment.NewLine}"); File.WriteAllText(file, $"{beginCertificate}{segments[0]}{endCertificate}{Environment.NewLine}");

296
ADO2024/PI4/.editorconfig Normal file
View File

@ -0,0 +1,296 @@
[*.md]
end_of_line = crlf
file_header_template = unset
indent_size = 2
indent_style = space
insert_final_newline = false
root = true
tab_width = 2
[*.csproj]
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
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true
csharp_prefer_braces = true
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
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = false
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
csharp_style_allow_embedded_statements_on_same_line_experimental = true
csharp_style_conditional_delegate_call = true
csharp_style_deconstructed_variable_declaration = false
csharp_style_expression_bodied_accessors = when_on_single_line:warning
csharp_style_expression_bodied_constructors = when_on_single_line:warning
csharp_style_expression_bodied_indexers = when_on_single_line:warning
csharp_style_expression_bodied_lambdas = when_on_single_line:warning
csharp_style_expression_bodied_local_functions = when_on_single_line:warning
csharp_style_expression_bodied_methods = when_on_single_line:warning
csharp_style_expression_bodied_operators = when_on_single_line:warning
csharp_style_expression_bodied_properties = when_on_single_line:warning
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
csharp_style_inlined_variable_declaration = false
csharp_style_namespace_declarations = file_scoped:warning
csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_not_pattern = true:warning
csharp_style_prefer_null_check_over_type_check = true
csharp_style_prefer_pattern_matching = true:warning
csharp_style_prefer_range_operator = true:warning
csharp_style_prefer_switch_expression = true:warning
csharp_style_throw_expression = true
csharp_style_unused_value_assignment_preference = discard_variable:warning
csharp_style_unused_value_expression_statement_preference = discard_variable:warning
csharp_style_var_elsewhere = false:warning
csharp_style_var_for_built_in_types = false:warning
csharp_style_var_when_type_is_apparent = false:warning
csharp_using_directive_placement = outside_namespace
dotnet_analyzer_diagnostic.category-Design.severity = error
dotnet_analyzer_diagnostic.category-Documentation.severity = error
dotnet_analyzer_diagnostic.category-Globalization.severity = none
dotnet_analyzer_diagnostic.category-Interoperability.severity = error
dotnet_analyzer_diagnostic.category-Maintainability.severity = error
dotnet_analyzer_diagnostic.category-Naming.severity = none
dotnet_analyzer_diagnostic.category-Performance.severity = none
dotnet_analyzer_diagnostic.category-Reliability.severity = error
dotnet_analyzer_diagnostic.category-Security.severity = error
dotnet_analyzer_diagnostic.category-SingleFile.severity = error
dotnet_analyzer_diagnostic.category-Style.severity = error
dotnet_analyzer_diagnostic.category-Usage.severity = error
dotnet_code_quality_unused_parameters = all
dotnet_code_quality_unused_parameters = non_public
dotnet_code_quality.CAXXXX.api_surface = private, internal
dotnet_diagnostic.CA1001.severity = error # CA1001: Types that own disposable fields should be disposable
dotnet_diagnostic.CA1051.severity = error # CA1051: Do not declare visible instance fields
dotnet_diagnostic.CA1511.severity = warning # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1513.severity = warning # Use 'ObjectDisposedException.ThrowIf' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1825.severity = warning # CA1825: 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.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'
dotnet_diagnostic.CA1869.severity = none # CA1869: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead.
dotnet_diagnostic.CA2201.severity = none # CA2201: Exception type System.NullReferenceException is reserved by the runtime
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.IDE0010.severity = none # Add missing cases to switch statement (IDE0010)
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.IDE0048.severity = none # Parentheses preferences (IDE0047 and IDE0048)
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
dotnet_diagnostic.IDE0051.severity = error # Private member '' is unused [, ]
dotnet_diagnostic.IDE0058.severity = warning # IDE0058: Expression value is never used
dotnet_diagnostic.IDE0060.severity = error # IDE0060: Remove unused parameter
dotnet_diagnostic.IDE0074.severity = warning # IDE0074: Use compound assignment
dotnet_diagnostic.IDE0130.severity = none # Namespace does not match folder structure (IDE0130)
dotnet_diagnostic.IDE0270.severity = warning # IDE0270: Null check can be simplified
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
dotnet_naming_rule.class_should_be_pascal_case.severity = warning
dotnet_naming_rule.class_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.class_should_be_pascal_case.symbols = class
dotnet_naming_rule.delegate_should_be_pascal_case.severity = warning
dotnet_naming_rule.delegate_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.delegate_should_be_pascal_case.symbols = delegate
dotnet_naming_rule.enum_should_be_pascal_case.severity = warning
dotnet_naming_rule.enum_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.enum_should_be_pascal_case.symbols = enum
dotnet_naming_rule.event_should_be_pascal_case.severity = warning
dotnet_naming_rule.event_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.event_should_be_pascal_case.symbols = event
dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.method_should_be_pascal_case.severity = warning
dotnet_naming_rule.method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.method_should_be_pascal_case.symbols = method
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.private_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.private_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.private_method_should_be_pascal_case.symbols = private_method
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.symbols = private_or_internal_field
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.symbols = private_or_internal_static_field
dotnet_naming_rule.property_should_be_pascal_case.severity = warning
dotnet_naming_rule.property_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.property_should_be_pascal_case.symbols = property
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.symbols = public_or_protected_field
dotnet_naming_rule.static_field_should_be_pascal_case.severity = warning
dotnet_naming_rule.static_field_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_field_should_be_pascal_case.symbols = static_field
dotnet_naming_rule.static_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.static_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_method_should_be_pascal_case.symbols = static_method
dotnet_naming_rule.struct_should_be_pascal_case.severity = warning
dotnet_naming_rule.struct_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.struct_should_be_pascal_case.symbols = struct
dotnet_naming_rule.types_should_be_pascal_case.severity = warning
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.private_of_internal_field.capitalization = pascal_case
dotnet_naming_style.private_of_internal_field.required_prefix = _
dotnet_naming_style.private_of_internal_field.required_suffix =
dotnet_naming_style.private_of_internal_field.word_separator =
dotnet_naming_symbols.abstract_method.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.abstract_method.applicable_kinds = method
dotnet_naming_symbols.abstract_method.required_modifiers = abstract
dotnet_naming_symbols.class.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.class.applicable_kinds = class
dotnet_naming_symbols.class.required_modifiers =
dotnet_naming_symbols.delegate.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.delegate.applicable_kinds = delegate
dotnet_naming_symbols.delegate.required_modifiers =
dotnet_naming_symbols.enum.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.enum.applicable_kinds = enum
dotnet_naming_symbols.enum.required_modifiers =
dotnet_naming_symbols.event.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.event.applicable_kinds = event
dotnet_naming_symbols.event.required_modifiers =
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.method.applicable_accessibilities = public
dotnet_naming_symbols.method.applicable_kinds = method
dotnet_naming_symbols.method.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_symbols.private_method.applicable_accessibilities = private
dotnet_naming_symbols.private_method.applicable_kinds = method
dotnet_naming_symbols.private_method.required_modifiers =
dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected
dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_field.required_modifiers =
dotnet_naming_symbols.private_or_internal_static_field.applicable_accessibilities = internal, private, private_protected
dotnet_naming_symbols.private_or_internal_static_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_static_field.required_modifiers = static
dotnet_naming_symbols.property.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.property.applicable_kinds = property
dotnet_naming_symbols.property.required_modifiers =
dotnet_naming_symbols.public_or_protected_field.applicable_accessibilities = public, protected
dotnet_naming_symbols.public_or_protected_field.applicable_kinds = field
dotnet_naming_symbols.public_or_protected_field.required_modifiers =
dotnet_naming_symbols.static_field.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.static_field.applicable_kinds = field
dotnet_naming_symbols.static_field.required_modifiers = static
dotnet_naming_symbols.static_method.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.static_method.applicable_kinds = method
dotnet_naming_symbols.static_method.required_modifiers = static
dotnet_naming_symbols.struct.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.struct.applicable_kinds = struct
dotnet_naming_symbols.struct.required_modifiers =
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.required_modifiers =
dotnet_remove_unnecessary_suppression_exclusions = 0
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
dotnet_style_allow_multiple_blank_lines_experimental = false:warning
dotnet_style_allow_statement_immediately_after_block_experimental = true
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true:warning
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_namespace_match_folder = true
dotnet_style_null_propagation = true:warning
dotnet_style_object_initializer = true:warning
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
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:warning
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_compound_assignment = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = false
dotnet_style_prefer_conditional_expression_over_return = false
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
dotnet_style_prefer_simplified_boolean_expressions = true:warning
dotnet_style_prefer_simplified_interpolation = true
dotnet_style_qualification_for_event = false:error
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false:error
dotnet_style_qualification_for_property = false:error
dotnet_style_readonly_field = true:warning
dotnet_style_require_accessibility_modifiers = for_non_interface_members
end_of_line = crlf
file_header_template = unset
indent_size = 4
indent_style = space
insert_final_newline = false
root = true
tab_width = 4
# https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1822
# https://github.com/dotnet/aspnetcore/blob/main/.editorconfig
# https://github.com/dotnet/project-system/blob/main/.editorconfig

View File

@ -7,8 +7,7 @@ using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2024.PI4; namespace File_Folder_Helper.ADO2024.PI4;
internal static partial class Helper20241108 internal static partial class Helper20241108 {
{
#if WorkItems #if WorkItems
@ -49,13 +48,11 @@ internal static partial class Helper20241108
string Title, string Title,
string? Violation, string? Violation,
long? WeightedShortestJobFirst, long? WeightedShortestJobFirst,
string WorkItemType) string WorkItemType) {
{
public override string ToString() => $"{Id} - {WorkItemType} - {Title}"; public override string ToString() => $"{Id} - {WorkItemType} - {Title}";
public static WorkItem Get(WorkItem workItem, Relation[] relations) public static WorkItem Get(WorkItem workItem, Relation[] relations) {
{
WorkItem result = new(workItem.ActivatedDate, WorkItem result = new(workItem.ActivatedDate,
workItem.AreaPath, workItem.AreaPath,
workItem.AssignedTo, workItem.AssignedTo,
@ -87,8 +84,7 @@ internal static partial class Helper20241108
return result; return result;
} }
public static WorkItem? GetWithOutRelations(WorkItem? workItem) public static WorkItem? GetWithOutRelations(WorkItem? workItem) {
{
WorkItem? result = workItem is null ? null : new(workItem.ActivatedDate, WorkItem? result = workItem is null ? null : new(workItem.ActivatedDate,
workItem.AreaPath, workItem.AreaPath,
workItem.AssignedTo, workItem.AssignedTo,
@ -124,21 +120,17 @@ internal static partial class Helper20241108
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WorkItem))] [JsonSerializable(typeof(WorkItem))]
private partial class WorkItemSourceGenerationContext : JsonSerializerContext private partial class WorkItemSourceGenerationContext : JsonSerializerContext {
{
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WorkItem[]))] [JsonSerializable(typeof(WorkItem[]))]
private partial class WorkItemCollectionSourceGenerationContext : JsonSerializerContext private partial class WorkItemCollectionSourceGenerationContext : JsonSerializerContext {
{
} }
private record Record(WorkItem WorkItem, WorkItem? Parent, Record[]? Children, Record[]? Related, Record[]? Successors) private record Record(WorkItem WorkItem, WorkItem? Parent, Record[]? Children, Record[]? Related, Record[]? Successors) {
{
internal static Record GetWithoutNesting(Record record, string? violation) internal static Record GetWithoutNesting(Record record, string? violation) {
{
Record result; Record result;
WorkItem workItem = new(record.WorkItem.ActivatedDate, WorkItem workItem = new(record.WorkItem.ActivatedDate,
record.WorkItem.AreaPath, record.WorkItem.AreaPath,
@ -172,8 +164,7 @@ internal static partial class Helper20241108
return result; return result;
} }
private static Record Get(Record record, bool keepRelations) private static Record Get(Record record, bool keepRelations) {
{
Record result; Record result;
Record[]? childRecords; Record[]? childRecords;
Record[]? relatedRecords; Record[]? relatedRecords;
@ -183,8 +174,7 @@ internal static partial class Helper20241108
WorkItem? workItem = keepRelations ? record.WorkItem : WorkItem.GetWithOutRelations(record.WorkItem) ?? throw new Exception(); WorkItem? workItem = keepRelations ? record.WorkItem : WorkItem.GetWithOutRelations(record.WorkItem) ?? throw new Exception();
if (record.Children is null) if (record.Children is null)
childRecords = null; childRecords = null;
else else {
{
relationRecords = []; relationRecords = [];
foreach (Record r in record.Children) foreach (Record r in record.Children)
relationRecords.Add(Get(r, keepRelations)); relationRecords.Add(Get(r, keepRelations));
@ -192,8 +182,7 @@ internal static partial class Helper20241108
} }
if (record.Related is null) if (record.Related is null)
relatedRecords = null; relatedRecords = null;
else else {
{
relationRecords = []; relationRecords = [];
foreach (Record r in record.Related) foreach (Record r in record.Related)
relationRecords.Add(Get(r, keepRelations)); relationRecords.Add(Get(r, keepRelations));
@ -201,8 +190,7 @@ internal static partial class Helper20241108
} }
if (record.Successors is null) if (record.Successors is null)
successorRecords = null; successorRecords = null;
else else {
{
relationRecords = []; relationRecords = [];
foreach (Record r in record.Successors) foreach (Record r in record.Successors)
relationRecords.Add(Get(r, keepRelations)); relationRecords.Add(Get(r, keepRelations));
@ -212,16 +200,14 @@ internal static partial class Helper20241108
return result; return result;
} }
internal static Record Get(WorkItem workItem, WorkItem? parent, ReadOnlyCollection<Record>? children, ReadOnlyCollection<Record>? related, ReadOnlyCollection<Record>? successors, bool keepRelations) internal static Record Get(WorkItem workItem, WorkItem? parent, ReadOnlyCollection<Record>? children, ReadOnlyCollection<Record>? related, ReadOnlyCollection<Record>? successors, bool keepRelations) {
{
Record result; Record result;
Record record = new(workItem, parent, children?.ToArray(), related?.ToArray(), successors?.ToArray()); Record record = new(workItem, parent, children?.ToArray(), related?.ToArray(), successors?.ToArray());
result = Get(record, keepRelations); result = Get(record, keepRelations);
return result; return result;
} }
internal static ReadOnlyCollection<Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, WorkItem workItem, string relationName, List<bool> nests, bool keepRelations) internal static ReadOnlyCollection<Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, WorkItem workItem, string relationName, List<bool> nests, bool keepRelations) {
{
List<Record> results = []; List<Record> results = [];
Record record; Record record;
nests.Add(true); nests.Add(true);
@ -231,11 +217,9 @@ internal static partial class Helper20241108
ReadOnlyCollection<Record>? childRecords; ReadOnlyCollection<Record>? childRecords;
ReadOnlyCollection<Record>? relatedRecords; ReadOnlyCollection<Record>? relatedRecords;
ReadOnlyCollection<Record>? successorRecords; ReadOnlyCollection<Record>? successorRecords;
if (workItem.Relations is not null && workItem.Relations.Length > 0) if (workItem.Relations is not null && workItem.Relations.Length > 0) {
{
collection.Clear(); collection.Clear();
foreach (Relation relation in workItem.Relations) foreach (Relation relation in workItem.Relations) {
{
if (relation.Attributes.Name != relationName) if (relation.Attributes.Name != relationName)
continue; continue;
if (workItem.Parent is not null && relation.Id == workItem.Parent.Value) if (workItem.Parent is not null && relation.Id == workItem.Parent.Value)
@ -245,8 +229,7 @@ internal static partial class Helper20241108
collection.Add(relationWorkItem); collection.Add(relationWorkItem);
} }
collection = (from l in collection orderby l.State != "Closed", l.Id select l).ToList(); collection = (from l in collection orderby l.State != "Closed", l.Id select l).ToList();
foreach (WorkItem w in collection) foreach (WorkItem w in collection) {
{
if (nests.Count > 500) if (nests.Count > 500)
break; break;
if (w.Parent is null) if (w.Parent is null)
@ -268,12 +251,10 @@ internal static partial class Helper20241108
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Record[]))] [JsonSerializable(typeof(Record[]))]
private partial class RecordCollectionBCommonSourceGenerationContext : JsonSerializerContext private partial class RecordCollectionBCommonSourceGenerationContext : JsonSerializerContext {
{
} }
private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations) private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations) {
{
Dictionary<int, Record> results = []; Dictionary<int, Record> results = [];
Record record; Record record;
List<bool> nests = []; List<bool> nests = [];
@ -281,23 +262,19 @@ internal static partial class Helper20241108
ReadOnlyCollection<Record> childRecords; ReadOnlyCollection<Record> childRecords;
ReadOnlyCollection<Record> relatedRecords; ReadOnlyCollection<Record> relatedRecords;
ReadOnlyCollection<Record> successorRecords; ReadOnlyCollection<Record> successorRecords;
foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs) foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs) {
{
nests.Clear(); nests.Clear();
if (keyValuePair.Value.Parent is null) if (keyValuePair.Value.Parent is null)
parentWorkItem = null; parentWorkItem = null;
else else
_ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem); _ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem);
try try {
{
childRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Child", nests, keepRelations); // Forward childRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Child", nests, keepRelations); // Forward
// records = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Predecessor", nests, keepRelations); // Reverse // records = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Predecessor", nests, keepRelations); // Reverse
relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related
successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward
record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations); record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations);
} } catch (Exception) {
catch (Exception)
{
record = new(keyValuePair.Value, parentWorkItem, [], [], []); record = new(keyValuePair.Value, parentWorkItem, [], [], []);
} }
results.Add(keyValuePair.Key, record); results.Add(keyValuePair.Key, record);
@ -305,8 +282,7 @@ internal static partial class Helper20241108
return new(results); return new(results);
} }
private static ReadOnlyDictionary<int, Record> GetWorkItems(ReadOnlyCollection<WorkItem> workItems, bool keepRelations) private static ReadOnlyDictionary<int, Record> GetWorkItems(ReadOnlyCollection<WorkItem> workItems, bool keepRelations) {
{
ReadOnlyDictionary<int, Record> results; ReadOnlyDictionary<int, Record> results;
Dictionary<int, WorkItem> keyValuePairs = []; Dictionary<int, WorkItem> keyValuePairs = [];
foreach (WorkItem workItem in workItems) foreach (WorkItem workItem in workItems)
@ -315,14 +291,12 @@ internal static partial class Helper20241108
return results; return results;
} }
private static ReadOnlyCollection<WorkItem>? GetWorkItems(string fileName, string sourceDirectory) private static ReadOnlyCollection<WorkItem>? GetWorkItems(string fileName, string sourceDirectory) {
{
WorkItem[]? results; WorkItem[]? results;
string? checkFile = null; string? checkFile = null;
string? checkDirectory = sourceDirectory; string? checkDirectory = sourceDirectory;
string? pathRoot = Path.GetPathRoot(sourceDirectory); string? pathRoot = Path.GetPathRoot(sourceDirectory);
for (int i = 0; i < int.MaxValue; i++) for (int i = 0; i < int.MaxValue; i++) {
{
checkDirectory = Path.GetDirectoryName(checkDirectory); checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot) if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
break; break;
@ -333,16 +307,14 @@ internal static partial class Helper20241108
} }
if (checkFile is null) if (checkFile is null)
results = null; results = null;
else else {
{
string json = File.ReadAllText(checkFile); string json = File.ReadAllText(checkFile);
results = JsonSerializer.Deserialize(json, WorkItemCollectionSourceGenerationContext.Default.WorkItemArray); results = JsonSerializer.Deserialize(json, WorkItemCollectionSourceGenerationContext.Default.WorkItemArray);
} }
return results is null ? null : new(results); return results is null ? null : new(results);
} }
internal static void WriteMarkdown(ILogger<Worker> logger, List<string> args) internal static void WriteMarkdown(ILogger<Worker> logger, List<string> args) {
{
// string url = args[5]; // string url = args[5];
bool keepRelations = true; bool keepRelations = true;
string fileName = args[2]; string fileName = args[2];
@ -351,20 +323,17 @@ internal static partial class Helper20241108
string idCheck = sourceDirectoryName.Split('-', StringSplitOptions.None)[0]; string idCheck = sourceDirectoryName.Split('-', StringSplitOptions.None)[0];
if (!int.TryParse(idCheck, out int id)) if (!int.TryParse(idCheck, out int id))
logger.LogInformation("Not valid directory!"); logger.LogInformation("Not valid directory!");
else else {
{
ReadOnlyCollection<WorkItem>? workItems = GetWorkItems(fileName, sourceDirectory); ReadOnlyCollection<WorkItem>? workItems = GetWorkItems(fileName, sourceDirectory);
if (workItems is null) if (workItems is null)
logger.LogInformation("No file found!"); logger.LogInformation("No file found!");
else else {
{
Record? record; Record? record;
ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations);
logger.LogInformation("Found {keyValuePairs}", keyValuePairs.Count); logger.LogInformation("Found {keyValuePairs}", keyValuePairs.Count);
if (!keyValuePairs.TryGetValue(id, out record)) if (!keyValuePairs.TryGetValue(id, out record))
logger.LogInformation($"Id {id} not found!"); logger.LogInformation($"Id {id} not found!");
else else {
{
logger.LogInformation($"Id {id} found with title {record.WorkItem.Title}!"); logger.LogInformation($"Id {id} found with title {record.WorkItem.Title}!");
} }
} }
@ -373,8 +342,7 @@ internal static partial class Helper20241108
#else #else
internal static void WriteMarkdown(ILogger<Worker> logger, List<string> args) internal static void WriteMarkdown(ILogger<Worker> logger, List<string> args) {
{
logger.LogError("WriteMarkdown is not available in WorkItems {args[0]}", args[0]); logger.LogError("WriteMarkdown is not available in WorkItems {args[0]}", args[0]);
logger.LogError("WriteMarkdown is not available in WorkItems {args[1]}", args[1]); logger.LogError("WriteMarkdown is not available in WorkItems {args[1]}", args[1]);
} }

View File

@ -2,13 +2,11 @@ using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2024.PI4; namespace File_Folder_Helper.ADO2024.PI4;
internal static partial class Helper20241115 internal static partial class Helper20241115 {
{
#if BIORAD #if BIORAD
internal static void ScanPast(string text, int[] i, string search) internal static void ScanPast(string text, int[] i, string search) {
{
int num = text.IndexOf(search, i[0]); int num = text.IndexOf(search, i[0]);
if (num > -1) if (num > -1)
i[0] = num + search.Length; i[0] = num + search.Length;
@ -16,15 +14,13 @@ internal static partial class Helper20241115
i[0] = text.Length; i[0] = text.Length;
} }
internal static void GetComplete(ILogger<Worker> logger, List<string> args) internal static void GetComplete(ILogger<Worker> logger, List<string> args) {
{
string searchPattern = args[2]; string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
if (files.Length != 1) if (files.Length != 1)
logger.LogError("No files found in {sourceDirectory} with search pattern {searchPattern}", sourceDirectory, searchPattern); logger.LogError("No files found in {sourceDirectory} with search pattern {searchPattern}", sourceDirectory, searchPattern);
else else {
{
List<string> group = []; List<string> group = [];
string text = File.ReadAllText(files[0]); string text = File.ReadAllText(files[0]);
int[] i = [0]; int[] i = [0];
@ -34,12 +30,10 @@ internal static partial class Helper20241115
string[] segments = text.Substring(i[0]).Split('*'); string[] segments = text.Substring(i[0]).Split('*');
string[] segmentsB; string[] segmentsB;
string[] segmentsC; string[] segmentsC;
foreach (string segment in segments) foreach (string segment in segments) {
{
segmentsB = segment.Split(Environment.NewLine); segmentsB = segment.Split(Environment.NewLine);
segmentsC = segmentsB[0].Split(' '); segmentsC = segmentsB[0].Split(' ');
if (segment.Contains("Group")) if (segment.Contains("Group")) {
{
} }
} }
} }
@ -47,13 +41,13 @@ internal static partial class Helper20241115
#else #else
internal static void GetComplete(ILogger<Worker> logger, List<string> args) internal static void GetComplete(ILogger<Worker> logger, List<string> args) {
{
string searchPattern = args[2]; string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
if (files.Length != 1) if (files.Length != 1) {
logger.LogError("No files found in {sourceDirectory} with search pattern {searchPattern}", sourceDirectory, searchPattern); logger.LogError("No files found in {sourceDirectory} with search pattern {searchPattern}", sourceDirectory, searchPattern);
}
logger.LogError("GetComplete is not available in BioRad {args[1]}", args[1]); logger.LogError("GetComplete is not available in BioRad {args[1]}", args[1]);
} }

View File

@ -3,19 +3,17 @@ using System.Text;
namespace File_Folder_Helper.ADO2024.PI4; namespace File_Folder_Helper.ADO2024.PI4;
internal static partial class Helper20241204 internal static partial class Helper20241204 {
{
internal static void ConvertToUTF8(ILogger<Worker> logger, List<string> args) internal static void ConvertToUTF8(ILogger<Worker> logger, List<string> args) {
{
string text; string text;
string searchPattern = args[2]; string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
if (files.Length == 0) if (files.Length == 0) {
logger.LogError("No files found in {sourceDirectory} with search pattern {searchPattern}", sourceDirectory, searchPattern); logger.LogError("No files found in {sourceDirectory} with search pattern {searchPattern}", sourceDirectory, searchPattern);
foreach (string file in files) }
{ foreach (string file in files) {
text = File.ReadAllText(file); text = File.ReadAllText(file);
File.WriteAllText(file, text, Encoding.UTF8); File.WriteAllText(file, text, Encoding.UTF8);
} }

View File

@ -2,11 +2,9 @@ using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2024.PI4; namespace File_Folder_Helper.ADO2024.PI4;
internal static partial class Helper20241212 internal static partial class Helper20241212 {
{
internal static void Rename(ILogger<Worker> logger, List<string> args) internal static void Rename(ILogger<Worker> logger, List<string> args) {
{
string newFile; string newFile;
string fileName; string fileName;
string newFileName; string newFileName;
@ -15,20 +13,22 @@ internal static partial class Helper20241212
string[] searchPatterns = args[3].Split('~'); string[] searchPatterns = args[3].Split('~');
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
if (files.Length == 0) if (files.Length == 0) {
logger.LogError("No files found in {sourceDirectory} with search pattern {searchPattern}", sourceDirectory, searchPattern); logger.LogError("No files found in {sourceDirectory} with search pattern {searchPattern}", sourceDirectory, searchPattern);
foreach (string file in files) }
{ foreach (string file in files) {
fileName = Path.GetFileName(file); fileName = Path.GetFileName(file);
directoryName = Path.GetDirectoryName(file) ?? throw new Exception(); directoryName = Path.GetDirectoryName(file) ?? throw new Exception();
newFileName = fileName; newFileName = fileName;
foreach (string pattern in searchPatterns) foreach (string pattern in searchPatterns) {
newFileName = newFileName.Replace(pattern, ""); newFileName = newFileName.Replace(pattern, "");
}
newFile = Path.Combine(directoryName, newFileName); newFile = Path.Combine(directoryName, newFileName);
if (File.Exists(newFile)) if (File.Exists(newFile)) {
logger.LogError("File {newFile} already exists", newFile); logger.LogError("File {newFile} already exists", newFile);
else } else {
File.Move(file, newFile); File.Move(file, newFile);
}
} }
} }

View File

@ -8,8 +8,7 @@ using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2024.PI4; namespace File_Folder_Helper.ADO2024.PI4;
internal static partial class Helper20241217 internal static partial class Helper20241217 {
{
private record SecureShell( private record SecureShell(
); );
@ -42,21 +41,18 @@ internal static partial class Helper20241217
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Job))] [JsonSerializable(typeof(Job))]
private partial class JobSourceGenerationContext : JsonSerializerContext private partial class JobSourceGenerationContext : JsonSerializerContext {
{
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(File[]))] [JsonSerializable(typeof(File[]))]
private partial class FilesSourceGenerationContext : JsonSerializerContext private partial class FilesSourceGenerationContext : JsonSerializerContext {
{
} }
private static ReadOnlyCollection<File> GetFiles(string searchPattern, string[] ignoreFileNames, Record record) => private static ReadOnlyCollection<File> GetFiles(string searchPattern, string[] ignoreFileNames, Record record) =>
GetFiles(record.SourceDirectory, searchPattern, ignoreFileNames); GetFiles(record.SourceDirectory, searchPattern, ignoreFileNames);
internal static void Backup(ILogger<Worker> logger, List<string> args) internal static void Backup(ILogger<Worker> logger, List<string> args) {
{
Job jobNew; Job jobNew;
string path; string path;
string? json; string? json;
@ -76,37 +72,33 @@ internal static partial class Helper20241217
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string? snap2HyperTextMarkupLanguage = args.Count < 6 ? null : Path.GetFullPath(args[5]); string? snap2HyperTextMarkupLanguage = args.Count < 6 ? null : Path.GetFullPath(args[5]);
logger.LogInformation("Searching <{sourceDirectory}> with search pattern {searchPattern}", args[0], searchPattern); logger.LogInformation("Searching <{sourceDirectory}> with search pattern {searchPattern}", args[0], searchPattern);
if (Debugger.IsAttached) if (Debugger.IsAttached) {
Verify(searchPattern, ignoreFileNames); Verify(searchPattern, ignoreFileNames);
for (int i = 1; i < 3; i++) }
{ for (int i = 1; i < 3; i++) {
if (i == 1) if (i == 1) {
{
searchPatternFiles = Directory.EnumerateFiles(sourceDirectory, searchPattern, new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true }); searchPatternFiles = Directory.EnumerateFiles(sourceDirectory, searchPattern, new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true });
} } else if (i == 2) {
else if (i == 2)
{
searchPatternFiles = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); searchPatternFiles = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
} } else {
else
throw new NotImplementedException(); throw new NotImplementedException();
}
records = GetRecords(sourceDirectory, destination, searchPatternFiles); records = GetRecords(sourceDirectory, destination, searchPatternFiles);
foreach (Record record in records) foreach (Record record in records) {
{ 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);
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 (snap2HyperTextMarkupLanguage is not null && System.IO.File.Exists(snap2HyperTextMarkupLanguage)) {
{ if (!areTheyTheSame || (areTheyTheSame && !System.IO.File.Exists(record.Snap2HyperTextMarkupLanguage))) {
if (!areTheyTheSame || (areTheyTheSame && !System.IO.File.Exists(record.Snap2HyperTextMarkupLanguage)))
WriteSnap2HyperTextMarkupLanguage(logger, snap2HyperTextMarkupLanguage, record); WriteSnap2HyperTextMarkupLanguage(logger, snap2HyperTextMarkupLanguage, record);
}
} }
if (areTheyTheSame) if (areTheyTheSame) {
{
WriteAllText(record.Path, json); WriteAllText(record.Path, json);
continue; continue;
} }
@ -121,15 +113,15 @@ internal static partial class Helper20241217
} }
} }
private static void Verify(string searchPattern, string[] ignoreFileNames) private static void Verify(string searchPattern, string[] ignoreFileNames) {
{
List<Target> targets = [ List<Target> targets = [
new(new SecureShell(), null), new(new SecureShell(), null),
new(null, new ServerMessageBlock("\\\\mesfs.infineon.com\\EC_APC\\DEV", true)) new(null, new ServerMessageBlock("\\\\mesfs.infineon.com\\EC_APC\\DEV", true))
]; ];
string directory = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper"); string directory = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper");
if (!Directory.Exists(directory)) if (!Directory.Exists(directory)) {
_ = Directory.CreateDirectory(directory); _ = Directory.CreateDirectory(directory);
}
string path = Path.Combine(directory, "verify.json"); string path = Path.Combine(directory, "verify.json");
ReadOnlyCollection<File> files = GetFiles(directory, searchPattern, ignoreFileNames); ReadOnlyCollection<File> files = GetFiles(directory, searchPattern, ignoreFileNames);
ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, files); ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, files);
@ -146,28 +138,29 @@ internal static partial class Helper20241217
WriteAllText(path, json); WriteAllText(path, json);
} }
private static ReadOnlyCollection<File> GetFilteredFiles(string searchPattern, string[] ignoreFileNames, ReadOnlyCollection<File> files) private static ReadOnlyCollection<File> GetFilteredFiles(string searchPattern, string[] ignoreFileNames, ReadOnlyCollection<File> files) {
{
List<File> results = []; List<File> results = [];
string fileName; string fileName;
foreach (File file in files) foreach (File file in files) {
{ if (file.RelativePath == searchPattern) {
if (file.RelativePath == searchPattern)
continue; continue;
}
fileName = Path.GetFileName(file.RelativePath); fileName = Path.GetFileName(file.RelativePath);
if (fileName == searchPattern) if (fileName == searchPattern) {
throw new Exception("Found nested file!"); throw new Exception("Found nested file!");
if (ignoreFileNames.Any(l => l == fileName)) }
if (ignoreFileNames.Any(l => l == fileName)) {
continue; continue;
if (file.Length == 0) }
if (file.Length == 0) {
continue; continue;
}
results.Add(file); results.Add(file);
} }
return results.AsReadOnly(); return results.AsReadOnly();
} }
private static IEnumerable<Record> GetRecords(string directory, string destination, IEnumerable<string> files) private static IEnumerable<Record> GetRecords(string directory, string destination, IEnumerable<string> files) {
{
Job? job; Job? job;
string json; string json;
Record record; Record record;
@ -176,22 +169,21 @@ internal static partial class Helper20241217
string sourceDirectory; string sourceDirectory;
string destinationDirectory; string destinationDirectory;
string snap2HyperTextMarkupLanguage; string snap2HyperTextMarkupLanguage;
foreach (string file in files) foreach (string file in files) {
{
fileName = Path.GetFileName(file); fileName = Path.GetFileName(file);
sourceDirectory = Path.GetDirectoryName(file) ?? throw new Exception(); sourceDirectory = Path.GetDirectoryName(file) ?? throw new Exception();
directoryName = Path.GetFileName(sourceDirectory); directoryName = Path.GetFileName(sourceDirectory);
if (!fileName.StartsWith('.')) if (!fileName.StartsWith('.')) {
{
System.IO.File.Move(file, Path.Combine(sourceDirectory, $".{fileName}")); System.IO.File.Move(file, Path.Combine(sourceDirectory, $".{fileName}"));
continue; continue;
} }
json = System.IO.File.ReadAllText(file); json = System.IO.File.ReadAllText(file);
snap2HyperTextMarkupLanguage = Path.Combine(sourceDirectory, ".html"); snap2HyperTextMarkupLanguage = Path.Combine(sourceDirectory, ".html");
if (string.IsNullOrEmpty(json) || json is "{}" or "[]") if (string.IsNullOrEmpty(json) || json is "{}" or "[]") {
job = null; job = null;
else } else {
job = JsonSerializer.Deserialize(json, JobSourceGenerationContext.Default.Job); job = JsonSerializer.Deserialize(json, JobSourceGenerationContext.Default.Job);
}
job ??= new(AlternatePath: null, job ??= new(AlternatePath: null,
Directory: directory, Directory: directory,
Extension: ".iso", Extension: ".iso",
@ -201,8 +193,9 @@ internal static partial class Helper20241217
Keep: 3, Keep: 3,
Targets: []); Targets: []);
destinationDirectory = $"{destination}{sourceDirectory[2..]}"; destinationDirectory = $"{destination}{sourceDirectory[2..]}";
if (!Directory.Exists(destinationDirectory)) if (!Directory.Exists(destinationDirectory)) {
_ = Directory.CreateDirectory(destinationDirectory); _ = Directory.CreateDirectory(destinationDirectory);
}
record = new(DestinationDirectory: destinationDirectory, record = new(DestinationDirectory: destinationDirectory,
DirectoryName: directoryName, DirectoryName: directoryName,
Job: job, Job: job,
@ -213,49 +206,33 @@ internal static partial class Helper20241217
} }
} }
private static void WriteSnap2HyperTextMarkupLanguage(ILogger<Worker> logger, string snap2HyperTextMarkupLanguage, Record record) private static ReadOnlyCollection<File> GetFiles(string directory, string searchPattern, string[] ignoreFileNames) {
{
string title = Path.GetFileName(record.SourceDirectory);
ProcessStartInfo processStartInfo = new()
{
Arguments = $"-path:\"{record.SourceDirectory}\" -outfile:\"{record.Snap2HyperTextMarkupLanguage}\" -title:\"{title}\" -hidden -silent",
FileName = snap2HyperTextMarkupLanguage,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
WorkingDirectory = record.SourceDirectory
};
Process? process = Process.Start(processStartInfo) ?? throw new Exception("Process should not be null.");
process.WaitForExit();
logger.LogInformation($"Snap2HyperTextMarkupLanguage: {process.StandardOutput.ReadToEnd()}{Environment.NewLine}{process.StandardError.ReadToEnd()}{Environment.NewLine}{process.ExitCode}");
}
private static ReadOnlyCollection<File> GetFiles(string directory, string searchPattern, string[] ignoreFileNames)
{
List<File> results = []; List<File> results = [];
File file; File file;
string relativePath; string relativePath;
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories); string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
FileInfo[] fileInfoCollection = files.Select(l => new FileInfo(l)).ToArray(); FileInfo[] fileInfoCollection = files.Select(l => new FileInfo(l)).ToArray();
foreach (FileInfo fileInfo in fileInfoCollection) foreach (FileInfo fileInfo in fileInfoCollection) {
{ if (fileInfo.Name == searchPattern) {
if (fileInfo.Name == searchPattern)
continue; continue;
if (ignoreFileNames.Any(l => l == fileInfo.Name)) }
if (ignoreFileNames.Any(l => l == fileInfo.Name)) {
continue; continue;
if (!string.IsNullOrEmpty(fileInfo.LinkTarget)) }
if (!string.IsNullOrEmpty(fileInfo.LinkTarget)) {
continue; continue;
}
relativePath = Path.GetRelativePath(directory, fileInfo.FullName).Replace(';', '_'); relativePath = Path.GetRelativePath(directory, fileInfo.FullName).Replace(';', '_');
if (relativePath.StartsWith("..")) if (relativePath.StartsWith("..")) {
relativePath = relativePath[3..]; relativePath = relativePath[3..];
}
file = new(LastWriteTicks: fileInfo.LastWriteTime.Ticks, Length: fileInfo.Length, RelativePath: relativePath); file = new(LastWriteTicks: fileInfo.LastWriteTime.Ticks, Length: fileInfo.Length, RelativePath: relativePath);
results.Add(file); results.Add(file);
} }
return results.AsReadOnly(); return results.AsReadOnly();
} }
private static Job GetJob(string searchPattern, string[] ignoreFileNames, Record record, ReadOnlyCollection<File> files) private static Job GetJob(string searchPattern, string[] ignoreFileNames, Record record, ReadOnlyCollection<File> files) {
{
Job result; Job result;
ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, files); ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, files);
double filesTotalLengthNew = collection.Select(l => l.Length).Sum(); double filesTotalLengthNew = collection.Select(l => l.Length).Sum();
@ -270,37 +247,28 @@ internal static partial class Helper20241217
return result; return result;
} }
private static bool GetAreTheyTheSame(ILogger<Worker> logger, string searchPattern, string[] ignoreFileNames, Record record, Job jobNew) private static bool GetAreTheyTheSame(ILogger<Worker> logger, string searchPattern, string[] ignoreFileNames, Record record, Job jobNew) {
{
bool result; bool result;
ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, record.Job.Files.AsReadOnly()); ReadOnlyCollection<File> collection = GetFilteredFiles(searchPattern, ignoreFileNames, record.Job.Files.AsReadOnly());
int filesCountOld = collection.Count; int filesCountOld = collection.Count;
int filesCountNew = jobNew.Files.Length; int filesCountNew = jobNew.Files.Length;
if (filesCountNew != filesCountOld) if (filesCountNew != filesCountOld) {
{
result = false; result = false;
logger.LogWarning("<{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
{
double filesTotalLengthOld = collection.Select(l => l.Length).Sum(); double filesTotalLengthOld = collection.Select(l => l.Length).Sum();
double filesTotalLengthNew = jobNew.Files.Select(l => l.Length).Sum(); double filesTotalLengthNew = jobNew.Files.Select(l => l.Length).Sum();
if (filesTotalLengthNew != filesTotalLengthOld) if (filesTotalLengthNew != filesTotalLengthOld) {
{
result = false; result = false;
logger.LogWarning("<{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
{
string jsonNew = JsonSerializer.Serialize(jobNew.Files, FilesSourceGenerationContext.Default.FileArray); string jsonNew = JsonSerializer.Serialize(jobNew.Files, FilesSourceGenerationContext.Default.FileArray);
string jsonOld = JsonSerializer.Serialize(collection.ToArray(), FilesSourceGenerationContext.Default.FileArray); string jsonOld = JsonSerializer.Serialize(collection.ToArray(), FilesSourceGenerationContext.Default.FileArray);
if (jsonNew == jsonOld) if (jsonNew == jsonOld) {
result = true; result = true;
else } else {
{
result = false; result = false;
if (Debugger.IsAttached) if (Debugger.IsAttached) {
{
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);
} }
@ -311,55 +279,70 @@ internal static partial class Helper20241217
return result; return result;
} }
private static void WriteAllText(string path, string text) private static void WriteSnap2HyperTextMarkupLanguage(ILogger<Worker> logger, string snap2HyperTextMarkupLanguage, Record record) {
{ string title = Path.GetFileName(record.SourceDirectory);
ProcessStartInfo processStartInfo = new() {
Arguments = $"-path:\"{record.SourceDirectory}\" -outfile:\"{record.Snap2HyperTextMarkupLanguage}\" -title:\"{title}\" -hidden -silent",
FileName = snap2HyperTextMarkupLanguage,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
WorkingDirectory = record.SourceDirectory
};
Process? process = Process.Start(processStartInfo) ?? throw new Exception("Process should not be null.");
process.WaitForExit();
logger.LogInformation($"Snap2HyperTextMarkupLanguage: {process.StandardOutput.ReadToEnd()}{Environment.NewLine}{process.StandardError.ReadToEnd()}{Environment.NewLine}{process.ExitCode}");
}
private static void WriteAllText(string path, string text) {
string check = !System.IO.File.Exists(path) ? string.Empty : System.IO.File.ReadAllText(path); string check = !System.IO.File.Exists(path) ? string.Empty : System.IO.File.ReadAllText(path);
if (check != text) if (check != text) {
System.IO.File.WriteAllText(path, text); System.IO.File.WriteAllText(path, text);
}
} }
private static void WritePassedExtension(Record record, ReadOnlyCollection<File> files, string directoryName, string path) private static void WritePassedExtension(Record record, ReadOnlyCollection<File> files, string directoryName, string path) {
{ if (record.Job.Extension.Equals(".iso", StringComparison.OrdinalIgnoreCase)) {
if (record.Job.Extension.Equals(".iso", StringComparison.OrdinalIgnoreCase))
WriteISO(record, files, path, directoryName); WriteISO(record, files, path, directoryName);
else if (record.Job.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)) } else if (record.Job.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)) {
WriteZIP(record, files, path); WriteZIP(record, files, path);
else } else {
throw new NotImplementedException(); throw new NotImplementedException();
}
} }
private static void WriteISO(Record record, ReadOnlyCollection<File> files, string path, string directoryName) private static void WriteISO(Record record, ReadOnlyCollection<File> files, string path, string directoryName) {
{
CDBuilder builder = new() { UseJoliet = true, VolumeIdentifier = directoryName.Length < 25 ? directoryName : directoryName[..25] }; CDBuilder builder = new() { UseJoliet = true, VolumeIdentifier = directoryName.Length < 25 ? directoryName : directoryName[..25] };
foreach (File file in files) foreach (File file in files) {
_ = builder.AddFile(file.RelativePath, Path.Combine(record.SourceDirectory, file.RelativePath)); _ = builder.AddFile(file.RelativePath, Path.Combine(record.SourceDirectory, file.RelativePath));
}
builder.Build(path); builder.Build(path);
} }
private static void WriteZIP(Record record, ReadOnlyCollection<File> files, string path) private static void WriteZIP(Record record, ReadOnlyCollection<File> files, string path) {
{
using ZipArchive zip = ZipFile.Open(path, ZipArchiveMode.Create); using ZipArchive zip = ZipFile.Open(path, ZipArchiveMode.Create);
string directoryEntry; string directoryEntry;
List<string> directoryEntries = []; List<string> directoryEntries = [];
foreach (File file in files) foreach (File file in files) {
{
directoryEntry = Path.GetDirectoryName(file.RelativePath) ?? throw new Exception(); directoryEntry = Path.GetDirectoryName(file.RelativePath) ?? throw new Exception();
if (!directoryEntries.Contains(directoryEntry)) if (!directoryEntries.Contains(directoryEntry)) {
continue; continue;
}
directoryEntries.Add(directoryEntry); directoryEntries.Add(directoryEntry);
_ = zip.CreateEntry(file.RelativePath); _ = zip.CreateEntry(file.RelativePath);
} }
foreach (File file in files) foreach (File file in files) {
_ = zip.CreateEntryFromFile(Path.Combine(record.SourceDirectory, file.RelativePath), file.RelativePath); _ = zip.CreateEntryFromFile(Path.Combine(record.SourceDirectory, file.RelativePath), file.RelativePath);
}
} }
private static void WriteAllText(Record record, string text, string path) private static void WriteAllText(Record record, string text, string path) {
{
WriteAllText(record.Path, text); WriteAllText(record.Path, text);
System.IO.File.Copy(record.Path, $"{path}.json"); System.IO.File.Copy(record.Path, $"{path}.json");
string checkFile = Path.Combine(record.SourceDirectory, ".html"); string checkFile = Path.Combine(record.SourceDirectory, ".html");
if (System.IO.File.Exists(checkFile)) if (System.IO.File.Exists(checkFile)) {
System.IO.File.Copy(checkFile, $"{path}.html"); System.IO.File.Copy(checkFile, $"{path}.html");
}
} }
} }

View File

@ -9,165 +9,13 @@ using System.Text.Json;
namespace File_Folder_Helper.ADO2024.PI4; namespace File_Folder_Helper.ADO2024.PI4;
internal static partial class Helper20241224 internal static partial class Helper20241224 {
{
private static readonly HttpClient _HttpClient = new(); private static readonly HttpClient _HttpClient = new();
private record Record(Uri URI, string Path, DateTime LastModified); private record Record(Uri URI, string Path, DateTime LastModified);
private static ReadOnlyCollection<NginxFileSystem>? GetRecursiveCollection(string host, string page) internal static void Compare(ILogger<Worker> logger, List<string> args) {
{
List<NginxFileSystem>? results;
Uri uri = new($"https://{host}/{page}");
string format = NginxFileSystem.GetFormat();
TimeZoneInfo timeZoneInfo = TimeZoneInfo.Local;
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(uri);
taskHttpResponseMessage.Wait();
if (!taskHttpResponseMessage.Result.IsSuccessStatusCode)
results = null;
else
{
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
taskString.Wait();
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
if (nginxFileSystems is null)
results = null;
else
{
results = [];
NginxFileSystem nginxFileSystem;
ReadOnlyCollection<NginxFileSystem>? directory;
for (int i = 0; i < nginxFileSystems.Length; i++)
{
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
if (nginxFileSystem.Type == "file")
results.Add(nginxFileSystem);
else
{
directory = GetRecursiveCollection(host, $"{page}/{nginxFileSystem.Name}");
if (directory is null)
continue;
results.AddRange(directory);
}
}
}
}
return results?.AsReadOnly();
}
private static ReadOnlyCollection<NginxFileSystem>? GetCollection(string format, TimeZoneInfo timeZoneInfo, Uri uri)
{
List<NginxFileSystem>? results;
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(uri);
taskHttpResponseMessage.Wait();
if (!taskHttpResponseMessage.Result.IsSuccessStatusCode)
results = null;
else
{
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
taskString.Wait();
if (taskString.Result.StartsWith('<'))
results = null;
else
{
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
if (nginxFileSystems is null)
results = null;
else
{
results = [];
NginxFileSystem nginxFileSystem;
for (int i = 0; i < nginxFileSystems.Length; i++)
{
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
results.Add(nginxFileSystem);
}
}
}
}
return results?.AsReadOnly();
}
private static Record? CompareFile(string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem)
{
Record? result;
if (nginxFileSystem.LastModified is null || nginxFileSystem.Length is null)
result = null;
else
{
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}/{nginxFileSystem.Name}");
FileInfo fileInfo = new($"{compareDirectory}\\{string.Join('\\', directoryNames)}\\{nginxFileSystem.Name}");
if (!fileInfo.Exists || fileInfo.Length != nginxFileSystem.Length.Value)
result = new(uri, fileInfo.FullName, nginxFileSystem.LastModified.Value);
else
{
double totalSeconds = new TimeSpan(fileInfo.LastWriteTime.Ticks - nginxFileSystem.LastModified.Value.Ticks).TotalSeconds;
if (totalSeconds is < 2 and > -2)
result = null;
else
result = new(uri, fileInfo.FullName, nginxFileSystem.LastModified.Value);
}
}
return result;
}
private static ReadOnlyCollection<Record> CompareDirectory(string format, TimeZoneInfo timeZoneInfo, string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem)
{
ReadOnlyCollection<Record> results;
List<string> collection = directoryNames.ToList();
collection.Add(nginxFileSystem.Name);
results = GetRecord(format, timeZoneInfo, host, collection.AsReadOnly(), compareDirectory);
return results;
}
private static ReadOnlyCollection<Record> GetRecord(string format, TimeZoneInfo timeZoneInfo, string host, ReadOnlyCollection<string> directoryNames, string compareDirectory)
{
List<Record> results = [];
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}");
ReadOnlyCollection<NginxFileSystem>? nginxFileSystems = GetCollection(format, timeZoneInfo, uri);
if (nginxFileSystems is not null)
{
NginxFileSystem nginxFileSystem;
ReadOnlyCollection<Record> records;
string checkDirectory = $"{compareDirectory}\\{string.Join('\\', directoryNames)}";
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
for (int i = 0; i < nginxFileSystems.Count; i++)
{
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
if (nginxFileSystem.Type == "file")
{
Record? record = CompareFile(host, directoryNames, compareDirectory, nginxFileSystem);
if (record is not null)
results.Add(record);
}
else
{
records = CompareDirectory(format, timeZoneInfo, host, directoryNames, compareDirectory, nginxFileSystem);
foreach (Record record in records)
results.Add(record);
}
}
}
return results.AsReadOnly();
}
private static void Download(Record record)
{
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(record.URI);
taskHttpResponseMessage.Wait();
if (taskHttpResponseMessage.Result.IsSuccessStatusCode)
{
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
taskString.Wait();
File.WriteAllText(record.Path, taskString.Result);
File.SetLastWriteTime(record.Path, record.LastModified);
}
}
internal static void Compare(ILogger<Worker> logger, List<string> args)
{
string host = args[2]; string host = args[2];
string rootDirectoryName = args[3]; string rootDirectoryName = args[3];
string format = NginxFileSystem.GetFormat(); string format = NginxFileSystem.GetFormat();
@ -178,8 +26,7 @@ internal static partial class Helper20241224
#if ShellProgressBar #if ShellProgressBar
ProgressBar progressBar = new(records.Count, "Downloading", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }); ProgressBar progressBar = new(records.Count, "Downloading", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
#endif #endif
foreach (Record record in records) foreach (Record record in records) {
{
#if ShellProgressBar #if ShellProgressBar
progressBar.Tick(); progressBar.Tick();
#endif #endif
@ -188,13 +35,146 @@ internal static partial class Helper20241224
#if ShellProgressBar #if ShellProgressBar
progressBar.Dispose(); progressBar.Dispose();
#endif #endif
if (Debugger.IsAttached) if (Debugger.IsAttached) {
{
ReadOnlyCollection<NginxFileSystem>? recursiveCollection = GetRecursiveCollection(host, rootDirectoryName); ReadOnlyCollection<NginxFileSystem>? recursiveCollection = GetRecursiveCollection(host, rootDirectoryName);
string? json = recursiveCollection is null ? null : JsonSerializer.Serialize(recursiveCollection.ToArray(), NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray); string? json = recursiveCollection is null ? null : JsonSerializer.Serialize(recursiveCollection.ToArray(), NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
if (!string.IsNullOrEmpty(json)) if (!string.IsNullOrEmpty(json)) {
File.WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", ".json"), json); File.WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", ".json"), json);
}
} }
} }
private static ReadOnlyCollection<Record> GetRecord(string format, TimeZoneInfo timeZoneInfo, string host, ReadOnlyCollection<string> directoryNames, string compareDirectory) {
List<Record> results = [];
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}");
ReadOnlyCollection<NginxFileSystem>? nginxFileSystems = GetCollection(format, timeZoneInfo, uri);
if (nginxFileSystems is not null) {
NginxFileSystem nginxFileSystem;
ReadOnlyCollection<Record> records;
string checkDirectory = $"{compareDirectory}\\{string.Join('\\', directoryNames)}";
if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory);
}
for (int i = 0; i < nginxFileSystems.Count; i++) {
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
if (nginxFileSystem.Type == "file") {
Record? record = CompareFile(host, directoryNames, compareDirectory, nginxFileSystem);
if (record is not null) {
results.Add(record);
}
} else {
records = CompareDirectory(format, timeZoneInfo, host, directoryNames, compareDirectory, nginxFileSystem);
foreach (Record record in records) {
results.Add(record);
}
}
}
}
return results.AsReadOnly();
}
private static ReadOnlyCollection<NginxFileSystem>? GetCollection(string format, TimeZoneInfo timeZoneInfo, Uri uri) {
List<NginxFileSystem>? results;
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(uri);
taskHttpResponseMessage.Wait();
if (!taskHttpResponseMessage.Result.IsSuccessStatusCode) {
results = null;
} else {
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
taskString.Wait();
if (taskString.Result.StartsWith('<')) {
results = null;
} else {
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
if (nginxFileSystems is null) {
results = null;
} else {
results = [];
NginxFileSystem nginxFileSystem;
for (int i = 0; i < nginxFileSystems.Length; i++) {
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
results.Add(nginxFileSystem);
}
}
}
}
return results?.AsReadOnly();
}
private static Record? CompareFile(string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem) {
Record? result;
if (nginxFileSystem.LastModified is null || nginxFileSystem.Length is null) {
result = null;
} else {
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}/{nginxFileSystem.Name}");
FileInfo fileInfo = new($"{compareDirectory}\\{string.Join('\\', directoryNames)}\\{nginxFileSystem.Name}");
if (!fileInfo.Exists || fileInfo.Length != nginxFileSystem.Length.Value) {
result = new(uri, fileInfo.FullName, nginxFileSystem.LastModified.Value);
} else {
double totalSeconds = new TimeSpan(fileInfo.LastWriteTime.Ticks - nginxFileSystem.LastModified.Value.Ticks).TotalSeconds;
if (totalSeconds is < 2 and > -2) {
result = null;
} else {
result = new(uri, fileInfo.FullName, nginxFileSystem.LastModified.Value);
}
}
}
return result;
}
private static ReadOnlyCollection<Record> CompareDirectory(string format, TimeZoneInfo timeZoneInfo, string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem) {
ReadOnlyCollection<Record> results;
List<string> collection = directoryNames.ToList();
collection.Add(nginxFileSystem.Name);
results = GetRecord(format, timeZoneInfo, host, collection.AsReadOnly(), compareDirectory);
return results;
}
private static void Download(Record record) {
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(record.URI);
taskHttpResponseMessage.Wait();
if (taskHttpResponseMessage.Result.IsSuccessStatusCode) {
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
taskString.Wait();
File.WriteAllText(record.Path, taskString.Result);
File.SetLastWriteTime(record.Path, record.LastModified);
}
}
private static ReadOnlyCollection<NginxFileSystem>? GetRecursiveCollection(string host, string page) {
List<NginxFileSystem>? results;
Uri uri = new($"https://{host}/{page}");
string format = NginxFileSystem.GetFormat();
TimeZoneInfo timeZoneInfo = TimeZoneInfo.Local;
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(uri);
taskHttpResponseMessage.Wait();
if (!taskHttpResponseMessage.Result.IsSuccessStatusCode) {
results = null;
} else {
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
taskString.Wait();
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
if (nginxFileSystems is null) {
results = null;
} else {
results = [];
NginxFileSystem nginxFileSystem;
ReadOnlyCollection<NginxFileSystem>? directory;
for (int i = 0; i < nginxFileSystems.Length; i++) {
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
if (nginxFileSystem.Type == "file") {
results.Add(nginxFileSystem);
} else {
directory = GetRecursiveCollection(host, $"{page}/{nginxFileSystem.Name}");
if (directory is null) {
continue;
}
results.AddRange(directory);
}
}
}
}
return results?.AsReadOnly();
}
} }

296
ADO2025/PI4/.editorconfig Normal file
View File

@ -0,0 +1,296 @@
[*.md]
end_of_line = crlf
file_header_template = unset
indent_size = 2
indent_style = space
insert_final_newline = false
root = true
tab_width = 2
[*.csproj]
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
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true
csharp_prefer_braces = true
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
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = false
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
csharp_style_allow_embedded_statements_on_same_line_experimental = true
csharp_style_conditional_delegate_call = true
csharp_style_deconstructed_variable_declaration = false
csharp_style_expression_bodied_accessors = when_on_single_line:warning
csharp_style_expression_bodied_constructors = when_on_single_line:warning
csharp_style_expression_bodied_indexers = when_on_single_line:warning
csharp_style_expression_bodied_lambdas = when_on_single_line:warning
csharp_style_expression_bodied_local_functions = when_on_single_line:warning
csharp_style_expression_bodied_methods = when_on_single_line:warning
csharp_style_expression_bodied_operators = when_on_single_line:warning
csharp_style_expression_bodied_properties = when_on_single_line:warning
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
csharp_style_inlined_variable_declaration = false
csharp_style_namespace_declarations = file_scoped:warning
csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_not_pattern = true:warning
csharp_style_prefer_null_check_over_type_check = true
csharp_style_prefer_pattern_matching = true:warning
csharp_style_prefer_range_operator = true:warning
csharp_style_prefer_switch_expression = true:warning
csharp_style_throw_expression = true
csharp_style_unused_value_assignment_preference = discard_variable:warning
csharp_style_unused_value_expression_statement_preference = discard_variable:warning
csharp_style_var_elsewhere = false:warning
csharp_style_var_for_built_in_types = false:warning
csharp_style_var_when_type_is_apparent = false:warning
csharp_using_directive_placement = outside_namespace
dotnet_analyzer_diagnostic.category-Design.severity = error
dotnet_analyzer_diagnostic.category-Documentation.severity = error
dotnet_analyzer_diagnostic.category-Globalization.severity = none
dotnet_analyzer_diagnostic.category-Interoperability.severity = error
dotnet_analyzer_diagnostic.category-Maintainability.severity = error
dotnet_analyzer_diagnostic.category-Naming.severity = none
dotnet_analyzer_diagnostic.category-Performance.severity = none
dotnet_analyzer_diagnostic.category-Reliability.severity = error
dotnet_analyzer_diagnostic.category-Security.severity = error
dotnet_analyzer_diagnostic.category-SingleFile.severity = error
dotnet_analyzer_diagnostic.category-Style.severity = error
dotnet_analyzer_diagnostic.category-Usage.severity = error
dotnet_code_quality_unused_parameters = all
dotnet_code_quality_unused_parameters = non_public
dotnet_code_quality.CAXXXX.api_surface = private, internal
dotnet_diagnostic.CA1001.severity = error # CA1001: Types that own disposable fields should be disposable
dotnet_diagnostic.CA1051.severity = error # CA1051: Do not declare visible instance fields
dotnet_diagnostic.CA1511.severity = warning # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1513.severity = warning # Use 'ObjectDisposedException.ThrowIf' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1825.severity = warning # CA1825: 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.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'
dotnet_diagnostic.CA1869.severity = none # CA1869: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead.
dotnet_diagnostic.CA2201.severity = none # CA2201: Exception type System.NullReferenceException is reserved by the runtime
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.IDE0010.severity = none # Add missing cases to switch statement (IDE0010)
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.IDE0048.severity = none # Parentheses preferences (IDE0047 and IDE0048)
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
dotnet_diagnostic.IDE0051.severity = error # Private member '' is unused [, ]
dotnet_diagnostic.IDE0058.severity = warning # IDE0058: Expression value is never used
dotnet_diagnostic.IDE0060.severity = error # IDE0060: Remove unused parameter
dotnet_diagnostic.IDE0074.severity = warning # IDE0074: Use compound assignment
dotnet_diagnostic.IDE0130.severity = none # Namespace does not match folder structure (IDE0130)
dotnet_diagnostic.IDE0270.severity = warning # IDE0270: Null check can be simplified
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
dotnet_naming_rule.class_should_be_pascal_case.severity = warning
dotnet_naming_rule.class_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.class_should_be_pascal_case.symbols = class
dotnet_naming_rule.delegate_should_be_pascal_case.severity = warning
dotnet_naming_rule.delegate_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.delegate_should_be_pascal_case.symbols = delegate
dotnet_naming_rule.enum_should_be_pascal_case.severity = warning
dotnet_naming_rule.enum_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.enum_should_be_pascal_case.symbols = enum
dotnet_naming_rule.event_should_be_pascal_case.severity = warning
dotnet_naming_rule.event_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.event_should_be_pascal_case.symbols = event
dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.method_should_be_pascal_case.severity = warning
dotnet_naming_rule.method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.method_should_be_pascal_case.symbols = method
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.private_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.private_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.private_method_should_be_pascal_case.symbols = private_method
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.symbols = private_or_internal_field
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.symbols = private_or_internal_static_field
dotnet_naming_rule.property_should_be_pascal_case.severity = warning
dotnet_naming_rule.property_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.property_should_be_pascal_case.symbols = property
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.severity = warning
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.style = private_of_internal_field
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.symbols = public_or_protected_field
dotnet_naming_rule.static_field_should_be_pascal_case.severity = warning
dotnet_naming_rule.static_field_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_field_should_be_pascal_case.symbols = static_field
dotnet_naming_rule.static_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.static_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_method_should_be_pascal_case.symbols = static_method
dotnet_naming_rule.struct_should_be_pascal_case.severity = warning
dotnet_naming_rule.struct_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.struct_should_be_pascal_case.symbols = struct
dotnet_naming_rule.types_should_be_pascal_case.severity = warning
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.private_of_internal_field.capitalization = pascal_case
dotnet_naming_style.private_of_internal_field.required_prefix = _
dotnet_naming_style.private_of_internal_field.required_suffix =
dotnet_naming_style.private_of_internal_field.word_separator =
dotnet_naming_symbols.abstract_method.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.abstract_method.applicable_kinds = method
dotnet_naming_symbols.abstract_method.required_modifiers = abstract
dotnet_naming_symbols.class.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.class.applicable_kinds = class
dotnet_naming_symbols.class.required_modifiers =
dotnet_naming_symbols.delegate.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.delegate.applicable_kinds = delegate
dotnet_naming_symbols.delegate.required_modifiers =
dotnet_naming_symbols.enum.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.enum.applicable_kinds = enum
dotnet_naming_symbols.enum.required_modifiers =
dotnet_naming_symbols.event.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.event.applicable_kinds = event
dotnet_naming_symbols.event.required_modifiers =
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.method.applicable_accessibilities = public
dotnet_naming_symbols.method.applicable_kinds = method
dotnet_naming_symbols.method.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_symbols.private_method.applicable_accessibilities = private
dotnet_naming_symbols.private_method.applicable_kinds = method
dotnet_naming_symbols.private_method.required_modifiers =
dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected
dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_field.required_modifiers =
dotnet_naming_symbols.private_or_internal_static_field.applicable_accessibilities = internal, private, private_protected
dotnet_naming_symbols.private_or_internal_static_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_static_field.required_modifiers = static
dotnet_naming_symbols.property.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.property.applicable_kinds = property
dotnet_naming_symbols.property.required_modifiers =
dotnet_naming_symbols.public_or_protected_field.applicable_accessibilities = public, protected
dotnet_naming_symbols.public_or_protected_field.applicable_kinds = field
dotnet_naming_symbols.public_or_protected_field.required_modifiers =
dotnet_naming_symbols.static_field.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.static_field.applicable_kinds = field
dotnet_naming_symbols.static_field.required_modifiers = static
dotnet_naming_symbols.static_method.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.static_method.applicable_kinds = method
dotnet_naming_symbols.static_method.required_modifiers = static
dotnet_naming_symbols.struct.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.struct.applicable_kinds = struct
dotnet_naming_symbols.struct.required_modifiers =
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.required_modifiers =
dotnet_remove_unnecessary_suppression_exclusions = 0
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
dotnet_style_allow_multiple_blank_lines_experimental = false:warning
dotnet_style_allow_statement_immediately_after_block_experimental = true
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true:warning
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_namespace_match_folder = true
dotnet_style_null_propagation = true:warning
dotnet_style_object_initializer = true:warning
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
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:warning
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_compound_assignment = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = false
dotnet_style_prefer_conditional_expression_over_return = false
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
dotnet_style_prefer_simplified_boolean_expressions = true:warning
dotnet_style_prefer_simplified_interpolation = true
dotnet_style_qualification_for_event = false:error
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false:error
dotnet_style_qualification_for_property = false:error
dotnet_style_readonly_field = true:warning
dotnet_style_require_accessibility_modifiers = for_non_interface_members
end_of_line = crlf
file_header_template = unset
indent_size = 4
indent_style = space
insert_final_newline = false
root = true
tab_width = 4
# https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1822
# https://github.com/dotnet/aspnetcore/blob/main/.editorconfig
# https://github.com/dotnet/project-system/blob/main/.editorconfig

View File

@ -3,52 +3,9 @@ using System.Collections.ObjectModel;
namespace File_Folder_Helper.ADO2025.PI4; namespace File_Folder_Helper.ADO2025.PI4;
internal static partial class Helper20250101 internal static partial class Helper20250101 {
{
private static ReadOnlyDictionary<string, List<FileInfo>> GetKeyValuePairs(string directory, string searchPattern, string split) internal static void MoveToDelete(ILogger<Worker> logger, List<string> args) {
{
string key;
List<FileInfo>? collection;
Dictionary<string, List<FileInfo>> results = [];
string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
FileInfo[] fileInfoCollection = files.Select(l => new FileInfo(l)).ToArray();
foreach (FileInfo fileInfo in fileInfoCollection.OrderBy(l => l.LastWriteTime))
{
key = fileInfo.Name.Split(split)[0];
if (!results.TryGetValue(key, out collection))
{
results.Add(key, []);
if (!results.TryGetValue(key, out collection))
throw new Exception();
}
collection.Add(fileInfo);
}
return results.AsReadOnly();
}
private static void MoveToDelete(ILogger<Worker> logger, string appendage, ReadOnlyDictionary<string, List<FileInfo>> keyValuePairs)
{
string checkFile;
FileInfo fileInfo;
foreach (KeyValuePair<string, List<FileInfo>> keyValuePair in keyValuePairs)
{
if (keyValuePair.Value.Count < 3)
continue;
for (int i = 1; i < keyValuePair.Value.Count - 1; i++)
{
fileInfo = keyValuePair.Value[i];
checkFile = Path.Combine($"{fileInfo.Directory}{appendage}", fileInfo.Name);
if (File.Exists(checkFile))
continue;
logger.LogInformation("Moving <{fileInfo.FullName}> to <{checkFile}>", fileInfo.FullName, checkFile);
File.Move(fileInfo.FullName, checkFile);
}
}
}
internal static void MoveToDelete(ILogger<Worker> logger, List<string> args)
{
string split = args[3]; string split = args[3];
string appendage = args[4]; string appendage = args[4];
string searchPattern = args[2]; string searchPattern = args[2];
@ -58,4 +15,42 @@ internal static partial class Helper20250101
MoveToDelete(logger, appendage, keyValuePairs); MoveToDelete(logger, appendage, keyValuePairs);
} }
private static ReadOnlyDictionary<string, List<FileInfo>> GetKeyValuePairs(string directory, string searchPattern, string split) {
string key;
List<FileInfo>? collection;
Dictionary<string, List<FileInfo>> results = [];
string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
FileInfo[] fileInfoCollection = files.Select(l => new FileInfo(l)).ToArray();
foreach (FileInfo fileInfo in fileInfoCollection.OrderBy(l => l.LastWriteTime)) {
key = fileInfo.Name.Split(split)[0];
if (!results.TryGetValue(key, out collection)) {
results.Add(key, []);
if (!results.TryGetValue(key, out collection)) {
throw new Exception();
}
}
collection.Add(fileInfo);
}
return results.AsReadOnly();
}
private static void MoveToDelete(ILogger<Worker> logger, string appendage, ReadOnlyDictionary<string, List<FileInfo>> keyValuePairs) {
string checkFile;
FileInfo fileInfo;
foreach (KeyValuePair<string, List<FileInfo>> keyValuePair in keyValuePairs) {
if (keyValuePair.Value.Count < 3) {
continue;
}
for (int i = 1; i < keyValuePair.Value.Count - 1; i++) {
fileInfo = keyValuePair.Value[i];
checkFile = Path.Combine($"{fileInfo.Directory}{appendage}", fileInfo.Name);
if (File.Exists(checkFile)) {
continue;
}
logger.LogInformation("Moving <{fileInfo.FullName}> to <{checkFile}>", fileInfo.FullName, checkFile);
File.Move(fileInfo.FullName, checkFile);
}
}
}
} }

View File

@ -2,53 +2,50 @@ using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI4; namespace File_Folder_Helper.ADO2025.PI4;
internal static partial class Helper20250114 internal static partial class Helper20250114 {
{
private static void Rename(string[] directories, string dateFormat) internal static void Rename(ILogger<Worker> logger, List<string> args) {
{ string dateFormat = args[3];
string[] searchPatterns = args[2].Split('~');
string sourceDirectory = Path.GetFullPath(args[0]);
foreach (string searchPattern in searchPatterns) {
Rename(logger, sourceDirectory, searchPattern, dateFormat);
}
}
private static void Rename(string[] directories, string dateFormat) {
string[] files; string[] files;
DateTime dateTime; DateTime dateTime;
FileInfo fileInfo; FileInfo fileInfo;
string checkDirectory; string checkDirectory;
foreach (string directory in directories) foreach (string directory in directories) {
{
dateTime = DateTime.MinValue; dateTime = DateTime.MinValue;
files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories); files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
foreach (string file in files) foreach (string file in files) {
{
fileInfo = new(file); fileInfo = new(file);
if (dateTime > fileInfo.LastWriteTime) if (dateTime > fileInfo.LastWriteTime) {
continue; continue;
}
dateTime = fileInfo.LastWriteTime; dateTime = fileInfo.LastWriteTime;
} }
if (dateTime == DateTime.MinValue) if (dateTime == DateTime.MinValue) {
continue; continue;
}
checkDirectory = Path.Combine(Path.GetDirectoryName(directory) ?? throw new Exception(), dateTime.ToString(dateFormat)); checkDirectory = Path.Combine(Path.GetDirectoryName(directory) ?? throw new Exception(), dateTime.ToString(dateFormat));
if (checkDirectory != directory) if (checkDirectory != directory) {
{ if (Directory.Exists(checkDirectory)) {
if (Directory.Exists(checkDirectory))
continue; continue;
}
Directory.Move(directory, checkDirectory); Directory.Move(directory, checkDirectory);
} }
Directory.SetLastWriteTime(checkDirectory, dateTime); Directory.SetLastWriteTime(checkDirectory, dateTime);
} }
} }
private static void Rename(ILogger<Worker> logger, string sourceDirectory, string searchPattern, string dateFormat) private static void Rename(ILogger<Worker> logger, string sourceDirectory, string searchPattern, string dateFormat) {
{
string[] directories = Directory.GetDirectories(sourceDirectory, searchPattern); string[] directories = Directory.GetDirectories(sourceDirectory, searchPattern);
logger.LogInformation("directories: {directories}", directories.Length); logger.LogInformation("directories: {directories}", directories.Length);
Rename(directories, dateFormat); Rename(directories, dateFormat);
} }
internal static void Rename(ILogger<Worker> logger, List<string> args)
{
string dateFormat = args[3];
string[] searchPatterns = args[2].Split('~');
string sourceDirectory = Path.GetFullPath(args[0]);
foreach (string searchPattern in searchPatterns)
Rename(logger, sourceDirectory, searchPattern, dateFormat);
}
} }

View File

@ -4,76 +4,9 @@ using System.Globalization;
namespace File_Folder_Helper.ADO2025.PI4; namespace File_Folder_Helper.ADO2025.PI4;
internal static partial class Helper20250126 internal static partial class Helper20250126 {
{
private static void Move(string file, string fileName, string checkFile, List<string> foundLines, ReadOnlyCollection<DateTime> dateTimes) internal static void Move(ILogger<Worker> logger, List<string> args) {
{
string checkDirectory = Path.Combine(Path.GetDirectoryName(file) ?? throw new Exception(), dateTimes[0].ToString("yyyy-MM"));
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
string fileNameB = Path.GetFileName(checkFile);
string checkFileB = Path.Combine(checkDirectory, fileName);
string checkFileC = Path.Combine(checkDirectory, fileNameB);
string contents = string.Join(Environment.NewLine, foundLines);
string checkFileD = Path.Combine(checkDirectory, $"{fileName}.txt");
if (!File.Exists(checkFileB))
File.Move(file, checkFileB);
if (!File.Exists(checkFileC))
File.Move(checkFile, checkFileC);
File.WriteAllText(checkFileD, contents);
}
private static void Move(ILogger<Worker> logger, string dateFormat, string file, string checkFile, string fileName, ReadOnlyCollection<string> statementPeriodSegments, List<string> foundLines)
{
DateTime dateTime;
List<DateTime> dateTimes = [];
foreach (string check in statementPeriodSegments)
{
if (!DateTime.TryParseExact(check, dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
continue;
dateTimes.Add(dateTime);
}
if (dateTimes.Count != 2)
logger.LogInformation($"Only {dateTimes.Count} date(s) were found in <{fileName}>!");
else
Move(file, fileName, checkFile, foundLines, dateTimes.AsReadOnly());
}
private static void Move(ILogger<Worker> logger, string file, string checkFile, string dateFormat, string statementPeriod, string search)
{
List<string> foundLines = [];
bool statementPeriodFound = false;
string[]? statementPeriodSegments = null;
string fileName = Path.GetFileName(file);
string[] lines = File.ReadAllLines(file);
foreach (string line in lines)
{
if (statementPeriodSegments is not null)
{
if (line.Contains(search))
foundLines.Add(line);
}
else
{
if (statementPeriodFound)
{
statementPeriodSegments = line.Split(' ');
continue;
}
if (!line.Contains(statementPeriod))
continue;
statementPeriodFound = true;
}
}
if (statementPeriodSegments is null || statementPeriodSegments.Length < 4)
logger.LogInformation($"{nameof(statementPeriod)}: {statementPeriod}; wasn't found in <{fileName}>!");
else
Move(logger, dateFormat, file, checkFile, fileName, statementPeriodSegments.AsReadOnly(), foundLines);
}
internal static void Move(ILogger<Worker> logger, List<string> args)
{
string checkFile; string checkFile;
string search = args[5]; string search = args[5];
string dateFormat = args[3]; string dateFormat = args[3];
@ -81,13 +14,77 @@ internal static partial class Helper20250126
string statementPeriod = args[4]; string statementPeriod = args[4];
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPatterns, SearchOption.AllDirectories); string[] files = Directory.GetFiles(sourceDirectory, searchPatterns, SearchOption.AllDirectories);
foreach (string file in files) foreach (string file in files) {
{
checkFile = Path.ChangeExtension(file, ".pdf"); checkFile = Path.ChangeExtension(file, ".pdf");
if (!File.Exists(checkFile)) if (!File.Exists(checkFile)) {
continue; continue;
}
Move(logger, file, checkFile, dateFormat, statementPeriod, search); Move(logger, file, checkFile, dateFormat, statementPeriod, search);
} }
} }
private static void Move(ILogger<Worker> logger, string file, string checkFile, string dateFormat, string statementPeriod, string search) {
List<string> foundLines = [];
bool statementPeriodFound = false;
string[]? statementPeriodSegments = null;
string fileName = Path.GetFileName(file);
string[] lines = File.ReadAllLines(file);
foreach (string line in lines) {
if (statementPeriodSegments is not null) {
if (line.Contains(search)) {
foundLines.Add(line);
}
} else {
if (statementPeriodFound) {
statementPeriodSegments = line.Split(' ');
continue;
}
if (!line.Contains(statementPeriod)) {
continue;
}
statementPeriodFound = true;
}
}
if (statementPeriodSegments is null || statementPeriodSegments.Length < 4) {
logger.LogInformation($"{nameof(statementPeriod)}: {statementPeriod}; wasn't found in <{fileName}>!");
} else {
Move(logger, dateFormat, file, checkFile, fileName, statementPeriodSegments.AsReadOnly(), foundLines);
}
}
private static void Move(ILogger<Worker> logger, string dateFormat, string file, string checkFile, string fileName, ReadOnlyCollection<string> statementPeriodSegments, List<string> foundLines) {
DateTime dateTime;
List<DateTime> dateTimes = [];
foreach (string check in statementPeriodSegments) {
if (!DateTime.TryParseExact(check, dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime)) {
continue;
}
dateTimes.Add(dateTime);
}
if (dateTimes.Count != 2) {
logger.LogInformation($"Only {dateTimes.Count} date(s) were found in <{fileName}>!");
} else {
Move(file, fileName, checkFile, foundLines, dateTimes.AsReadOnly());
}
}
private static void Move(string file, string fileName, string checkFile, List<string> foundLines, ReadOnlyCollection<DateTime> dateTimes) {
string checkDirectory = Path.Combine(Path.GetDirectoryName(file) ?? throw new Exception(), dateTimes[0].ToString("yyyy-MM"));
if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory);
}
string fileNameB = Path.GetFileName(checkFile);
string checkFileB = Path.Combine(checkDirectory, fileName);
string checkFileC = Path.Combine(checkDirectory, fileNameB);
string contents = string.Join(Environment.NewLine, foundLines);
string checkFileD = Path.Combine(checkDirectory, $"{fileName}.txt");
if (!File.Exists(checkFileB)) {
File.Move(file, checkFileB);
}
if (!File.Exists(checkFileC)) {
File.Move(checkFile, checkFileC);
}
File.WriteAllText(checkFileD, contents);
}
} }

View File

@ -8,8 +8,7 @@ using System.Text.RegularExpressions;
namespace File_Folder_Helper.ADO2025.PI4; namespace File_Folder_Helper.ADO2025.PI4;
internal static partial class Helper20250204 internal static partial class Helper20250204 {
{
[GeneratedRegex("([A-Z]+(.))")] [GeneratedRegex("([A-Z]+(.))")]
private static partial Regex UpperCase(); private static partial Regex UpperCase();
@ -17,41 +16,6 @@ internal static partial class Helper20250204
[GeneratedRegex("[\\s!?.,@:;|\\\\/\"'`£$%\\^&*{}[\\]()<>~#+\\-=_¬]+")] [GeneratedRegex("[\\s!?.,@:;|\\\\/\"'`£$%\\^&*{}[\\]()<>~#+\\-=_¬]+")]
private static partial Regex InvalidCharacter(); private static partial Regex InvalidCharacter();
private record H1ParamCaseAndState(string H1, string ParamCase, string State)
{
private static string GetParamCase(string value)
{
string result;
StringBuilder stringBuilder = new(value);
Match[] matches = UpperCase().Matches(value).ToArray();
for (int i = matches.Length - 1; i > -1; i--)
_ = stringBuilder.Insert(matches[i].Index, '-');
string[] segments = InvalidCharacter().Split(stringBuilder.ToString().ToLower());
result = string.Join('-', segments).Trim('-');
return result;
}
private static string GetState(string value) =>
value switch
{
"New" => "ToDo",
"Active" => "In Progress",
"Closed" => "Done",
_ => "Backlog",
};
internal static H1ParamCaseAndState Get(WorkItem workItem)
{
H1ParamCaseAndState result;
string paramCase = GetParamCase(workItem.Title);
string state = GetState(workItem.State);
result = new(workItem.Title, paramCase, state);
return result;
}
}
private record Attribute([property: JsonPropertyName("isLocked")] bool IsLocked, private record Attribute([property: JsonPropertyName("isLocked")] bool IsLocked,
[property: JsonPropertyName("name")] string Name, [property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("parameterTitle")] string? ParameterTitle, [property: JsonPropertyName("parameterTitle")] string? ParameterTitle,
@ -91,8 +55,7 @@ internal static partial class Helper20250204
string Title, string Title,
string? Violation, string? Violation,
long? WeightedShortestJobFirst, long? WeightedShortestJobFirst,
string WorkItemType) string WorkItemType) {
{
public override string ToString() => $"{Id} - {WorkItemType} - {Title}"; public override string ToString() => $"{Id} - {WorkItemType} - {Title}";
@ -100,14 +63,12 @@ internal static partial class Helper20250204
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WorkItem))] [JsonSerializable(typeof(WorkItem))]
private partial class WorkItemSourceGenerationContext : JsonSerializerContext private partial class WorkItemSourceGenerationContext : JsonSerializerContext {
{
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WorkItem[]))] [JsonSerializable(typeof(WorkItem[]))]
private partial class WorkItemCollectionSourceGenerationContext : JsonSerializerContext private partial class WorkItemCollectionSourceGenerationContext : JsonSerializerContext {
{
} }
private static string[] GetTaskLines(string directory, string rootDirectory) => private static string[] GetTaskLines(string directory, string rootDirectory) =>
@ -156,18 +117,6 @@ internal static partial class Helper20250204
private static string GetTaskText(string directory, string rootDirectory) => private static string GetTaskText(string directory, string rootDirectory) =>
string.Join(Environment.NewLine, GetTaskLines(directory, rootDirectory)); string.Join(Environment.NewLine, GetTaskLines(directory, rootDirectory));
private static void WriteTaskFile(string sourceDirectory, string rootDirectory)
{
string tasksFile = Path.Combine(sourceDirectory, ".vscode", "tasks.json");
string oldText = File.ReadAllText(tasksFile);
string jsonSafeDirectory = sourceDirectory.Replace('\\', '/');
if (!oldText.Contains(jsonSafeDirectory))
{
string text = GetTaskText(jsonSafeDirectory, rootDirectory);
File.WriteAllText(tasksFile, text);
}
}
private static string GetFilter(ReadOnlyCollection<H1ParamCaseAndState> collection, string filter) => private static string GetFilter(ReadOnlyCollection<H1ParamCaseAndState> collection, string filter) =>
string.Join(Environment.NewLine, from l in collection where l.State == filter select $"- [{l.ParamCase}](tasks/{l.ParamCase}.md)"); string.Join(Environment.NewLine, from l in collection where l.State == filter select $"- [{l.ParamCase}](tasks/{l.ParamCase}.md)");
@ -202,13 +151,108 @@ internal static partial class Helper20250204
private static string GetIndexText(WorkItem workItem, H1ParamCaseAndState h1ParamCaseAndState, ReadOnlyCollection<H1ParamCaseAndState> collection) => private static string GetIndexText(WorkItem workItem, H1ParamCaseAndState h1ParamCaseAndState, ReadOnlyCollection<H1ParamCaseAndState> collection) =>
string.Join(Environment.NewLine, GetIndexLines(workItem, h1ParamCaseAndState, collection)); string.Join(Environment.NewLine, GetIndexLines(workItem, h1ParamCaseAndState, collection));
private static string GetIndexMarkdown(FileInfo fileInfo, ReadOnlyCollection<WorkItem> workItems) internal static void ExtractKanban(ILogger<Worker> logger, List<string> args) {
{ string searchPattern = "*.json";
string fullPath = Path.GetFullPath(args[0]);
string sourceDirectory = GetSourceDirectory(fullPath);
string rootDirectory = args.Count < 3 || args[2].Length < 16 ? "D:/5-Other-Small/Kanban-mestsa003/{}" : args[2];
WriteTaskFile(sourceDirectory, rootDirectory);
string sourceDirectoryName = Path.GetFileName(sourceDirectory);
DirectoryInfo directoryInfo = new(Path.Combine(sourceDirectory, ".kanbn"));
FileInfo? fileInfo = !directoryInfo.Exists ? null : new(Path.Combine(directoryInfo.FullName, $"{sourceDirectoryName}.json"));
if (directoryInfo.Exists && fileInfo is not null && fileInfo.Exists) {
ExtractKanban(searchPattern, rootDirectory, directoryInfo, fileInfo);
} else {
logger.LogWarning("<{directoryInfo}> doesn't exist", directoryInfo.FullName);
}
}
private static string GetSourceDirectory(string directory) {
string? result = null;
DirectoryInfo directoryInfo;
string? checkDirectory = directory;
string? pathRoot = Path.GetPathRoot(directory);
for (int i = 0; i < int.MaxValue; i++) {
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot) {
break;
}
directoryInfo = new(checkDirectory);
if (string.IsNullOrEmpty(directoryInfo.LinkTarget)) {
continue;
}
result = directory.Replace(checkDirectory, directoryInfo.LinkTarget);
break;
}
result ??= directory;
return result;
}
private static void WriteTaskFile(string sourceDirectory, string rootDirectory) {
string tasksFile = Path.Combine(sourceDirectory, ".vscode", "tasks.json");
string oldText = File.ReadAllText(tasksFile);
string jsonSafeDirectory = sourceDirectory.Replace('\\', '/');
if (!oldText.Contains(jsonSafeDirectory)) {
string text = GetTaskText(jsonSafeDirectory, rootDirectory);
File.WriteAllText(tasksFile, text);
}
}
private static void ExtractKanban(string searchPattern, string rootDirectory, DirectoryInfo kanbanDirectory, FileInfo fileInfo) {
string checkFile;
string weekOfYear;
string workItemDirectory;
string line = Environment.NewLine;
H1ParamCaseAndState h1ParamCaseAndState;
Calendar calendar = new CultureInfo("en-US").Calendar;
string tasksDirectory = Path.Combine(kanbanDirectory.FullName, "tasks");
if (!Directory.Exists(tasksDirectory)) {
_ = Directory.CreateDirectory(tasksDirectory);
}
string[] files = Directory.GetFiles(tasksDirectory, searchPattern, SearchOption.TopDirectoryOnly);
ReadOnlyCollection<WorkItem> workItems = GetWorkItems(files);
string markdown = GetIndexMarkdown(fileInfo, workItems);
string indexFile = Path.Combine(kanbanDirectory.FullName, "index.md");
string markdownOld = File.Exists(indexFile) ? File.ReadAllText(indexFile) : string.Empty;
if (markdown != markdownOld) {
File.WriteAllText(indexFile, markdown);
}
foreach (WorkItem workItem in workItems) {
h1ParamCaseAndState = H1ParamCaseAndState.Get(workItem);
checkFile = Path.Combine(tasksDirectory, $"{h1ParamCaseAndState.ParamCase}.md");
markdownOld = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty;
if (markdownOld.Contains("](")) {
continue;
}
weekOfYear = calendar.GetWeekOfYear(workItem.CreatedDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
workItemDirectory = Path.GetFullPath(Path.Combine(rootDirectory, $"{workItem.CreatedDate:yyyy}", $"{workItem.CreatedDate:yyyy}_Week_{weekOfYear}", $"{workItem.Id}"));
markdown = $"# {h1ParamCaseAndState.H1}{line}{line}## Id {workItem.Id}{line}{line}## Code Insiders{line}{line}- [code-insiders]({workItemDirectory}){line}";
if (markdown != markdownOld) {
File.WriteAllText(checkFile, markdown);
}
}
}
private static ReadOnlyCollection<WorkItem> GetWorkItems(string[] files) {
List<WorkItem> results = [];
string json;
WorkItem? workItem;
foreach (string file in files) {
json = File.ReadAllText(file);
workItem = JsonSerializer.Deserialize(json, WorkItemSourceGenerationContext.Default.WorkItem);
if (workItem is null) {
continue;
}
results.Add(workItem);
}
return results.AsReadOnly();
}
private static string GetIndexMarkdown(FileInfo fileInfo, ReadOnlyCollection<WorkItem> workItems) {
string result; string result;
H1ParamCaseAndState h1ParamCaseAndState; H1ParamCaseAndState h1ParamCaseAndState;
List<H1ParamCaseAndState> collection = []; List<H1ParamCaseAndState> collection = [];
foreach (WorkItem w in workItems) foreach (WorkItem w in workItems) {
{
h1ParamCaseAndState = H1ParamCaseAndState.Get(w); h1ParamCaseAndState = H1ParamCaseAndState.Get(w);
collection.Add(h1ParamCaseAndState); collection.Add(h1ParamCaseAndState);
} }
@ -222,90 +266,36 @@ internal static partial class Helper20250204
return result; return result;
} }
private static ReadOnlyCollection<WorkItem> GetWorkItems(string[] files) private record H1ParamCaseAndState(string H1, string ParamCase, string State) {
{
List<WorkItem> results = [];
string json;
WorkItem? workItem;
foreach (string file in files)
{
json = File.ReadAllText(file);
workItem = JsonSerializer.Deserialize(json, WorkItemSourceGenerationContext.Default.WorkItem);
if (workItem is null)
continue;
results.Add(workItem);
}
return results.AsReadOnly();
}
private static void ExtractKanban(string searchPattern, string rootDirectory, DirectoryInfo kanbanDirectory, FileInfo fileInfo) private static string GetParamCase(string value) {
{ string result;
string checkFile; StringBuilder stringBuilder = new(value);
string weekOfYear; Match[] matches = UpperCase().Matches(value).ToArray();
string workItemDirectory; for (int i = matches.Length - 1; i > -1; i--) {
string line = Environment.NewLine; _ = stringBuilder.Insert(matches[i].Index, '-');
H1ParamCaseAndState h1ParamCaseAndState; }
Calendar calendar = new CultureInfo("en-US").Calendar; string[] segments = InvalidCharacter().Split(stringBuilder.ToString().ToLower());
string tasksDirectory = Path.Combine(kanbanDirectory.FullName, "tasks"); result = string.Join('-', segments).Trim('-');
if (!Directory.Exists(tasksDirectory)) return result;
_ = Directory.CreateDirectory(tasksDirectory);
string[] files = Directory.GetFiles(tasksDirectory, searchPattern, SearchOption.TopDirectoryOnly);
ReadOnlyCollection<WorkItem> workItems = GetWorkItems(files);
string markdown = GetIndexMarkdown(fileInfo, workItems);
string indexFile = Path.Combine(kanbanDirectory.FullName, "index.md");
string markdownOld = File.Exists(indexFile) ? File.ReadAllText(indexFile) : string.Empty;
if (markdown != markdownOld)
File.WriteAllText(indexFile, markdown);
foreach (WorkItem workItem in workItems)
{
h1ParamCaseAndState = H1ParamCaseAndState.Get(workItem);
checkFile = Path.Combine(tasksDirectory, $"{h1ParamCaseAndState.ParamCase}.md");
markdownOld = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty;
if (markdownOld.Contains("]("))
continue;
weekOfYear = calendar.GetWeekOfYear(workItem.CreatedDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
workItemDirectory = Path.GetFullPath(Path.Combine(rootDirectory, $"{workItem.CreatedDate:yyyy}", $"{workItem.CreatedDate:yyyy}_Week_{weekOfYear}", $"{workItem.Id}"));
markdown = $"# {h1ParamCaseAndState.H1}{line}{line}## Id {workItem.Id}{line}{line}## Code Insiders{line}{line}- [code-insiders]({workItemDirectory}){line}";
if (markdown != markdownOld)
File.WriteAllText(checkFile, markdown);
} }
}
private static string GetSourceDirectory(string directory) private static string GetState(string value) =>
{ value switch {
string? result = null; "New" => "ToDo",
DirectoryInfo directoryInfo; "Active" => "In Progress",
string? checkDirectory = directory; "Closed" => "Done",
string? pathRoot = Path.GetPathRoot(directory); _ => "Backlog",
for (int i = 0; i < int.MaxValue; i++) };
{
checkDirectory = Path.GetDirectoryName(checkDirectory); internal static H1ParamCaseAndState Get(WorkItem workItem) {
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot) H1ParamCaseAndState result;
break; string paramCase = GetParamCase(workItem.Title);
directoryInfo = new(checkDirectory); string state = GetState(workItem.State);
if (string.IsNullOrEmpty(directoryInfo.LinkTarget)) result = new(workItem.Title, paramCase, state);
continue; return result;
result = directory.Replace(checkDirectory, directoryInfo.LinkTarget);
break;
} }
result ??= directory;
return result;
}
internal static void ExtractKanban(ILogger<Worker> logger, List<string> args)
{
string searchPattern = "*.json";
string fullPath = Path.GetFullPath(args[0]);
string sourceDirectory = GetSourceDirectory(fullPath);
string rootDirectory = args.Count < 3 || args[2].Length < 16 ? "D:/5-Other-Small/Kanban-mestsa003/{}" : args[2];
WriteTaskFile(sourceDirectory, rootDirectory);
string sourceDirectoryName = Path.GetFileName(sourceDirectory);
DirectoryInfo directoryInfo = new(Path.Combine(sourceDirectory, ".kanbn"));
FileInfo? fileInfo = !directoryInfo.Exists ? null : new(Path.Combine(directoryInfo.FullName, $"{sourceDirectoryName}.json"));
if (directoryInfo.Exists && fileInfo is not null && fileInfo.Exists)
ExtractKanban(searchPattern, rootDirectory, directoryInfo, fileInfo);
else
logger.LogWarning("<{directoryInfo}> doesn't exist", directoryInfo.FullName);
} }
} }

View File

@ -28,7 +28,7 @@ csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true csharp_new_line_between_query_expression_clauses = true
csharp_prefer_braces = false csharp_prefer_braces = true
csharp_prefer_qualified_reference = true:error csharp_prefer_qualified_reference = true:error
csharp_prefer_simple_default_expression = true:warning csharp_prefer_simple_default_expression = true:warning
csharp_prefer_simple_using_statement = true:warning csharp_prefer_simple_using_statement = true:warning
@ -59,9 +59,6 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false csharp_space_between_square_brackets = false
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
csharp_style_allow_embedded_statements_on_same_line_experimental = true csharp_style_allow_embedded_statements_on_same_line_experimental = true
csharp_style_conditional_delegate_call = true csharp_style_conditional_delegate_call = true
@ -113,7 +110,7 @@ dotnet_diagnostic.CA1051.severity = error # CA1051: Do not declare visible insta
dotnet_diagnostic.CA1511.severity = warning # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance dotnet_diagnostic.CA1511.severity = warning # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1513.severity = warning # Use 'ObjectDisposedException.ThrowIf' instead of explicitly throwing a new exception instance dotnet_diagnostic.CA1513.severity = warning # Use 'ObjectDisposedException.ThrowIf' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1825.severity = warning # CA1825: Avoid zero-length array allocations dotnet_diagnostic.CA1825.severity = warning # CA1825: Avoid zero-length array allocations
dotnet_diagnostic.CA1829.severity = error # CA1829: Use Length/Count property instead of Count() when available 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.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.CA1860.severity = error # CA1860: Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
dotnet_diagnostic.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase' dotnet_diagnostic.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'
@ -123,7 +120,7 @@ dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name 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.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.IDE0004.severity = warning # IDE0004: Cast is redundant.
dotnet_diagnostic.IDE0005.severity = error # Using directive is unnecessary dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary
dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement (IDE0010) dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement (IDE0010)
dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031) dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
@ -131,7 +128,7 @@ dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be remov
dotnet_diagnostic.IDE0048.severity = none # Parentheses preferences (IDE0047 and IDE0048) dotnet_diagnostic.IDE0048.severity = none # Parentheses preferences (IDE0047 and IDE0048)
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049) dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
dotnet_diagnostic.IDE0051.severity = error # Private member '' is unused [, ] dotnet_diagnostic.IDE0051.severity = error # Private member '' is unused [, ]
dotnet_diagnostic.IDE0058.severity = error # IDE0058: Expression value is never used dotnet_diagnostic.IDE0058.severity = warning # IDE0058: Expression value is never used
dotnet_diagnostic.IDE0060.severity = error # IDE0060: Remove unused parameter dotnet_diagnostic.IDE0060.severity = error # IDE0060: Remove unused parameter
dotnet_diagnostic.IDE0074.severity = warning # IDE0074: Use compound assignment dotnet_diagnostic.IDE0074.severity = warning # IDE0074: Use compound assignment
dotnet_diagnostic.IDE0130.severity = none # Namespace does not match folder structure (IDE0130) dotnet_diagnostic.IDE0130.severity = none # Namespace does not match folder structure (IDE0130)
@ -140,7 +137,6 @@ dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]cs
dotnet_diagnostic.IDE0300.severity = error # IDE0300: Collection initialization can be simplified dotnet_diagnostic.IDE0300.severity = error # IDE0300: Collection initialization can be simplified
dotnet_diagnostic.IDE0301.severity = error #IDE0301: 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_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified
dotnet_diagnostic.IDE2000.severity = error # IDE2000: Allow multiple blank lines
dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning 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.style = pascal_case
dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method
@ -256,8 +252,8 @@ dotnet_naming_symbols.types.applicable_accessibilities = public, internal, priva
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.required_modifiers = dotnet_naming_symbols.types.required_modifiers =
dotnet_remove_unnecessary_suppression_exclusions = 0 dotnet_remove_unnecessary_suppression_exclusions = 0
dotnet_separate_import_directive_groups = true dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = true dotnet_sort_system_directives_first = false
dotnet_style_allow_multiple_blank_lines_experimental = false:warning dotnet_style_allow_multiple_blank_lines_experimental = false:warning
dotnet_style_allow_statement_immediately_after_block_experimental = true dotnet_style_allow_statement_immediately_after_block_experimental = true
dotnet_style_coalesce_expression = true dotnet_style_coalesce_expression = true
@ -297,85 +293,4 @@ root = true
tab_width = 4 tab_width = 4
# https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1822 # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1822
# https://github.com/dotnet/aspnetcore/blob/main/.editorconfig # https://github.com/dotnet/aspnetcore/blob/main/.editorconfig
# https://github.com/dotnet/project-system/blob/main/.editorconfig # https://github.com/dotnet/project-system/blob/main/.editorconfig
# Question
csharp_prefer_simple_using_statement = false # Question
csharp_style_expression_bodied_constructors = when_on_single_line:none # Question
csharp_style_expression_bodied_properties = true # Question
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning # Question
csharp_style_pattern_matching_over_as_with_null_check = false # Question
csharp_style_prefer_pattern_matching = false # Question
csharp_style_prefer_range_operator = false # Question
csharp_style_prefer_switch_expression = false # Question
csharp_style_unused_value_assignment_preference = unused_local_variable # Question
csharp_style_unused_value_expression_statement_preference = false # Question
csharp_style_var_elsewhere = false:none # Question
csharp_style_var_for_built_in_types = false:none # Question
csharp_style_var_when_type_is_apparent = false:warning # Question
dotnet_diagnostic.CA1001.severity = none # Question - Types that own disposable fields should be disposable
dotnet_diagnostic.CA1051.severity = none # Question - Do not declare visible instance fields
dotnet_diagnostic.CA1416.severity = none # Question - This call site is reachable on all platforms.
dotnet_diagnostic.CA1510.severity = none # Question - Use
dotnet_diagnostic.CA1834.severity = none # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
dotnet_diagnostic.CA1860.severity = none # Question - Avoid using
dotnet_diagnostic.CA1862.severity = none # Question - Prefer using
dotnet_diagnostic.CA2208.severity = none # Question - Instantiate argument exceptions correctly
dotnet_diagnostic.CA2211.severity = none # Question - Non-constant fields should not be visible
dotnet_diagnostic.CA2249.severity = none # Question - Use
dotnet_diagnostic.CA2253.severity = none # Question - Named placeholders should not be numeric values
dotnet_diagnostic.CS0103.severity = none # Question - The name
dotnet_diagnostic.CS0168.severity = none # Question - The variable
dotnet_diagnostic.CS0219.severity = none # Question - The variable
dotnet_diagnostic.CS0612.severity = none # Question - is obsolete
dotnet_diagnostic.CS0618.severity = none # Question - Compiler Warning (level 2)
dotnet_diagnostic.CS0659.severity = none # Question - Compiler Warning (level 3)
dotnet_diagnostic.CS8019.severity = warning # Question - Unnecessary using directive.
dotnet_diagnostic.CS8600.severity = none # Question - Converting null literal or possible null value to non-nullable type
dotnet_diagnostic.CS8602.severity = none # Question - Dereference of a possibly null reference.
dotnet_diagnostic.CS8603.severity = none # Question - Possible null reference return
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.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.CS8765.severity = none # Question - Nullability of type of parameter
dotnet_diagnostic.IDE0005.severity = none # Question - Remove unnecessary using directives
dotnet_diagnostic.IDE0008.severity = warning # Question - Use explicit type instead of
dotnet_diagnostic.IDE0017.severity = none # Question - Object initialization can be simplified
dotnet_diagnostic.IDE0019.severity = none # Question - Use pattern matching
dotnet_diagnostic.IDE0021.severity = none # Question - Use expression body for constructor
dotnet_diagnostic.IDE0022.severity = none # Question - Use expression body for method
dotnet_diagnostic.IDE0025.severity = none # Question - Use expression body for property
dotnet_diagnostic.IDE0027.severity = none # Question - Use expression body for accessor
dotnet_diagnostic.IDE0028.severity = none # Question - Use collection initializers or expressions
dotnet_diagnostic.IDE0031.severity = none # Question - Null check can be simplified
dotnet_diagnostic.IDE0032.severity = none # Question - Use auto property
dotnet_diagnostic.IDE0037.severity = none # Question - Member name can be simplified
dotnet_diagnostic.IDE0041.severity = none # Question - Null check can be simplified
dotnet_diagnostic.IDE0047.severity = none # Question - Parentheses preferences
dotnet_diagnostic.IDE0049.severity = warning # Question - Name can be simplified
dotnet_diagnostic.IDE0051.severity = none # Question - Remove unused private member
dotnet_diagnostic.IDE0053.severity = none # Question - Use expression body for lambdas
dotnet_diagnostic.IDE0054.severity = none # Question - Use compound assignment
dotnet_diagnostic.IDE0055.severity = none # Question - Formatting rule
dotnet_diagnostic.IDE0057.severity = none # Question - Substring can be simplified
dotnet_diagnostic.IDE0058.severity = none # Question - Remove unnecessary expression value
dotnet_diagnostic.IDE0059.severity = none # Question - Unnecessary assignment of a value to
dotnet_diagnostic.IDE0060.severity = none # Question - Remove unused parameter
dotnet_diagnostic.IDE0063.severity = none # Question - Use simple
dotnet_diagnostic.IDE0065.severity = none # Question -
dotnet_diagnostic.IDE0066.severity = none # Question - Use
dotnet_diagnostic.IDE0078.severity = none # Question - Use pattern matching (may change code meaning)
dotnet_diagnostic.IDE0090.severity = warning # Question - Simplify new expression
dotnet_diagnostic.IDE0100.severity = error # Question - Remove redundant equality
dotnet_diagnostic.IDE0160.severity = warning # Question - Use block-scoped namespace
dotnet_diagnostic.IDE0161.severity = warning # Question - Namespace declaration preferences
dotnet_diagnostic.IDE0270.severity = none # Question - Null check can be simplified
dotnet_diagnostic.IDE0300.severity = none # Question - Collection initialization can be simplified
dotnet_diagnostic.IDE1006.severity = none # Question - Use collection expression for builder dotnet_style_prefer_collection_expression
dotnet_style_null_propagation = false # Question
dotnet_style_object_initializer = false # Question
dotnet_style_prefer_auto_properties = false # Question
dotnet_style_allow_statement_immediately_after_block_experimental = true # Question
dotnet_style_prefer_inferred_anonymous_type_member_names = false:warning # Question
dotnet_style_prefer_is_null_check_over_reference_equality_method = false # Question

View File

@ -1,6 +1,5 @@
using System.Globalization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Globalization;
namespace File_Folder_Helper.ADO2025.PI5; namespace File_Folder_Helper.ADO2025.PI5;
@ -17,18 +16,20 @@ internal static partial class Helper20250218 {
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly); string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories) { foreach (string directory in directories) {
checkDirectory = Path.Combine(directory, checkDirectoryName); checkDirectory = Path.Combine(directory, checkDirectoryName);
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory)) {
continue; continue;
}
MoveToArchive(logger, searchPattern, searchMES, searchSequence, destinationRoot, checkDirectory); MoveToArchive(logger, searchPattern, searchMES, searchSequence, destinationRoot, checkDirectory);
} }
} }
private static void MoveToArchive(ILogger<Worker> logger, string searchPattern, string searchMES, string searchSequence, string destinationRoot, string checkDirectory) { private static void MoveToArchive(ILogger<Worker> logger, string searchPattern, string searchMES, string searchSequence, string destinationRoot, string checkDirectory) {
string[] files = Directory.GetFiles(checkDirectory, searchPattern, SearchOption.AllDirectories); string[] files = Directory.GetFiles(checkDirectory, searchPattern, SearchOption.AllDirectories);
if (files.Length == 0) if (files.Length == 0) {
logger.LogInformation("<{files}>(s)", files.Length); logger.LogInformation("<{files}>(s)", files.Length);
else } else {
MoveToArchive(logger, searchMES, searchSequence, destinationRoot, files); MoveToArchive(logger, searchMES, searchSequence, destinationRoot, files);
}
} }
private static void MoveToArchive(ILogger<Worker> logger, string searchMES, string searchSequence, string destinationRoot, string[] files) { private static void MoveToArchive(ILogger<Worker> logger, string searchMES, string searchSequence, string destinationRoot, string[] files) {
@ -46,15 +47,18 @@ internal static partial class Helper20250218 {
Calendar calendar = new CultureInfo("en-US").Calendar; Calendar calendar = new CultureInfo("en-US").Calendar;
foreach (string file in files) { foreach (string file in files) {
fileInfo = new(file); fileInfo = new(file);
if (string.IsNullOrEmpty(fileInfo.DirectoryName)) if (string.IsNullOrEmpty(fileInfo.DirectoryName)) {
continue; continue;
}
text = File.ReadAllText(file); text = File.ReadAllText(file);
segments = text.Split(searchMES); segments = text.Split(searchMES);
if (segments.Length < 2) if (segments.Length < 2) {
continue; continue;
}
segmentsB = text.Split(searchSequence); segmentsB = text.Split(searchSequence);
if (segmentsB.Length < 2) if (segmentsB.Length < 2) {
continue; continue;
}
mes = segments[1].Split(';')[0]; mes = segments[1].Split(';')[0];
sequence = segmentsB[1].Split(';')[0]; sequence = segmentsB[1].Split(';')[0];
segmentsC = Path.GetFileName(fileInfo.DirectoryName).Split('-'); segmentsC = Path.GetFileName(fileInfo.DirectoryName).Split('-');

View File

@ -1,10 +1,9 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI5; namespace File_Folder_Helper.ADO2025.PI5;
internal static partial class Helper20250219 { internal static partial class Helper20250219 {
@ -42,10 +41,12 @@ internal static partial class Helper20250219 {
ReadOnlyCollection<int> columnIndices = args[10].Split(',').Select(int.Parse).ToArray().AsReadOnly(); ReadOnlyCollection<int> columnIndices = args[10].Split(',').Select(int.Parse).ToArray().AsReadOnly();
foreach (string segment in segments) { foreach (string segment in segments) {
segmentsB = segment.Split('|'); segmentsB = segment.Split('|');
if (segmentsB.Length != 2) if (segmentsB.Length != 2) {
continue; continue;
if (distinct.Contains(segmentsB[0])) }
if (distinct.Contains(segmentsB[0])) {
continue; continue;
}
distinct.Add(segmentsB[0]); distinct.Add(segmentsB[0]);
keyValuePairs.Add(segmentsB[0], segmentsB[1]); keyValuePairs.Add(segmentsB[0], segmentsB[1]);
} }
@ -77,13 +78,15 @@ internal static partial class Helper20250219 {
directory = fileInfo.DirectoryName ?? throw new Exception(); directory = fileInfo.DirectoryName ?? throw new Exception();
directoryFiles = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); directoryFiles = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
matches = (from l in directoryFiles where l != fileInfo.FullName select l).ToArray(); matches = (from l in directoryFiles where l != fileInfo.FullName select l).ToArray();
if (matches.Length < 1) if (matches.Length < 1) {
continue; continue;
}
directorySegment = directory[sourceDirectoryLength..]; directorySegment = directory[sourceDirectoryLength..];
processDataStandardFormat = GetProcessDataStandardFormat(logger, fileInfo.LastWriteTime, pdsfMapping.NewColumnNames.Count, columnsLine, fileInfo.FullName, lines: null); processDataStandardFormat = GetProcessDataStandardFormat(logger, fileInfo.LastWriteTime, pdsfMapping.NewColumnNames.Count, columnsLine, fileInfo.FullName, lines: null);
jsonElementsNew = GetArray(logger, pdsfMapping.NewColumnNames.Count, processDataStandardFormat, lookForNumbers: false); jsonElementsNew = GetArray(logger, pdsfMapping.NewColumnNames.Count, processDataStandardFormat, lookForNumbers: false);
if (jsonElementsNew is null) if (jsonElementsNew is null) {
continue; continue;
}
if (pdsfMapping.OldColumnNames.Count == pdsfMapping.ColumnIndices.Count) { if (pdsfMapping.OldColumnNames.Count == pdsfMapping.ColumnIndices.Count) {
processDataStandardFormat = GetProcessDataStandardFormat(logger, pdsfMapping, jsonElementsNew, processDataStandardFormat); processDataStandardFormat = GetProcessDataStandardFormat(logger, pdsfMapping, jsonElementsNew, processDataStandardFormat);
Write(logger, fileInfo, processDataStandardFormat); Write(logger, fileInfo, processDataStandardFormat);
@ -132,13 +135,15 @@ internal static partial class Helper20250219 {
valueOld = jsonPropertyOld.Value.ToString(); valueOld = jsonPropertyOld.Value.ToString();
if (processDataStandardFormatMapping.KeyValuePairs.TryGetValue(jsonPropertyOld.Name, out string? name) && !string.IsNullOrEmpty(name)) { if (processDataStandardFormatMapping.KeyValuePairs.TryGetValue(jsonPropertyOld.Name, out string? name) && !string.IsNullOrEmpty(name)) {
q = TryGetPropertyIndex(jsonPropertiesNew, name); q = TryGetPropertyIndex(jsonPropertiesNew, name);
if (q is null && i == 0) if (q is null && i == 0) {
unknownColumns.Add($"{jsonPropertyOld.Name}|{name}"); unknownColumns.Add($"{jsonPropertyOld.Name}|{name}");
}
} else { } else {
q = TryGetPropertyIndex(jsonPropertiesNew, jsonPropertyOld.Name); q = TryGetPropertyIndex(jsonPropertiesNew, jsonPropertyOld.Name);
if (q is null) { if (q is null) {
if (i == 0) if (i == 0) {
unknownColumns.Add(jsonPropertyOld.Name); unknownColumns.Add(jsonPropertyOld.Name);
}
} }
} }
if (q is null) { if (q is null) {
@ -153,8 +158,9 @@ internal static partial class Helper20250219 {
if (i == last) { if (i == last) {
columns.Add("-1"); columns.Add("-1");
columnPairs.Add($"{jsonPropertyOld.Name}:"); columnPairs.Add($"{jsonPropertyOld.Name}:");
if (!string.IsNullOrEmpty(valueOld)) if (!string.IsNullOrEmpty(valueOld)) {
logger.LogDebug("{p} )) {jsonPropertyOld.Name} ??", p, jsonPropertyOld.Name); logger.LogDebug("{p} )) {jsonPropertyOld.Name} ??", p, jsonPropertyOld.Name);
}
} }
} else { } else {
jsonPropertyNew = jsonPropertiesNew[q.Value]; jsonPropertyNew = jsonPropertiesNew[q.Value];
@ -163,16 +169,19 @@ internal static partial class Helper20250219 {
columnPairs.Add($"{jsonPropertyOld.Name}:{jsonPropertyNew.Name}"); columnPairs.Add($"{jsonPropertyOld.Name}:{jsonPropertyNew.Name}");
} }
valueNew = jsonPropertyNew.Value.ToString(); valueNew = jsonPropertyNew.Value.ToString();
if (i == last) if (i == last) {
logger.LogDebug("{p} )) {jsonPropertyOld.Name} ~~ {q.Value} => {jsonPropertyNew.Name}", p, jsonPropertyOld.Name, q.Value, jsonPropertyNew.Name); logger.LogDebug("{p} )) {jsonPropertyOld.Name} ~~ {q.Value} => {jsonPropertyNew.Name}", p, jsonPropertyOld.Name, q.Value, jsonPropertyNew.Name);
}
if (valueNew != valueOld && !differentColumns.Contains(jsonPropertyOld.Name)) { if (valueNew != valueOld && !differentColumns.Contains(jsonPropertyOld.Name)) {
if (valueNew.Length >= 2 && valueNew.Split(' ')[0] == valueOld) if (valueNew.Length >= 2 && valueNew.Split(' ')[0] == valueOld) {
sameAfterSpaceSplitColumns.Add(jsonPropertyOld.Name); sameAfterSpaceSplitColumns.Add(jsonPropertyOld.Name);
else { } else {
if (processDataStandardFormatMapping.BackfillColumns.Contains(jsonPropertyOld.Name) && i != last) if (processDataStandardFormatMapping.BackfillColumns.Contains(jsonPropertyOld.Name) && i != last) {
continue; continue;
if (processDataStandardFormatMapping.IndexOnlyColumns.Contains(jsonPropertyOld.Name) && int.TryParse(jsonPropertyOld.Name[^2..], out int index) && i != index - 1) }
if (processDataStandardFormatMapping.IndexOnlyColumns.Contains(jsonPropertyOld.Name) && int.TryParse(jsonPropertyOld.Name[^2..], out int index) && i != index - 1) {
continue; continue;
}
logger.LogWarning("For [{jsonProperty.Name}] <{directory}> doesn't match (valueNew:{valueNew} != valueOld:{valueOld})!", jsonPropertyOld.Name, directory, valueNew, valueOld); logger.LogWarning("For [{jsonProperty.Name}] <{directory}> doesn't match (valueNew:{valueNew} != valueOld:{valueOld})!", jsonPropertyOld.Name, directory, valueNew, valueOld);
differentColumns.Add(jsonPropertyOld.Name); differentColumns.Add(jsonPropertyOld.Name);
} }
@ -191,19 +200,23 @@ internal static partial class Helper20250219 {
private static int? TryGetPropertyIndex(JsonProperty[] jsonProperties, string propertyName) { private static int? TryGetPropertyIndex(JsonProperty[] jsonProperties, string propertyName) {
int? result = null; int? result = null;
for (int i = 0; i < jsonProperties.Length; i++) { for (int i = 0; i < jsonProperties.Length; i++) {
if (jsonProperties[i].Name != propertyName) if (jsonProperties[i].Name != propertyName) {
continue; continue;
}
result = i; result = i;
break; break;
} }
if (result is null) { if (result is null) {
for (int i = 0; i < jsonProperties.Length; i++) { for (int i = 0; i < jsonProperties.Length; i++) {
if (jsonProperties[i].Name[0] != propertyName[0]) if (jsonProperties[i].Name[0] != propertyName[0]) {
continue; continue;
if (jsonProperties[i].Name.Length != propertyName.Length) }
if (jsonProperties[i].Name.Length != propertyName.Length) {
continue; continue;
if (jsonProperties[i].Name != propertyName) }
if (jsonProperties[i].Name != propertyName) {
continue; continue;
}
result = i; result = i;
break; break;
} }
@ -219,9 +232,9 @@ internal static partial class Helper20250219 {
List<string> logistics = []; List<string> logistics = [];
bool lookForLogistics = false; bool lookForLogistics = false;
lines ??= File.ReadAllLines(path); lines ??= File.ReadAllLines(path);
if (lines.Length <= columnsLine) if (lines.Length <= columnsLine) {
segments = []; segments = [];
else { } else {
segments = lines[columnsLine].Split('\t'); segments = lines[columnsLine].Split('\t');
if (segments.Length != expectedColumns) { if (segments.Length != expectedColumns) {
logger.LogWarning("{segments} != {expectedColumns}", segments.Length, expectedColumns); logger.LogWarning("{segments} != {expectedColumns}", segments.Length, expectedColumns);
@ -230,24 +243,26 @@ internal static partial class Helper20250219 {
} }
string[] columns = segments.Select(l => l.Trim('"')).ToArray(); string[] columns = segments.Select(l => l.Trim('"')).ToArray();
for (int r = columnsLine + 1; r < lines.Length; r++) { for (int r = columnsLine + 1; r < lines.Length; r++) {
if (lines[r].StartsWith("NUM_DATA_ROWS")) if (lines[r].StartsWith("NUM_DATA_ROWS")) {
lookForLogistics = true; lookForLogistics = true;
}
if (!lookForLogistics) { if (!lookForLogistics) {
body.Add(lines[r]); body.Add(lines[r]);
continue; continue;
} }
if (lines[r].StartsWith("LOGISTICS_1")) { if (lines[r].StartsWith("LOGISTICS_1")) {
for (int i = r; i < lines.Length; i++) { for (int i = r; i < lines.Length; i++) {
if (lines[r].StartsWith("END_HEADER")) if (lines[r].StartsWith("END_HEADER")) {
break; break;
}
logistics.Add(lines[i]); logistics.Add(lines[i]);
} }
break; break;
} }
} }
if (logistics.Count == 0) if (logistics.Count == 0) {
sequence = lastWriteTime.Ticks; sequence = lastWriteTime.Ticks;
else { } else {
segments = logistics[0].Split("SEQUENCE="); segments = logistics[0].Split("SEQUENCE=");
sequence = segments.Length < 2 || !long.TryParse(segments[1].Split(';')[0], out long s) ? lastWriteTime.Ticks : s; sequence = segments.Length < 2 || !long.TryParse(segments[1].Split(';')[0], out long s) ? lastWriteTime.Ticks : s;
} }
@ -260,9 +275,9 @@ internal static partial class Helper20250219 {
private static JsonElement[]? GetArray(ILogger<Worker> logger, int expectedColumns, ProcessDataStandardFormat processDataStandardFormat, bool lookForNumbers) { private static JsonElement[]? GetArray(ILogger<Worker> logger, int expectedColumns, ProcessDataStandardFormat processDataStandardFormat, bool lookForNumbers) {
JsonElement[]? results; JsonElement[]? results;
if (processDataStandardFormat.Body.Count == 0 || !processDataStandardFormat.Body[0].Contains('\t')) if (processDataStandardFormat.Body.Count == 0 || !processDataStandardFormat.Body[0].Contains('\t')) {
results = JsonSerializer.Deserialize("[]", JsonElementCollectionSourceGenerationContext.Default.JsonElementArray) ?? throw new Exception(); results = JsonSerializer.Deserialize("[]", JsonElementCollectionSourceGenerationContext.Default.JsonElementArray) ?? throw new Exception();
else { } else {
string value; string value;
string[] segments; string[] segments;
List<string> lines = []; List<string> lines = [];
@ -283,12 +298,13 @@ internal static partial class Helper20250219 {
} else { } else {
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("\"", "\\\"");
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value)) {
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,"); _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,");
else if (value.All(char.IsDigit)) } else if (value.All(char.IsDigit)) {
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append(','); _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append(',');
else } else {
_ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\",");
}
} }
} }
_ = stringBuilder.Remove(stringBuilder.Length - 1, 1); _ = stringBuilder.Remove(stringBuilder.Length - 1, 1);
@ -323,9 +339,9 @@ internal static partial class Helper20250219 {
} }
for (int c = 0; c < processDataStandardFormatMapping.ColumnIndices.Count; c++) { for (int c = 0; c < processDataStandardFormatMapping.ColumnIndices.Count; c++) {
column = processDataStandardFormatMapping.ColumnIndices[c]; column = processDataStandardFormatMapping.ColumnIndices[c];
if (column == -1) if (column == -1) {
value = processDataStandardFormatMapping.OldColumnNames[c]; value = processDataStandardFormatMapping.OldColumnNames[c];
else { } else {
jsonProperty = jsonProperties[column]; jsonProperty = jsonProperties[column];
value = jsonProperty.Value.ToString(); value = jsonProperty.Value.ToString();
} }
@ -342,8 +358,9 @@ internal static partial class Helper20250219 {
private static void Write(ILogger<Worker> logger, FileInfo fileInfo, ProcessDataStandardFormat processDataStandardFormat) { private static void Write(ILogger<Worker> logger, FileInfo fileInfo, ProcessDataStandardFormat processDataStandardFormat) {
List<string> results = []; List<string> results = [];
if (processDataStandardFormat.Sequence is null) if (processDataStandardFormat.Sequence is null) {
throw new NullReferenceException(nameof(processDataStandardFormat.Sequence)); throw new NullReferenceException(nameof(processDataStandardFormat.Sequence));
}
string endOffset = "E#######T"; string endOffset = "E#######T";
string dataOffset = "D#######T"; string dataOffset = "D#######T";
string headerOffset = "H#######T"; string headerOffset = "H#######T";

View File

@ -1,8 +1,7 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Text.Json; using System.Text.Json;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI5; namespace File_Folder_Helper.ADO2025.PI5;
internal static partial class Helper20250228 { internal static partial class Helper20250228 {
@ -15,18 +14,20 @@ internal static partial class Helper20250228 {
string headerB = args[4].Replace('_', ' '); string headerB = args[4].Replace('_', ' ');
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
if (files.Length != 1) if (files.Length != 1) {
logger.LogWarning("<{files}>(s)", files.Length); logger.LogWarning("<{files}>(s)", files.Length);
else } else {
PostgresDumpToJson(logger, headerA, headerB, files[0]); PostgresDumpToJson(logger, headerA, headerB, files[0]);
}
} }
private static void PostgresDumpToJson(ILogger<Worker> logger, string headerA, string headerB, string file) { private static void PostgresDumpToJson(ILogger<Worker> logger, string headerA, string headerB, string file) {
ReadOnlyCollection<Record> records = GetRecords(headerA, headerB, file); ReadOnlyCollection<Record> records = GetRecords(headerA, headerB, file);
if (records.Count > 0) if (records.Count > 0) {
WriteFile(file, records); WriteFile(file, records);
else } else {
logger.LogWarning("<{records}>(s)", records.Count); logger.LogWarning("<{records}>(s)", records.Count);
}
} }
private static ReadOnlyCollection<Record> GetRecords(string headerA, string headerB, string file) { private static ReadOnlyCollection<Record> GetRecords(string headerA, string headerB, string file) {
@ -46,32 +47,38 @@ internal static partial class Helper20250228 {
line = lines[i]; line = lines[i];
if (tableName is null) { if (tableName is null) {
segmentsA = line.Split(headerA); segmentsA = line.Split(headerA);
if (segmentsA.Length != 2) if (segmentsA.Length != 2) {
continue; continue;
}
segmentsB = segmentsA[1].Split(headerB); segmentsB = segmentsA[1].Split(headerB);
if (segmentsB.Length != 2) if (segmentsB.Length != 2) {
continue; continue;
}
segmentsC = segmentsB[0].Split('('); segmentsC = segmentsB[0].Split('(');
if (segmentsC.Length != 2) if (segmentsC.Length != 2) {
continue; continue;
}
segmentsD = segmentsC[1].Split(')'); segmentsD = segmentsC[1].Split(')');
if (segmentsD.Length != 2) if (segmentsD.Length != 2) {
continue; continue;
}
columns = segmentsD[0].Split(',').Select(l => l.Trim(' ').Trim('"')).ToArray().AsReadOnly(); columns = segmentsD[0].Split(',').Select(l => l.Trim(' ').Trim('"')).ToArray().AsReadOnly();
if (columns.Count == 0) if (columns.Count == 0) {
continue; continue;
}
segmentsE = segmentsB[0].Split(' '); segmentsE = segmentsB[0].Split(' ');
tableName = segmentsE[0]; tableName = segmentsE[0];
} else if (columns is null) } else if (columns is null) {
break; break;
else { } else {
rows = []; rows = [];
for (int j = i + 1; j < lines.Length; j++) { for (int j = i + 1; j < lines.Length; j++) {
i = j; i = j;
segmentsF = lines[j].Split('\t'); segmentsF = lines[j].Split('\t');
if (segmentsF.Length != columns.Count) { if (segmentsF.Length != columns.Count) {
if (rows.Count > 0) if (rows.Count > 0) {
results.Add(new(TableName: tableName, Columns: columns, Rows: rows.AsReadOnly())); results.Add(new(TableName: tableName, Columns: columns, Rows: rows.AsReadOnly()));
}
break; break;
} }
rows.Add(segmentsF); rows.Add(segmentsF);
@ -93,10 +100,11 @@ internal static partial class Helper20250228 {
foreach (string[] row in record.Rows) { foreach (string[] row in record.Rows) {
keyValuePairs.Clear(); keyValuePairs.Clear();
for (int i = 0; i < row.Length; i++) { for (int i = 0; i < row.Length; i++) {
if (row[i] == "\\N") if (row[i] == "\\N") {
keyValuePairs.Add(record.Columns[i], null); keyValuePairs.Add(record.Columns[i], null);
else } else {
keyValuePairs.Add(record.Columns[i], row[i]); keyValuePairs.Add(record.Columns[i], row[i]);
}
} }
#pragma warning disable IL3050, IL2026 #pragma warning disable IL3050, IL2026
json = JsonSerializer.Serialize(keyValuePairs); json = JsonSerializer.Serialize(keyValuePairs);

View File

@ -1,6 +1,5 @@
using System.Collections.ObjectModel;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.ADO2025.PI5; namespace File_Folder_Helper.ADO2025.PI5;
@ -14,23 +13,25 @@ internal static partial class Helper20250301 {
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string workingDirectory = Path.GetFullPath(args[4]); string workingDirectory = Path.GetFullPath(args[4]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
if (files.Length == 0) if (files.Length == 0) {
logger.LogWarning("<{files}>(s)", files.Length); logger.LogWarning("<{files}>(s)", files.Length);
else } else {
PocketBaseImportWithDeno(logger, split, workingDirectory, scriptName, directory, files); PocketBaseImportWithDeno(logger, split, workingDirectory, scriptName, directory, files);
}
} }
private static void PocketBaseImportWithDeno(ILogger<Worker> logger, char split, string workingDirectory, string scriptName, string directory, string[] files) { private static void PocketBaseImportWithDeno(ILogger<Worker> logger, char split, string workingDirectory, string scriptName, string directory, string[] files) {
string checkFile = Path.Combine(workingDirectory, scriptName); string checkFile = Path.Combine(workingDirectory, scriptName);
if (!File.Exists(checkFile)) if (!File.Exists(checkFile)) {
logger.LogWarning("<{checkFile}> doesn't exist!", checkFile); logger.LogWarning("<{checkFile}> doesn't exist!", checkFile);
else { } else {
ReadOnlyCollection<string> fileNames = CopyFiles(split, workingDirectory, directory, files); ReadOnlyCollection<string> fileNames = CopyFiles(split, workingDirectory, directory, files);
if (fileNames.Count == 0) if (fileNames.Count == 0) {
logger.LogWarning("<{fileNames}>(s)", fileNames.Count); logger.LogWarning("<{fileNames}>(s)", fileNames.Count);
else { } else {
foreach (string fileName in fileNames) foreach (string fileName in fileNames) {
logger.LogInformation("deno run --unstable --allow-read --allow-env --allow-net {scriptName} --id=true --input={fileName}", scriptName, fileName); logger.LogInformation("deno run --unstable --allow-read --allow-env --allow-net {scriptName} --id=true --input={fileName}", scriptName, fileName);
}
} }
} }
} }
@ -40,13 +41,15 @@ internal static partial class Helper20250301 {
string fileName; string fileName;
string checkFile; string checkFile;
string checkDirectory = Path.Combine(workingDirectory, directory); string checkDirectory = Path.Combine(workingDirectory, directory);
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
}
foreach (string file in files) { foreach (string file in files) {
fileName = Path.GetFileName(file).Split(split)[^1]; fileName = Path.GetFileName(file).Split(split)[^1];
checkFile = Path.Combine(checkDirectory, fileName); checkFile = Path.Combine(checkDirectory, fileName);
if (File.Exists(checkFile)) if (File.Exists(checkFile)) {
File.Delete(checkFile); File.Delete(checkFile);
}
File.Copy(file, checkFile); File.Copy(file, checkFile);
results.Add(fileName); results.Add(fileName);
} }

View File

@ -1,10 +1,8 @@
using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Text.Json; using System.Text.Json;
using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI5; namespace File_Folder_Helper.ADO2025.PI5;
internal static partial class Helper20250305 { internal static partial class Helper20250305 {
@ -28,14 +26,15 @@ internal static partial class Helper20250305 {
#if ShellProgressBar #if ShellProgressBar
progressBar.Tick(); progressBar.Tick();
#endif #endif
if (record.TotalSeconds is null) if (record.TotalSeconds is null) {
Download(record); Download(record);
else if (record.TotalSeconds.Value == 0) } else if (record.TotalSeconds.Value == 0) {
logger.LogInformation("Different lengths"); logger.LogInformation("Different lengths");
else if (record.TotalSeconds.Value > 0) } else if (record.TotalSeconds.Value > 0) {
logger.LogInformation("Overwrite remote (https)"); logger.LogInformation("Overwrite remote (https)");
else } else {
logger.LogInformation("Overwrite local"); logger.LogInformation("Overwrite local");
}
} }
#if ShellProgressBar #if ShellProgressBar
progressBar.Dispose(); progressBar.Dispose();
@ -50,18 +49,21 @@ internal static partial class Helper20250305 {
NginxFileSystem nginxFileSystem; NginxFileSystem nginxFileSystem;
ReadOnlyCollection<Record> records; ReadOnlyCollection<Record> records;
string checkDirectory = $"{compareDirectory}\\{string.Join('\\', directoryNames)}"; string checkDirectory = $"{compareDirectory}\\{string.Join('\\', directoryNames)}";
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
}
for (int i = 0; i < nginxFileSystems.Count; i++) { for (int i = 0; i < nginxFileSystems.Count; i++) {
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]); nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
if (nginxFileSystem.Type == "file") { if (nginxFileSystem.Type == "file") {
Record? record = CompareFile(host, directoryNames, compareDirectory, nginxFileSystem); Record? record = CompareFile(host, directoryNames, compareDirectory, nginxFileSystem);
if (record is not null) if (record is not null) {
results.Add(record); results.Add(record);
}
} else { } else {
records = CompareDirectory(format, timeZoneInfo, host, directoryNames, compareDirectory, nginxFileSystem); records = CompareDirectory(format, timeZoneInfo, host, directoryNames, compareDirectory, nginxFileSystem);
foreach (Record record in records) foreach (Record record in records) {
results.Add(record); results.Add(record);
}
} }
} }
} }
@ -72,18 +74,18 @@ internal static partial class Helper20250305 {
List<NginxFileSystem>? results; List<NginxFileSystem>? results;
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(uri); Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(uri);
taskHttpResponseMessage.Wait(); taskHttpResponseMessage.Wait();
if (!taskHttpResponseMessage.Result.IsSuccessStatusCode) if (!taskHttpResponseMessage.Result.IsSuccessStatusCode) {
results = null; results = null;
else { } else {
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync(); Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
taskString.Wait(); taskString.Wait();
if (taskString.Result.StartsWith('<')) if (taskString.Result.StartsWith('<')) {
results = null; results = null;
else { } else {
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray); NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
if (nginxFileSystems is null) if (nginxFileSystems is null) {
results = null; results = null;
else { } else {
results = []; results = [];
NginxFileSystem nginxFileSystem; NginxFileSystem nginxFileSystem;
for (int i = 0; i < nginxFileSystems.Length; i++) { for (int i = 0; i < nginxFileSystems.Length; i++) {
@ -98,21 +100,22 @@ internal static partial class Helper20250305 {
private static Record? CompareFile(string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem) { private static Record? CompareFile(string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem) {
Record? result; Record? result;
if (nginxFileSystem.LastModified is null || nginxFileSystem.Length is null) if (nginxFileSystem.LastModified is null || nginxFileSystem.Length is null) {
result = null; result = null;
else { } else {
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}/{nginxFileSystem.Name}"); Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}/{nginxFileSystem.Name}");
FileInfo fileInfo = new($"{compareDirectory}\\{string.Join('\\', directoryNames)}\\{nginxFileSystem.Name}"); FileInfo fileInfo = new($"{compareDirectory}\\{string.Join('\\', directoryNames)}\\{nginxFileSystem.Name}");
if (!fileInfo.Exists) if (!fileInfo.Exists) {
result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: null); result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: null);
else { } else {
int totalSeconds = (int)new TimeSpan(fileInfo.LastWriteTime.Ticks - nginxFileSystem.LastModified.Value.Ticks).TotalSeconds; int totalSeconds = (int)new TimeSpan(fileInfo.LastWriteTime.Ticks - nginxFileSystem.LastModified.Value.Ticks).TotalSeconds;
if (totalSeconds is not < 2 or not > -2) if (totalSeconds is not < 2 or not > -2) {
result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: totalSeconds); result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: totalSeconds);
else if (fileInfo.Length != nginxFileSystem.Length.Value) } else if (fileInfo.Length != nginxFileSystem.Length.Value) {
result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: 0); result = new(URI: uri, Path: fileInfo.FullName, LastModified: nginxFileSystem.LastModified.Value, TotalSeconds: 0);
else } else {
result = null; result = null;
}
} }
} }
return result; return result;

View File

@ -8,23 +8,24 @@ internal static partial class Helper20250306 {
string searchPattern = args[2]; string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
if (files.Length != 1) if (files.Length != 1) {
logger.LogWarning("<{files}>(s)", files.Length); logger.LogWarning("<{files}>(s)", files.Length);
else } else {
ProcessDataStandardFormatToJson(logger, files[0]); ProcessDataStandardFormatToJson(logger, files[0]);
}
} }
private static void ProcessDataStandardFormatToJson(ILogger<Worker> logger, string file) { private static void ProcessDataStandardFormatToJson(ILogger<Worker> logger, string file) {
string[] lines = File.ReadAllLines(file); string[] lines = File.ReadAllLines(file);
int? columnTitlesLine = GetProcessDataStandardFormatColumnTitlesLine(lines); int? columnTitlesLine = GetProcessDataStandardFormatColumnTitlesLine(lines);
if (columnTitlesLine is null) if (columnTitlesLine is null) {
logger.LogWarning("<{columnTitlesLine}> is null", nameof(columnTitlesLine)); logger.LogWarning("<{columnTitlesLine}> is null", nameof(columnTitlesLine));
else { } else {
string? text = ProcessDataStandardFormatToLastDataLine(lines, columnTitlesLine.Value); string? text = ProcessDataStandardFormatToLastDataLine(lines, columnTitlesLine.Value);
File.WriteAllText(Path.Combine(".vscode", "helper", ".lbl"), text); File.WriteAllText(Path.Combine(".vscode", "helper", ".lbl"), text);
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 {
string json = ProcessDataStandardFormatToJson(columnTitlesLine.Value, [], lines); string json = ProcessDataStandardFormatToJson(columnTitlesLine.Value, [], lines);
File.WriteAllText(Path.Combine(".vscode", "helper", ".json"), json); File.WriteAllText(Path.Combine(".vscode", "helper", ".json"), json);
} }
@ -35,8 +36,9 @@ internal static partial class Helper20250306 {
int? result = null; int? result = null;
bool foundEndOfFile = false; bool foundEndOfFile = false;
for (int i = 0; i < lines.Length; i++) { for (int i = 0; i < lines.Length; i++) {
if (lines[i] == "EOF") if (lines[i] == "EOF") {
foundEndOfFile = true; foundEndOfFile = true;
}
if (foundEndOfFile && lines[i].StartsWith("END_OFFSET") && i + 3 < lines.Length) { if (foundEndOfFile && lines[i].StartsWith("END_OFFSET") && i + 3 < lines.Length) {
result = i + 2; result = i + 2;
break; break;
@ -62,14 +64,16 @@ internal static partial class Helper20250306 {
string line; string line;
string value; string value;
string[] segments; string[] segments;
if (columns.Length == 0) if (columns.Length == 0) {
columns = lines[columnTitlesLine].Trim().Split('|'); columns = lines[columnTitlesLine].Trim().Split('|');
}
int columnsLength = columns.Length - 2; int columnsLength = columns.Length - 2;
for (int i = columnTitlesLine + 1; i < lines.Length; i++) { for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
line = "{"; line = "{";
segments = lines[i].Trim().Split('|'); segments = lines[i].Trim().Split('|');
if (segments.Length != columnsLength) if (segments.Length != columnsLength) {
continue; continue;
}
for (int c = 1; c < segments.Length; c++) { for (int c = 1; c < segments.Length; c++) {
value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\""); value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\"");
line += '"' + columns[c].Trim('"') + '"' + ':' + '"' + value + '"' + ','; line += '"' + columns[c].Trim('"') + '"' + ':' + '"' + value + '"' + ',';

View File

@ -11,16 +11,17 @@ internal static partial class Helper20250315 {
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
if (searchPatterns.Length == 1) { if (searchPatterns.Length == 1) {
string[] files = Directory.GetFiles(sourceDirectory, searchPatterns[0], SearchOption.AllDirectories); string[] files = Directory.GetFiles(sourceDirectory, searchPatterns[0], SearchOption.AllDirectories);
if (files.Length == 0) if (files.Length == 0) {
logger.LogWarning("<{files}>(s)", files.Length); logger.LogWarning("<{files}>(s)", files.Length);
else { } else {
string directoryName; string directoryName;
string[] directories; string[] directories;
foreach (string file in files) { foreach (string file in files) {
directoryName = Path.GetDirectoryName(file) ?? throw new Exception(); directoryName = Path.GetDirectoryName(file) ?? throw new Exception();
directories = Directory.GetDirectories(directoryName, "*", SearchOption.TopDirectoryOnly); directories = Directory.GetDirectories(directoryName, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories) foreach (string directory in directories) {
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, directory); HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, directory);
}
} }
} }
} else { } else {
@ -29,13 +30,14 @@ internal static partial class Helper20250315 {
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory); HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
foreach (string searchPattern in searchPatterns) { foreach (string searchPattern in searchPatterns) {
files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
if (files.Length == 0) if (files.Length == 0) {
logger.LogWarning("<{files}>(s)", files.Length); logger.LogWarning("<{files}>(s)", files.Length);
else { } else {
foreach (string file in files) { foreach (string file in files) {
checkFile = $"{file}.json"; checkFile = $"{file}.json";
if (File.Exists(checkFile)) if (File.Exists(checkFile)) {
continue; continue;
}
File.Move(file, checkFile); File.Move(file, checkFile);
} }
} }

View File

@ -1,11 +1,10 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI5; namespace File_Folder_Helper.ADO2025.PI5;
internal static partial class Helper20250320 { internal static partial class Helper20250320 {
@ -40,7 +39,6 @@ internal static partial class Helper20250320 {
string result = JsonSerializer.Serialize(this, MethodCollectionCommonSourceGenerationContext.Default.Method); string result = JsonSerializer.Serialize(this, MethodCollectionCommonSourceGenerationContext.Default.Method);
return result; return result;
} }
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
@ -63,7 +61,6 @@ internal static partial class Helper20250320 {
string result = JsonSerializer.Serialize(this, MethodCollectionCommonSourceGenerationContext.Default.Method); string result = JsonSerializer.Serialize(this, MethodCollectionCommonSourceGenerationContext.Default.Method);
return result; return result;
} }
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
@ -102,8 +99,9 @@ internal static partial class Helper20250320 {
string[] cSharpFiles = Directory.GetFiles(repositoryDirectory, "*.cs", SearchOption.AllDirectories); string[] cSharpFiles = Directory.GetFiles(repositoryDirectory, "*.cs", SearchOption.AllDirectories);
ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles = logOnly ? new(cSharpFiles) : Helpers.HelperGit.GetOthersModifiedAndDeletedExcludingStandardFiles(repositoryDirectory, usePathCombine, cancellationToken); ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles = logOnly ? new(cSharpFiles) : Helpers.HelperGit.GetOthersModifiedAndDeletedExcludingStandardFiles(repositoryDirectory, usePathCombine, cancellationToken);
foreach (string cSharpFile in cSharpFiles) { foreach (string cSharpFile in cSharpFiles) {
if (!gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(cSharpFile)) if (!gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(cSharpFile)) {
continue; continue;
}
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
lines = File.ReadAllLines(cSharpFile); lines = File.ReadAllLines(cSharpFile);
check = SortFile(logger, logOnly, scopeSpaces, cSharpFile, lines); check = SortFile(logger, logOnly, scopeSpaces, cSharpFile, lines);
@ -111,34 +109,38 @@ internal static partial class Helper20250320 {
Thread.Sleep(500); Thread.Sleep(500);
changed.Add($"{i + 1:00}) {cSharpFile}"); changed.Add($"{i + 1:00}) {cSharpFile}");
} }
if (logOnly || !check) if (logOnly || !check) {
break; break;
}
} }
} }
if (changed.Count == 0) if (changed.Count == 0) {
logger.LogInformation("No changes :)"); logger.LogInformation("No changes :)");
else { } else {
changed.Reverse(); changed.Reverse();
foreach (string c in changed) foreach (string c in changed) {
logger.LogInformation(c); logger.LogInformation(c);
}
} }
} }
private static bool SortFile(ILogger<Worker> logger, bool logOnly, int scopeSpaces, string cSharpFile, string[] lines) { private static bool SortFile(ILogger<Worker> logger, bool logOnly, int scopeSpaces, string cSharpFile, string[] lines) {
bool result; bool result;
ReadOnlyCollection<Method> methods = GetMethods(logger, scopeSpaces, cSharpFile, lines); ReadOnlyCollection<Method> methods = GetMethods(logger, scopeSpaces, cSharpFile, lines);
if (methods.Count == 0) if (methods.Count == 0) {
result = false; result = false;
else if (methods.Any(l => l.EndLine is null)) } else if (methods.Any(l => l.EndLine is null)) {
result = false; result = false;
else if (logOnly) { } else if (logOnly) {
foreach (Method method in methods) foreach (Method method in methods) {
logger.LogInformation("{cSharpFile} - {Name} has {lines} line(s)", cSharpFile, method.Match.Name, (method.EndLine is null ? 999999 : method.EndLine.Value - method.StartLine).ToString("000000")); logger.LogInformation("{cSharpFile} - {Name} has {lines} line(s)", cSharpFile, method.Match.Name, (method.EndLine is null ? 999999 : method.EndLine.Value - method.StartLine).ToString("000000"));
}
result = false; result = false;
} else { } else {
ReadOnlyCollection<Method> sortedMethods = GetSortedMethods(methods); ReadOnlyCollection<Method> sortedMethods = GetSortedMethods(methods);
if (Debugger.IsAttached) if (Debugger.IsAttached) {
File.WriteAllText(Path.Combine(".vscode", "helper", ".json"), JsonSerializer.Serialize(sortedMethods.ToArray(), MethodCollectionCommonSourceGenerationContext.Default.MethodArray)); File.WriteAllText(Path.Combine(".vscode", "helper", ".json"), JsonSerializer.Serialize(sortedMethods.ToArray(), MethodCollectionCommonSourceGenerationContext.Default.MethodArray));
}
ReadOnlyCollection<MethodWith> collection = GetCollection(logger, lines, sortedMethods); ReadOnlyCollection<MethodWith> collection = GetCollection(logger, lines, sortedMethods);
result = WriteAllLines(cSharpFile, lines, collection); result = WriteAllLines(cSharpFile, lines, collection);
} }
@ -166,18 +168,23 @@ internal static partial class Helper20250320 {
System.Text.RegularExpressions.Match regularExpressionsMatch; System.Text.RegularExpressions.Match regularExpressionsMatch;
for (int i = 0; i < lines.Length; i++) { for (int i = 0; i < lines.Length; i++) {
check = GetNumberOfStartSpaces(lines, i); check = GetNumberOfStartSpaces(lines, i);
if (check != scopeSpaces) if (check != scopeSpaces) {
continue; continue;
}
line = lines[i].Trim(); line = lines[i].Trim();
if (string.IsNullOrEmpty(line)) if (string.IsNullOrEmpty(line)) {
continue; continue;
if (line.Length < 5) }
if (line.Length < 5) {
continue; continue;
if (line.EndsWith(',')) }
if (line.EndsWith(',')) {
continue; continue;
}
regularExpressionsMatch = CSharpMethodLine().Match(line); regularExpressionsMatch = CSharpMethodLine().Match(line);
if (!regularExpressionsMatch.Success) if (!regularExpressionsMatch.Success) {
continue; continue;
}
match = new(Async: regularExpressionsMatch.Groups[_Async].Value, match = new(Async: regularExpressionsMatch.Groups[_Async].Value,
Name: regularExpressionsMatch.Groups[_Name].Value, Name: regularExpressionsMatch.Groups[_Name].Value,
Parameters: regularExpressionsMatch.Groups[_Parameters].Value, Parameters: regularExpressionsMatch.Groups[_Parameters].Value,
@ -194,50 +201,61 @@ internal static partial class Helper20250320 {
Not: $"!{match.Name}(", Not: $"!{match.Name}(",
Wrap: $"({match.Name}("); Wrap: $"({match.Name}(");
logger.LogInformation("{line} {a} // {results}", line.Split(" =>")[0], "{ }", results.Count); logger.LogInformation("{line} {a} // {results}", line.Split(" =>")[0], "{ }", results.Count);
if (string.IsNullOrEmpty(match.Name)) if (string.IsNullOrEmpty(match.Name)) {
continue; continue;
}
blocks = 0; blocks = 0;
startLine = GetStartLine(lines, i); startLine = GetStartLine(lines, i);
if (!lines[startLine].StartsWith("#pragma") && !lines[startLine].StartsWith("#nullable")) if (!lines[startLine].StartsWith("#pragma") && !lines[startLine].StartsWith("#nullable")) {
firstLine = lines[startLine].Trim(); firstLine = lines[startLine].Trim();
else } else {
firstLine = lines[startLine + 1].Trim(); firstLine = lines[startLine + 1].Trim();
}
isLinq = !lines[i + 1].StartsWith("#pragma") && !lines[i + 1].StartsWith("#nullable") && lines[i].Trim()[^1] != '{' && lines[i + 1].Trim() != "{"; isLinq = !lines[i + 1].StartsWith("#pragma") && !lines[i + 1].StartsWith("#nullable") && lines[i].Trim()[^1] != '{' && lines[i + 1].Trim() != "{";
if (isLinq) if (isLinq) {
blocks++; blocks++;
}
endLine = null; endLine = null;
if (lines[i].Trim()[^1] == '{') if (lines[i].Trim()[^1] == '{') {
blocks++; blocks++;
}
for (int j = i + 1; j < lines.Length; j++) { for (int j = i + 1; j < lines.Length; j++) {
innerLine = lines[j].Trim(); innerLine = lines[j].Trim();
if (innerLine.StartsWith("#pragma") || innerLine.StartsWith("#nullable")) if (innerLine.StartsWith("#pragma") || innerLine.StartsWith("#nullable")) {
continue; continue;
}
if (isLinq && string.IsNullOrEmpty(innerLine)) { if (isLinq && string.IsNullOrEmpty(innerLine)) {
if (line.EndsWith(';')) if (line.EndsWith(';')) {
blocks--; blocks--;
}
} }
blocks += GetLineBlockCount(innerLine, isLinq); blocks += GetLineBlockCount(innerLine, isLinq);
if (blocks != 0) if (blocks != 0) {
continue; continue;
}
endLine = j; endLine = j;
if (lines.Length > j + 1 && string.IsNullOrEmpty(lines[j + 1].Trim())) if (lines.Length > j + 1 && string.IsNullOrEmpty(lines[j + 1].Trim())) {
endLine++; endLine++;
if (j > lines.Length - 2) }
if (j > lines.Length - 2) {
throw new Exception(); throw new Exception();
}
break; break;
} }
referenceToLineNumbers = GetReferenceToLineNumbers(lines: lines, start: 0, end: lines.Length, i: i, search: search, parameters: parameters); referenceToLineNumbers = GetReferenceToLineNumbers(lines: lines, start: 0, end: lines.Length, i: i, search: search, parameters: parameters);
if (referenceToLineNumbers.Count == 0) { if (referenceToLineNumbers.Count == 0) {
lineSegmentFirst = line.Split(match.Name)[0]; lineSegmentFirst = line.Split(match.Name)[0];
if (!lines[i - 1].Trim().StartsWith("[Obsolete")) { if (!lines[i - 1].Trim().StartsWith("[Obsolete")) {
if (lineSegmentFirst.StartsWith("private")) if (lineSegmentFirst.StartsWith("private")) {
logger.LogWarning("// <{cSharpFileName}> {name} with {parameters} parameter(s) <{line}>", Path.GetFileName(cSharpFile), match.Name, parameters, lineSegmentFirst); logger.LogWarning("// <{cSharpFileName}> {name} with {parameters} parameter(s) <{line}>", Path.GetFileName(cSharpFile), match.Name, parameters, lineSegmentFirst);
else } else {
logger.LogInformation("// <{cSharpFileName}> {name} with {parameters} parameter(s) <{line}>", Path.GetFileName(cSharpFile), match.Name, parameters, lineSegmentFirst); logger.LogInformation("// <{cSharpFileName}> {name} with {parameters} parameter(s) <{line}>", Path.GetFileName(cSharpFile), match.Name, parameters, lineSegmentFirst);
}
} }
} }
if (referenceToLineNumbers.Count == 0) if (referenceToLineNumbers.Count == 0) {
referenceToLineNumbers.Add(-1); referenceToLineNumbers.Add(-1);
}
logger.LogInformation("{line} {a} // {results} ~~~ {startLine} => {firstUsedLine}", line.Split(" =>")[0], "{ }", results.Count, startLine, referenceToLineNumbers.First()); logger.LogInformation("{line} {a} // {results} ~~~ {startLine} => {firstUsedLine}", line.Split(" =>")[0], "{ }", results.Count, startLine, referenceToLineNumbers.First());
method = new(EndLine: endLine, method = new(EndLine: endLine,
FirstLine: firstLine, FirstLine: firstLine,
@ -257,8 +275,9 @@ internal static partial class Helper20250320 {
private static int GetNumberOfStartSpaces(string[] lines, int i) { private static int GetNumberOfStartSpaces(string[] lines, int i) {
int result = 0; int result = 0;
foreach (char @char in lines[i]) { foreach (char @char in lines[i]) {
if (@char != ' ') if (@char != ' ') {
break; break;
}
result += 1; result += 1;
} }
return result; return result;
@ -289,8 +308,9 @@ internal static partial class Helper20250320 {
System.Text.RegularExpressions.Match[] matches = parameterRegex.Matches($"{match.Parameters},").ToArray(); System.Text.RegularExpressions.Match[] matches = parameterRegex.Matches($"{match.Parameters},").ToArray();
try { try {
foreach (System.Text.RegularExpressions.Match m in matches) { foreach (System.Text.RegularExpressions.Match m in matches) {
if (!m.Success) if (!m.Success) {
continue; continue;
}
value = m.Value.Trim()[..^1]; value = m.Value.Trim()[..^1];
segments = value.Split(' '); segments = value.Split(' ');
results.Add(segments[^1], value); results.Add(segments[^1], value);
@ -300,8 +320,9 @@ internal static partial class Helper20250320 {
System.Text.RegularExpressions.Match m; System.Text.RegularExpressions.Match m;
for (int i = 0; i < matches.Length; i++) { for (int i = 0; i < matches.Length; i++) {
m = matches[i]; m = matches[i];
if (!m.Success) if (!m.Success) {
continue; continue;
}
results.Add(i.ToString(), i.ToString()); results.Add(i.ToString(), i.ToString());
} }
} }
@ -313,8 +334,9 @@ internal static partial class Helper20250320 {
string line; string line;
for (int j = i - 1; j > -1; j--) { for (int j = i - 1; j > -1; j--) {
line = lines[j].Trim(); line = lines[j].Trim();
if (!line.StartsWith('[') && !line.StartsWith('#') && !line.StartsWith("/// ")) if (!line.StartsWith('[') && !line.StartsWith('#') && !line.StartsWith("/// ")) {
break; break;
}
result--; result--;
} }
return result; return result;
@ -324,16 +346,17 @@ internal static partial class Helper20250320 {
int result = 0; int result = 0;
bool ignore = false; bool ignore = false;
for (int i = 0; i < line.Length; i++) { for (int i = 0; i < line.Length; i++) {
if (line[i] == '\'') if (line[i] == '\'') {
i++; i++;
else if (!isLinq && !ignore && line[i] == '{') } else if (!isLinq && !ignore && line[i] == '{') {
result++; result++;
else if (!isLinq && !ignore && line[i] == '}') } else if (!isLinq && !ignore && line[i] == '}') {
result--; result--;
else if (isLinq && !ignore && line[i] == ';') } else if (isLinq && !ignore && line[i] == ';') {
result--; result--;
else if (i > 0 && line[i] == '"' && line[i - 1] != '\\') } else if (i > 0 && line[i] == '"' && line[i - 1] != '\\') {
ignore = !ignore; ignore = !ignore;
}
} }
return result; return result;
} }
@ -344,8 +367,9 @@ internal static partial class Helper20250320 {
string[] afterSegments; string[] afterSegments;
string lastSegmentBeforeDot; string lastSegmentBeforeDot;
for (int j = start; j < end; j++) { for (int j = start; j < end; j++) {
if (j == i) if (j == i) {
continue; continue;
}
segments = lines[j].Split(search.Name); segments = lines[j].Split(search.Name);
if (segments.Length == 1) { if (segments.Length == 1) {
segments = lines[j].Split(search.Not); segments = lines[j].Split(search.Not);
@ -354,23 +378,26 @@ internal static partial class Helper20250320 {
if (segments.Length == 1) { if (segments.Length == 1) {
if (!lines[j].EndsWith(search.Delegate)) { if (!lines[j].EndsWith(search.Delegate)) {
segments = lines[j].Split(search.Constructor); segments = lines[j].Split(search.Constructor);
if (segments.Length == 1) if (segments.Length == 1) {
continue; continue;
}
} }
} }
} }
} }
if (lines[j].EndsWith(search.Delegate)) if (lines[j].EndsWith(search.Delegate)) {
results.Add(j); results.Add(j);
else { } else {
lastSegmentBeforeDot = segments[^1].Split(").")[0]; lastSegmentBeforeDot = segments[^1].Split(").")[0];
if (parameters.Count == 0) { if (parameters.Count == 0) {
if (lastSegmentBeforeDot.Contains(',')) if (lastSegmentBeforeDot.Contains(',')) {
continue; continue;
}
} else { } else {
afterSegments = lastSegmentBeforeDot.Split(','); afterSegments = lastSegmentBeforeDot.Split(',');
if (afterSegments.Length != parameters.Count) if (afterSegments.Length != parameters.Count) {
continue; continue;
}
} }
results.Add(j); results.Add(j);
} }
@ -383,10 +410,12 @@ internal static partial class Helper20250320 {
List<Method> check = sortedMethods.ToList(); List<Method> check = sortedMethods.ToList();
foreach (Method method in sortedMethods) { foreach (Method method in sortedMethods) {
logger.LogInformation($"{method.Match.Name} => {method.Parameters.Count}"); logger.LogInformation($"{method.Match.Name} => {method.Parameters.Count}");
if (method.EndLine is null) if (method.EndLine is null) {
continue; continue;
if (!check.Remove(method)) }
if (!check.Remove(method)) {
continue; continue;
}
MethodWith methodWith = GetMethodWith(lines, sortedMethods, check, method, method.EndLine.Value); MethodWith methodWith = GetMethodWith(lines, sortedMethods, check, method, method.EndLine.Value);
results.Add(methodWith); results.Add(methodWith);
} }
@ -399,27 +428,32 @@ internal static partial class Helper20250320 {
MethodWith[] sortedReferences; MethodWith[] sortedReferences;
Dictionary<int, MethodWith> references = []; Dictionary<int, MethodWith> references = [];
foreach (Method m in methods) { foreach (Method m in methods) {
if (m.EndLine is null) if (m.EndLine is null) {
continue; continue;
if (m == method) }
if (m == method) {
continue; continue;
}
referenceToLineNumbers = GetReferenceToLineNumbers(lines: lines, start: method.StartLine, end: methodEndLineValue, i: -1, search: m.Search, parameters: m.Parameters); referenceToLineNumbers = GetReferenceToLineNumbers(lines: lines, start: method.StartLine, end: methodEndLineValue, i: -1, search: m.Search, parameters: m.Parameters);
if (referenceToLineNumbers.Count > 0) { if (referenceToLineNumbers.Count > 0) {
if (!check.Remove(m)) if (!check.Remove(m)) {
continue; continue;
}
foreach (int i in referenceToLineNumbers) { foreach (int i in referenceToLineNumbers) {
if (references.ContainsKey(i)) if (references.ContainsKey(i)) {
continue; continue;
}
methodWith = GetMethodWith(lines, methods, check, m, m.EndLine.Value); methodWith = GetMethodWith(lines, methods, check, m, m.EndLine.Value);
references.Add(i, methodWith); references.Add(i, methodWith);
break; break;
} }
} }
} }
if (references.Count < 2) if (references.Count < 2) {
sortedReferences = (from l in references select l.Value).ToArray(); sortedReferences = (from l in references select l.Value).ToArray();
else } else {
sortedReferences = (from l in references orderby l.Key select l.Value).ToArray(); sortedReferences = (from l in references orderby l.Key select l.Value).ToArray();
}
methodWith = new(EndLine: method.EndLine, methodWith = new(EndLine: method.EndLine,
FirstLine: method.FirstLine, FirstLine: method.FirstLine,
Line: method.Line, Line: method.Line,
@ -435,29 +469,33 @@ internal static partial class Helper20250320 {
private static bool WriteAllLines(string cSharpFile, string[] lines, ReadOnlyCollection<MethodWith> collection) { private static bool WriteAllLines(string cSharpFile, string[] lines, ReadOnlyCollection<MethodWith> collection) {
bool result; bool result;
if (Debugger.IsAttached) if (Debugger.IsAttached) {
WriteDebug(collection); WriteDebug(collection);
}
List<string> results = []; List<string> results = [];
ReadOnlyCollection<int> methodLines = GetMethodLines(collection); ReadOnlyCollection<int> methodLines = GetMethodLines(collection);
int maxMethodLines = methodLines.Max(); int maxMethodLines = methodLines.Max();
for (int i = 0; i < maxMethodLines; i++) { for (int i = 0; i < maxMethodLines; i++) {
if (methodLines.Contains(i)) if (methodLines.Contains(i)) {
continue; continue;
}
results.Add(lines[i]); results.Add(lines[i]);
} }
List<bool> nests = [true]; List<bool> nests = [true];
foreach (MethodWith methodWith in collection) { foreach (MethodWith methodWith in collection) {
if (methodWith.EndLine is null) if (methodWith.EndLine is null) {
continue; continue;
}
AppendLines(results, nests, lines, methodWith, methodWith.EndLine.Value); AppendLines(results, nests, lines, methodWith, methodWith.EndLine.Value);
} }
for (int i = maxMethodLines + 1; i < lines.Length; i++) for (int i = maxMethodLines + 1; i < lines.Length; i++) {
results.Add(lines[i]); results.Add(lines[i]);
}
string text = File.ReadAllText(cSharpFile); string text = File.ReadAllText(cSharpFile);
string join = string.Join(Environment.NewLine, results); string join = string.Join(Environment.NewLine, results);
if (join == text) if (join == text) {
result = false; result = false;
else { } else {
result = true; result = true;
File.WriteAllText(cSharpFile, join); File.WriteAllText(cSharpFile, join);
} }
@ -467,16 +505,18 @@ internal static partial class Helper20250320 {
private static void WriteDebug(ReadOnlyCollection<MethodWith> collection) { private static void WriteDebug(ReadOnlyCollection<MethodWith> collection) {
List<string> results = []; List<string> results = [];
List<bool> nests = [true]; List<bool> nests = [true];
foreach (MethodWith methodWith in collection) foreach (MethodWith methodWith in collection) {
AppendLines(results, nests, methodWith); AppendLines(results, nests, methodWith);
}
File.WriteAllText(Path.Combine(".vscode", "helper", ".md"), string.Join(Environment.NewLine, results)); File.WriteAllText(Path.Combine(".vscode", "helper", ".md"), string.Join(Environment.NewLine, results));
} }
private static void AppendLines(List<string> results, List<bool> nests, MethodWith methodWith) { private static void AppendLines(List<string> results, List<bool> nests, MethodWith methodWith) {
nests.Add(true); nests.Add(true);
results.Add($" - {new string('#', nests.Count)} {methodWith.Match.Name} => {methodWith.Parameters.Count}"); results.Add($" - {new string('#', nests.Count)} {methodWith.Match.Name} => {methodWith.Parameters.Count}");
foreach (MethodWith m in methodWith.References) foreach (MethodWith m in methodWith.References) {
AppendLines(results, nests, m); AppendLines(results, nests, m);
}
nests.RemoveAt(nests.Count - 1); nests.RemoveAt(nests.Count - 1);
} }
@ -484,23 +524,27 @@ internal static partial class Helper20250320 {
List<int> results = []; List<int> results = [];
List<bool> nests = [true]; List<bool> nests = [true];
foreach (MethodWith methodWith in collection) { foreach (MethodWith methodWith in collection) {
if (methodWith.EndLine is null) if (methodWith.EndLine is null) {
continue; continue;
}
AppendLineNumbers(results, nests, methodWith, methodWith.EndLine.Value); AppendLineNumbers(results, nests, methodWith, methodWith.EndLine.Value);
} }
int[] distinct = results.Distinct().ToArray(); int[] distinct = results.Distinct().ToArray();
if (distinct.Length != results.Count) if (distinct.Length != results.Count) {
throw new Exception(); throw new Exception();
}
return new(results); return new(results);
} }
private static void AppendLineNumbers(List<int> results, List<bool> nests, MethodWith methodWith, int methodWithEndLineValue) { private static void AppendLineNumbers(List<int> results, List<bool> nests, MethodWith methodWith, int methodWithEndLineValue) {
nests.Add(true); nests.Add(true);
for (int i = methodWith.StartLine; i < methodWithEndLineValue + 1; i++) for (int i = methodWith.StartLine; i < methodWithEndLineValue + 1; i++) {
results.Add(i); results.Add(i);
}
foreach (MethodWith m in methodWith.References) { foreach (MethodWith m in methodWith.References) {
if (m.EndLine is null) if (m.EndLine is null) {
continue; continue;
}
AppendLineNumbers(results, nests, m, m.EndLine.Value); AppendLineNumbers(results, nests, m, m.EndLine.Value);
} }
nests.RemoveAt(nests.Count - 1); nests.RemoveAt(nests.Count - 1);
@ -508,11 +552,13 @@ internal static partial class Helper20250320 {
private static void AppendLines(List<string> results, List<bool> nests, string[] lines, MethodWith methodWith, int methodWithEndLineValue) { private static void AppendLines(List<string> results, List<bool> nests, string[] lines, MethodWith methodWith, int methodWithEndLineValue) {
nests.Add(true); nests.Add(true);
for (int i = methodWith.StartLine; i < methodWithEndLineValue + 1; i++) for (int i = methodWith.StartLine; i < methodWithEndLineValue + 1; i++) {
results.Add(lines[i]); results.Add(lines[i]);
}
foreach (MethodWith m in methodWith.References) { foreach (MethodWith m in methodWith.References) {
if (m.EndLine is null) if (m.EndLine is null) {
continue; continue;
}
AppendLines(results, nests, lines, m, m.EndLine.Value); AppendLines(results, nests, lines, m, m.EndLine.Value);
} }
nests.RemoveAt(nests.Count - 1); nests.RemoveAt(nests.Count - 1);

View File

@ -1,8 +1,6 @@
using System.Collections.ObjectModel;
using File_Folder_Helper.Helpers; using File_Folder_Helper.Helpers;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.ADO2025.PI5; namespace File_Folder_Helper.ADO2025.PI5;
@ -21,14 +19,15 @@ internal static partial class Helper20250321 {
bool check = searchPattern.Split('.').Length == 3; bool check = searchPattern.Split('.').Length == 3;
ReadOnlyCollection<ThreeDeep> collection = ThreeDeep.GetCollection(files); ReadOnlyCollection<ThreeDeep> collection = ThreeDeep.GetCollection(files);
foreach (ThreeDeep threeDeep in collection) { foreach (ThreeDeep threeDeep in collection) {
if (!json && check) if (!json && check) {
fileNameWithoutExtension = threeDeep.DirectoryName; fileNameWithoutExtension = threeDeep.DirectoryName;
else if (!json && !check) } else if (!json && !check) {
fileNameWithoutExtension = threeDeep.FileNameWithoutExtension; fileNameWithoutExtension = threeDeep.FileNameWithoutExtension;
else if (json) } else if (json) {
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(threeDeep.FileNameWithoutExtension); fileNameWithoutExtension = Path.GetFileNameWithoutExtension(threeDeep.FileNameWithoutExtension);
else } else {
throw new NotImplementedException(); throw new NotImplementedException();
}
directory = $"{fileNameWithoutExtension[^1]}{fileNameWithoutExtension[^3..][..2]}"; directory = $"{fileNameWithoutExtension[^1]}{fileNameWithoutExtension[^3..][..2]}";
if (json || (!json && !check)) { if (json || (!json && !check)) {
record = new(Directory: Path.Combine(sourceDirectory, "new-a", directory), record = new(Directory: Path.Combine(sourceDirectory, "new-a", directory),
@ -38,13 +37,13 @@ internal static partial class Helper20250321 {
record = new(Directory: Path.Combine(sourceDirectory, "new-b", directory, threeDeep.DirectoryName), record = new(Directory: Path.Combine(sourceDirectory, "new-b", directory, threeDeep.DirectoryName),
File: $"{threeDeep.FileNameWithoutExtension}{threeDeep.Extension}", File: $"{threeDeep.FileNameWithoutExtension}{threeDeep.Extension}",
ThreeDeep: threeDeep); ThreeDeep: threeDeep);
} else } else {
throw new NotImplementedException(); throw new NotImplementedException();
}
results.Add(record); results.Add(record);
} }
return results.AsReadOnly(); return results.AsReadOnly();
} }
} }
private record ThreeDeep(string Extension, private record ThreeDeep(string Extension,
@ -83,17 +82,19 @@ internal static partial class Helper20250321 {
internal static void MoveToLast(ILogger<Worker> logger, List<string> args) { internal static void MoveToLast(ILogger<Worker> logger, List<string> args) {
string[] searchPatterns = args[2].Split('~'); string[] searchPatterns = args[2].Split('~');
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
if (searchPatterns.Length == 1) if (searchPatterns.Length == 1) {
logger.LogInformation("No code for just one!"); logger.LogInformation("No code for just one!");
else { } else {
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory); HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
ReadOnlyCollection<Record> collection = GetCollection(logger, searchPatterns, sourceDirectory); ReadOnlyCollection<Record> collection = GetCollection(logger, searchPatterns, sourceDirectory);
if (collection.Count != 0) if (collection.Count != 0) {
UseCollection(collection); UseCollection(collection);
else } else {
logger.LogInformation("No files!"); logger.LogInformation("No files!");
if (collection.Count != 0) }
if (collection.Count != 0) {
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory); HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
}
} }
} }
@ -102,9 +103,9 @@ internal static partial class Helper20250321 {
List<Record> results = []; List<Record> results = [];
foreach (string searchPattern in searchPatterns) { foreach (string searchPattern in searchPatterns) {
files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
if (files.Length == 0) if (files.Length == 0) {
logger.LogWarning("<{files}>(s)", files.Length); logger.LogWarning("<{files}>(s)", files.Length);
else { } else {
ReadOnlyCollection<Record> collection = Record.GetCollection(sourceDirectory, searchPattern, files); ReadOnlyCollection<Record> collection = Record.GetCollection(sourceDirectory, searchPattern, files);
results.AddRange(collection); results.AddRange(collection);
} }
@ -117,19 +118,22 @@ internal static partial class Helper20250321 {
string checkFile; string checkFile;
List<string> distinct = []; List<string> distinct = [];
foreach (Record record in collection) { foreach (Record record in collection) {
if (distinct.Contains(record.Directory)) if (distinct.Contains(record.Directory)) {
continue; continue;
}
distinct.Add(record.Directory); distinct.Add(record.Directory);
} }
foreach (string directory in distinct) { foreach (string directory in distinct) {
if (Directory.Exists(directory)) if (Directory.Exists(directory)) {
continue; continue;
}
_ = Directory.CreateDirectory(directory); _ = Directory.CreateDirectory(directory);
} }
foreach (Record record in collection) { foreach (Record record in collection) {
checkFile = Path.Combine(record.Directory, record.File); checkFile = Path.Combine(record.Directory, record.File);
if (File.Exists(checkFile)) if (File.Exists(checkFile)) {
continue; continue;
}
fullPath = ThreeDeep.GetFullPath(record.ThreeDeep); fullPath = ThreeDeep.GetFullPath(record.ThreeDeep);
File.Move(fullPath, checkFile); File.Move(fullPath, checkFile);
} }

View File

@ -1,8 +1,7 @@
using Microsoft.Extensions.Logging;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI5; namespace File_Folder_Helper.ADO2025.PI5;
internal static partial class Helper20250404 { internal static partial class Helper20250404 {
@ -128,10 +127,11 @@ internal static partial class Helper20250404 {
ParseMetrics(logger, fileName, url); ParseMetrics(logger, fileName, url);
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
if (files.Length == 0) if (files.Length == 0) {
logger.LogWarning("<{files}>(s)", files.Length); logger.LogWarning("<{files}>(s)", files.Length);
else } else {
KumaToGatus(files); KumaToGatus(files);
}
} }
private static void ParseMetrics(ILogger<Worker> logger, string fileName, string url) { private static void ParseMetrics(ILogger<Worker> logger, string fileName, string url) {
@ -174,12 +174,14 @@ internal static partial class Helper20250404 {
string checkFile; string checkFile;
foreach (string file in files) { foreach (string file in files) {
checkFile = file.ToLower().Replace('_', '-'); checkFile = file.ToLower().Replace('_', '-');
if (checkFile != file) if (checkFile != file) {
File.Move(file, checkFile); File.Move(file, checkFile);
}
json = File.ReadAllText(checkFile); json = File.ReadAllText(checkFile);
kuma = JsonSerializer.Deserialize(json, KumaCommonSourceGenerationContext.Default.Kuma); kuma = JsonSerializer.Deserialize(json, KumaCommonSourceGenerationContext.Default.Kuma);
if (kuma is null) if (kuma is null) {
continue; continue;
}
WriteGatus(checkFile, kuma); WriteGatus(checkFile, kuma);
} }
} }
@ -193,8 +195,9 @@ internal static partial class Helper20250404 {
]; ];
string[] segments; string[] segments;
foreach (MonitorList monitorList in kuma.MonitorList) { foreach (MonitorList monitorList in kuma.MonitorList) {
if (monitorList.Type is not "http" and not "postgres") if (monitorList.Type is not "http" and not "postgres") {
continue; continue;
}
results.Add($" - name: {monitorList.Name}"); results.Add($" - name: {monitorList.Name}");
results.Add($" group: {monitorList.PathName.Split(' ')[0]}"); results.Add($" group: {monitorList.PathName.Split(' ')[0]}");
results.Add($" enabled: {monitorList.Active.ToString().ToLower()}"); results.Add($" enabled: {monitorList.Active.ToString().ToLower()}");
@ -208,19 +211,22 @@ internal static partial class Helper20250404 {
} }
results.Add(" conditions:"); results.Add(" conditions:");
results.Add(" - \"[STATUS] < 300\""); results.Add(" - \"[STATUS] < 300\"");
if (monitorList.Url.Contains("https")) if (monitorList.Url.Contains("https")) {
results.Add(" - \"[CERTIFICATE_EXPIRATION] > 48h\""); results.Add(" - \"[CERTIFICATE_EXPIRATION] > 48h\"");
}
results.Add($" - \"[RESPONSE_TIME] < {monitorList.Timeout}\""); results.Add($" - \"[RESPONSE_TIME] < {monitorList.Timeout}\"");
} else if (monitorList.Type == "postgres") { } else if (monitorList.Type == "postgres") {
segments = monitorList.DatabaseConnectionString.Split('@'); segments = monitorList.DatabaseConnectionString.Split('@');
if (segments.Length != 2) if (segments.Length != 2) {
continue; continue;
}
results.Add($" # connectionString: \"{monitorList.DatabaseConnectionString}\""); results.Add($" # connectionString: \"{monitorList.DatabaseConnectionString}\"");
results.Add($" url: \"tcp://{segments[1].Split('/')[0]}\""); results.Add($" url: \"tcp://{segments[1].Split('/')[0]}\"");
results.Add(" conditions:"); results.Add(" conditions:");
results.Add(" - \"[CONNECTED] == true\""); results.Add(" - \"[CONNECTED] == true\"");
} else } else {
throw new NotImplementedException(); throw new NotImplementedException();
}
results.Add(" alerts:"); results.Add(" alerts:");
results.Add(" - type: email"); results.Add(" - type: email");
results.Add(" description: \"healthcheck failed\""); results.Add(" description: \"healthcheck failed\"");

View File

@ -1,12 +1,10 @@
using File_Folder_Helper.Models;
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using File_Folder_Helper.Models;
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.Logging;
#if ShellProgressBar #if ShellProgressBar
using ShellProgressBar; using ShellProgressBar;
#endif #endif
@ -65,53 +63,53 @@ internal static partial class Helper20250407 {
const int rightSideOnlyIndex = 4; const int rightSideOnlyIndex = 4;
const int leftSideIsNewerIndex = 1; const int leftSideIsNewerIndex = 1;
const int rightSideIsNewerIndex = 3; const int rightSideIsNewerIndex = 3;
if (string.IsNullOrEmpty(segments[leftSideOnlyIndex])) if (string.IsNullOrEmpty(segments[leftSideOnlyIndex])) {
leftSideOnly = null; leftSideOnly = null;
else if (segments[leftSideOnlyIndex][0] == plus) } else if (segments[leftSideOnlyIndex][0] == plus) {
leftSideOnly = true; leftSideOnly = true;
else if (segments[leftSideOnlyIndex][0] == minus) } else if (segments[leftSideOnlyIndex][0] == minus) {
leftSideOnly = false; leftSideOnly = false;
else { } else {
check = false; check = false;
leftSideOnly = null; leftSideOnly = null;
} }
if (string.IsNullOrEmpty(segments[leftSideIsNewerIndex])) if (string.IsNullOrEmpty(segments[leftSideIsNewerIndex])) {
leftSideIsNewer = null; leftSideIsNewer = null;
else if (segments[leftSideIsNewerIndex][0] == greaterThan) } else if (segments[leftSideIsNewerIndex][0] == greaterThan) {
leftSideIsNewer = true; leftSideIsNewer = true;
else if (segments[leftSideIsNewerIndex][0] == lessThan) } else if (segments[leftSideIsNewerIndex][0] == lessThan) {
leftSideIsNewer = false; leftSideIsNewer = false;
else { } else {
check = false; check = false;
leftSideIsNewer = null; leftSideIsNewer = null;
} }
if (string.IsNullOrEmpty(segments[notEqualButIndex])) if (string.IsNullOrEmpty(segments[notEqualButIndex])) {
notEqualBut = null; notEqualBut = null;
else if (segments[notEqualButIndex][0] == greaterThan) } else if (segments[notEqualButIndex][0] == greaterThan) {
notEqualBut = true; notEqualBut = true;
else if (segments[notEqualButIndex][0] == lessThan) } else if (segments[notEqualButIndex][0] == lessThan) {
notEqualBut = false; notEqualBut = false;
else { } else {
check = false; check = false;
notEqualBut = null; notEqualBut = null;
} }
if (string.IsNullOrEmpty(segments[rightSideIsNewerIndex])) if (string.IsNullOrEmpty(segments[rightSideIsNewerIndex])) {
rightSideIsNewer = null; rightSideIsNewer = null;
else if (segments[rightSideIsNewerIndex][0] == greaterThan) } else if (segments[rightSideIsNewerIndex][0] == greaterThan) {
rightSideIsNewer = true; rightSideIsNewer = true;
else if (segments[rightSideIsNewerIndex][0] == lessThan) } else if (segments[rightSideIsNewerIndex][0] == lessThan) {
rightSideIsNewer = false; rightSideIsNewer = false;
else { } else {
check = false; check = false;
rightSideIsNewer = null; rightSideIsNewer = null;
} }
if (string.IsNullOrEmpty(segments[rightSideOnlyIndex])) if (string.IsNullOrEmpty(segments[rightSideOnlyIndex])) {
rightSideOnly = null; rightSideOnly = null;
else if (segments[rightSideOnlyIndex][0] == plus) } else if (segments[rightSideOnlyIndex][0] == plus) {
rightSideOnly = true; rightSideOnly = true;
else if (segments[rightSideOnlyIndex][0] == minus) } else if (segments[rightSideOnlyIndex][0] == minus) {
rightSideOnly = false; rightSideOnly = false;
else { } else {
check = false; check = false;
rightSideOnly = null; rightSideOnly = null;
} }
@ -160,9 +158,9 @@ internal static partial class Helper20250407 {
matcher.AddIncludePatterns(!File.Exists(includePatternsFile) ? ["*"] : File.ReadAllLines(includePatternsFile)); matcher.AddIncludePatterns(!File.Exists(includePatternsFile) ? ["*"] : File.ReadAllLines(includePatternsFile));
matcher.AddExcludePatterns(!File.Exists(excludePatternsFile) ? ["System Volume Information"] : File.ReadAllLines(excludePatternsFile)); matcher.AddExcludePatterns(!File.Exists(excludePatternsFile) ? ["System Volume Information"] : File.ReadAllLines(excludePatternsFile));
ReadOnlyCollection<Record> rightRecords = GetRecords(rightDirectory, matcher); ReadOnlyCollection<Record> rightRecords = GetRecords(rightDirectory, matcher);
if (rightRecords.Count == 0) if (rightRecords.Count == 0) {
logger.LogInformation("No source records"); logger.LogInformation("No source records");
else { } else {
string checkFile = Path.Combine(rightDirectory, fileName); string checkFile = Path.Combine(rightDirectory, fileName);
Review review = new(AreEqual: null, Review review = new(AreEqual: null,
LeftSideIsNewer: null, LeftSideIsNewer: null,
@ -173,9 +171,9 @@ internal static partial class Helper20250407 {
RightSideOnly: null); RightSideOnly: null);
string json = JsonSerializer.Serialize(review, ReviewCommonSourceGenerationContext.Default.Review); string json = JsonSerializer.Serialize(review, ReviewCommonSourceGenerationContext.Default.Review);
WriteAllText(checkFile, json); WriteAllText(checkFile, json);
if (rootUniformResourceLocators.Length == 0) if (rootUniformResourceLocators.Length == 0) {
logger.LogInformation("No urls"); logger.LogInformation("No urls");
else { } else {
string format = NginxFileSystem.GetFormat(); string format = NginxFileSystem.GetFormat();
TimeZoneInfo timeZoneInfo = TimeZoneInfo.Local; TimeZoneInfo timeZoneInfo = TimeZoneInfo.Local;
Sync(logger, rightDirectory, fileName, logic, rootUniformResourceLocators, rightRecords, format, timeZoneInfo); Sync(logger, rightDirectory, fileName, logic, rootUniformResourceLocators, rightRecords, format, timeZoneInfo);
@ -194,11 +192,13 @@ internal static partial class Helper20250407 {
ReadOnlyCollection<ReadOnlyCollection<string>> collection = Helpers.HelperDirectory.GetFilesCollection(rightDirectory, "*", "*"); ReadOnlyCollection<ReadOnlyCollection<string>> collection = Helpers.HelperDirectory.GetFilesCollection(rightDirectory, "*", "*");
foreach (ReadOnlyCollection<string> c in collection) { foreach (ReadOnlyCollection<string> c in collection) {
foreach (string f in c) { foreach (string f in c) {
if (!matcher.Match(rightDirectory, f).HasMatches) if (!matcher.Match(rightDirectory, f).HasMatches) {
continue; continue;
}
fileInfo = new(f); fileInfo = new(f);
if (fileInfo.Length == 0) if (fileInfo.Length == 0) {
continue; continue;
}
relativePath = Path.GetRelativePath(rightDirectory, fileInfo.FullName); relativePath = Path.GetRelativePath(rightDirectory, fileInfo.FullName);
record = new(RelativePath: relativePath, record = new(RelativePath: relativePath,
Size: fileInfo.Length, Size: fileInfo.Length,
@ -211,20 +211,21 @@ internal static partial class Helper20250407 {
private static void WriteAllText(string path, string text) { private static void WriteAllText(string path, string text) {
string check = !File.Exists(path) ? string.Empty : File.ReadAllText(path); string check = !File.Exists(path) ? string.Empty : File.ReadAllText(path);
if (check != text) if (check != text) {
File.WriteAllText(path, text); File.WriteAllText(path, text);
}
} }
private static void Sync(ILogger<Worker> logger, string rightDirectory, string fileName, Logic? logic, string[] rootUniformResourceLocators, ReadOnlyCollection<Record> rightRecords, string format, TimeZoneInfo timeZoneInfo) { private static void Sync(ILogger<Worker> logger, string rightDirectory, string fileName, Logic? logic, string[] rootUniformResourceLocators, ReadOnlyCollection<Record> rightRecords, string format, TimeZoneInfo timeZoneInfo) {
Review? review; Review? review;
foreach (string rootUniformResourceLocator in rootUniformResourceLocators) { foreach (string rootUniformResourceLocator in rootUniformResourceLocators) {
if (!rootUniformResourceLocator.StartsWith("https:")) if (!rootUniformResourceLocator.StartsWith("https:")) {
logger.LogInformation("Not supported URL <{url}>", rootUniformResourceLocator); logger.LogInformation("Not supported URL <{url}>", rootUniformResourceLocator);
else { } else {
review = GetJsonResponse(logger, fileName, rootUniformResourceLocator, format, timeZoneInfo); review = GetJsonResponse(logger, fileName, rootUniformResourceLocator, format, timeZoneInfo);
if (review?.Records is null || review.Records.Length == 0) if (review?.Records is null || review.Records.Length == 0) {
logger.LogInformation("No response records"); logger.LogInformation("No response records");
else { } else {
ReadOnlyCollection<Record> leftRecords = review.Records.AsReadOnly(); ReadOnlyCollection<Record> leftRecords = review.Records.AsReadOnly();
Sync(logger, rightDirectory, fileName, logic, rightRecords, rootUniformResourceLocator, leftRecords); Sync(logger, rightDirectory, fileName, logic, rightRecords, rootUniformResourceLocator, leftRecords);
} }
@ -285,8 +286,9 @@ internal static partial class Helper20250407 {
match = nginxFileSystem.LastModified.Value; match = nginxFileSystem.LastModified.Value;
continue; continue;
} }
if (nginxFileSystem.LastModified is null || nginxFileSystem.LastModified <= dateTime) if (nginxFileSystem.LastModified is null || nginxFileSystem.LastModified <= dateTime) {
continue; continue;
}
dateTime = nginxFileSystem.LastModified.Value; dateTime = nginxFileSystem.LastModified.Value;
} }
result = match is not null && match.Value > dateTime; result = match is not null && match.Value > dateTime;
@ -298,8 +300,9 @@ internal static partial class Helper20250407 {
string checkFile; string checkFile;
HttpClient httpClient = new(); HttpClient httpClient = new();
checkFile = Path.Combine(rightDirectory, fileName); checkFile = Path.Combine(rightDirectory, fileName);
if (File.Exists(checkFile)) if (File.Exists(checkFile)) {
File.Delete(checkFile); File.Delete(checkFile);
}
ReadOnlyCollection<Segment> areEqual = GetAreEqual(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords); ReadOnlyCollection<Segment> areEqual = GetAreEqual(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords);
ReadOnlyCollection<Segment> notEqualBut = GetNotEqualBut(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords); ReadOnlyCollection<Segment> notEqualBut = GetNotEqualBut(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords);
ReadOnlyCollection<Segment> leftSideOnly = GetLeftSideOnly(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords); ReadOnlyCollection<Segment> leftSideOnly = GetLeftSideOnly(rightDirectory, fileName, rightRecords, rootUniformResourceLocators, leftRecords);
@ -316,26 +319,36 @@ internal static partial class Helper20250407 {
json = JsonSerializer.Serialize(review, ReviewCommonSourceGenerationContext.Default.Review); json = JsonSerializer.Serialize(review, ReviewCommonSourceGenerationContext.Default.Review);
checkFile = Path.Combine(rightDirectory, fileName); checkFile = Path.Combine(rightDirectory, fileName);
WriteAllText(checkFile, json); WriteAllText(checkFile, json);
if (notEqualBut.Count > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Minus && !l.NotEqualBut.Value) if (notEqualBut.Count > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Minus && !l.NotEqualBut.Value) {
logger.LogDebug("Doing nothing with {name}", nameof(Logic.NotEqualBut)); logger.LogDebug("Doing nothing with {name}", nameof(Logic.NotEqualBut));
if (leftSideOnly.Count > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Minus && !l.LeftSideOnly.Value) }
if (leftSideOnly.Count > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Minus && !l.LeftSideOnly.Value) {
throw new NotImplementedException("Not possible with https!"); throw new NotImplementedException("Not possible with https!");
if (leftSideIsNewer.Count > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.LessThan && !l.LeftSideIsNewer.Value) }
if (leftSideIsNewer.Count > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.LessThan && !l.LeftSideIsNewer.Value) {
throw new NotImplementedException("Not possible with https!"); throw new NotImplementedException("Not possible with https!");
if (rightSideIsNewer.Count > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.LessThan && !l.RightSideIsNewer.Value) }
if (rightSideIsNewer.Count > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.LessThan && !l.RightSideIsNewer.Value) {
throw new NotImplementedException("Not possible with https!"); throw new NotImplementedException("Not possible with https!");
if (rightSideOnly.Count > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Plus && l.RightSideOnly.Value) }
if (rightSideOnly.Count > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Plus && l.RightSideOnly.Value) {
throw new NotImplementedException("Not possible with https!"); throw new NotImplementedException("Not possible with https!");
if (rightSideOnly.Count > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Minus && !l.RightSideOnly.Value) }
if (rightSideOnly.Count > 0 && l is not null && l.RightSideOnly is not null && l.Raw[l.RightSideOnlyIndex][0] == l.Minus && !l.RightSideOnly.Value) {
DoWork(logger, rightDirectory, httpClient, rightSideOnly, delete: true, download: false); DoWork(logger, rightDirectory, httpClient, rightSideOnly, delete: true, download: false);
if (leftSideOnly.Count > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Plus && l.LeftSideOnly.Value) }
if (leftSideOnly.Count > 0 && l is not null && l.LeftSideOnly is not null && l.Raw[l.LeftSideOnlyIndex][0] == l.Plus && l.LeftSideOnly.Value) {
DoWork(logger, rightDirectory, httpClient, leftSideOnly, delete: false, download: true); DoWork(logger, rightDirectory, httpClient, leftSideOnly, delete: false, download: true);
if (leftSideIsNewer.Count > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.GreaterThan && l.LeftSideIsNewer.Value) }
if (leftSideIsNewer.Count > 0 && l is not null && l.LeftSideIsNewer is not null && l.Raw[l.LeftSideIsNewerIndex][0] == l.GreaterThan && l.LeftSideIsNewer.Value) {
DoWork(logger, rightDirectory, httpClient, leftSideIsNewer, delete: true, download: true); DoWork(logger, rightDirectory, httpClient, leftSideIsNewer, delete: true, download: true);
if (notEqualBut.Count > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Plus && l.NotEqualBut.Value) }
if (notEqualBut.Count > 0 && l is not null && l.NotEqualBut is not null && l.Raw[l.NotEqualButIndex][0] == l.Plus && l.NotEqualBut.Value) {
DoWork(logger, rightDirectory, httpClient, notEqualBut, delete: true, download: true); DoWork(logger, rightDirectory, httpClient, notEqualBut, delete: true, download: true);
if (rightSideIsNewer.Count > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.GreaterThan && l.RightSideIsNewer.Value) }
if (rightSideIsNewer.Count > 0 && l is not null && l.RightSideIsNewer is not null && l.Raw[l.RightSideIsNewerIndex][0] == l.GreaterThan && l.RightSideIsNewer.Value) {
DoWork(logger, rightDirectory, httpClient, rightSideIsNewer, delete: true, download: true); DoWork(logger, rightDirectory, httpClient, rightSideIsNewer, delete: true, download: true);
}
} }
private static ReadOnlyCollection<Segment> GetAreEqual(string rightDirectory, string fileName, ReadOnlyCollection<Record> rightRecords, string rootUniformResourceLocators, ReadOnlyCollection<Record> leftRecords) { private static ReadOnlyCollection<Segment> GetAreEqual(string rightDirectory, string fileName, ReadOnlyCollection<Record> rightRecords, string rootUniformResourceLocators, ReadOnlyCollection<Record> leftRecords) {
@ -350,13 +363,16 @@ internal static partial class Helper20250407 {
checkDirectory = r.RelativePath; checkDirectory = r.RelativePath;
continue; continue;
} }
if (r.RelativePath == rightDirectory || r.RelativePath == fileName) if (r.RelativePath == rightDirectory || r.RelativePath == fileName) {
continue; continue;
if (!keyValuePairs.TryGetValue(r.RelativePath, out record)) }
if (!keyValuePairs.TryGetValue(r.RelativePath, out record)) {
continue; continue;
}
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds; totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
if (record.Size != r.Size || totalSeconds is > 2 or < -2) if (record.Size != r.Size || totalSeconds is > 2 or < -2) {
continue; continue;
}
segment = new(Left: r, segment = new(Left: r,
LeftDirectory: checkDirectory, LeftDirectory: checkDirectory,
Right: record, Right: record,
@ -369,8 +385,9 @@ internal static partial class Helper20250407 {
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(ReadOnlyCollection<Record> records) { private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(ReadOnlyCollection<Record> records) {
Dictionary<string, Record> results = []; Dictionary<string, Record> results = [];
foreach (Record record in records) foreach (Record record in records) {
results.Add(record.RelativePath, record); results.Add(record.RelativePath, record);
}
return new(results); return new(results);
} }
@ -386,15 +403,19 @@ internal static partial class Helper20250407 {
checkDirectory = r.RelativePath; checkDirectory = r.RelativePath;
continue; continue;
} }
if (r.RelativePath == rightDirectory || r.RelativePath == fileName) if (r.RelativePath == rightDirectory || r.RelativePath == fileName) {
continue; continue;
if (!keyValuePairs.TryGetValue(r.RelativePath, out record)) }
if (!keyValuePairs.TryGetValue(r.RelativePath, out record)) {
continue; continue;
if (record.Size == r.Size) }
if (record.Size == r.Size) {
continue; continue;
}
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds; totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
if (totalSeconds is >= 2 or <= -2) if (totalSeconds is >= 2 or <= -2) {
continue; continue;
}
segment = new(Left: r, segment = new(Left: r,
LeftDirectory: checkDirectory, LeftDirectory: checkDirectory,
Right: record, Right: record,
@ -416,10 +437,12 @@ internal static partial class Helper20250407 {
checkDirectory = r.RelativePath; checkDirectory = r.RelativePath;
continue; continue;
} }
if (r.RelativePath == rightDirectory || r.RelativePath == fileName) if (r.RelativePath == rightDirectory || r.RelativePath == fileName) {
continue; continue;
if (keyValuePairs.TryGetValue(r.RelativePath, out record)) }
if (keyValuePairs.TryGetValue(r.RelativePath, out record)) {
continue; continue;
}
segment = new(Left: r, segment = new(Left: r,
LeftDirectory: checkDirectory, LeftDirectory: checkDirectory,
Right: record, Right: record,
@ -441,10 +464,12 @@ internal static partial class Helper20250407 {
checkDirectory = r.RelativePath; checkDirectory = r.RelativePath;
continue; continue;
} }
if (r.RelativePath == rightDirectory || r.RelativePath == fileName) if (r.RelativePath == rightDirectory || r.RelativePath == fileName) {
continue; continue;
if (keyValuePairs.TryGetValue(r.RelativePath, out record)) }
if (keyValuePairs.TryGetValue(r.RelativePath, out record)) {
continue; continue;
}
segment = new(Left: record, segment = new(Left: record,
LeftDirectory: null, LeftDirectory: null,
Right: r, Right: r,
@ -467,13 +492,16 @@ internal static partial class Helper20250407 {
checkDirectory = r.RelativePath; checkDirectory = r.RelativePath;
continue; continue;
} }
if (r.RelativePath == rightDirectory || r.RelativePath == fileName) if (r.RelativePath == rightDirectory || r.RelativePath == fileName) {
continue; continue;
if (!keyValuePairs.TryGetValue(r.RelativePath, out record)) }
if (!keyValuePairs.TryGetValue(r.RelativePath, out record)) {
continue; continue;
}
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds; totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
if (totalSeconds is > -2) if (totalSeconds is > -2) {
continue; continue;
}
segment = new(Left: r, segment = new(Left: r,
LeftDirectory: checkDirectory, LeftDirectory: checkDirectory,
Right: record, Right: record,
@ -496,13 +524,16 @@ internal static partial class Helper20250407 {
checkDirectory = r.RelativePath; checkDirectory = r.RelativePath;
continue; continue;
} }
if (r.RelativePath == rightDirectory || r.RelativePath == fileName) if (r.RelativePath == rightDirectory || r.RelativePath == fileName) {
continue; continue;
if (!keyValuePairs.TryGetValue(r.RelativePath, out record)) }
if (!keyValuePairs.TryGetValue(r.RelativePath, out record)) {
continue; continue;
}
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds; totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
if (totalSeconds is > -2) if (totalSeconds is > -2) {
continue; continue;
}
segment = new(Left: record, segment = new(Left: record,
LeftDirectory: null, LeftDirectory: null,
Right: r, Right: r,
@ -546,20 +577,6 @@ internal static partial class Helper20250407 {
return result; return result;
} }
private static string GetDurationWithSuffix(long ticks) {
string result;
TimeSpan timeSpan = new(DateTime.Now.Ticks - ticks);
if (timeSpan.TotalMilliseconds < 1000)
result = $"{timeSpan.Milliseconds} ms";
else if (timeSpan.TotalMilliseconds < 60000)
result = $"{Math.Floor(timeSpan.TotalSeconds)} s";
else if (timeSpan.TotalMilliseconds < 3600000)
result = $"{Math.Floor(timeSpan.TotalMinutes)} m";
else
result = $"{Math.Floor(timeSpan.TotalHours)} h";
return result;
}
private static void DoDeletes(ILogger<Worker> logger, string rightDirectory, ReadOnlyCollection<Segment> segments) { private static void DoDeletes(ILogger<Worker> logger, string rightDirectory, ReadOnlyCollection<Segment> segments) {
Record? record; Record? record;
string size; string size;
@ -572,8 +589,9 @@ internal static partial class Helper20250407 {
progressBar.Tick(); progressBar.Tick();
#endif #endif
record = segments[i].Right; record = segments[i].Right;
if (record is null) if (record is null) {
continue; continue;
}
size = GetSizeWithSuffix(record.Size); size = GetSizeWithSuffix(record.Size);
try { try {
File.Delete(Path.Combine(rightDirectory, record.RelativePath)); File.Delete(Path.Combine(rightDirectory, record.RelativePath));
@ -609,9 +627,9 @@ internal static partial class Helper20250407 {
size = GetSizeWithSuffix(download.Size); size = GetSizeWithSuffix(download.Size);
httpResponseMessage = httpClient.GetAsync(download.UniformResourceLocator); httpResponseMessage = httpClient.GetAsync(download.UniformResourceLocator);
httpResponseMessage.Wait(-1); httpResponseMessage.Wait(-1);
if (!httpResponseMessage.Result.IsSuccessStatusCode) if (!httpResponseMessage.Result.IsSuccessStatusCode) {
logger.LogInformation("Failed to download: <{checkURL}> - {size};", download.UniformResourceLocator, size); logger.LogInformation("Failed to download: <{checkURL}> - {size};", download.UniformResourceLocator, size);
else { } else {
response = httpResponseMessage.Result.Content.ReadAsStringAsync(); response = httpResponseMessage.Result.Content.ReadAsStringAsync();
response.Wait(); response.Wait();
try { try {
@ -643,19 +661,24 @@ internal static partial class Helper20250407 {
List<Download> collection = []; List<Download> collection = [];
string? checkUniformResourceLocator; string? checkUniformResourceLocator;
foreach (Segment segment in segments) { foreach (Segment segment in segments) {
if (segment.Left is null) if (segment.Left is null) {
continue; continue;
}
checkFile = Path.Combine(rightDirectory, segment.Left.RelativePath); checkFile = Path.Combine(rightDirectory, segment.Left.RelativePath);
checkDirectory = Path.GetDirectoryName(checkFile); checkDirectory = Path.GetDirectoryName(checkFile);
if (string.IsNullOrEmpty(checkDirectory)) if (string.IsNullOrEmpty(checkDirectory)) {
continue; continue;
if (!Directory.Exists(checkDirectory)) }
if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
if (File.Exists(checkFile) && new FileInfo(checkFile).Length == 0) }
if (File.Exists(checkFile) && new FileInfo(checkFile).Length == 0) {
File.Delete(checkFile); File.Delete(checkFile);
}
checkUniformResourceLocator = ConvertTo(segment.RootUniformResourceLocator, segment.Left.RelativePath); checkUniformResourceLocator = ConvertTo(segment.RootUniformResourceLocator, segment.Left.RelativePath);
if (string.IsNullOrEmpty(checkUniformResourceLocator)) if (string.IsNullOrEmpty(checkUniformResourceLocator)) {
continue; continue;
}
download = new(Directory: checkDirectory, download = new(Directory: checkDirectory,
Display: checkUniformResourceLocator[segment.RootUniformResourceLocator.Length..], Display: checkUniformResourceLocator[segment.RootUniformResourceLocator.Length..],
File: checkFile, File: checkFile,
@ -666,12 +689,15 @@ internal static partial class Helper20250407 {
} }
Download[] sorted = (from l in collection orderby l.Size select l).ToArray(); Download[] sorted = (from l in collection orderby l.Size select l).ToArray();
int stop = sorted.Length < 100 ? sorted.Length : 100; int stop = sorted.Length < 100 ? sorted.Length : 100;
for (int i = 0; i < stop; i++) for (int i = 0; i < stop; i++) {
results.Add(sorted[i]); results.Add(sorted[i]);
for (int i = sorted.Length - 1; i > stop - 1; i--) }
for (int i = sorted.Length - 1; i > stop - 1; i--) {
results.Add(sorted[i]); results.Add(sorted[i]);
if (collection.Count != results.Count) }
if (collection.Count != results.Count) {
throw new Exception(); throw new Exception();
}
return results.AsReadOnly(); return results.AsReadOnly();
} }
@ -682,12 +708,28 @@ internal static partial class Helper20250407 {
string fileName = Path.GetFileName(windowsMock); string fileName = Path.GetFileName(windowsMock);
ReadOnlyCollection<string> directoryNames = Helpers.HelperDirectory.GetDirectoryNames(windowsMock); ReadOnlyCollection<string> directoryNames = Helpers.HelperDirectory.GetDirectoryNames(windowsMock);
foreach (string directoryName in directoryNames) { foreach (string directoryName in directoryNames) {
if (directoryName == windowsRoot || directoryName == fileName) if (directoryName == windowsRoot || directoryName == fileName) {
continue; continue;
}
result = $"{result}/{directoryName}"; result = $"{result}/{directoryName}";
} }
result = result == rootURL ? null : $"{result}/{fileName}"; result = result == rootURL ? null : $"{result}/{fileName}";
return result; return result;
} }
private static string GetDurationWithSuffix(long ticks) {
string result;
TimeSpan timeSpan = new(DateTime.Now.Ticks - ticks);
if (timeSpan.TotalMilliseconds < 1000) {
result = $"{timeSpan.Milliseconds} ms";
} else if (timeSpan.TotalMilliseconds < 60000) {
result = $"{Math.Floor(timeSpan.TotalSeconds)} s";
} else if (timeSpan.TotalMilliseconds < 3600000) {
result = $"{Math.Floor(timeSpan.TotalMinutes)} m";
} else {
result = $"{Math.Floor(timeSpan.TotalHours)} h";
}
return result;
}
} }

View File

@ -8,15 +8,17 @@ internal static partial class Helper20250421 {
string searchPattern = args[2]; string searchPattern = args[2];
string[] searchPatterns = args[3].Split('~'); string[] searchPatterns = args[3].Split('~');
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
if (searchPatterns.Length != 2) if (searchPatterns.Length != 2) {
throw new NotImplementedException($"Not the correct number of {searchPatterns} were passed!"); throw new NotImplementedException($"Not the correct number of {searchPatterns} were passed!");
}
string lastSyncSearch = $"{searchPatterns[0]}=\""; string lastSyncSearch = $"{searchPatterns[0]}=\"";
string configurationFileSearch = $"{searchPatterns[1]}=\""; string configurationFileSearch = $"{searchPatterns[1]}=\"";
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
if (files.Length != 1) if (files.Length != 1) {
logger.LogWarning("<{files}>(s)", files.Length); logger.LogWarning("<{files}>(s)", files.Length);
else } else {
ChangeCreatedDate(lastSyncSearch, configurationFileSearch, files[0]); ChangeCreatedDate(lastSyncSearch, configurationFileSearch, files[0]);
}
} }
private static void ChangeCreatedDate(string lastSyncSearch, string configurationFileSearch, string sourceFile) { private static void ChangeCreatedDate(string lastSyncSearch, string configurationFileSearch, string sourceFile) {
@ -29,17 +31,21 @@ internal static partial class Helper20250421 {
string[] lines = File.ReadAllLines(sourceFile); string[] lines = File.ReadAllLines(sourceFile);
foreach (string line in lines) { foreach (string line in lines) {
segments = line.Split(lastSyncSearch); segments = line.Split(lastSyncSearch);
if (segments.Length != 2) if (segments.Length != 2) {
continue; continue;
}
segmentsB = line.Split(configurationFileSearch); segmentsB = line.Split(configurationFileSearch);
if (segmentsB.Length != 2) if (segmentsB.Length != 2) {
continue; continue;
}
lastSync = segments[1].Split('"')[0]; lastSync = segments[1].Split('"')[0];
if (!long.TryParse(lastSync, out epoch) || epoch == 0) if (!long.TryParse(lastSync, out epoch) || epoch == 0) {
continue; continue;
}
configurationFile = segmentsB[1].Split('"')[0]; configurationFile = segmentsB[1].Split('"')[0];
if (!File.Exists(configurationFile)) if (!File.Exists(configurationFile)) {
continue; continue;
}
creationTime = new(DateTimeOffset.UnixEpoch.AddSeconds(epoch).ToLocalTime().Ticks); creationTime = new(DateTimeOffset.UnixEpoch.AddSeconds(epoch).ToLocalTime().Ticks);
File.SetCreationTime(configurationFile, creationTime); File.SetCreationTime(configurationFile, creationTime);
} }

View File

@ -1,10 +1,8 @@
using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Text.Json; using System.Text.Json;
using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI5; namespace File_Folder_Helper.ADO2025.PI5;
internal static partial class Helper20250429 { internal static partial class Helper20250429 {
@ -15,29 +13,11 @@ internal static partial class Helper20250429 {
string searchPattern = args[2]; string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0]); string sourceDirectory = Path.GetFullPath(args[0]);
ReadOnlyCollection<Record> subDirectories = GetSubDirectories(searchPattern, sourceDirectory); ReadOnlyCollection<Record> subDirectories = GetSubDirectories(searchPattern, sourceDirectory);
if (subDirectories.Count == 0) if (subDirectories.Count == 0) {
logger.LogWarning("<{results}>(s)", subDirectories.Count); logger.LogWarning("<{results}>(s)", subDirectories.Count);
else } else {
WriteNginxFileSystem(searchPattern, subDirectories); WriteNginxFileSystem(searchPattern, subDirectories);
}
private static ReadOnlyCollection<Record> GetSubDirectories(string searchPattern, string sourceDirectory) {
List<Record> results = [];
bool exists;
Record record;
string checkFile;
string[] subDirectories;
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories) {
subDirectories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
foreach (string subDirectory in subDirectories) {
checkFile = Path.Combine(subDirectory, $"{searchPattern.Split('*')[^1]}.json");
exists = File.Exists(checkFile);
record = new(Directory: subDirectory, File: checkFile, FileExists: exists);
results.Add(record);
}
} }
return results.OrderByDescending(l => l.FileExists).ToArray().AsReadOnly();
} }
private static void WriteNginxFileSystem(string searchPattern, ReadOnlyCollection<Record> subDirectories) { private static void WriteNginxFileSystem(string searchPattern, ReadOnlyCollection<Record> subDirectories) {
@ -60,13 +40,34 @@ internal static partial class Helper20250429 {
Length: fileInfo.Length); Length: fileInfo.Length);
results.Add(JsonSerializer.Serialize(nginxFileSystem, NginxFileSystemSingleLineSourceGenerationContext.Default.NginxFileSystem)); results.Add(JsonSerializer.Serialize(nginxFileSystem, NginxFileSystemSingleLineSourceGenerationContext.Default.NginxFileSystem));
} }
if (results.Count == 0) if (results.Count == 0) {
continue; continue;
}
result = $"[{Environment.NewLine}{string.Join($",{Environment.NewLine}", results)}{Environment.NewLine}]"; result = $"[{Environment.NewLine}{string.Join($",{Environment.NewLine}", results)}{Environment.NewLine}]";
lines = !record.FileExists ? string.Empty : File.ReadAllText(record.File); lines = !record.FileExists ? string.Empty : File.ReadAllText(record.File);
if (result == lines) if (result == lines) {
continue; continue;
}
File.WriteAllText(record.File, result); File.WriteAllText(record.File, result);
} }
} }
private static ReadOnlyCollection<Record> GetSubDirectories(string searchPattern, string sourceDirectory) {
List<Record> results = [];
bool exists;
Record record;
string checkFile;
string[] subDirectories;
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories) {
subDirectories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
foreach (string subDirectory in subDirectories) {
checkFile = Path.Combine(subDirectory, $"{searchPattern.Split('*')[^1]}.json");
exists = File.Exists(checkFile);
record = new(Directory: subDirectory, File: checkFile, FileExists: exists);
results.Add(record);
}
}
return results.OrderByDescending(l => l.FileExists).ToArray().AsReadOnly();
}
} }

View File

@ -21,12 +21,15 @@ internal static partial class Helper20250505 {
// <PackageReference Include="iText.pdfhtml" Version="6.1.0" /> // <PackageReference Include="iText.pdfhtml" Version="6.1.0" />
internal static void HyperTextMarkupLanguageToPortableDocumentFormat(ILogger<Worker> logger, List<string> args) { internal static void HyperTextMarkupLanguageToPortableDocumentFormat(ILogger<Worker> logger, List<string> args) {
if (args.Count == 999) if (args.Count == 999) {
TestA(); TestA();
if (args.Count == 999) }
if (args.Count == 999) {
TestB(); TestB();
if (args.Count != 999) }
if (args.Count != 999) {
TestC(logger); TestC(logger);
}
} }
private static void TestA() { private static void TestA() {

View File

@ -28,7 +28,7 @@ csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true csharp_new_line_between_query_expression_clauses = true
csharp_prefer_braces = false csharp_prefer_braces = true
csharp_prefer_qualified_reference = true:error csharp_prefer_qualified_reference = true:error
csharp_prefer_simple_default_expression = true:warning csharp_prefer_simple_default_expression = true:warning
csharp_prefer_simple_using_statement = true:warning csharp_prefer_simple_using_statement = true:warning
@ -59,9 +59,6 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false csharp_space_between_square_brackets = false
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
csharp_style_allow_embedded_statements_on_same_line_experimental = true csharp_style_allow_embedded_statements_on_same_line_experimental = true
csharp_style_conditional_delegate_call = true csharp_style_conditional_delegate_call = true
@ -113,7 +110,7 @@ dotnet_diagnostic.CA1051.severity = error # CA1051: Do not declare visible insta
dotnet_diagnostic.CA1511.severity = warning # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance dotnet_diagnostic.CA1511.severity = warning # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1513.severity = warning # Use 'ObjectDisposedException.ThrowIf' instead of explicitly throwing a new exception instance dotnet_diagnostic.CA1513.severity = warning # Use 'ObjectDisposedException.ThrowIf' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1825.severity = warning # CA1825: Avoid zero-length array allocations dotnet_diagnostic.CA1825.severity = warning # CA1825: Avoid zero-length array allocations
dotnet_diagnostic.CA1829.severity = error # CA1829: Use Length/Count property instead of Count() when available 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.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.CA1860.severity = error # CA1860: Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
dotnet_diagnostic.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase' dotnet_diagnostic.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'
@ -123,7 +120,7 @@ dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name 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.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.IDE0004.severity = warning # IDE0004: Cast is redundant.
dotnet_diagnostic.IDE0005.severity = error # Using directive is unnecessary dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary
dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement (IDE0010) dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement (IDE0010)
dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031) dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
@ -131,7 +128,7 @@ dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be remov
dotnet_diagnostic.IDE0048.severity = none # Parentheses preferences (IDE0047 and IDE0048) dotnet_diagnostic.IDE0048.severity = none # Parentheses preferences (IDE0047 and IDE0048)
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049) dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
dotnet_diagnostic.IDE0051.severity = error # Private member '' is unused [, ] dotnet_diagnostic.IDE0051.severity = error # Private member '' is unused [, ]
dotnet_diagnostic.IDE0058.severity = error # IDE0058: Expression value is never used dotnet_diagnostic.IDE0058.severity = warning # IDE0058: Expression value is never used
dotnet_diagnostic.IDE0060.severity = error # IDE0060: Remove unused parameter dotnet_diagnostic.IDE0060.severity = error # IDE0060: Remove unused parameter
dotnet_diagnostic.IDE0074.severity = warning # IDE0074: Use compound assignment dotnet_diagnostic.IDE0074.severity = warning # IDE0074: Use compound assignment
dotnet_diagnostic.IDE0130.severity = none # Namespace does not match folder structure (IDE0130) dotnet_diagnostic.IDE0130.severity = none # Namespace does not match folder structure (IDE0130)
@ -140,7 +137,6 @@ dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]cs
dotnet_diagnostic.IDE0300.severity = error # IDE0300: Collection initialization can be simplified dotnet_diagnostic.IDE0300.severity = error # IDE0300: Collection initialization can be simplified
dotnet_diagnostic.IDE0301.severity = error #IDE0301: 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_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified
dotnet_diagnostic.IDE2000.severity = error # IDE2000: Allow multiple blank lines
dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning 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.style = pascal_case
dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method
@ -256,8 +252,8 @@ dotnet_naming_symbols.types.applicable_accessibilities = public, internal, priva
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.required_modifiers = dotnet_naming_symbols.types.required_modifiers =
dotnet_remove_unnecessary_suppression_exclusions = 0 dotnet_remove_unnecessary_suppression_exclusions = 0
dotnet_separate_import_directive_groups = true dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = true dotnet_sort_system_directives_first = false
dotnet_style_allow_multiple_blank_lines_experimental = false:warning dotnet_style_allow_multiple_blank_lines_experimental = false:warning
dotnet_style_allow_statement_immediately_after_block_experimental = true dotnet_style_allow_statement_immediately_after_block_experimental = true
dotnet_style_coalesce_expression = true dotnet_style_coalesce_expression = true
@ -297,85 +293,4 @@ root = true
tab_width = 4 tab_width = 4
# https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1822 # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1822
# https://github.com/dotnet/aspnetcore/blob/main/.editorconfig # https://github.com/dotnet/aspnetcore/blob/main/.editorconfig
# https://github.com/dotnet/project-system/blob/main/.editorconfig # https://github.com/dotnet/project-system/blob/main/.editorconfig
# Question
csharp_prefer_simple_using_statement = false # Question
csharp_style_expression_bodied_constructors = when_on_single_line:none # Question
csharp_style_expression_bodied_properties = true # Question
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning # Question
csharp_style_pattern_matching_over_as_with_null_check = false # Question
csharp_style_prefer_pattern_matching = false # Question
csharp_style_prefer_range_operator = false # Question
csharp_style_prefer_switch_expression = false # Question
csharp_style_unused_value_assignment_preference = unused_local_variable # Question
csharp_style_unused_value_expression_statement_preference = false # Question
csharp_style_var_elsewhere = false:none # Question
csharp_style_var_for_built_in_types = false:none # Question
csharp_style_var_when_type_is_apparent = false:warning # Question
dotnet_diagnostic.CA1001.severity = none # Question - Types that own disposable fields should be disposable
dotnet_diagnostic.CA1051.severity = none # Question - Do not declare visible instance fields
dotnet_diagnostic.CA1416.severity = none # Question - This call site is reachable on all platforms.
dotnet_diagnostic.CA1510.severity = none # Question - Use
dotnet_diagnostic.CA1834.severity = none # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
dotnet_diagnostic.CA1860.severity = none # Question - Avoid using
dotnet_diagnostic.CA1862.severity = none # Question - Prefer using
dotnet_diagnostic.CA2208.severity = none # Question - Instantiate argument exceptions correctly
dotnet_diagnostic.CA2211.severity = none # Question - Non-constant fields should not be visible
dotnet_diagnostic.CA2249.severity = none # Question - Use
dotnet_diagnostic.CA2253.severity = none # Question - Named placeholders should not be numeric values
dotnet_diagnostic.CS0103.severity = none # Question - The name
dotnet_diagnostic.CS0168.severity = warning # Question - The variable
dotnet_diagnostic.CS0219.severity = none # Question - The variable
dotnet_diagnostic.CS0612.severity = none # Question - is obsolete
dotnet_diagnostic.CS0618.severity = none # Question - Compiler Warning (level 2)
dotnet_diagnostic.CS0659.severity = none # Question - Compiler Warning (level 3)
dotnet_diagnostic.CS8019.severity = warning # Question - Unnecessary using directive.
dotnet_diagnostic.CS8600.severity = none # Question - Converting null literal or possible null value to non-nullable type
dotnet_diagnostic.CS8602.severity = none # Question - Dereference of a possibly null reference.
dotnet_diagnostic.CS8603.severity = none # Question - Possible null reference return
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.CS8625.severity = none # Question - Cannot convert null literal to non-nullable reference type.
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.IDE0005.severity = none # Question - Remove unnecessary using directives
dotnet_diagnostic.IDE0008.severity = warning # Question - Use explicit type instead of
dotnet_diagnostic.IDE0017.severity = none # Question - Object initialization can be simplified
dotnet_diagnostic.IDE0019.severity = none # Question - Use pattern matching
dotnet_diagnostic.IDE0021.severity = none # Question - Use expression body for constructor
dotnet_diagnostic.IDE0022.severity = none # Question - Use expression body for method
dotnet_diagnostic.IDE0025.severity = none # Question - Use expression body for property
dotnet_diagnostic.IDE0027.severity = none # Question - Use expression body for accessor
dotnet_diagnostic.IDE0028.severity = none # Question - Use collection initializers or expressions
dotnet_diagnostic.IDE0031.severity = none # Question - Null check can be simplified
dotnet_diagnostic.IDE0032.severity = none # Question - Use auto property
dotnet_diagnostic.IDE0037.severity = none # Question - Member name can be simplified
dotnet_diagnostic.IDE0041.severity = none # Question - Null check can be simplified
dotnet_diagnostic.IDE0047.severity = none # Question - Parentheses preferences
dotnet_diagnostic.IDE0049.severity = warning # Question - Name can be simplified
dotnet_diagnostic.IDE0051.severity = none # Question - Remove unused private member
dotnet_diagnostic.IDE0053.severity = none # Question - Use expression body for lambdas
dotnet_diagnostic.IDE0054.severity = none # Question - Use compound assignment
dotnet_diagnostic.IDE0055.severity = none # Question - Formatting rule
dotnet_diagnostic.IDE0057.severity = none # Question - Substring can be simplified
dotnet_diagnostic.IDE0058.severity = none # Question - Remove unnecessary expression value
dotnet_diagnostic.IDE0059.severity = none # Question - Unnecessary assignment of a value to
dotnet_diagnostic.IDE0060.severity = warning # Question - Remove unused parameter
dotnet_diagnostic.IDE0063.severity = none # Question - Use simple
dotnet_diagnostic.IDE0065.severity = none # Question -
dotnet_diagnostic.IDE0066.severity = none # Question - Use
dotnet_diagnostic.IDE0078.severity = none # Question - Use pattern matching (may change code meaning)
dotnet_diagnostic.IDE0090.severity = warning # Question - Simplify new expression
dotnet_diagnostic.IDE0100.severity = error # Question - Remove redundant equality
dotnet_diagnostic.IDE0160.severity = warning # Question - Use block-scoped namespace
dotnet_diagnostic.IDE0161.severity = warning # Question - Namespace declaration preferences
dotnet_diagnostic.IDE0270.severity = none # Question - Null check can be simplified
dotnet_diagnostic.IDE0300.severity = none # Question - Collection initialization can be simplified
dotnet_diagnostic.IDE1006.severity = none # Question - Use collection expression for builder dotnet_style_prefer_collection_expression
dotnet_style_null_propagation = false # Question
dotnet_style_object_initializer = false # Question
dotnet_style_prefer_auto_properties = false # Question
dotnet_style_allow_statement_immediately_after_block_experimental = true # Question
dotnet_style_prefer_inferred_anonymous_type_member_names = false:warning # Question
dotnet_style_prefer_is_null_check_over_reference_equality_method = false # Question

View File

@ -11,25 +11,22 @@ namespace IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
[System.ComponentModel.DesignerCategory("code")] [System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")] [System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
[System.Xml.Serialization.XmlRoot(Namespace = "http://www.w3.org/2003/05/soap-envelope", IsNullable = false)] [System.Xml.Serialization.XmlRoot(Namespace = "http://www.w3.org/2003/05/soap-envelope", IsNullable = false)]
public partial class Envelope public partial class Envelope {
{
private EnvelopeHeader? headerField; private EnvelopeHeader? headerField;
private EnvelopeBody? bodyField; private EnvelopeBody? bodyField;
/// <remarks/> /// <remarks/>
public EnvelopeHeader Header public EnvelopeHeader Header {
{ get => headerField;
get => this.headerField; set => headerField = value;
set => this.headerField = value;
} }
/// <remarks/> /// <remarks/>
public EnvelopeBody Body public EnvelopeBody Body {
{ get => bodyField;
get => this.bodyField; set => bodyField = value;
set => this.bodyField = value;
} }
} }
@ -37,8 +34,7 @@ public partial class Envelope
[Serializable()] [Serializable()]
[System.ComponentModel.DesignerCategory("code")] [System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")] [System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public partial class EnvelopeHeader public partial class EnvelopeHeader {
{
private Sequence? sequenceField; private Sequence? sequenceField;
private SequenceAcknowledgement? sequenceAcknowledgementField; private SequenceAcknowledgement? sequenceAcknowledgementField;
@ -47,33 +43,29 @@ public partial class EnvelopeHeader
private string? relatesToField; private string? relatesToField;
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")] [System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
public Sequence Sequence public Sequence Sequence {
{ get => sequenceField;
get => this.sequenceField; set => sequenceField = value;
set => this.sequenceField = value;
} }
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")] [System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
public SequenceAcknowledgement SequenceAcknowledgement public SequenceAcknowledgement SequenceAcknowledgement {
{ get => sequenceAcknowledgementField;
get => this.sequenceAcknowledgementField; set => sequenceAcknowledgementField = value;
set => this.sequenceAcknowledgementField = value;
} }
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")] [System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")]
public Action Action public Action Action {
{ get => actionField;
get => this.actionField; set => actionField = value;
set => this.actionField = value;
} }
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")] [System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")]
public string RelatesTo public string RelatesTo {
{ get => relatesToField;
get => this.relatesToField; set => relatesToField = value;
set => this.relatesToField = value;
} }
} }
/// <remarks/> /// <remarks/>
@ -81,36 +73,31 @@ public partial class EnvelopeHeader
[System.ComponentModel.DesignerCategory("code")] [System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")] [System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
[System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)] [System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)]
public partial class Sequence public partial class Sequence {
{
private string? identifierField; private string? identifierField;
private byte messageNumberField; private byte messageNumberField;
private object? lastMessageField; private object? lastMessageField;
private byte mustUnderstandField; private byte mustUnderstandField;
/// <remarks/> /// <remarks/>
public string Identifier public string Identifier {
{ get => identifierField;
get => this.identifierField; set => identifierField = value;
set => this.identifierField = value;
} }
/// <remarks/> /// <remarks/>
public byte MessageNumber public byte MessageNumber {
{ get => messageNumberField;
get => this.messageNumberField; set => messageNumberField = value;
set => this.messageNumberField = value;
} }
/// <remarks/> /// <remarks/>
public object LastMessage public object LastMessage {
{ get => lastMessageField;
get => this.lastMessageField; set => lastMessageField = value;
set => this.lastMessageField = value;
} }
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2003/05/soap-envelope")] [System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public byte mustUnderstand public byte mustUnderstand {
{ get => mustUnderstandField;
get => this.mustUnderstandField; set => mustUnderstandField = value;
set => this.mustUnderstandField = value;
} }
} }
/// <remarks/> /// <remarks/>
@ -118,52 +105,45 @@ public partial class Sequence
[System.ComponentModel.DesignerCategory("code")] [System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")] [System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
[System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)] [System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)]
public partial class SequenceAcknowledgement public partial class SequenceAcknowledgement {
{
private string? identifierField; private string? identifierField;
private SequenceAcknowledgementAcknowledgementRange? acknowledgementRangeField; private SequenceAcknowledgementAcknowledgementRange? acknowledgementRangeField;
private byte bufferRemainingField; private byte bufferRemainingField;
/// <remarks/> /// <remarks/>
public string Identifier public string Identifier {
{ get => identifierField;
get => this.identifierField; set => identifierField = value;
set => this.identifierField = value;
} }
/// <remarks/> /// <remarks/>
public SequenceAcknowledgementAcknowledgementRange AcknowledgementRange public SequenceAcknowledgementAcknowledgementRange AcknowledgementRange {
{ get => acknowledgementRangeField;
get => this.acknowledgementRangeField; set => acknowledgementRangeField = value;
set => this.acknowledgementRangeField = value;
} }
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.microsoft.com/ws/2006/05/rm")] [System.Xml.Serialization.XmlElement(Namespace = "http://schemas.microsoft.com/ws/2006/05/rm")]
public byte BufferRemaining public byte BufferRemaining {
{ get => bufferRemainingField;
get => this.bufferRemainingField; set => bufferRemainingField = value;
set => this.bufferRemainingField = value;
} }
} }
/// <remarks/> /// <remarks/>
[Serializable()] [Serializable()]
[System.ComponentModel.DesignerCategory("code")] [System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")] [System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
public partial class SequenceAcknowledgementAcknowledgementRange public partial class SequenceAcknowledgementAcknowledgementRange {
{
private byte lowerField; private byte lowerField;
private byte upperField; private byte upperField;
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlAttribute()] [System.Xml.Serialization.XmlAttribute()]
public byte Lower public byte Lower {
{ get => lowerField;
get => this.lowerField; set => lowerField = value;
set => this.lowerField = value;
} }
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlAttribute()] [System.Xml.Serialization.XmlAttribute()]
public byte Upper public byte Upper {
{ get => upperField;
get => this.upperField; set => upperField = value;
set => this.upperField = value;
} }
} }
@ -172,8 +152,7 @@ public partial class SequenceAcknowledgementAcknowledgementRange
[System.ComponentModel.DesignerCategory("code")] [System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2005/08/addressing")] [System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2005/08/addressing")]
[System.Xml.Serialization.XmlRoot(Namespace = "http://www.w3.org/2005/08/addressing", IsNullable = false)] [System.Xml.Serialization.XmlRoot(Namespace = "http://www.w3.org/2005/08/addressing", IsNullable = false)]
public partial class Action public partial class Action {
{
private byte mustUnderstandField; private byte mustUnderstandField;
@ -181,18 +160,16 @@ public partial class Action
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2003/05/soap-envelope")] [System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public byte mustUnderstand public byte mustUnderstand {
{ get => mustUnderstandField;
get => this.mustUnderstandField; set => mustUnderstandField = value;
set => this.mustUnderstandField = value;
} }
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlText()] [System.Xml.Serialization.XmlText()]
public string Value public string Value {
{ get => valueField;
get => this.valueField; set => valueField = value;
set => this.valueField = value;
} }
} }
@ -200,17 +177,15 @@ public partial class Action
[Serializable()] [Serializable()]
[System.ComponentModel.DesignerCategory("code")] [System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")] [System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public partial class EnvelopeBody public partial class EnvelopeBody {
{
private CreateSequenceResponse? createSequenceResponseField; private CreateSequenceResponse? createSequenceResponseField;
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")] [System.Xml.Serialization.XmlElement(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
public CreateSequenceResponse CreateSequenceResponse public CreateSequenceResponse CreateSequenceResponse {
{ get => createSequenceResponseField;
get => this.createSequenceResponseField; set => createSequenceResponseField = value;
set => this.createSequenceResponseField = value;
} }
} }
@ -219,25 +194,22 @@ public partial class EnvelopeBody
[System.ComponentModel.DesignerCategory("code")] [System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")] [System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
[System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)] [System.Xml.Serialization.XmlRoot(Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm", IsNullable = false)]
public partial class CreateSequenceResponse public partial class CreateSequenceResponse {
{
private string? identifierField; private string? identifierField;
private CreateSequenceResponseAccept? acceptField; private CreateSequenceResponseAccept? acceptField;
/// <remarks/> /// <remarks/>
public string Identifier public string Identifier {
{ get => identifierField;
get => this.identifierField; set => identifierField = value;
set => this.identifierField = value;
} }
/// <remarks/> /// <remarks/>
public CreateSequenceResponseAccept Accept public CreateSequenceResponseAccept Accept {
{ get => acceptField;
get => this.acceptField; set => acceptField = value;
set => this.acceptField = value;
} }
} }
@ -245,16 +217,14 @@ public partial class CreateSequenceResponse
[Serializable()] [Serializable()]
[System.ComponentModel.DesignerCategory("code")] [System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")] [System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
public partial class CreateSequenceResponseAccept public partial class CreateSequenceResponseAccept {
{
private CreateSequenceResponseAcceptAcksTo? acksToField; private CreateSequenceResponseAcceptAcksTo? acksToField;
/// <remarks/> /// <remarks/>
public CreateSequenceResponseAcceptAcksTo AcksTo public CreateSequenceResponseAcceptAcksTo AcksTo {
{ get => acksToField;
get => this.acksToField; set => acksToField = value;
set => this.acksToField = value;
} }
} }
@ -262,16 +232,14 @@ public partial class CreateSequenceResponseAccept
[Serializable()] [Serializable()]
[System.ComponentModel.DesignerCategory("code")] [System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")] [System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/ws/2005/02/rm")]
public partial class CreateSequenceResponseAcceptAcksTo public partial class CreateSequenceResponseAcceptAcksTo {
{
private string? addressField; private string? addressField;
/// <remarks/> /// <remarks/>
[System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")] [System.Xml.Serialization.XmlElement(Namespace = "http://www.w3.org/2005/08/addressing")]
public string Address public string Address {
{ get => addressField;
get => this.addressField; set => addressField = value;
set => this.addressField = value;
} }
} }

View File

@ -1,12 +1,11 @@
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Web; using System.Web;
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250519 { internal static partial class Helper20250519 {
@ -19,7 +18,6 @@ internal static partial class Helper20250519 {
string result = JsonSerializer.Serialize(this, Helper20250519RelativePath.Default.RelativePath); string result = JsonSerializer.Serialize(this, Helper20250519RelativePath.Default.RelativePath);
return result; return result;
} }
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
@ -39,7 +37,6 @@ internal static partial class Helper20250519 {
string result = JsonSerializer.Serialize(this, Helper20250519Review.Default.Review); string result = JsonSerializer.Serialize(this, Helper20250519Review.Default.Review);
return result; return result;
} }
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
@ -288,8 +285,9 @@ internal static partial class Helper20250519 {
if (!baseAddress.StartsWith("http:")) { if (!baseAddress.StartsWith("http:")) {
logger.LogInformation("Not supported URL <{url}>", baseAddress); logger.LogInformation("Not supported URL <{url}>", baseAddress);
} else { } else {
HttpClient httpClient = new(); HttpClient httpClient = new() {
httpClient.BaseAddress = new(baseAddress); BaseAddress = new(baseAddress)
};
StringContent stringContent = new(json, Encoding.UTF8, "application/json"); StringContent stringContent = new(json, Encoding.UTF8, "application/json");
httpResponseMessage = httpClient.PostAsync(page, stringContent); httpResponseMessage = httpClient.PostAsync(page, stringContent);
httpResponseMessage.Wait(); httpResponseMessage.Wait();
@ -342,22 +340,6 @@ internal static partial class Helper20250519 {
} }
} }
private static void LiveSync(ILogger<Worker> logger, string page, RelativePath relativePath, HttpClient httpClient, string directory, ReadOnlyCollection<Record> records, HttpMethod? httpMethod, bool delete) {
long sum;
try { sum = records.Sum(l => l.Size); } catch (Exception) { sum = 0; }
string size = GetSizeWithSuffix(sum);
if (delete) {
logger.LogInformation("Starting to delete {count} file(s) [{sum}]", records.Count, size);
PreformDeletes(logger, relativePath.RightDirectory, records);
logger.LogInformation("Deleted {count} file(s) [{sum}]", records.Count, size);
}
if (httpMethod is not null) {
logger.LogInformation("Starting to {httpMethod} {count} file(s) [{sum}]", httpMethod.ToString().ToLower(), records.Count, size);
Preform(logger, page, directory, records, httpClient, httpMethod);
logger.LogInformation("{httpMethod}'ed {count} file(s) [{sum}]", httpMethod.ToString(), records.Count, size);
}
}
private static string GetSizeWithSuffix(long value) { private static string GetSizeWithSuffix(long value) {
string result; string result;
int i = 0; int i = 0;
@ -374,102 +356,22 @@ internal static partial class Helper20250519 {
return result; return result;
} }
private static void PreformDeletes(ILogger<Worker> logger, string directory, ReadOnlyCollection<Record> records) { private static string GetDurationWithSuffix(long ticks) {
string size; string result;
Record? record; TimeSpan timeSpan = new(DateTime.Now.Ticks - ticks);
string count = records.Count.ToString("000000"); if (timeSpan.TotalMilliseconds < 1000) {
#if ShellProgressBar result = $"{timeSpan.Milliseconds} ms";
ProgressBar progressBar = new(records.Count, $"Deleting: {count};", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }); } else if (timeSpan.TotalMilliseconds < 60000) {
#endif result = $"{Math.Floor(timeSpan.TotalSeconds)} s";
for (int i = 0; i < records.Count; i++) { } else if (timeSpan.TotalMilliseconds < 3600000) {
#if ShellProgressBar result = $"{Math.Floor(timeSpan.TotalMinutes)} m";
progressBar.Tick(); } else {
#endif result = $"{Math.Floor(timeSpan.TotalHours)} h";
record = records[i];
if (record is null) {
continue;
}
size = GetSizeWithSuffix(record.Size);
try {
File.Delete(Path.Combine(directory, record.RelativePath));
logger.LogInformation("{i} of {count} - Deleted: <{RelativePath}> - {size};", i.ToString("000000"), count, record.RelativePath, size);
} catch (Exception) {
logger.LogInformation("Failed to delete: <{RelativePath}> - {size};", record.RelativePath, size);
}
} }
#if ShellProgressBar return result;
progressBar.Dispose();
#endif
} }
private static void Preform(ILogger<Worker> logger, string page, string directory, ReadOnlyCollection<Record> records, HttpClient httpClient, HttpMethod httpMethod) { private static ReadOnlyCollection<Verb> GetVerbCollection(string? directory, ReadOnlyCollection<Record> records) {
Verb verb;
long ticks;
string size;
string iValue;
string duration;
DateTime dateTime;
Task<string> response;
HttpRequestMessage httpRequestMessage;
Task<HttpResponseMessage> httpResponseMessage;
string count = records.Count.ToString("000000");
MultipartFormDataContent multipartFormDataContent;
ReadOnlyCollection<Verb> collection = GetVerbCollection(directory, records);
#if ShellProgressBar
ProgressBar progressBar = new(downloads.Count, $"{httpMethod}ing: {count};", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
#endif
for (int i = 0; i < collection.Count; i++) {
verb = collection[i];
#if ShellProgressBar
progressBar.Tick();
#endif
ticks = DateTime.Now.Ticks;
iValue = (i + 1).ToString("000000");
size = GetSizeWithSuffix(verb.Size);
if (httpMethod == HttpMethod.Get || httpMethod == HttpMethod.Delete) {
httpRequestMessage = new(httpMethod, $"{page}size={verb.Size}&ticks={verb.Ticks}&path={verb.UrlEncodedFile}");
} else if (httpMethod == HttpMethod.Patch || httpMethod == HttpMethod.Put) {
httpRequestMessage = new(httpMethod, $"{page}path={verb.Directory}");
multipartFormDataContent = new();
multipartFormDataContent.Add(new ByteArrayContent(File.ReadAllBytes(verb.File)), "formFiles", verb.Multipart);
multipartFormDataContent.Add(new StringContent(verb.Directory), "path", iValue);
httpRequestMessage.Content = multipartFormDataContent;
} else
throw new NotImplementedException();
httpResponseMessage = httpClient.SendAsync(httpRequestMessage);
httpResponseMessage.Wait(-1);
if (!httpResponseMessage.Result.IsSuccessStatusCode) {
logger.LogInformation("Failed to {httpMethod}: <{display}> - {size};", httpMethod, verb.Display, size);
} else {
try {
if (httpMethod != HttpMethod.Get) {
duration = GetDurationWithSuffix(ticks);
} else {
response = httpResponseMessage.Result.Content.ReadAsStringAsync();
response.Wait();
File.WriteAllText(verb.File, response.Result);
duration = GetDurationWithSuffix(ticks);
dateTime = new DateTime(verb.Ticks).ToLocalTime();
File.SetLastWriteTime(verb.File, dateTime);
}
logger.LogInformation("{i} of {count} - {httpMethod}'ed: <{display}> - {size} - {timeSpan};",
iValue,
count,
httpMethod,
verb.Display,
size,
duration);
} catch (Exception) {
logger.LogInformation("Failed to {httpMethod}: <{display}> - {size};", httpMethod, verb.Display, size);
}
}
}
#if ShellProgressBar
progressBar.Dispose();
#endif
}
private static ReadOnlyCollection<Verb> GetVerbCollection(string directory, ReadOnlyCollection<Record> records) {
List<Verb> results = []; List<Verb> results = [];
Verb verb; Verb verb;
string checkFile; string checkFile;
@ -477,6 +379,9 @@ internal static partial class Helper20250519 {
string? checkDirectory; string? checkDirectory;
List<Verb> collection = []; List<Verb> collection = [];
foreach (Record record in records) { foreach (Record record in records) {
if (string.IsNullOrEmpty(directory)) {
continue;
}
checkFile = Path.Combine(directory, record.RelativePath); checkFile = Path.Combine(directory, record.RelativePath);
checkFileName = Path.GetFileName(checkFile); checkFileName = Path.GetFileName(checkFile);
checkDirectory = Path.GetDirectoryName(checkFile); checkDirectory = Path.GetDirectoryName(checkFile);
@ -513,19 +418,117 @@ internal static partial class Helper20250519 {
return results.AsReadOnly(); return results.AsReadOnly();
} }
private static string GetDurationWithSuffix(long ticks) { private static void PreformDeletes(ILogger<Worker> logger, string? directory, ReadOnlyCollection<Record> records) {
string result; string size;
TimeSpan timeSpan = new(DateTime.Now.Ticks - ticks); Record? record;
if (timeSpan.TotalMilliseconds < 1000) { string count = records.Count.ToString("000000");
result = $"{timeSpan.Milliseconds} ms"; #if ShellProgressBar
} else if (timeSpan.TotalMilliseconds < 60000) { ProgressBar progressBar = new(records.Count, $"Deleting: {count};", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
result = $"{Math.Floor(timeSpan.TotalSeconds)} s"; #endif
} else if (timeSpan.TotalMilliseconds < 3600000) { for (int i = 0; i < records.Count; i++) {
result = $"{Math.Floor(timeSpan.TotalMinutes)} m"; #if ShellProgressBar
} else { progressBar.Tick();
result = $"{Math.Floor(timeSpan.TotalHours)} h"; #endif
record = records[i];
if (record is null || string.IsNullOrEmpty(directory)) {
continue;
}
size = GetSizeWithSuffix(record.Size);
try {
File.Delete(Path.Combine(directory, record.RelativePath));
logger.LogInformation("{i} of {count} - Deleted: <{RelativePath}> - {size};", i.ToString("000000"), count, record.RelativePath, size);
} catch (Exception) {
logger.LogInformation("Failed to delete: <{RelativePath}> - {size};", record.RelativePath, size);
}
}
#if ShellProgressBar
progressBar.Dispose();
#endif
}
private static void Preform(ILogger<Worker> logger, string page, string? directory, ReadOnlyCollection<Record> records, HttpClient httpClient, HttpMethod httpMethod) {
Verb verb;
long ticks;
string size;
string iValue;
string duration;
DateTime dateTime;
Task<string> response;
HttpRequestMessage httpRequestMessage;
Task<HttpResponseMessage> httpResponseMessage;
string count = records.Count.ToString("000000");
MultipartFormDataContent multipartFormDataContent;
ReadOnlyCollection<Verb> collection = GetVerbCollection(directory, records);
#if ShellProgressBar
ProgressBar progressBar = new(downloads.Count, $"{httpMethod}ing: {count};", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
#endif
for (int i = 0; i < collection.Count; i++) {
verb = collection[i];
#if ShellProgressBar
progressBar.Tick();
#endif
ticks = DateTime.Now.Ticks;
iValue = (i + 1).ToString("000000");
size = GetSizeWithSuffix(verb.Size);
if (httpMethod == HttpMethod.Get || httpMethod == HttpMethod.Delete) {
httpRequestMessage = new(httpMethod, $"{page}size={verb.Size}&ticks={verb.Ticks}&path={verb.UrlEncodedFile}");
} else if (httpMethod == HttpMethod.Patch || httpMethod == HttpMethod.Put) {
httpRequestMessage = new(httpMethod, $"{page}path={verb.Directory}");
multipartFormDataContent = new() {
{ new ByteArrayContent(File.ReadAllBytes(verb.File)), "formFiles", verb.Multipart },
{ new StringContent(verb.Directory), "path", iValue }
};
httpRequestMessage.Content = multipartFormDataContent;
} else {
throw new NotImplementedException();
}
httpResponseMessage = httpClient.SendAsync(httpRequestMessage);
httpResponseMessage.Wait(-1);
if (!httpResponseMessage.Result.IsSuccessStatusCode) {
logger.LogInformation("Failed to {httpMethod}: <{display}> - {size};", httpMethod, verb.Display, size);
} else {
try {
if (httpMethod != HttpMethod.Get) {
duration = GetDurationWithSuffix(ticks);
} else {
response = httpResponseMessage.Result.Content.ReadAsStringAsync();
response.Wait();
File.WriteAllText(verb.File, response.Result);
duration = GetDurationWithSuffix(ticks);
dateTime = new DateTime(verb.Ticks).ToLocalTime();
File.SetLastWriteTime(verb.File, dateTime);
}
logger.LogInformation("{i} of {count} - {httpMethod}'ed: <{display}> - {size} - {timeSpan};",
iValue,
count,
httpMethod,
verb.Display,
size,
duration);
} catch (Exception) {
logger.LogInformation("Failed to {httpMethod}: <{display}> - {size};", httpMethod, verb.Display, size);
}
}
}
#if ShellProgressBar
progressBar.Dispose();
#endif
}
private static void LiveSync(ILogger<Worker> logger, string page, RelativePath relativePath, HttpClient httpClient, string? directory, ReadOnlyCollection<Record> records, HttpMethod? httpMethod, bool delete) {
long sum;
try { sum = records.Sum(l => l.Size); } catch (Exception) { sum = 0; }
string size = GetSizeWithSuffix(sum);
if (delete) {
logger.LogInformation("Starting to delete {count} file(s) [{sum}]", records.Count, size);
PreformDeletes(logger, relativePath.RightDirectory, records);
logger.LogInformation("Deleted {count} file(s) [{sum}]", records.Count, size);
}
if (httpMethod is not null) {
logger.LogInformation("Starting to {httpMethod} {count} file(s) [{sum}]", httpMethod.ToString().ToLower(), records.Count, size);
Preform(logger, page, directory, records, httpClient, httpMethod);
logger.LogInformation("{httpMethod}'ed {count} file(s) [{sum}]", httpMethod.ToString(), records.Count, size);
} }
return result;
} }
} }

View File

@ -1,12 +1,11 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Globalization; using System.Globalization;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250521 { internal static partial class Helper20250521 {
@ -19,24 +18,6 @@ internal static partial class Helper20250521 {
private record Record(string Directory, string FileNameWithoutExtension); private record Record(string Directory, string FileNameWithoutExtension);
private record LineCheck(string[] Segments, DateTime TransactionDate, DateTime EffectiveDate) {
internal static LineCheck Get(int dateLineSegmentCount, string datePattern, string line) {
LineCheck result;
string[] segments = line.Split(' ');
if (segments.Length >= dateLineSegmentCount
&& segments[0].Length == datePattern.Length
&& segments[1].Length == datePattern.Length
&& DateTime.TryParseExact(segments[0], datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime transactionDate)
&& DateTime.TryParseExact(segments[1], datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime effectiveDate)) {
result = new(Segments: segments, TransactionDate: transactionDate, EffectiveDate: effectiveDate);
} else {
result = new(Segments: segments, TransactionDate: DateTime.MinValue, EffectiveDate: DateTime.MinValue);
}
return result;
}
}
private record RecordB(int I, private record RecordB(int I,
DateTime TransactionDate, DateTime TransactionDate,
DateTime EffectiveDate, DateTime EffectiveDate,
@ -59,12 +40,11 @@ internal static partial class Helper20250521 {
string datePattern = args[5]; string datePattern = args[5];
string searchPattern = args[2]; string searchPattern = args[2];
string searchPatternB = args[3]; string searchPatternB = args[3];
string columns = args[6].Replace('~', ',');
int dateLineSegmentCount = int.Parse(args[4]); int dateLineSegmentCount = int.Parse(args[4]);
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]); string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
ReadOnlyDictionary<string, string> keyValuePairs = GetKeyValuePairs(searchPattern, sourceDirectory); ReadOnlyDictionary<string, string> keyValuePairs = GetKeyValuePairs(searchPattern, sourceDirectory);
MoveMatchDirectory(searchPatternB, keyValuePairs, sourceDirectory); MoveMatchDirectory(searchPatternB, keyValuePairs, sourceDirectory);
ReadOnlyCollection<RecordB> records = GetRecords(searchPatternB, sourceDirectory, dateLineSegmentCount, datePattern, columns); ReadOnlyCollection<RecordB> records = GetRecords(searchPatternB, sourceDirectory, dateLineSegmentCount, datePattern);
WriteRecords(sourceDirectory, records); WriteRecords(sourceDirectory, records);
} }
@ -72,7 +52,7 @@ internal static partial class Helper20250521 {
Dictionary<string, string> results = []; Dictionary<string, string> results = [];
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
foreach (string file in files) { foreach (string file in files) {
results.Add(Path.GetFileNameWithoutExtension(file), Path.GetDirectoryName(file)); results.Add(Path.GetFileNameWithoutExtension(file), Path.GetDirectoryName(file) ?? throw new Exception());
} }
return results.AsReadOnly(); return results.AsReadOnly();
} }
@ -83,16 +63,18 @@ internal static partial class Helper20250521 {
string[] files = Directory.GetFiles(sourceDirectory, searchPatternB, SearchOption.AllDirectories); string[] files = Directory.GetFiles(sourceDirectory, searchPatternB, SearchOption.AllDirectories);
foreach (string file in files) { foreach (string file in files) {
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file); fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
if (!keyValuePairs.TryGetValue(fileNameWithoutExtension, out string? match)) if (!keyValuePairs.TryGetValue(fileNameWithoutExtension, out string? match)) {
continue; continue;
}
checkFile = Path.Combine(match, Path.GetFileName(file)); checkFile = Path.Combine(match, Path.GetFileName(file));
if (File.Exists(checkFile)) if (File.Exists(checkFile)) {
continue; continue;
}
File.Move(file, checkFile); File.Move(file, checkFile);
} }
} }
private static ReadOnlyCollection<RecordB> GetRecords(string searchPatternB, string sourceDirectory, int dateLineSegmentCount, string datePattern, string columns) { private static ReadOnlyCollection<RecordB> GetRecords(string searchPatternB, string sourceDirectory, int dateLineSegmentCount, string datePattern) {
List<RecordB> results = []; List<RecordB> results = [];
string line; string line;
string[] lines; string[] lines;
@ -110,7 +92,7 @@ internal static partial class Helper20250521 {
if (lineCheck.EffectiveDate == DateTime.MinValue || lineCheck.TransactionDate == DateTime.MinValue) { if (lineCheck.EffectiveDate == DateTime.MinValue || lineCheck.TransactionDate == DateTime.MinValue) {
continue; continue;
} else { } else {
record = GetRecord(dateLineSegmentCount, datePattern, lines, i, lineCheck.Segments, lineCheck.TransactionDate, lineCheck.EffectiveDate); record = GetRecord(dateLineSegmentCount, datePattern, lines, i, lineCheck.TransactionDate, lineCheck.EffectiveDate);
if (record is not null) { if (record is not null) {
i = record.I; i = record.I;
results.Add(record); results.Add(record);
@ -121,7 +103,7 @@ internal static partial class Helper20250521 {
return results.AsReadOnly(); return results.AsReadOnly();
} }
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, DateTime transactionDate, DateTime effectiveDate) {
RecordB? result = null; RecordB? result = null;
string line; string line;
LineCheck lineCheck; LineCheck lineCheck;
@ -148,7 +130,7 @@ internal static partial class Helper20250521 {
return result; return result;
} }
private static RecordB GetRecord(DateTime transactionDate, DateTime effectiveDate, ReadOnlyCollection<string> collection, int i) { private static RecordB? GetRecord(DateTime transactionDate, DateTime effectiveDate, ReadOnlyCollection<string> collection, int i) {
RecordB? result; RecordB? result;
List<string> verified = []; List<string> verified = [];
foreach (string check in collection) { foreach (string check in collection) {
@ -180,9 +162,28 @@ internal static partial class Helper20250521 {
private static void WriteRecords(string sourceDirectory, ReadOnlyCollection<RecordB> records) { private static void WriteRecords(string sourceDirectory, ReadOnlyCollection<RecordB> records) {
string json = JsonSerializer.Serialize(records.ToArray(), Helper20250521RecordB.Default.RecordBArray); string json = JsonSerializer.Serialize(records.ToArray(), Helper20250521RecordB.Default.RecordBArray);
string sourceDirectoryVsCode = Path.Combine(sourceDirectory, ".vscode"); string sourceDirectoryVsCode = Path.Combine(sourceDirectory, ".vscode");
if (!Directory.Exists(sourceDirectoryVsCode)) if (!Directory.Exists(sourceDirectoryVsCode)) {
_ = Directory.CreateDirectory(sourceDirectoryVsCode); _ = Directory.CreateDirectory(sourceDirectoryVsCode);
}
File.WriteAllText(Path.Combine(sourceDirectoryVsCode, $"{DateTime.Now.Ticks}.json"), json); File.WriteAllText(Path.Combine(sourceDirectoryVsCode, $"{DateTime.Now.Ticks}.json"), json);
} }
private record LineCheck(string[] Segments, DateTime TransactionDate, DateTime EffectiveDate) {
internal static LineCheck Get(int dateLineSegmentCount, string datePattern, string line) {
LineCheck result;
string[] segments = line.Split(' ');
if (segments.Length >= dateLineSegmentCount
&& segments[0].Length == datePattern.Length
&& segments[1].Length == datePattern.Length
&& DateTime.TryParseExact(segments[0], datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime transactionDate)
&& DateTime.TryParseExact(segments[1], datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime effectiveDate)) {
result = new(Segments: segments, TransactionDate: transactionDate, EffectiveDate: effectiveDate);
} else {
result = new(Segments: segments, TransactionDate: DateTime.MinValue, EffectiveDate: DateTime.MinValue);
}
return result;
}
}
} }

View File

@ -1,4 +1,6 @@
using IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Globalization; using System.Globalization;
using System.Net; using System.Net;
@ -6,10 +8,6 @@ using System.Text;
using System.Xml; using System.Xml;
using System.Xml.Serialization; using System.Xml.Serialization;
using IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250601 { internal static partial class Helper20250601 {
@ -33,6 +31,24 @@ internal static partial class Helper20250601 {
string StopTime, string StopTime,
string Text); string Text);
private static T? ParseXML<T>(string value, bool throwExceptions) where T : class {
object? result = null;
try {
Stream stream = ToStream(value.Trim());
XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
#pragma warning disable IL2026, IL2090
XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes());
result = xmlSerializer.Deserialize(xmlReader);
#pragma warning restore IL2026, IL2090
stream.Dispose();
} catch (Exception) {
if (throwExceptions) {
throw;
}
}
return result as T;
}
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;
@ -141,41 +157,6 @@ internal static partial class Helper20250601 {
return results; return results;
} }
private static ReadOnlyCollection<string> GetUrls(bool development, bool staging, bool production) {
List<string> results = [];
if (development) {
results.Add("eaf-dev.mes.infineon.com:9003");
}
if (staging) {
results.Add("eaf-staging.mes.infineon.com:9003");
}
if (production) {
results.Add("eaf-prod.mes.infineon.com:9003");
}
return results.AsReadOnly();
}
private static List<UnicodeCategory> GetUnicodeCategory() {
List<UnicodeCategory> unicodeCategories = [
// UnicodeCategory.Control, // 33 - <20>
UnicodeCategory.UppercaseLetter, // 25 - ABCDEFGHIJKLMNOPQRSTUVWXY
UnicodeCategory.LowercaseLetter, // 25 - abcdefghiklmnopqrstuvwxyz
UnicodeCategory.DecimalDigitNumber, // 10 - 0123456789
UnicodeCategory.OtherPunctuation, // 10 - !"#%&,./:@
UnicodeCategory.ClosePunctuation, // 2 - )]
UnicodeCategory.MathSymbol, // 2 - |؈
UnicodeCategory.OpenPunctuation, // 2 - ([
// UnicodeCategory.OtherSymbol, // 1 - <20>
UnicodeCategory.DashPunctuation, // 1 - -
UnicodeCategory.ConnectorPunctuation, // 1 - _
UnicodeCategory.ModifierSymbol, // 1 - `
UnicodeCategory.NonSpacingMark, // 1 - ̵
UnicodeCategory.SpaceSeparator, // 1 -
UnicodeCategory.CurrencySymbol, // 1 - $
];
return unicodeCategories;
}
private static void EquipmentAutomationFrameworkCellInstanceParseCheck() { private static void EquipmentAutomationFrameworkCellInstanceParseCheck() {
Envelope? envelope; Envelope? envelope;
string xmlStart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:6eb7a538-0b2b-4d04-8f2a-ab50e1e5338a</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>"; string xmlStart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:6eb7a538-0b2b-4d04-8f2a-ab50e1e5338a</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
@ -196,33 +177,6 @@ internal static partial class Helper20250601 {
} }
} }
private static T? ParseXML<T>(string value, bool throwExceptions) where T : class {
object? result = null;
try {
Stream stream = ToStream(value.Trim());
XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
#pragma warning disable IL2026, IL2090
XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes());
result = xmlSerializer.Deserialize(xmlReader);
#pragma warning restore IL2026, IL2090
stream.Dispose();
} catch (Exception) {
if (throwExceptions) {
throw;
}
}
return result as T;
}
private static Stream ToStream(string value) {
MemoryStream memoryStream = new();
StreamWriter streamWriter = new(memoryStream);
streamWriter.Write(value);
streamWriter.Flush();
memoryStream.Position = 0;
return memoryStream;
}
private static Dictionary<char, char> GetUnicodeReplaces() { private static Dictionary<char, char> GetUnicodeReplaces() {
Dictionary<char, char> results = new() { Dictionary<char, char> results = new() {
{ '\u0000', ' ' }, { '\u0000', ' ' },
@ -295,6 +249,41 @@ internal static partial class Helper20250601 {
return results; return results;
} }
private static List<UnicodeCategory> GetUnicodeCategory() {
List<UnicodeCategory> unicodeCategories = [
// UnicodeCategory.Control, // 33 - <20>
UnicodeCategory.UppercaseLetter, // 25 - ABCDEFGHIJKLMNOPQRSTUVWXY
UnicodeCategory.LowercaseLetter, // 25 - abcdefghiklmnopqrstuvwxyz
UnicodeCategory.DecimalDigitNumber, // 10 - 0123456789
UnicodeCategory.OtherPunctuation, // 10 - !"#%&,./:@
UnicodeCategory.ClosePunctuation, // 2 - )]
UnicodeCategory.MathSymbol, // 2 - |؈
UnicodeCategory.OpenPunctuation, // 2 - ([
// UnicodeCategory.OtherSymbol, // 1 - <20>
UnicodeCategory.DashPunctuation, // 1 - -
UnicodeCategory.ConnectorPunctuation, // 1 - _
UnicodeCategory.ModifierSymbol, // 1 - `
UnicodeCategory.NonSpacingMark, // 1 - ̵
UnicodeCategory.SpaceSeparator, // 1 -
UnicodeCategory.CurrencySymbol, // 1 - $
];
return unicodeCategories;
}
private static ReadOnlyCollection<string> GetUrls(bool development, bool staging, bool production) {
List<string> results = [];
if (development) {
results.Add("eaf-dev.mes.infineon.com:9003");
}
if (staging) {
results.Add("eaf-staging.mes.infineon.com:9003");
}
if (production) {
results.Add("eaf-prod.mes.infineon.com:9003");
}
return results.AsReadOnly();
}
private static Status EquipmentAutomationFrameworkCellInstanceStatus(string cellInstanceName, Record record) { private static Status EquipmentAutomationFrameworkCellInstanceStatus(string cellInstanceName, Record record) {
Status result; Status result;
bool stop = false; bool stop = false;
@ -390,4 +379,13 @@ internal static partial class Helper20250601 {
return results; return results;
} }
private static Stream ToStream(string value) {
MemoryStream memoryStream = new();
StreamWriter streamWriter = new(memoryStream);
streamWriter.Write(value);
streamWriter.Flush();
memoryStream.Position = 0;
return memoryStream;
}
} }

View File

@ -1,4 +1,6 @@
using IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Globalization; using System.Globalization;
using System.Net; using System.Net;
@ -6,10 +8,6 @@ using System.Text;
using System.Xml; using System.Xml;
using System.Xml.Serialization; using System.Xml.Serialization;
using IFX.Shared.PasteSpecialXml.EAF.XML.API.Envelope;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250602 { internal static partial class Helper20250602 {
@ -31,6 +29,24 @@ internal static partial class Helper20250602 {
string StopTime, string StopTime,
string Text); string Text);
private static T? ParseXML<T>(string value, bool throwExceptions) where T : class {
object? result = null;
try {
Stream stream = ToStream(value.Trim());
XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
#pragma warning disable IL2026, IL2090
XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes());
result = xmlSerializer.Deserialize(xmlReader);
#pragma warning restore IL2026, IL2090
stream.Dispose();
} catch (Exception) {
if (throwExceptions) {
throw;
}
}
return result as T;
}
internal static void EquipmentAutomationFrameworkCellInstanceStateImageVerbIf(ILogger<Worker> logger, List<string> args) { internal static void EquipmentAutomationFrameworkCellInstanceStateImageVerbIf(ILogger<Worker> logger, List<string> args) {
string path; string path;
Status status; Status status;
@ -56,25 +72,6 @@ internal static partial class Helper20250602 {
} }
} }
private static Status GetEquipmentAutomationFrameworkCellInstanceStateImageVerbIf(ILogger<Worker> logger, string verbBy, string cellInstanceName, Record record) {
Status result;
Dictionary<string, DateTime> equipmentAutomationFrameworkTriggers = [];
if (!equipmentAutomationFrameworkTriggers.ContainsKey(cellInstanceName)) {
equipmentAutomationFrameworkTriggers.Add(cellInstanceName, DateTime.MinValue);
}
result = EquipmentAutomationFrameworkCellInstanceStatus(cellInstanceName, record);
if (equipmentAutomationFrameworkTriggers[cellInstanceName] < DateTime.Now.AddSeconds(-60)) {
if (result.State == "Offline") {
EquipmentAutomationFrameworkCellInstanceStart(record.Host, record.Port, cellInstanceName, verbBy);
logger.LogInformation("Start invoked for {cellName}", cellInstanceName);
} else if (result.State == "Warning") {
EquipmentAutomationFrameworkCellInstanceRestart(record.Host, record.Port, cellInstanceName, verbBy);
logger.LogInformation("Restart invoked for {cellName}", cellInstanceName);
}
}
return result;
}
private static Dictionary<string, Record> GetEquipmentAutomationFrameworkCellInstanceStatus(bool development, bool staging, bool production) { private static Dictionary<string, Record> GetEquipmentAutomationFrameworkCellInstanceStatus(bool development, bool staging, bool production) {
Dictionary<string, Record> results = []; Dictionary<string, Record> results = [];
string key; string key;
@ -160,41 +157,6 @@ internal static partial class Helper20250602 {
return results; return results;
} }
private static ReadOnlyCollection<string> GetUrls(bool development, bool staging, bool production) {
List<string> results = [];
if (development) {
results.Add("eaf-dev.mes.infineon.com:9003");
}
if (staging) {
results.Add("eaf-staging.mes.infineon.com:9003");
}
if (production) {
results.Add("eaf-prod.mes.infineon.com:9003");
}
return results.AsReadOnly();
}
private static List<UnicodeCategory> GetUnicodeCategory() {
List<UnicodeCategory> unicodeCategories = [
// UnicodeCategory.Control, // 33 - <20>
UnicodeCategory.UppercaseLetter, // 25 - ABCDEFGHIJKLMNOPQRSTUVWXY
UnicodeCategory.LowercaseLetter, // 25 - abcdefghiklmnopqrstuvwxyz
UnicodeCategory.DecimalDigitNumber, // 10 - 0123456789
UnicodeCategory.OtherPunctuation, // 10 - !"#%&,./:@
UnicodeCategory.ClosePunctuation, // 2 - )]
UnicodeCategory.MathSymbol, // 2 - |؈
UnicodeCategory.OpenPunctuation, // 2 - ([
// UnicodeCategory.OtherSymbol, // 1 - <20>
UnicodeCategory.DashPunctuation, // 1 - -
UnicodeCategory.ConnectorPunctuation, // 1 - _
UnicodeCategory.ModifierSymbol, // 1 - `
UnicodeCategory.NonSpacingMark, // 1 - ̵
UnicodeCategory.SpaceSeparator, // 1 -
UnicodeCategory.CurrencySymbol, // 1 - $
];
return unicodeCategories;
}
private static void EquipmentAutomationFrameworkCellInstanceParseCheck() { private static void EquipmentAutomationFrameworkCellInstanceParseCheck() {
Envelope? envelope; Envelope? envelope;
string xmlStart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:6eb7a538-0b2b-4d04-8f2a-ab50e1e5338a</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>"; string xmlStart621 = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action><a:RelatesTo>urn:uuid:6eb7a538-0b2b-4d04-8f2a-ab50e1e5338a</a:RelatesTo></s:Header><s:Body><CreateSequenceResponse xmlns=\"http://schemas.xmlsoap.org/ws/2005/02/rm\"><Identifier>urn:uuid:31c290af-2312-4b00-a57c-d5e1ab51e02a</Identifier><Accept><AcksTo><a:Address>http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:Address></AcksTo></Accept></CreateSequenceResponse></s:Body></s:Envelope>";
@ -215,33 +177,6 @@ internal static partial class Helper20250602 {
} }
} }
private static T? ParseXML<T>(string value, bool throwExceptions) where T : class {
object? result = null;
try {
Stream stream = ToStream(value.Trim());
XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
#pragma warning disable IL2026, IL2090
XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes());
result = xmlSerializer.Deserialize(xmlReader);
#pragma warning restore IL2026, IL2090
stream.Dispose();
} catch (Exception) {
if (throwExceptions) {
throw;
}
}
return result as T;
}
private static Stream ToStream(string value) {
MemoryStream memoryStream = new();
StreamWriter streamWriter = new(memoryStream);
streamWriter.Write(value);
streamWriter.Flush();
memoryStream.Position = 0;
return memoryStream;
}
private static Dictionary<char, char> GetUnicodeReplaces() { private static Dictionary<char, char> GetUnicodeReplaces() {
Dictionary<char, char> results = new() { Dictionary<char, char> results = new() {
{ '\u0000', ' ' }, { '\u0000', ' ' },
@ -314,6 +249,60 @@ internal static partial class Helper20250602 {
return results; return results;
} }
private static List<UnicodeCategory> GetUnicodeCategory() {
List<UnicodeCategory> unicodeCategories = [
// UnicodeCategory.Control, // 33 - <20>
UnicodeCategory.UppercaseLetter, // 25 - ABCDEFGHIJKLMNOPQRSTUVWXY
UnicodeCategory.LowercaseLetter, // 25 - abcdefghiklmnopqrstuvwxyz
UnicodeCategory.DecimalDigitNumber, // 10 - 0123456789
UnicodeCategory.OtherPunctuation, // 10 - !"#%&,./:@
UnicodeCategory.ClosePunctuation, // 2 - )]
UnicodeCategory.MathSymbol, // 2 - |؈
UnicodeCategory.OpenPunctuation, // 2 - ([
// UnicodeCategory.OtherSymbol, // 1 - <20>
UnicodeCategory.DashPunctuation, // 1 - -
UnicodeCategory.ConnectorPunctuation, // 1 - _
UnicodeCategory.ModifierSymbol, // 1 - `
UnicodeCategory.NonSpacingMark, // 1 - ̵
UnicodeCategory.SpaceSeparator, // 1 -
UnicodeCategory.CurrencySymbol, // 1 - $
];
return unicodeCategories;
}
private static ReadOnlyCollection<string> GetUrls(bool development, bool staging, bool production) {
List<string> results = [];
if (development) {
results.Add("eaf-dev.mes.infineon.com:9003");
}
if (staging) {
results.Add("eaf-staging.mes.infineon.com:9003");
}
if (production) {
results.Add("eaf-prod.mes.infineon.com:9003");
}
return results.AsReadOnly();
}
private static Status GetEquipmentAutomationFrameworkCellInstanceStateImageVerbIf(ILogger<Worker> logger, string verbBy, string cellInstanceName, Record record) {
Status result;
Dictionary<string, DateTime> equipmentAutomationFrameworkTriggers = [];
if (!equipmentAutomationFrameworkTriggers.ContainsKey(cellInstanceName)) {
equipmentAutomationFrameworkTriggers.Add(cellInstanceName, DateTime.MinValue);
}
result = EquipmentAutomationFrameworkCellInstanceStatus(cellInstanceName, record);
if (equipmentAutomationFrameworkTriggers[cellInstanceName] < DateTime.Now.AddSeconds(-60)) {
if (result.State == "Offline") {
EquipmentAutomationFrameworkCellInstanceStart(record.Host, record.Port, cellInstanceName, verbBy);
logger.LogInformation("Start invoked for {cellName}", cellInstanceName);
} else if (result.State == "Warning") {
EquipmentAutomationFrameworkCellInstanceRestart(record.Host, record.Port, cellInstanceName, verbBy);
logger.LogInformation("Restart invoked for {cellName}", cellInstanceName);
}
}
return result;
}
private static Status EquipmentAutomationFrameworkCellInstanceStatus(string cellInstanceName, Record record) { private static Status EquipmentAutomationFrameworkCellInstanceStatus(string cellInstanceName, Record record) {
Status result; Status result;
bool stop = false; bool stop = false;
@ -409,27 +398,6 @@ internal static partial class Helper20250602 {
return results; return results;
} }
private static void EquipmentAutomationFrameworkCellInstanceRestart(string host, int port, string cellName = "R71-HSMS", string verbBy = @"EC\EcMesEaf") {
EquipmentAutomationFrameworkCellInstanceParseCheck();
// Restart
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action><a:MessageID>urn:uuid:09fd9303-dcfe-4563-803b-678441b12949</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><CreateSequence xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm"><AcksTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></AcksTo><Offer><Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</Identifier></Offer></CreateSequence></s:Body></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/RestartAllCellInstances</a:Action><a:MessageID>urn:uuid:c9f80db4-a2c2-4e53-9bed-8ba3a60b653c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><RestartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Restarted by EC\ecphares</updateInfo></RestartAllCellInstances></s:Body></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</r:Identifier><r:AcknowledgementRange Lower="1" Upper="1"/></r:SequenceAcknowledgement><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body/></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</r:Identifier><r:AcknowledgementRange Lower="1" Upper="2"/></r:SequenceAcknowledgement><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action><a:MessageID>urn:uuid:3b063df5-e6df-47a5-b530-aa380a4c6a38</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>
EquipmentAutomationFrameworkCellInstanceVerb(host, port, cellName, verbBy, restart: true, stop: false, start: false);
}
private static void EquipmentAutomationFrameworkCellInstanceStart(string host, int port, string cellName = "R71-HSMS", string verbBy = @"EC\EcMesEaf") {
EquipmentAutomationFrameworkCellInstanceParseCheck();
// Start
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action><a:MessageID>urn:uuid:a1188d61-df04-4955-b1e4-b90faff95d4d</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><CreateSequence xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm"><AcksTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></AcksTo><Offer><Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</Identifier></Offer></CreateSequence></s:Body></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/StartAllCellInstances</a:Action><a:MessageID>urn:uuid:8758eec2-b4dc-4338-ba3d-235aa15e634c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><StartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Started by EC\ecphares</updateInfo></StartAllCellInstances></s:Body></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/StartAllCellInstances</a:Action><a:MessageID>urn:uuid:8758eec2-b4dc-4338-ba3d-235aa15e634c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><StartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Started by EC\ecphares</updateInfo></StartAllCellInstances></s:Body></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</r:Identifier><r:AcknowledgementRange Lower="1" Upper="1"/></r:SequenceAcknowledgement><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body/></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</r:Identifier><r:AcknowledgementRange Lower="1" Upper="2"/></r:SequenceAcknowledgement><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action><a:MessageID>urn:uuid:b2bb5329-c846-4cd1-98a8-343136923702</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>
EquipmentAutomationFrameworkCellInstanceVerb(host, port, cellName, verbBy, restart: false, stop: false, start: true);
}
private static void EquipmentAutomationFrameworkCellInstanceVerb(string host, int port, string cellName, string verbBy, bool restart, bool stop, bool start) { private static void EquipmentAutomationFrameworkCellInstanceVerb(string host, int port, string cellName, string verbBy, bool restart, bool stop, bool start) {
#pragma warning disable SYSLIB0014 #pragma warning disable SYSLIB0014
WebClient webClient = new(); WebClient webClient = new();
@ -453,8 +421,9 @@ internal static partial class Helper20250602 {
} else if (start) { } else if (start) {
updateInfoVerb = "Started"; updateInfoVerb = "Started";
verb = "StartAllCellInstances"; verb = "StartAllCellInstances";
} else } else {
throw new Exception(); throw new Exception();
}
string headerMessageID621 = Guid.NewGuid().ToString(); string headerMessageID621 = Guid.NewGuid().ToString();
string bodyIdentifier621 = Guid.NewGuid().ToString(); string bodyIdentifier621 = Guid.NewGuid().ToString();
_ = stringBuilder.Append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">"). _ = stringBuilder.Append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">").
@ -542,4 +511,34 @@ internal static partial class Helper20250602 {
_ = ParseXML<Envelope>(xml, throwExceptions: true); _ = ParseXML<Envelope>(xml, throwExceptions: true);
} }
private static Stream ToStream(string value) {
MemoryStream memoryStream = new();
StreamWriter streamWriter = new(memoryStream);
streamWriter.Write(value);
streamWriter.Flush();
memoryStream.Position = 0;
return memoryStream;
}
private static void EquipmentAutomationFrameworkCellInstanceStart(string host, int port, string cellName = "R71-HSMS", string verbBy = @"EC\EcMesEaf") {
EquipmentAutomationFrameworkCellInstanceParseCheck();
// Start
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action><a:MessageID>urn:uuid:a1188d61-df04-4955-b1e4-b90faff95d4d</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><CreateSequence xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm"><AcksTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></AcksTo><Offer><Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</Identifier></Offer></CreateSequence></s:Body></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/StartAllCellInstances</a:Action><a:MessageID>urn:uuid:8758eec2-b4dc-4338-ba3d-235aa15e634c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><StartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Started by EC\ecphares</updateInfo></StartAllCellInstances></s:Body></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/StartAllCellInstances</a:Action><a:MessageID>urn:uuid:8758eec2-b4dc-4338-ba3d-235aa15e634c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><StartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Started by EC\ecphares</updateInfo></StartAllCellInstances></s:Body></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</r:Identifier><r:AcknowledgementRange Lower="1" Upper="1"/></r:SequenceAcknowledgement><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body/></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:35310d6d-3d17-419c-9b4f-cf20b705e5c9</r:Identifier><r:AcknowledgementRange Lower="1" Upper="2"/></r:SequenceAcknowledgement><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action><a:MessageID>urn:uuid:b2bb5329-c846-4cd1-98a8-343136923702</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:739e01d3-5573-48a4-8bbb-53e2dfc344af</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>
EquipmentAutomationFrameworkCellInstanceVerb(host, port, cellName, verbBy, restart: false, stop: false, start: true);
}
private static void EquipmentAutomationFrameworkCellInstanceRestart(string host, int port, string cellName = "R71-HSMS", string verbBy = @"EC\EcMesEaf") {
EquipmentAutomationFrameworkCellInstanceParseCheck();
// Restart
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action><a:MessageID>urn:uuid:09fd9303-dcfe-4563-803b-678441b12949</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><CreateSequence xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm"><AcksTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></AcksTo><Offer><Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</Identifier></Offer></CreateSequence></s:Body></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier><r:MessageNumber>1</r:MessageNumber></r:Sequence><a:Action s:mustUnderstand="1">http://tempuri.org/ICellControllerManager/RestartAllCellInstances</a:Action><a:MessageID>urn:uuid:c9f80db4-a2c2-4e53-9bed-8ba3a60b653c</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><RestartAllCellInstances xmlns="http://tempuri.org/"><cellInstances xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:string>SP101_FileArchiver</b:string></cellInstances><updateInfo>Restarted by EC\ecphares</updateInfo></RestartAllCellInstances></s:Body></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</r:Identifier><r:AcknowledgementRange Lower="1" Upper="1"/></r:SequenceAcknowledgement><r:Sequence s:mustUnderstand="1"><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier><r:MessageNumber>2</r:MessageNumber><r:LastMessage/></r:Sequence><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage</a:Action><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body/></s:Envelope>
// <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><r:SequenceAcknowledgement><r:Identifier>urn:uuid:4f2050da-4287-411b-992f-3126a5b3b35b</r:Identifier><r:AcknowledgementRange Lower="1" Upper="2"/></r:SequenceAcknowledgement><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</a:Action><a:MessageID>urn:uuid:3b063df5-e6df-47a5-b530-aa380a4c6a38</a:MessageID><a:To s:mustUnderstand="1">http://eaf-prod.mes.infineon.com:9003/CellControllerManager</a:To></s:Header><s:Body><r:TerminateSequence><r:Identifier>urn:uuid:fbf34c20-f381-4e82-b81f-b4c1809f14fa</r:Identifier></r:TerminateSequence></s:Body></s:Envelope>
EquipmentAutomationFrameworkCellInstanceVerb(host, port, cellName, verbBy, restart: true, stop: false, start: false);
}
} }

View File

@ -1,7 +1,6 @@
using System.Collections.ObjectModel;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;
@ -77,10 +76,12 @@ internal static partial class Helper20250618 {
file = keyValuePair.Value[i]; file = keyValuePair.Value[i];
checkFile = $"{destinationDirectory}{file[sourceDirectoryLength..]}"; checkFile = $"{destinationDirectory}{file[sourceDirectoryLength..]}";
checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new Exception(); checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new Exception();
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory)) {
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
if (File.Exists(checkFile)) }
if (File.Exists(checkFile)) {
continue; continue;
}
File.Move(file, checkFile); File.Move(file, checkFile);
logger.LogInformation("<{file}> moved", file); logger.LogInformation("<{file}> moved", file);
} }

View File

@ -1,8 +1,6 @@
using System.Collections.ObjectModel;
using DiscUtils.Iso9660; using DiscUtils.Iso9660;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;
@ -35,22 +33,6 @@ internal static partial class Helper20250628 {
return results.AsReadOnly(); return results.AsReadOnly();
} }
private static string GetSizeWithSuffix(long value) {
string result;
int i = 0;
string[] SizeSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
if (value < 0) {
result = "-" + GetSizeWithSuffix(-value);
} else {
while (Math.Round(value / 1024f) >= 1) {
value /= 1024;
i++;
}
result = string.Format("{0:n1} {1}", value, SizeSuffixes[i]);
}
return result;
}
private static void LogIsoInformation(ILogger<Worker> logger, ReadOnlyCollection<Record> records, string letter) { private static void LogIsoInformation(ILogger<Worker> logger, ReadOnlyCollection<Record> records, string letter) {
string size; string size;
string[] files; string[] files;
@ -85,4 +67,20 @@ internal static partial class Helper20250628 {
} }
} }
private static string GetSizeWithSuffix(long value) {
string result;
int i = 0;
string[] SizeSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
if (value < 0) {
result = "-" + GetSizeWithSuffix(-value);
} else {
while (Math.Round(value / 1024f) >= 1) {
value /= 1024;
i++;
}
result = string.Format("{0:n1} {1}", value, SizeSuffixes[i]);
}
return result;
}
} }

View File

@ -1,10 +1,9 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250701 { internal static partial class Helper20250701 {
@ -55,7 +54,7 @@ internal static partial class Helper20250701 {
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 (sizeFilter < 987654321 && Path.GetFileName(directory).Contains('-')) { if (sizeFilter < 987654321 && Path.GetFileName(directory).Contains('-')) {
@ -68,6 +67,9 @@ internal static partial class Helper20250701 {
continue; continue;
} }
directoryName = Path.GetFileName(fileInfo.DirectoryName); directoryName = Path.GetFileName(fileInfo.DirectoryName);
if (string.IsNullOrEmpty(directoryName)) {
continue;
}
if (fileInfo.Length > sizeFilter && !directoryName.StartsWith('Z')) { if (fileInfo.Length > sizeFilter && !directoryName.StartsWith('Z')) {
checkDirectory = Path.Combine(sourceDirectory, $"Z{directoryName}"); checkDirectory = Path.Combine(sourceDirectory, $"Z{directoryName}");
if (!Directory.Exists(checkDirectory)) { if (!Directory.Exists(checkDirectory)) {
@ -142,51 +144,6 @@ internal static partial class Helper20250701 {
return result; return result;
} }
private static int? GetProcessDataStandardFormatColumnTitlesLine(string[] lines) {
int? result = null;
for (int i = 0; i < lines.Length; i++) {
if (lines[i].StartsWith("END_OFFSET") && i + 3 < lines.Length) {
result = i + 1;
break;
}
}
return result;
}
private static ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetKeyValuePairs(int columnTitlesLine, string[] lines) {
Dictionary<string, ReadOnlyCollection<string>> results = [];
string[] segments;
List<List<string>> collections = [];
string[] columns = lines[columnTitlesLine].Split('\t');
foreach (string column in columns) {
collections.Add([]);
}
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
break;
}
segments = lines[i].Split('\t');
if (segments.Length > columns.Length) {
continue;
}
for (int c = 0; c < segments.Length; c++) {
collections[c].Add(segments[c]);
}
}
for (int i = 0; i < collections.Count; i++) {
if (collections[i].Count > 1) {
if (string.IsNullOrEmpty(collections[i][0])) {
collections[i][0] = collections[i][1];
}
if (string.IsNullOrEmpty(collections[i][^1])) {
collections[i][^1] = collections[i][^2];
}
}
results.Add(columns[i].Trim('"'), collections[i].AsReadOnly());
}
return results.AsReadOnly();
}
private static string? GetMarkdown(string timeColumn, ReadOnlyDictionary<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 = [];
@ -242,6 +199,40 @@ internal static partial class Helper20250701 {
return result; return result;
} }
private static ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetKeyValuePairs(int columnTitlesLine, string[] lines) {
Dictionary<string, ReadOnlyCollection<string>> results = [];
string[] segments;
List<List<string>> collections = [];
string[] columns = lines[columnTitlesLine].Split('\t');
foreach (string _ in columns) {
collections.Add([]);
}
for (int i = columnTitlesLine + 1; i < lines.Length; i++) {
if (lines[i].StartsWith("NUM_DATA_ROWS")) {
break;
}
segments = lines[i].Split('\t');
if (segments.Length > columns.Length) {
continue;
}
for (int c = 0; c < segments.Length; c++) {
collections[c].Add(segments[c]);
}
}
for (int i = 0; i < collections.Count; i++) {
if (collections[i].Count > 1) {
if (string.IsNullOrEmpty(collections[i][0])) {
collections[i][0] = collections[i][1];
}
if (string.IsNullOrEmpty(collections[i][^1])) {
collections[i][^1] = collections[i][^2];
}
}
results.Add(columns[i].Trim('"'), collections[i].AsReadOnly());
}
return results.AsReadOnly();
}
private static string? GetJavaScriptObjectNotation(ILogger<Worker> logger, string file) { private static string? GetJavaScriptObjectNotation(ILogger<Worker> logger, string file) {
string? result = null; string? result = null;
string[] lines = File.ReadAllLines(file); string[] lines = File.ReadAllLines(file);
@ -321,8 +312,9 @@ internal static partial class Helper20250701 {
List<string> results = []; List<string> results = [];
for (int j = i; j < lines.Length; j++) { for (int j = i; j < lines.Length; j++) {
results.Add(lines[j]); results.Add(lines[j]);
if (lines[j].StartsWith("END_HEADER")) if (lines[j].StartsWith("END_HEADER")) {
break; break;
}
} }
return results.AsReadOnly(); return results.AsReadOnly();
} }
@ -385,6 +377,17 @@ internal static partial class Helper20250701 {
return results.AsReadOnly(); return results.AsReadOnly();
} }
private static int? GetProcessDataStandardFormatColumnTitlesLine(string[] lines) {
int? result = null;
for (int i = 0; i < lines.Length; i++) {
if (lines[i].StartsWith("END_OFFSET") && i + 3 < lines.Length) {
result = i + 1;
break;
}
}
return result;
}
private static string? GetPipeTable(string json) { private static string? GetPipeTable(string json) {
string? result = null; string? result = null;
string? value; string? value;
@ -406,6 +409,9 @@ internal static partial class Helper20250701 {
} }
keyValuePairs.Add(jsonProperty.Name, jsonProperty.Value.ToString()); keyValuePairs.Add(jsonProperty.Name, jsonProperty.Value.ToString());
} }
if (columns is null) {
continue;
}
foreach (string column in columns) { foreach (string column in columns) {
if (!keyValuePairs.TryGetValue(column, out value)) { if (!keyValuePairs.TryGetValue(column, out value)) {
values.Add(new string(' ', column.Length)); values.Add(new string(' ', column.Length));

View File

@ -1,6 +1,5 @@
using System.Drawing;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Drawing;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;

View File

@ -1,9 +1,8 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250709 { internal static partial class Helper20250709 {
@ -157,7 +156,6 @@ internal static partial class Helper20250709 {
string extension = args[4]; string extension = 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 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[6].Split('~')[0]);
string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly); string[] directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
@ -172,7 +170,7 @@ internal static partial class Helper20250709 {
string checkFile; string checkFile;
Reactor? reactor; Reactor? reactor;
FileInfo fileInfo; FileInfo fileInfo;
string directoryName; string? directoryName;
string checkDirectory; string checkDirectory;
foreach (string directory in directories) { foreach (string directory in directories) {
if (sizeFilter < 987654321 && Path.GetFileName(directory).Contains('-')) { if (sizeFilter < 987654321 && Path.GetFileName(directory).Contains('-')) {
@ -185,6 +183,9 @@ internal static partial class Helper20250709 {
continue; continue;
} }
directoryName = Path.GetFileName(fileInfo.DirectoryName); directoryName = Path.GetFileName(fileInfo.DirectoryName);
if (string.IsNullOrEmpty(directoryName)) {
continue;
}
if (fileInfo.Length > sizeFilter && !directoryName.StartsWith('Z')) { if (fileInfo.Length > sizeFilter && !directoryName.StartsWith('Z')) {
checkDirectory = Path.Combine(sourceDirectory, $"Z{directoryName}"); checkDirectory = Path.Combine(sourceDirectory, $"Z{directoryName}");
if (!Directory.Exists(checkDirectory)) { if (!Directory.Exists(checkDirectory)) {

View File

@ -1,8 +1,7 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250710 { internal static partial class Helper20250710 {
@ -28,7 +27,7 @@ internal static partial class Helper20250710 {
string[] files; string[] files;
string checkFile; string checkFile;
FileInfo fileInfo; FileInfo fileInfo;
string directoryName; string? directoryName;
const string extension = ".trc"; const string extension = ".trc";
foreach (string directory in directories) { foreach (string directory in directories) {
files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
@ -38,6 +37,9 @@ internal static partial class Helper20250710 {
continue; continue;
} }
directoryName = Path.GetFileName(fileInfo.DirectoryName); directoryName = Path.GetFileName(fileInfo.DirectoryName);
if (string.IsNullOrEmpty(directoryName)) {
continue;
}
checkFile = Path.Combine(directoryName, $"{fileInfo.Name}{extension}"); checkFile = Path.Combine(directoryName, $"{fileInfo.Name}{extension}");
if (File.Exists(checkFile)) { if (File.Exists(checkFile)) {
continue; continue;
@ -84,8 +86,9 @@ internal static partial class Helper20250710 {
string result; string result;
List<string> results = []; List<string> results = [];
for (int j = i + 1; j < lines.Length; j++) { for (int j = i + 1; j < lines.Length; j++) {
if (lines[j].StartsWith(segments[0])) if (lines[j].StartsWith(segments[0])) {
break; break;
}
results.Add(lines[j].Trim()); results.Add(lines[j].Trim());
} }
result = string.Join('_', results); result = string.Join('_', results);

View File

@ -1,16 +1,83 @@
using Microsoft.Extensions.Logging;
using Phares.Metadata.Models.Stateless;
using Phares.Shared.Models;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;
using Phares.Metadata.Models.Stateless;
using Phares.Shared.Models;
namespace File_Folder_Helper.ADO2025.PI6; namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250720 { internal static partial class Helper20250720 {
private record Helper20250720Settings(ResultSettings? ResultSettings, MetadataSettings? MetadataSettings);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Helper20250720Settings))]
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);
}
}
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);
}
}
}
}
internal static void WriteFaceData(ILogger<Worker> logger, List<string> args) { internal static void WriteFaceData(ILogger<Worker> logger, List<string> args) {
logger.LogInformation(args[0]); logger.LogInformation(args[0]);
logger.LogInformation(args[1]); logger.LogInformation(args[1]);
@ -45,21 +112,17 @@ internal static partial class Helper20250720 {
logger.LogError("Face file doesn't exist! <{faceFileInfo}>", faceFileInfo.FullName); logger.LogError("Face file doesn't exist! <{faceFileInfo}>", faceFileInfo.FullName);
} else { } else {
string json = File.ReadAllText(jsonFile); string json = File.ReadAllText(jsonFile);
ResultSettings? resultSettings = JsonSerializer.Deserialize(json, ResultSettingsSourceGenerationContext.Default.ResultSettings); Helper20250720Settings? settings = JsonSerializer.Deserialize(json, Helper20250720SettingsSourceGenerationContext.Default.Helper20250720Settings);
MetadataSettings? metadataSettings = JsonSerializer.Deserialize(json, MetadataSettingsSourceGenerationContext.Default.MetadataSettings); if (settings?.ResultSettings is null || settings.ResultSettings.ResultAllInOneSubdirectoryLength < 1 || settings.MetadataSettings is null) {
if (resultSettings is null) { throw new Exception(nameof(Helper20250720Settings));
logger.LogError(nameof(ResultSettings)); }
} else if (metadataSettings is null) { WriteFaceData(logger, outputDirectoryName, originalFile, faceFileInfo, digiKamFile, settings.ResultSettings, settings.MetadataSettings);
logger.LogError(nameof(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 { } else {
WriteFaceData(logger, outputDirectoryName, originalFile, faceFileInfo, digiKamFile, resultSettings, metadataSettings); WriteFaceData(logger, outputDirectoryName, keyValuePairs, keyValuePairsXMP);
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);
}
} }
} }
} }
@ -82,24 +145,6 @@ internal static partial class Helper20250720 {
} }
} }
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) { private static void WriteFaceData(string outputDirectoryName, string? originalFile, ReadOnlyDictionary<string, FaceFile> keyValuePairs, string digiKamFile, List<string> trimmed, int rdfLine) {
if (keyValuePairs.Count == 0) { if (keyValuePairs.Count == 0) {
throw new Exception(); throw new Exception();
@ -116,6 +161,9 @@ internal static partial class Helper20250720 {
FaceFile faceFile; FaceFile faceFile;
string descriptionLine = "</rdf:Description>"; string descriptionLine = "</rdf:Description>";
faceFile = keyValuePairs.ElementAt(0).Value; faceFile = keyValuePairs.ElementAt(0).Value;
if (faceFile.Location is null || faceFile.OutputResolution is null) {
throw new Exception();
}
List<string> regionLines = [ List<string> regionLines = [
"<MP:RegionInfo rdf:parseType=\"Resource\">", "<MP:RegionInfo rdf:parseType=\"Resource\">",
"<MPRI:Regions>", "<MPRI:Regions>",
@ -138,6 +186,9 @@ internal static partial class Helper20250720 {
foreach (KeyValuePair<string, FaceFile> keyValuePair in keyValuePairs) { foreach (KeyValuePair<string, FaceFile> keyValuePair in keyValuePairs) {
personKey = keyValuePair.Key; personKey = keyValuePair.Key;
faceFile = keyValuePair.Value; faceFile = keyValuePair.Value;
if (faceFile.Location is null || faceFile.OutputResolution is null) {
throw new Exception();
}
width = faceFile.Location.Right - faceFile.Location.Left; width = faceFile.Location.Right - faceFile.Location.Left;
height = faceFile.Location.Bottom - faceFile.Location.Top; height = faceFile.Location.Bottom - faceFile.Location.Top;
if (!string.IsNullOrEmpty(originalFile) && File.Exists(originalFile)) { if (!string.IsNullOrEmpty(originalFile) && File.Exists(originalFile)) {
@ -150,8 +201,9 @@ internal static partial class Helper20250720 {
} }
w = width / faceFile.OutputResolution.Width; w = width / faceFile.OutputResolution.Width;
h = height / faceFile.OutputResolution.Height; h = height / faceFile.OutputResolution.Height;
if (w == 0 || h == 0) if (w == 0 || h == 0) {
throw new NotImplementedException(); throw new NotImplementedException();
}
mpLeft = (double)faceFile.Location.Left / faceFile.OutputResolution.Width; mpLeft = (double)faceFile.Location.Left / faceFile.OutputResolution.Width;
mpTop = (double)faceFile.Location.Top / faceFile.OutputResolution.Height; mpTop = (double)faceFile.Location.Top / faceFile.OutputResolution.Height;
mwgLeft = (faceFile.Location.Left + (width * .5)) / faceFile.OutputResolution.Width; mwgLeft = (faceFile.Location.Left + (width * .5)) / faceFile.OutputResolution.Width;
@ -233,8 +285,8 @@ internal static partial class Helper20250720 {
// </dc:subject> // </dc:subject>
subjectLines.Add($"<rdf:li>{personKey}</rdf:li>"); subjectLines.Add($"<rdf:li>{personKey}</rdf:li>");
} }
regionLines.AddRange(["</rdf:Bag>","</MPRI:Regions>","</MP:RegionInfo>"]); regionLines.AddRange(["</rdf:Bag>", "</MPRI:Regions>", "</MP:RegionInfo>"]);
regionsLinesB.AddRange(["</rdf:Bag>", "</mwg-rs:RegionList>","</mwg-rs:Regions>"]); regionsLinesB.AddRange(["</rdf:Bag>", "</mwg-rs:RegionList>", "</mwg-rs:Regions>"]);
digiKamLines.AddRange(["</rdf:Seq>", "</digiKam:TagsList>"]); digiKamLines.AddRange(["</rdf:Seq>", "</digiKam:TagsList>"]);
microsoftPhotoLines.AddRange(["</rdf:Bag>", "</MicrosoftPhoto:LastKeywordXMP>"]); microsoftPhotoLines.AddRange(["</rdf:Bag>", "</MicrosoftPhoto:LastKeywordXMP>"]);
hierarchicalSubjectLines.AddRange(["</rdf:Bag>", "</lr:hierarchicalSubject>"]); hierarchicalSubjectLines.AddRange(["</rdf:Bag>", "</lr:hierarchicalSubject>"]);
@ -292,7 +344,7 @@ internal static partial class Helper20250720 {
private static ReadOnlyDictionary<string, FaceFile> GetKeyValuePairs(ILogger<Worker> logger, ReadOnlyCollection<ExifDirectory> exifDirectories) { private static ReadOnlyDictionary<string, FaceFile> GetKeyValuePairs(ILogger<Worker> logger, ReadOnlyCollection<ExifDirectory> exifDirectories) {
Dictionary<string, FaceFile> results = []; Dictionary<string, FaceFile> results = [];
string personKey; string? personKey;
FaceFile? faceFile; FaceFile? faceFile;
foreach (ExifDirectory exifDirectory in exifDirectories) { foreach (ExifDirectory exifDirectory in exifDirectories) {
faceFile = IMetadata.GetFaceFile(exifDirectory); faceFile = IMetadata.GetFaceFile(exifDirectory);
@ -304,6 +356,9 @@ internal static partial class Helper20250720 {
logger.LogWarning("faceFile output-resolution orientation is not aloud!"); logger.LogWarning("faceFile output-resolution orientation is not aloud!");
} else { } else {
personKey = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(exifDirectory.FilePath.FullName)))); personKey = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(exifDirectory.FilePath.FullName))));
if (string.IsNullOrEmpty(personKey)) {
continue;
}
if (results.ContainsKey(personKey)) { if (results.ContainsKey(personKey)) {
continue; continue;
} }
@ -329,12 +384,14 @@ internal static partial class Helper20250720 {
continue; continue;
} }
exifDirectory = IMetadata.GetExifDirectory(resultSettings, metadataSettings, faceFileInfo); exifDirectory = IMetadata.GetExifDirectory(resultSettings, metadataSettings, faceFileInfo);
if (exifDirectory is null) if (exifDirectory is null) {
continue; continue;
}
if (!keyValuePairs.TryGetValue(fileNameFirstSegment, out collection)) { if (!keyValuePairs.TryGetValue(fileNameFirstSegment, out collection)) {
keyValuePairs.Add(fileNameFirstSegment, []); keyValuePairs.Add(fileNameFirstSegment, []);
if (!keyValuePairs.TryGetValue(fileNameFirstSegment, out collection)) if (!keyValuePairs.TryGetValue(fileNameFirstSegment, out collection)) {
throw new Exception(); throw new Exception();
}
} }
collection.Add(exifDirectory); collection.Add(exifDirectory);
} }
@ -356,58 +413,15 @@ internal static partial class Helper20250720 {
} }
} }
private static void WriteFaceData(ILogger<Worker> logger, string outputDirectoryName, string? originalFile, long? fileNameFirstSegment, ReadOnlyCollection<string> digiKamFiles, ReadOnlyDictionary<string, FaceFile> keyValuePairs) { private static int? GetMatchingLine(string digiKamLine, ReadOnlyCollection<string> lines) {
#if xmp int? result = null;
IXmpMeta xmp; for (int i = 0; i < lines.Count; i++) {
using FileStream stream = File.OpenRead(digiKamFile); if (lines[i] == digiKamLine) {
xmp = XmpMetaFactory.Parse(stream); result = i;
foreach (var property in xmp.Properties) { break;
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);
}
} }
} }
return result;
} }
private static void Extract(string file, double width, double height, int left, int top, string suffix) { private static void Extract(string file, double width, double height, int left, int top, string suffix) {

View File

@ -0,0 +1,123 @@
using Microsoft.Extensions.Logging;
using Phares.Shared.Models;
using Phares.Shared.Models.Stateless;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2025.PI6;
internal static partial class Helper20250726 {
private record Helper20250726Settings(ResultSettings? ResultSettings, MetadataSettings? MetadataSettings);
private record Record(CombinedEnumAndIndex CombinedEnumAndIndex, FilePath FilePath, bool HasFlagHidden);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Helper20250726Settings))]
private partial class Helper20250726SettingsSourceGenerationContext : JsonSerializerContext {
}
internal static void CopyToCombinedEnumAndIndexFormat(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]);
string[] files;
string[] searchPatterns = args[4].Split('~');
string jsonFile = Path.GetFullPath(args[3]);
if (!File.Exists(jsonFile)) {
throw new Exception($"json file doesn't exist! <{jsonFile}>");
}
ReadOnlyCollection<Record> records;
string json = File.ReadAllText(jsonFile);
string destinationDirectoryName = args[6];
ReadOnlyDictionary<byte, ReadOnlyCollection<string>> keyValues;
string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]);
string destinationDirectory = Path.GetFullPath(args[5].Split('~')[0]);
long maxSize = long.Parse(args[2], System.Globalization.NumberStyles.Float);
ReadOnlyDictionary<int, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePairs;
Helper20250726Settings? settings = JsonSerializer.Deserialize(json, Helper20250726SettingsSourceGenerationContext.Default.Helper20250726Settings);
if (settings?.ResultSettings is null || settings.ResultSettings.ResultAllInOneSubdirectoryLength < 1 || settings.MetadataSettings is null) {
throw new Exception(nameof(Helper20250726Settings));
}
foreach (string searchPattern in searchPatterns) {
files = Directory.GetFiles(sourceDirectory, $"*{searchPattern}", SearchOption.AllDirectories);
if (files.Length == 0) {
logger.LogInformation($"Didn't find any {searchPattern} files");
continue;
}
logger.LogInformation($"Found {files.Length} {searchPattern} files");
keyValuePairs = GetKeyValuePairs(settings.ResultSettings, destinationDirectory, destinationDirectoryName);
records = GetRecords(logger, settings.ResultSettings, settings.MetadataSettings, files);
keyValues = keyValuePairs.ElementAt(0).Value;
CopyToCombinedEnumAndIndexFormat(logger, maxSize, records, keyValues);
}
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, destinationDirectory);
}
private static ReadOnlyDictionary<int, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> GetKeyValuePairs(ResultSettings resultSettings, string destinationDirectory, string destinationDirectoryName) {
Dictionary<int, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> results = [];
ReadOnlyDictionary<int, ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>>> keyValuePairs = IPath.GetKeyValuePairs(resultSettings, destinationDirectory, [destinationDirectoryName]);
foreach (KeyValuePair<int, ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>>> keyValuePair in keyValuePairs) {
foreach (KeyValuePair<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValue in keyValuePair.Value) {
if (keyValue.Key != destinationDirectoryName) {
throw new Exception("Never should happen!");
}
results.Add(keyValuePair.Key, keyValue.Value);
}
}
return results.AsReadOnly();
}
private static ReadOnlyCollection<Record> GetRecords(ILogger<Worker> logger, ResultSettings resultSettings, MetadataSettings metadataSettings, string[] files) {
List<Record> results = [];
Record record;
FileInfo fileInfo;
FilePath filePath;
bool hasFlagHidden;
FileHolder fileHolder;
CombinedEnumAndIndex combinedEnumAndIndex;
foreach (string file in files) {
fileInfo = new(file);
fileHolder = FileHolder.Get(fileInfo, id: null);
filePath = FilePath.Get(resultSettings, metadataSettings, fileHolder, index: null);
if (!filePath.IsIntelligentIdFormat) {
logger.LogWarning("<{file}> skipped because of name format!", filePath.Name);
continue;
}
hasFlagHidden = fileInfo.Attributes.HasFlag(FileAttributes.Hidden);
combinedEnumAndIndex = IPath.GetCombinedEnumAndIndex(resultSettings, filePath);
record = new(CombinedEnumAndIndex: combinedEnumAndIndex, FilePath: filePath, HasFlagHidden: hasFlagHidden);
results.Add(record);
}
return results.AsReadOnly();
}
private static void CopyToCombinedEnumAndIndexFormat(ILogger<Worker> logger, long maxSize, ReadOnlyCollection<Record> records, ReadOnlyDictionary<byte, ReadOnlyCollection<string>> keyValuePairs) {
string checkFile;
FileInfo fileInfo;
FileAttributes fileAttributes;
foreach (Record record in records) {
if (record.FilePath.Length > maxSize) {
logger.LogWarning("<{file}> skipped because it is over {size}!", record.FilePath.Name, maxSize);
continue;
}
checkFile = Path.Combine(keyValuePairs[record.CombinedEnumAndIndex.Enum][record.CombinedEnumAndIndex.Index], record.FilePath.Name);
if (File.Exists(checkFile)) {
logger.LogWarning("<{file}> skipped because it already exists!", record.FilePath.Name);
continue;
}
File.Copy(record.FilePath.FullName, checkFile);
if (record.HasFlagHidden) {
fileInfo = new(checkFile);
fileAttributes = fileInfo.Attributes & ~FileAttributes.Hidden;
File.SetAttributes(fileInfo.FullName, fileAttributes);
}
}
}
}

View File

@ -183,6 +183,8 @@ internal static class HelperDay
ADO2025.PI6.Helper20250710.StripLog(logger, args); ADO2025.PI6.Helper20250710.StripLog(logger, args);
else if (args[1] == "Day-Helper-2025-07-20") else if (args[1] == "Day-Helper-2025-07-20")
ADO2025.PI6.Helper20250720.WriteFaceData(logger, args); ADO2025.PI6.Helper20250720.WriteFaceData(logger, args);
else if (args[1] == "Day-Helper-2025-07-26")
ADO2025.PI6.Helper20250726.CopyToCombinedEnumAndIndexFormat(logger, args);
else else
throw new Exception(appSettings.Company); throw new Exception(appSettings.Company);
} }

View File

@ -25,7 +25,6 @@ internal static class Helper20231010
dateTime = new(ticks); dateTime = new(ticks);
logger.LogInformation("{directory.Name} at {LastWriteTime} took {TotalMinutes} minutes(s)", directoryInfo.Name.PadRight(padLength, ' '), directoryInfo.LastWriteTime, Math.Round(timeSpan.TotalMinutes, 3)); logger.LogInformation("{directory.Name} at {LastWriteTime} took {TotalMinutes} minutes(s)", directoryInfo.Name.PadRight(padLength, ' '), directoryInfo.LastWriteTime, Math.Round(timeSpan.TotalMinutes, 3));
} }
} }
} }

View File

@ -16,8 +16,8 @@
<PackageReference Include="DiscUtils.Iso9660" Version="0.16.13" /> <PackageReference Include="DiscUtils.Iso9660" Version="0.16.13" />
<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="Phares.Metadata" Version="8.0.118.14751" /> <PackageReference Include="Phares.Metadata" Version="8.0.118.14905" />
<PackageReference Include="Phares.Shared" Version="8.0.118.14751" /> <PackageReference Include="Phares.Shared" Version="8.0.118.14905" />
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.18" /> <PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.18" />
<PackageReference Include="System.Text.Json" Version="9.0.7" /> <PackageReference Include="System.Text.Json" Version="9.0.7" />
<PackageReference Include="TextCopy" Version="6.2.1" /> <PackageReference Include="TextCopy" Version="6.2.1" />

View File

@ -1,8 +1,8 @@
using File_Folder_Helper.Models; using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Text.Json;
using Phares.Metadata.Models.Stateless; using Phares.Metadata.Models.Stateless;
using Phares.Shared.Models; using Phares.Shared.Models;
using System.Text.Json;
namespace File_Folder_Helper.Helpers; namespace File_Folder_Helper.Helpers;