namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class Person { // ... internal static (Models.PersonBirthday?, string) Get(string personBirthdayFormat, string personDisplayDirectory, string personKeyDirectory, DateTime birthday) { Models.PersonBirthday? personBirthday = new(birthday); string personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personBirthday); string convertedPersonKeyDirectory = Path.Combine(personDisplayDirectory, personKeyFormatted); if (!Directory.Exists(convertedPersonKeyDirectory)) Directory.Move(personKeyDirectory, convertedPersonKeyDirectory); return new(personBirthday, personKeyFormatted); } private static void CleanExport() { List cleanLines = new(); string exportFile = "xD:/1) Images A/Images-9b89679-Results/A2) People/9b89679/([])/FamilyEcho/638157228251558818-RootsMagic-Export-Copy.ged"; string[] sourceLines = File.ReadAllLines(exportFile); for (int i = 0; i < sourceLines.Length; i++) { if (sourceLines[i].StartsWith("1 _UID")) continue; else if (sourceLines[i].StartsWith("1 SEX")) continue; else if (sourceLines[i].StartsWith("1 DEAT")) continue; else if (sourceLines[i].StartsWith("2 GIVN")) continue; // else if (sourceLines[i].StartsWith("2 NICK")) // continue; else if (sourceLines[i].StartsWith("2 SURN")) continue; else if (sourceLines[i] == "1 BIRT") { i += 1; continue; } else if (sourceLines[i] == "1 CHAN") { i += 1; continue; } cleanLines.Add(sourceLines[i]); } File.WriteAllLines(exportFile, cleanLines); } internal static (string[] headerLines, Dictionary> individuals, string[] footerLines) GetIndividuals(string gedCOMFile) { Dictionary> results = new(); string? nick; int startAt = 0; List lines = new(); List headerLines = new(); List footerLines = new(); string[] sourceLines = File.ReadAllLines(gedCOMFile); for (int i = 0; i < sourceLines.Length; i++) { lines.Add(sourceLines[i]); if (sourceLines[i].EndsWith("@ INDI")) { lines.RemoveAt(lines.Count - 1); headerLines.AddRange(lines); startAt = lines.Count; lines.Clear(); break; } } for (int i = startAt; i < sourceLines.Length; i++) { if (!sourceLines[i].StartsWith("0 @")) continue; nick = null; lines.Add(sourceLines[i]); for (int j = i + 1; j < sourceLines.Length; j++) { if (sourceLines[j].StartsWith("0 @I")) break; lines.Add(sourceLines[j]); if (!sourceLines[j].StartsWith("2 NICK ")) continue; nick = sourceLines[j][7..]; } if (string.IsNullOrEmpty(nick)) { if (lines[^1] != "0 TRLR") throw new Exception(string.Join(Environment.NewLine, lines)); else { footerLines.AddRange(lines); break; } } results.Add(nick, new()); results[nick].AddRange(lines); lines.Clear(); } return (headerLines.ToArray(), results, footerLines.ToArray()); } private static void WriteGedFile(string personKeyFormatted, Models.PersonBirthday personBirthday, string[]? filteredIndividualsLines, Models.PersonName name, string[] matches) { string? directory = Path.GetDirectoryName(matches[0]); if (directory is null) throw new Exception(); string? sexLine; string? deathLine = null; string jrOrSr; if (string.IsNullOrEmpty(name.Alias.Value)) jrOrSr = string.Empty; else { if (name.Alias.Value.Contains(" Jr")) jrOrSr = "Jr"; else if (name.Alias.Value.Contains(" Sr")) jrOrSr = "Sr"; else jrOrSr = string.Empty; } string nameLine = $"1 NAME {name.First.Value}/{name.Last.Value}/{jrOrSr}"; if (personKeyFormatted[^2..] is "23" or "21" or "19" or "17" or "15") { sexLine = "1 SEX M"; deathLine = "1 DEAT Y"; } else if (personKeyFormatted[^2..] is "22" or "20" or "18" or "16" or "14") { sexLine = "1 SEX F"; deathLine = "1 DEAT Y"; } else if (personKeyFormatted[^2..] is "13" or "11" or "09" or "07" or "05") sexLine = "1 SEX M"; else if (personKeyFormatted[^2..] is "12" or "10" or "08" or "06" or "04") sexLine = "1 SEX F"; else if (filteredIndividualsLines is null) sexLine = "1 SEX U"; else { sexLine = null; for (int i = 0; i < filteredIndividualsLines.Length; i++) { if (filteredIndividualsLines[i] != nameLine) continue; for (int j = i + 1; j < filteredIndividualsLines.Length; j++) { i = j; if (filteredIndividualsLines[j].StartsWith("0 @I")) break; if (filteredIndividualsLines[j].StartsWith("1 SEX ")) sexLine = filteredIndividualsLines[j]; else if (filteredIndividualsLines[j].StartsWith("1 DEAT ")) deathLine = filteredIndividualsLines[j]; } } if (sexLine is null) sexLine = "1 SEX U"; else { string sex; if (deathLine is null or not "1 DEAT Y") sex = sexLine[6] is 'M' ? "05" : sexLine[6] is 'F' ? "04" : sexLine[6] is 'U' ? "02" : throw new NotImplementedException(); else sex = sexLine[6] is 'M' ? "15" : sexLine[6] is 'F' ? "14" : sexLine[6] is 'U' ? "03" : throw new NotImplementedException(); if (directory.EndsWith("00")) directory = string.Concat(directory[..^2], sex); else if (directory.EndsWith("01")) directory = string.Concat(directory[..^2], sex); else throw new NotImplementedException(); personKeyFormatted = $"{personKeyFormatted[..^2]}{sex}"; } } List pGedLines = new(); if (filteredIndividualsLines is null || !filteredIndividualsLines.Any()) pGedLines.Add($"0 @I{personKeyFormatted}@ INDI"); else { if (!filteredIndividualsLines[0].StartsWith("0 @I")) throw new NotSupportedException(); pGedLines.Add(filteredIndividualsLines[0]); } pGedLines.Add(nameLine); if (!string.IsNullOrEmpty(name.First.Value)) pGedLines.Add($"2 GIVN {name.First.Value}"); if (!string.IsNullOrEmpty(name.Last.Value)) pGedLines.Add($"2 SURN {name.Last.Value}"); pGedLines.Add($"2 NICK {personKeyFormatted}"); pGedLines.Add(sexLine); if (!string.IsNullOrEmpty(deathLine)) pGedLines.Add(deathLine); if (!IPersonBirthday.IsCounterPersonBirthday(personBirthday)) { pGedLines.Add("1 BIRT"); pGedLines.Add($"2 DATE {personBirthday.Value:dd MMM yyyy}"); } if (filteredIndividualsLines is not null) { for (int i = 1; i < filteredIndividualsLines.Length; i++) pGedLines.Add(filteredIndividualsLines[i]); } if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); string text = string.Join(Environment.NewLine, pGedLines); _ = IPath.WriteAllText(Path.Combine(directory, $"{personKeyFormatted}.pged"), text, updateDateWhenMatches: false, compareBeforeWrite: true); } internal static string[] GetFiltered(List individualsLines) { List results = new(); for (int i = 0; i < individualsLines.Count; i++) { if (individualsLines[i].StartsWith("1 NAME")) continue; else if (individualsLines[i].StartsWith("2 GIVN")) continue; else if (individualsLines[i].StartsWith("2 SURN")) continue; else if (individualsLines[i].StartsWith("2 NICK")) continue; else if (individualsLines[i].StartsWith("1 SEX")) continue; else if (individualsLines[i].StartsWith("1 DEAT")) continue; else if (individualsLines[i] == "1 BIRT") { i += 1; continue; } else if (individualsLines[i] == "1 CHAN") { i += 1; continue; } results.Add(individualsLines[i]); } return results.ToArray(); } internal static void CreateTree(string mappingDefaultName, string personBirthdayFormat, string resultAllInOne, Models.PersonContainer[] personContainers, string[] gedCOMHeaderLines, string[] gedCOMFooterLines, long ticks, string a2PeopleContentDirectory, Dictionary> personKeyToIds) { string by; string[] matches; const int zero = 0; string[] pGedFiles; string[] pGedLines; string personKeyFormatted; List lines = new(); List distinct = new(); lines.AddRange(gedCOMHeaderLines); Models.PersonBirthday personBirthday; string rootDirectory = Path.Combine(a2PeopleContentDirectory, $"{ticks}-Tree"); foreach (Models.PersonContainer personContainer in personContainers) { if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Person is null || !personContainer.Birthdays.Any()) continue; if (personContainer.DisplayDirectoryName == mappingDefaultName || personContainer.Person.Name.Alias.Value == "Z") continue; if (distinct.Contains(personContainer.Key.Value)) continue; distinct.Add(personContainer.Key.Value); if (!personKeyToIds.ContainsKey(personContainer.Key.Value)) continue; personBirthday = personContainer.Birthdays[zero]; personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personBirthday); by = IPersonBirthday.IsCounterPersonBirthday(personBirthday) ? resultAllInOne : "People"; matches = (from l in personContainer.DisplayDirectoryAllFiles where !string.IsNullOrEmpty(personKeyFormatted) && l.Contains(personKeyFormatted) select l).ToArray(); if (!matches.Any()) continue; pGedFiles = (from l in matches where l.EndsWith(".pged") select l).ToArray(); if (!pGedFiles.Any()) continue; pGedLines = File.ReadAllLines(pGedFiles[0]); lines.AddRange(pGedLines); // segments = personContainer.DisplayDirectoryName.Split(_Configuration.PersonCharacters.ToArray()); // if (segments.Length < 2) // directory = Path.Combine(rootDirectory, $"000 {personKeyFormatted} {personContainer.DisplayDirectoryName}"); // else // directory = Path.Combine(rootDirectory, $"{segments[1].PadLeft(3, '0')} {personKeyFormatted} {personContainer.DisplayDirectoryName}"); // if (Directory.Exists(directory)) // continue; // _ = Directory.CreateDirectory(directory); } lines.AddRange(gedCOMFooterLines); File.WriteAllLines(Path.Combine(a2PeopleContentDirectory, $"{ticks}.ged"), lines); } internal static Models.Person GetPerson(string[] personDisplayDirectoryAllFiles, string? personKeyFormatted, long personKey, Models.PersonBirthday personBirthday, string[] segments, string[]? filteredIndividualsLines) { Models.Person result; const int zero = 0; List urls = new(); Models.PersonId id = new(personKey); List emails = new(); List numbers = new(); List comments = new(); List addresses = new(); Models.PersonName name = PersonName.Create(segments[zero]); string[] matches = (from l in personDisplayDirectoryAllFiles where !string.IsNullOrEmpty(personKeyFormatted) && l.Contains(personKeyFormatted) select l).ToArray(); if (!string.IsNullOrEmpty(personKeyFormatted) && matches.Any()) WriteGedFile(personKeyFormatted, personBirthday, filteredIndividualsLines, name, matches); result = new(id, personBirthday, name, comments, urls, numbers, emails, addresses); return result; } }