From 116d5e9734c13dae3fa1b1d986b1cf13efe5e098 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Wed, 18 Jun 2025 17:33:29 -0700 Subject: [PATCH] move-all-but-x-of-each (Day-Helper-2025-06-18) --- .vscode/launch.json | 8 +++ ADO2025/PI6/Helper-2025-06-18.cs | 89 ++++++++++++++++++++++++++++++++ Day/HelperDay.cs | 2 + File-Folder-Helper.csproj | 2 +- 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 ADO2025/PI6/Helper-2025-06-18.cs diff --git a/.vscode/launch.json b/.vscode/launch.json index fa2420b..1959b02 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,6 +11,14 @@ "preLaunchTask": "build", "program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/File-Folder-Helper.dll", "args": [ + "s", + "X", + "D:/5-Other-Small/Proxmox/DiskInfo", + "Day-Helper-2025-06-18", + "*.json", + "D:/5-Other-Small/Proxmox/Disk-Info-Old", + "-2025-", + "1", "s", "X", "D:/Tmp", diff --git a/ADO2025/PI6/Helper-2025-06-18.cs b/ADO2025/PI6/Helper-2025-06-18.cs new file mode 100644 index 0000000..5a999eb --- /dev/null +++ b/ADO2025/PI6/Helper-2025-06-18.cs @@ -0,0 +1,89 @@ + +using System.Collections.ObjectModel; + +using Microsoft.Extensions.Logging; + +namespace File_Folder_Helper.ADO2025.PI6; + +internal static partial class Helper20250618 { + + private record Record(string Directory, List Files); + + internal static void MoveAllButXOfEach(ILogger logger, List args) { + int keep = int.Parse(args[5]); + logger.LogInformation(args[0]); + logger.LogInformation(args[1]); + logger.LogInformation(args[2]); + string searchPattern = args[2]; + string split = args[4].Split('~')[0]; + string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]); + string destinationDirectory = Path.GetFullPath(args[3].Split('~')[0]); + if (destinationDirectory.Contains(sourceDirectory)) { + throw new Exception("Not allowed!"); + } + ReadOnlyCollection directories = GetDirectories(sourceDirectory); + MoveAllButXOfEachB(logger, searchPattern, sourceDirectory, destinationDirectory, split, keep, directories); + } + + private static ReadOnlyCollection GetDirectories(string sourceDirectory) { + List results = [sourceDirectory]; + results.AddRange(Directory.GetDirectories(sourceDirectory, "*", SearchOption.AllDirectories)); + return results.AsReadOnly(); + } + + private static void MoveAllButXOfEachB(ILogger logger, string searchPattern, string sourceDirectory, string destinationDirectory, string split, int keep, ReadOnlyCollection directories) { + string[] files; + int sourceDirectoryLength = sourceDirectory.Length; + ReadOnlyDictionary> keyValuePairs; + foreach (string directory in directories) { + files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); + keyValuePairs = GetFiles(split, files); + foreach (KeyValuePair> keyValuePair in keyValuePairs) { + if (keyValuePair.Value.Count <= keep) { + continue; + } else { + MoveAllButXOfEachC(logger, sourceDirectoryLength, destinationDirectory, keyValuePair); + } + } + } + } + + private static ReadOnlyDictionary> GetFiles(string split, string[] files) { + Dictionary> results = []; + string key; + List? collection; + Dictionary> keyValuePairs = []; + foreach (string file in files) { + key = Path.GetFileName(file).Split(split)[0]; + if (!keyValuePairs.TryGetValue(key, out collection)) { + keyValuePairs.Add(key, []); + if (!keyValuePairs.TryGetValue(key, out collection)) { + throw new Exception(); + } + } + collection.Add(file); + } + foreach (KeyValuePair> keyValuePair in keyValuePairs) { + results.Add(keyValuePair.Key, keyValuePair.Value.OrderByDescending(l => l).ToArray().AsReadOnly()); + } + return results.AsReadOnly(); + } + + private static void MoveAllButXOfEachC(ILogger logger, int sourceDirectoryLength, string destinationDirectory, KeyValuePair> keyValuePair) { + string file; + string checkFile; + string checkDirectory; + for (int i = 1; i < keyValuePair.Value.Count; i++) { + file = keyValuePair.Value[i]; + checkFile = $"{destinationDirectory}{file[sourceDirectoryLength..]}"; + checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new Exception(); + if (!Directory.Exists(checkDirectory)) + _ = Directory.CreateDirectory(checkDirectory); + if (File.Exists(checkFile)) + continue; + File.Move(file, checkFile); + logger.LogInformation("<{file}> moved", file); + } + } + +} \ No newline at end of file diff --git a/Day/HelperDay.cs b/Day/HelperDay.cs index b8130ab..5a1bfd0 100644 --- a/Day/HelperDay.cs +++ b/Day/HelperDay.cs @@ -169,6 +169,8 @@ internal static class HelperDay ADO2025.PI6.Helper20250601.EquipmentAutomationFrameworkStatus(logger, args); else if (args[1] == "Day-Helper-2025-06-02") ADO2025.PI6.Helper20250602.EquipmentAutomationFrameworkCellInstanceStateImageVerbIf(logger, args); + else if (args[1] == "Day-Helper-2025-06-18") + ADO2025.PI6.Helper20250618.MoveAllButXOfEach(logger, args); else throw new Exception(appSettings.Company); } diff --git a/File-Folder-Helper.csproj b/File-Folder-Helper.csproj index d58c688..ee3aab8 100644 --- a/File-Folder-Helper.csproj +++ b/File-Folder-Helper.csproj @@ -17,7 +17,7 @@ - +