From 02445261fe0e9a2efca3912f8bc98613f0c246bf Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Mon, 31 Jul 2023 09:54:55 -0700 Subject: [PATCH] Genealogical Data Communication but I still am dependant on directory --- .../HelperGenealogicalDataCommunication.cs | 634 ++++++++++++++++++ Models/AppSettings.cs | 2 + Models/Binder/AppSettings.cs | 8 + Worker.cs | 5 + 4 files changed, 649 insertions(+) create mode 100644 Helpers/HelperGenealogicalDataCommunication.cs diff --git a/Helpers/HelperGenealogicalDataCommunication.cs b/Helpers/HelperGenealogicalDataCommunication.cs new file mode 100644 index 0000000..1292c97 --- /dev/null +++ b/Helpers/HelperGenealogicalDataCommunication.cs @@ -0,0 +1,634 @@ +using File_Folder_Helper.Models; +using Microsoft.Extensions.Logging; +using System.Collections.ObjectModel; +using System.Globalization; + +namespace File_Folder_Helper.Helpers; + +internal static partial class HelperGenealogicalDataCommunication +{ + + private record Input(string People, + string? GenealogicalDataCommunicationFile, + string? GenealogicalDataCommunicationDirectory, + string? Destination); + + private record GenealogicalDataCommunicationCollections(string[] HeaderLines, + ReadOnlyDictionary IndividualsLines, + List FamilyGroupLines, + ReadOnlyDictionary PersonKeyToId, + string[] FooterLines); + + private record PersonHour(char Status, + char Sex, + char First); + + private record PersonName(string? First, + string? Middle, + string? Last, + string? Alias); + + private record PersonDirectory(string[] DirectoryNames, + DateTime? Birthday, + int? ApproximateYears, + PersonHour? PersonHour, + PersonName? PersonName, + string[]? BirthdayNotes, + string[]? Notes); + + private static Input GetInput(List args) + { + Input result; + string? destination = null; + string? genealogicalDataCommunicationFile = null; + string? genealogicalDataCommunicationDirectory = null; + for (int i = 1; i < args.Count; i++) + { + if (args[i].Length == 2 && i + 1 < args.Count) + { + if (args[i][1] == 'g') + genealogicalDataCommunicationFile = Path.GetFullPath(args[i + 1]); + else if (args[i][1] == 'd') + destination = Path.GetFullPath(args[i + 1]); + i++; + } + } + if (genealogicalDataCommunicationFile is not null) + { + string? root = Path.GetPathRoot(genealogicalDataCommunicationFile); + if (root is null || !Directory.Exists(root)) + throw new NotSupportedException($"This method requires valid -g path <{root}>!"); + if (!File.Exists(genealogicalDataCommunicationFile)) + throw new NotSupportedException($"This method requires valid -g path <{root}>!"); + string? directoryName = Path.GetDirectoryName(genealogicalDataCommunicationFile) ?? + throw new NotSupportedException($"This method requires valid -g path <{root}>!"); + genealogicalDataCommunicationDirectory = Path.Combine(directoryName, Path.GetFileNameWithoutExtension(genealogicalDataCommunicationFile)); + if (!Directory.Exists(genealogicalDataCommunicationDirectory)) + _ = Directory.CreateDirectory(genealogicalDataCommunicationDirectory); + } + if (destination is not null) + { + string? root = Path.GetPathRoot(destination); + if (root is null || !Directory.Exists(root)) + throw new NotSupportedException($"This method requires frontMatterYamlLines valid -d path <{root}>!"); + if (!Directory.Exists(destination)) + _ = Directory.CreateDirectory(destination); + } + result = new(Path.GetFullPath(args.First()), genealogicalDataCommunicationFile, genealogicalDataCommunicationDirectory, destination); + return result; + } + + private static string[] GetHeaderLines(string startsWith, string[] sourceLines) + { + List results = new(); + for (int i = 0; i < sourceLines.Length; i++) + { + if (sourceLines[i].StartsWith(startsWith)) + break; + results.Add(sourceLines[i]); + } + return results.ToArray(); + } + + private static ReadOnlyDictionary Convert(Dictionary> keyValuePairs) + { + Dictionary results = new(); + foreach (KeyValuePair> keyValuePair in keyValuePairs) + results.Add(keyValuePair.Key, keyValuePair.Value.ToArray()); + return new(results); + } + + private static GenealogicalDataCommunicationCollections GetGenealogicalDataCommunicationCollections(AppSettings appSettings, Input input) + { + GenealogicalDataCommunicationCollections result; + long? personKey; + string[] segments; + string personKeyFormatted; + List lines = new(); + const string startsWith = "0 @"; + List footerLines = new(); + List familyGroupLines = new(); + Dictionary personKeyToId = new(); + ReadOnlyDictionary individualsLines; + Dictionary> keyValuePairs = new(); + int length = appSettings.PersonBirthdayFormat.Length; + string[] sourceLines = string.IsNullOrEmpty(input.GenealogicalDataCommunicationFile) || !File.Exists(input.GenealogicalDataCommunicationFile) ? Array.Empty() : File.ReadAllLines(input.GenealogicalDataCommunicationFile); + string[] headerLines = GetHeaderLines(startsWith, sourceLines); + for (int i = headerLines.Length; i < sourceLines.Length; i++) + { + if (!sourceLines[i].StartsWith(startsWith)) + continue; + lines.Add(sourceLines[i]); + if (sourceLines[i].EndsWith("@ SOUR") || sourceLines[i].EndsWith("@ SUBM") || sourceLines[i].EndsWith("@ OBJE") || sourceLines[i].EndsWith("@ REPO")) + continue; + else if (sourceLines[i].EndsWith("@ FAM")) + { + lines.Clear(); + for (int j = sourceLines.Length - 1; j >= i; j--) + { + lines.Add(sourceLines[j]); + if (sourceLines[j].First() == '0') + { + if (!sourceLines[j].EndsWith("@ FAM")) + footerLines.AddRange(lines); + else + { + lines.Reverse(); + familyGroupLines.Add(lines.ToArray()); + } + lines.Clear(); + } + } + familyGroupLines.Reverse(); + footerLines.Reverse(); + break; + } + else if (sourceLines[i].EndsWith("@ INDI")) + { + personKey = null; + segments = sourceLines[i].Split('@'); + for (int j = i + 1; j < sourceLines.Length; j++) + { + if (sourceLines[j].StartsWith(startsWith)) + break; + lines.Add(sourceLines[j]); + if (sourceLines[j].StartsWith("2 NICK ")) + personKeyFormatted = sourceLines[j][7..]; + else if (sourceLines[j] == "1 BIRT" && sourceLines[j + 1].StartsWith("2 DATE") && sourceLines[j + 2].StartsWith("2 NOTE ")) + personKeyFormatted = sourceLines[j + 2][7..]; + else + continue; + if (segments.Length != 3 || personKeyFormatted.Length != length) + continue; + if (!DateTime.TryParseExact(personKeyFormatted, appSettings.PersonBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime)) + continue; + personKey = dateTime.Ticks; + if (segments[1].Length < 2 || !int.TryParse(segments[1][1..], out int id)) + continue; + personKeyToId.Add(personKey.Value, id); + } + if (personKey is null) + throw new Exception(string.Join(Environment.NewLine, lines)); + keyValuePairs.Add(personKey.Value, new()); + if (!lines.Any()) + continue; + keyValuePairs[personKey.Value].AddRange(lines); + lines.Clear(); + } + else + throw new NotSupportedException(); + } + individualsLines = Convert(keyValuePairs); + result = new(headerLines, individualsLines, familyGroupLines, new(personKeyToId), footerLines.ToArray()); + return result; + } + + private static List GetDirectoryNames(string directory) + { + List results = new(); + string? fileName; + string? checkDirectory = directory; + string? pathRoot = Path.GetPathRoot(directory); + string extension = Path.GetExtension(directory); + if (string.IsNullOrEmpty(pathRoot)) + throw new NullReferenceException(nameof(pathRoot)); + if (Directory.Exists(directory)) + { + fileName = Path.GetFileName(directory); + if (!string.IsNullOrEmpty(fileName)) + results.Add(fileName); + } + else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory)) + { + fileName = Path.GetFileName(directory); + if (!string.IsNullOrEmpty(fileName)) + results.Add(fileName); + } + for (int i = 0; i < int.MaxValue; i++) + { + checkDirectory = Path.GetDirectoryName(checkDirectory); + if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot) + break; + fileName = Path.GetFileName(checkDirectory); + if (string.IsNullOrEmpty(fileName)) + continue; + results.Add(fileName); + } + results.Add(pathRoot); + results.Reverse(); + return results; + } + + private static List GetPersonDirectoriesNull(AppSettings appSettings, Input input) + { + List results = new(); + DateTime? birthday; + string directoryName; + string subDirectoryName; + List directoryNames; + IEnumerable subDirectories; + int length = appSettings.PersonBirthdayFormat.Length; + string[] directories = Directory.GetDirectories(input.People, "*", SearchOption.TopDirectoryOnly); + foreach (string directory in directories) + { + directoryName = Path.GetFileName(directory); + if (directoryName.Length != 1 || !appSettings.PersonCharacters.Any(l => directoryName.First() == l)) + continue; + subDirectories = Directory.GetDirectories(directory, "*", SearchOption.AllDirectories); + foreach (string subDirectory in subDirectories) + { + subDirectoryName = Path.GetFileName(subDirectory); + if (subDirectoryName.Length != length) + continue; + if (subDirectoryName.First() is not '1' and not '2') + continue; + directoryNames = GetDirectoryNames(subDirectory); + birthday = !DateTime.TryParseExact(subDirectoryName, appSettings.PersonBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime) ? null : dateTime; + results.Add(new(directoryNames.ToArray(), birthday, null, null, null, null, null)); + } + } + return results; + } + + private static PersonName GetPersonName(string name) + { + PersonName result; + string? personNameLast; + string? personNameAlias; + string? personNameFirst; + string? personNameMiddle; + string[] segmentsA = name.Split('('); + string[] segmentsB = segmentsA.First().Trim().Split(' '); + if (segmentsB.Length == 1) + { + personNameFirst = null; + personNameLast = null; + personNameMiddle = null; + personNameAlias = segmentsA.Length == 1 ? segmentsB.First() : segmentsA.Last().Split(')').First(); + } + else + { + if (segmentsB.Length == 2) + { + personNameFirst = segmentsB.First(); + personNameLast = segmentsB.Last(); + personNameMiddle = null; + } + else if (segmentsB.Length == 3) + { + personNameFirst = segmentsB.First(); + personNameLast = segmentsB.Last(); + personNameMiddle = segmentsB[1]; + } + else + { + personNameFirst = segmentsB.First(); + personNameLast = string.Join(' ', segmentsB, 1, segmentsB.Length - 1); + personNameMiddle = null; + } + personNameAlias = segmentsA.Length == 1 ? null : segmentsA.Last().Split(')').First(); + } + result = new(personNameFirst, personNameMiddle, personNameLast, personNameAlias); + return result; + } + + private static PersonHour GetPersonHour(string personDisplayDirectoryName, int hour) => + hour == 0 ? new('U', 'U', 'U') : + hour == 1 ? new('U', 'U', 'U') : + hour == 2 ? new('U', 'U', 'U') : + hour == 3 ? new('A', 'U', 'Y') : + hour == 4 ? new('A', 'F', 'Y') : + hour == 5 ? new('A', 'M', 'Y') : + hour == 6 ? new('A', 'F', 'N') : + hour == 7 ? new('A', 'M', 'N') : + hour == 13 ? new('D', 'U', 'Y') : + hour == 14 ? new('D', 'F', 'Y') : + hour == 15 ? new('D', 'M', 'Y') : + hour == 16 ? new('D', 'F', 'N') : + hour == 17 ? new('D', 'M', 'N') : + throw new NotImplementedException(personDisplayDirectoryName); + + private static string GetHourGroup(string personDisplayDirectoryName, int hour) => + hour == 0 ? "Unknown-Unknown-Unknown" : + hour == 1 ? "Unknown-Unknown-Unknown" : + hour == 2 ? "Unknown-Unknown-Unknown" : + hour == 3 ? "Alive-Unknown-Yes" : + hour == 4 ? "Alive-Female-Yes" : + hour == 5 ? "Alive-Male-Yes" : + hour == 6 ? "Alive-Female-No" : + hour == 7 ? "Alive-Male-No" : + hour == 13 ? "Dead-Unknown-Yes" : + hour == 14 ? "Dead-Female-Yes" : + hour == 15 ? "Dead-Male-Yes" : + hour == 16 ? "Dead-Female-No" : + hour == 17 ? "Dead-Male-No" : + throw new NotImplementedException(personDisplayDirectoryName); + + private static List GetNotes(PersonDirectory personDirectory) + { + List results = new(); + string directory = string.Join(Path.DirectorySeparatorChar, personDirectory.DirectoryNames); + if (Directory.Exists(directory)) + { + string[] lines; + string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories); + foreach (string file in files) + { + if (file.EndsWith(".lnk") || file.EndsWith(".rel") || file.EndsWith(".pged") || file.EndsWith(".gif") || file.EndsWith(".jpg") || file.EndsWith(".png")) + continue; + lines = File.ReadAllLines(file); + if (lines.Length > 0 && lines.First().StartsWith("0 @I")) + continue; + if (!lines.Any(l => l.StartsWith("http"))) + continue; + results.AddRange(lines.Where(l => !string.IsNullOrEmpty(l))); + } + } + return results; + } + + private static string GetApproximateYears(AppSettings appSettings, string personDisplayDirectoryName) => + $"{appSettings.PersonCharacters.Where(l => personDisplayDirectoryName.Contains(l)).FirstOrDefault()}{personDisplayDirectoryName.Split(appSettings.PersonCharacters).Last()}"; + + private static List GetPersonDirectories(AppSettings appSettings, ReadOnlyDictionary> keyValuePairs) + { + List results = new(); + PersonDirectory[] sorted; + List notes = new(); + PersonDirectory personDirectory; + List birthdayNotes = new(); + foreach (KeyValuePair> keyValuePair in keyValuePairs) + { + if (keyValuePair.Value.Count == 0) + throw new NotSupportedException(); + sorted = (from l in keyValuePair.Value orderby l.Birthday is null, l.Birthday descending select l).ToArray(); + personDirectory = sorted.First(); + if (personDirectory.Birthday is null) + continue; + for (int i = 0; i < sorted.Length; i++) + { + notes.AddRange(GetNotes(sorted[i])); + if (i == 0) + birthdayNotes.Add(GetApproximateYears(appSettings, sorted[i].DirectoryNames[^2])); + if (i > 0) + birthdayNotes.Add(sorted[i].DirectoryNames.Last()); + if (i == sorted.Length - 1) + { + results.Add(new(personDirectory.DirectoryNames, personDirectory.Birthday, personDirectory.ApproximateYears, personDirectory.PersonHour, personDirectory.PersonName, birthdayNotes.ToArray(), notes.ToArray())); + notes.Clear(); + birthdayNotes.Clear(); + } + } + } + return results; + } + + private static ReadOnlyDictionary> Convert(List collection) + { + Dictionary> results = new(); + string personDisplayDirectoryName; + List? personDirectories; + foreach (PersonDirectory personDirectory in collection) + { + personDisplayDirectoryName = personDirectory.DirectoryNames[^2]; + if (!results.TryGetValue(personDisplayDirectoryName, out personDirectories)) + { + results.Add(personDisplayDirectoryName, new()); + if (!results.TryGetValue(personDisplayDirectoryName, out personDirectories)) + throw new NotSupportedException(); + } + personDirectories.Add(personDirectory); + } + return new(results); + } + + private static ReadOnlyCollection GetPersonDirectories(AppSettings appSettings, Input input) + { + List results; + string[] segments; + PersonName personName; + PersonHour? personHour; + string personDisplayDirectoryName; + List collection = new(); + List personDirectories = GetPersonDirectoriesNull(appSettings, input); + foreach (PersonDirectory personDirectory in personDirectories) + { + if (personDirectory.DirectoryNames.Length < 3) + continue; + personDisplayDirectoryName = personDirectory.DirectoryNames[^2]; + segments = personDisplayDirectoryName.Split(appSettings.PersonCharacters); + if (segments.Length == 1 || !int.TryParse(segments.Last().Split('-').First(), out int years)) + continue; + personName = GetPersonName(segments.First()); + personHour = personDirectory.Birthday is null ? null : GetPersonHour(personDisplayDirectoryName, personDirectory.Birthday.Value.Hour); + collection.Add(new(personDirectory.DirectoryNames, personDirectory.Birthday, years, personHour, personName, null, null)); + } + ReadOnlyDictionary> keyValuePairs = Convert(collection); + results = GetPersonDirectories(appSettings, keyValuePairs); + return new(results); + } + + private static Dictionary GetCopyOfPersonKeyToId(GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections) + { + Dictionary results = new(); + foreach (KeyValuePair keyValuePair in genealogicalDataCommunicationCollections.PersonKeyToId) + results.Add(keyValuePair.Key, keyValuePair.Value); + return results; + } + + private static ReadOnlyDictionary GetIndividualsLines(AppSettings appSettings, GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections, ReadOnlyCollection personDirectories) + { + Dictionary results = new(); + int id; + string suffix; + string segmentsFirst; + List lines = new(); + string personDisplayDirectoryName; + Dictionary copyOfPersonKeyToId = GetCopyOfPersonKeyToId(genealogicalDataCommunicationCollections); + int maxId = copyOfPersonKeyToId.Count == 0 ? 1 : copyOfPersonKeyToId.Values.Max(); + foreach (PersonDirectory personDirectory in personDirectories) + { + lines.Clear(); + if (personDirectory.Birthday is null || personDirectory.PersonName is null) + continue; + if (personDirectory.DirectoryNames.Length < 3) + continue; + if (!string.IsNullOrEmpty(personDirectory.PersonName.Alias) && personDirectory.PersonName.Alias.Contains("Jr")) + suffix = " Jr"; + else if (!string.IsNullOrEmpty(personDirectory.PersonName.Alias) && personDirectory.PersonName.Alias.Contains("Sr")) + suffix = " Sr"; + else + suffix = string.Empty; + if (copyOfPersonKeyToId.TryGetValue(personDirectory.Birthday.Value.Ticks, out id)) + _ = copyOfPersonKeyToId.Remove(personDirectory.Birthday.Value.Ticks); + else + { + maxId += 1; + id = maxId; + } + personDisplayDirectoryName = personDirectory.DirectoryNames[^2]; + segmentsFirst = personDisplayDirectoryName.Split(appSettings.PersonCharacters).First(); + lines.Add($"0 @I{id}@ INDI"); + lines.Add($"1 NAME {personDirectory.PersonName.First} /{personDirectory.PersonName.Last}/{suffix}"); + if (!string.IsNullOrEmpty(personDirectory.PersonName.First)) + lines.Add($"2 GIVN {personDirectory.PersonName.First}"); + if (!string.IsNullOrEmpty(personDirectory.PersonName.Last)) + lines.Add($"2 SURN {personDirectory.PersonName.Last}"); + if (!string.IsNullOrEmpty(suffix)) + lines.Add($"2 NSFX {suffix.Trim()}"); + if ($"{personDirectory.PersonName.First} {personDirectory.PersonName.Last}" != segmentsFirst) + lines.Add($"2 NICK {segmentsFirst}"); + if (personDirectory.PersonHour is not null && personDirectory.PersonHour.Sex != 'U') + lines.Add($"1 SEX {personDirectory.PersonHour.Sex}"); + lines.Add($"1 _UID {personDirectory.Birthday.Value.Ticks}"); + lines.Add("1 BIRT"); + lines.Add($"2 DATE {personDirectory.Birthday.Value:d MMM yyyy}".ToUpper()); + lines.Add($"2 NOTE {personDirectory.Birthday.Value.ToString(appSettings.PersonBirthdayFormat)}"); + if (personDirectory.BirthdayNotes is not null) + { + foreach (string birthdayNote in personDirectory.BirthdayNotes) + lines.Add($"3 CONT {birthdayNote}"); + } + if (personDirectory.PersonHour is not null) + { + if (personDirectory.PersonHour.Status == 'D') + lines.Add("1 DEAT Y"); + } + if (personDirectory.Notes is not null) + { + if (personDirectory.Notes.Length > 0) + { + lines.Add($"1 NOTE {personDirectory.Notes.First()}"); + for (int j = 1; j < personDirectory.Notes.Length; j++) + lines.Add($"2 CONT {personDirectory.Notes[j]}"); + } + } + results.Add(id, lines.ToArray()); + } + if (copyOfPersonKeyToId.Count > 0) + throw new Exception(string.Join(Environment.NewLine, copyOfPersonKeyToId.Keys.Select(l => new DateTime(l).ToString(appSettings.PersonBirthdayFormat)))); + return new(results); + } + + private static void WriteGenealogicalDataCommunicationCollections(Input input, GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections, ReadOnlyDictionary individualsLines) + { + if (input.GenealogicalDataCommunicationDirectory is not null) + { + List lines = new(); + List allLines = new(); + allLines.AddRange(genealogicalDataCommunicationCollections.HeaderLines); + if (genealogicalDataCommunicationCollections.HeaderLines.Length > 0) + File.WriteAllLines(Path.Combine(input.GenealogicalDataCommunicationDirectory, "a.pged"), genealogicalDataCommunicationCollections.HeaderLines); + if (individualsLines.Count > 0) + { + foreach (IEnumerable keyValuePair in from l in individualsLines orderby l.Key select l.Value) + allLines.AddRange(keyValuePair); + } + if (genealogicalDataCommunicationCollections.IndividualsLines.Count > 0) + { + lines.Clear(); + foreach (KeyValuePair keyValuePair in genealogicalDataCommunicationCollections.IndividualsLines) + lines.AddRange(keyValuePair.Value); + if (individualsLines.Count == 0) + allLines.AddRange(lines); + File.WriteAllLines(Path.Combine(input.GenealogicalDataCommunicationDirectory, "b.pged"), lines); + } + if (genealogicalDataCommunicationCollections.FamilyGroupLines.Count > 0) + { + lines.Clear(); + foreach (string[] keyValuePair in genealogicalDataCommunicationCollections.FamilyGroupLines) + lines.AddRange(keyValuePair); + allLines.AddRange(lines); + File.WriteAllLines(Path.Combine(input.GenealogicalDataCommunicationDirectory, "c.pged"), lines); + } + allLines.AddRange(genealogicalDataCommunicationCollections.FooterLines); + if (genealogicalDataCommunicationCollections.FooterLines.Length > 0) + File.WriteAllLines(Path.Combine(input.GenealogicalDataCommunicationDirectory, "d.pged"), genealogicalDataCommunicationCollections.FooterLines); + File.WriteAllLines(Path.Combine(input.GenealogicalDataCommunicationDirectory, "e.ged"), allLines); + } + } + + private static string? GetYearGroup(string year) => + !int.TryParse(year[2..], out int part) ? null : string.Concat(year[..^2], part < 50 ? "--" : "++"); + + private static void Export(AppSettings appSettings, Input input, long ticks, GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections, ReadOnlyCollection personDirectories, ReadOnlyDictionary individualsLines) + { + if (input.Destination is not null && personDirectories.Count > 0) + { + int id; + string[]? lines; + string directory; + string hourGroup; + string? yearGroup; + long count = ticks; + string personDisplayDirectoryName; + foreach (PersonDirectory personDirectory in personDirectories) + { + if (personDirectory.Birthday is null || personDirectory.PersonName is null) + continue; + if (personDirectory.DirectoryNames.Length < 3) + continue; + personDisplayDirectoryName = personDirectory.DirectoryNames[^2]; + hourGroup = GetHourGroup(personDisplayDirectoryName, personDirectory.Birthday.Value.Hour); + for (int i = 1; i < 3; i++) + { + if (i == 2) + yearGroup = GetYearGroup(personDirectory.Birthday.Value.Year.ToString()); + else if (i == 1) + yearGroup = appSettings.PersonCharacters.Where(l => personDisplayDirectoryName.Contains(l)).First().ToString(); + else + throw new NotSupportedException(); + if (string.IsNullOrEmpty(yearGroup)) + continue; + directory = Path.Combine(input.Destination, yearGroup, hourGroup, personDisplayDirectoryName, personDirectory.Birthday.Value.ToString(appSettings.PersonBirthdayFormat)); + if (!Directory.Exists(directory)) + _ = Directory.CreateDirectory(directory); + if (i == 2) + { + if (!genealogicalDataCommunicationCollections.IndividualsLines.TryGetValue(personDirectory.Birthday.Value.Ticks, out lines)) + lines = Array.Empty(); + count += 1; + File.WriteAllLines(Path.Combine(directory, $"{count}-A.pged"), lines); + } + if (!genealogicalDataCommunicationCollections.PersonKeyToId.TryGetValue(personDirectory.Birthday.Value.Ticks, out id)) + lines = null; + else + { + if (!individualsLines.TryGetValue(id, out lines)) + lines = null; + } + if (i == 1 && lines is null) + lines = Array.Empty(); + if (lines is not null) + { + count += 1; + if (i == 1) + File.WriteAllLines(Path.Combine(directory, $"B.pged"), lines); + else + File.WriteAllLines(Path.Combine(directory, $"{count}-B.pged"), lines); + } + } + } + } + } + + internal static void FileSystemToGenealogicalDataCommunication(AppSettings appSettings, ILogger logger, List args) + { + Input input = GetInput(args); + long ticks = DateTime.Now.Ticks; + logger.LogInformation("{ticks}", ticks); + logger.LogInformation("{newValue}", new DateTime(638258293638438812).AddDays(4).Ticks); + GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections = GetGenealogicalDataCommunicationCollections(appSettings, input); + ReadOnlyCollection personDirectories = GetPersonDirectories(appSettings, input); + ReadOnlyDictionary individualsLines = GetIndividualsLines(appSettings, genealogicalDataCommunicationCollections, personDirectories); + if (string.IsNullOrEmpty(input.GenealogicalDataCommunicationDirectory)) + logger.LogInformation("{distance} is null?", input.GenealogicalDataCommunicationDirectory); + else if (individualsLines.Count == 0) + logger.LogInformation("{count} lines?", individualsLines.Count); + if (input.GenealogicalDataCommunicationDirectory is not null) + WriteGenealogicalDataCommunicationCollections(input, genealogicalDataCommunicationCollections, individualsLines); + if (input.Destination is not null) + Export(appSettings, input, ticks, genealogicalDataCommunicationCollections, personDirectories, individualsLines); + } + +} \ No newline at end of file diff --git a/Models/AppSettings.cs b/Models/AppSettings.cs index cadc64f..4c3e289 100644 --- a/Models/AppSettings.cs +++ b/Models/AppSettings.cs @@ -7,6 +7,8 @@ public record AppSettings(string Company, string DefaultNoteType, string[] ExcludeDirectoryNames, string[] ExcludeSchemes, + string PersonBirthdayFormat, + char[] PersonCharacters, string WorkingDirectoryName) { diff --git a/Models/Binder/AppSettings.cs b/Models/Binder/AppSettings.cs index ba29eef..853c92e 100644 --- a/Models/Binder/AppSettings.cs +++ b/Models/Binder/AppSettings.cs @@ -11,6 +11,8 @@ public class AppSettings public string? DefaultNoteType { get; set; } public string[]? ExcludeDirectoryNames { get; set; } public string[]? ExcludeSchemes { get; set; } + public string? PersonBirthdayFormat { get; set; } + public string? PersonCharacters { get; set; } public string? WorkingDirectoryName { get; set; } public override string ToString() @@ -30,6 +32,10 @@ public class AppSettings throw new NullReferenceException(nameof(appSettings.ExcludeDirectoryNames)); if (appSettings?.ExcludeSchemes is null) throw new NullReferenceException(nameof(appSettings.ExcludeSchemes)); + if (appSettings?.PersonBirthdayFormat is null) + throw new NullReferenceException(nameof(appSettings.PersonBirthdayFormat)); + if (appSettings?.PersonCharacters is null) + throw new NullReferenceException(nameof(appSettings.PersonCharacters)); if (appSettings?.WorkingDirectoryName is null) throw new NullReferenceException(nameof(appSettings.WorkingDirectoryName)); result = new( @@ -37,6 +43,8 @@ public class AppSettings appSettings.DefaultNoteType, appSettings.ExcludeDirectoryNames, appSettings.ExcludeSchemes, + appSettings.PersonBirthdayFormat, + appSettings.PersonCharacters.ToArray(), appSettings.WorkingDirectoryName ); return result; diff --git a/Worker.cs b/Worker.cs index 842684a..d4b580a 100644 --- a/Worker.cs +++ b/Worker.cs @@ -32,6 +32,7 @@ public class Worker : BackgroundService ConsoleKey.D, ConsoleKey.E, ConsoleKey.F, + ConsoleKey.G, ConsoleKey.H, ConsoleKey.J, ConsoleKey.K, @@ -93,6 +94,7 @@ public class Worker : BackgroundService _Logger.LogInformation("D) Clipboard (All Directories),"); _Logger.LogInformation("E) Clipboard (Top Directory Only and File Name Without Extension),"); _Logger.LogInformation("F) Clipboard (All Directories and File Name Without Extension),"); + _Logger.LogInformation("G) Genealogical Data Communication"); _Logger.LogInformation("H) Hardcoded file search and sort,"); _Logger.LogInformation("J) Set Date from Json Entry"); _Logger.LogInformation("K) Kanban support"); @@ -117,6 +119,9 @@ public class Worker : BackgroundService case ConsoleKey.F: Helpers.HelperSaveOrCopyContents.SaveOrCopyContents(_Logger, _Args[0], consoleKey); break; + case ConsoleKey.G: + Helpers.HelperGenealogicalDataCommunication.FileSystemToGenealogicalDataCommunication(_AppSettings, _Logger, _Args); + break; case ConsoleKey.H: Helpers.HelperHardcodedFileSearchAndSort.HardcodedFileSearchAndSort(_Logger, _Args[0]); break;