diff --git a/.vscode/launch.json b/.vscode/launch.json index 3c2e4aa..bb200f7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,6 +11,13 @@ "preLaunchTask": "build", "program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/File-Folder-Helper.dll", "args": [ + "s", + "X", + "V:/7-Question/Event 2024 Directories-xmp", + "Day-Helper-2025-07-26", + "L:/Git/AA/Rename/.vscode/.UserSecrets/secrets.json", + "*.xmp", + "V:/7-Question/Event 2024 Directories-xmp-moved", "s", "X", "V:/1-Images-A/Images-0b793904", diff --git a/ADO2025/PI6/Helper-2025-07-26.cs b/ADO2025/PI6/Helper-2025-07-26.cs new file mode 100644 index 0000000..8b5fd19 --- /dev/null +++ b/ADO2025/PI6/Helper-2025-07-26.cs @@ -0,0 +1,106 @@ + +using System.Collections.ObjectModel; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Microsoft.Extensions.Logging; + +using Phares.Shared.Models; +using Phares.Shared.Models.Stateless; + +namespace File_Folder_Helper.ADO2025.PI6; + +internal static partial class Helper20250726 { + + private record Settings(ResultSettings? ResultSettings, MetadataSettings? MetadataSettings); + + private record Record(CombinedEnumAndIndex CombinedEnumAndIndex, FilePath FilePath, bool HasFlagHidden); + + [JsonSourceGenerationOptions(WriteIndented = true)] + [JsonSerializable(typeof(Settings))] + private partial class SettingsSourceGenerationContext : JsonSerializerContext { + } + + internal static void CopyToCombinedEnumAndIndexFormat(ILogger logger, List args) { + logger.LogInformation(args[0]); + logger.LogInformation(args[1]); + logger.LogInformation(args[2]); + logger.LogInformation(args[3]); + logger.LogInformation(args[4]); + string searchPattern = args[3]; + string jsonFile = Path.GetFullPath(args[2]); + if (!File.Exists(jsonFile)) { + throw new Exception($"json file doesn't exist! <{jsonFile}>"); + } + string json = File.ReadAllText(jsonFile); + string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]); + string destinationDirectory = Path.GetFullPath(args[4].Split('~')[0]); + Settings? settings = JsonSerializer.Deserialize(json, SettingsSourceGenerationContext.Default.Settings); + if (settings.ResultSettings is null || settings.ResultSettings.ResultAllInOneSubdirectoryLength < 1 || settings.MetadataSettings is null) { + throw new Exception(nameof(Settings)); + } + string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); + ReadOnlyDictionary>> keyValuePairs = GetKeyValuePairs(destinationDirectory, settings.ResultSettings); + ReadOnlyCollection records = GetRecords(logger, settings.ResultSettings, settings.MetadataSettings, files); + ReadOnlyDictionary> keyValues = keyValuePairs.ElementAt(0).Value; + CopyToCombinedEnumAndIndexFormat(logger, records, keyValues); + Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, destinationDirectory); + } + + private static ReadOnlyDictionary>> GetKeyValuePairs(string destinationDirectory, ResultSettings resultSettings) { + Dictionary>> results = []; + ReadOnlyDictionary>>> keyValuePairs = IPath.GetKeyValuePairs(resultSettings, destinationDirectory, [resultSettings.ResultSingleton]); + foreach (KeyValuePair>>> keyValuePair in keyValuePairs) { + foreach (KeyValuePair>> keyValue in keyValuePair.Value) { + if (keyValue.Key != resultSettings.ResultSingleton) + throw new Exception("Never should happen!"); + results.Add(keyValuePair.Key, keyValue.Value); + } + } + return results.AsReadOnly(); + } + + private static ReadOnlyCollection GetRecords(ILogger logger, ResultSettings resultSettings, MetadataSettings metadataSettings, string[] files) { + List 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 logger, ReadOnlyCollection records, ReadOnlyDictionary> keyValuePairs) { + string checkFile; + FileInfo fileInfo; + FileAttributes fileAttributes; + foreach (Record record in records) { + 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); + } + } + } + +} \ No newline at end of file diff --git a/Day/HelperDay.cs b/Day/HelperDay.cs index 12aa7db..622743f 100644 --- a/Day/HelperDay.cs +++ b/Day/HelperDay.cs @@ -183,6 +183,8 @@ internal static class HelperDay ADO2025.PI6.Helper20250710.StripLog(logger, args); else if (args[1] == "Day-Helper-2025-07-20") ADO2025.PI6.Helper20250720.WriteFaceData(logger, args); + else if (args[1] == "Day-Helper-2025-07-26") + ADO2025.PI6.Helper20250726.CopyToCombinedEnumAndIndexFormat(logger, args); else throw new Exception(appSettings.Company); } diff --git a/File-Folder-Helper.csproj b/File-Folder-Helper.csproj index f69b7d2..9080f78 100644 --- a/File-Folder-Helper.csproj +++ b/File-Folder-Helper.csproj @@ -16,8 +16,8 @@ - - + +