334 lines
15 KiB
C#

using System.Text.Json;
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<string> 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<string, List<string>> individuals, string[] footerLines) GetIndividuals(string? gedCOMFile)
{
Dictionary<string, List<string>> results = new();
string? nick;
int startAt = 0;
List<string> lines = new();
const string startsWith = "0 @";
List<string> headerLines = new();
List<string> footerLines = new();
string[] sourceLines = string.IsNullOrEmpty(gedCOMFile) ? Array.Empty<string>() : File.ReadAllLines(gedCOMFile);
for (int i = 0; i < sourceLines.Length; i++)
{
lines.Add(sourceLines[i]);
if (sourceLines[i].StartsWith(startsWith))
{
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(startsWith))
continue;
nick = null;
lines.Add(sourceLines[i]);
if (sourceLines[i].EndsWith("@ FAM"))
{
for (int j = i + 1; j < sourceLines.Length; j++)
lines.Add(sourceLines[j]);
footerLines.AddRange(lines);
break;
}
else if (sourceLines[i].EndsWith("@ INDI"))
{
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 "))
continue;
nick = sourceLines[j][7..];
}
if (string.IsNullOrEmpty(nick))
throw new Exception(string.Join(Environment.NewLine, lines));
results.Add(nick, new());
if (lines.Count > 25)
lines.Clear();
results[nick].AddRange(lines);
lines.Clear();
}
else
throw new NotSupportedException();
}
return (headerLines.ToArray(), results, footerLines.ToArray());
}
private static void WriteGedComFile(string personKeyFormatted, Models.PersonBirthday personBirthday, string[]? filteredIndividualsLines, Models.PersonName name, bool isDefaultName, string directory)
{
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
{
int hours = IPersonBirthday.GetHour(deathLine is null or not "1 DEAT Y", sexLine[6]);
string code = hours.ToString("00");
if (directory.EndsWith("00"))
directory = string.Concat(directory[..^2], code);
else if (directory.EndsWith("01"))
directory = string.Concat(directory[..^2], code);
else
throw new NotImplementedException();
personKeyFormatted = $"{personKeyFormatted[..^2]}{code}";
}
}
List<string> 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 (isDefaultName)
pGedLines.Add("9 NOTE");
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<string> individualsLines)
{
List<string> 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<long, List<int>> personKeyToIds)
{
string by;
string[] matches;
const int zero = 0;
string[] pGedFiles;
string[] pGedLines;
string personKeyFormatted;
List<string> lines = new();
List<long> 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 (IPerson.IsDefaultName(mappingDefaultName, personContainer.DisplayDirectoryName) || IPerson.IsDefaultName(mappingDefaultName, personContainer.Person))
continue;
if (distinct.Contains(personContainer.Key.Value))
continue;
distinct.Add(personContainer.Key.Value);
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);
if (!personKeyToIds.ContainsKey(personContainer.Key.Value))
lines.Add("1 NOTE");
// 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 mappingDefaultName, char[] personCharacters, string personDisplayDirectoryName, string[] personDisplayDirectoryAllFiles, string? personKeyFormatted, long personKey, Models.PersonBirthday personBirthday, string[]? filteredIndividualsLines)
{
Models.Person result;
string[] matches;
const int zero = 0;
List<Models.PersonURL> urls = new();
Models.PersonId id = new(personKey);
List<Models.PersonEmail> emails = new();
List<Models.PersonNumber> numbers = new();
List<Models.PersonComment> comments = new();
List<Models.PersonAddress> addresses = new();
string checkFileName = $"{personDisplayDirectoryName[zero]}.json";
bool isDefaultName = IPerson.IsDefaultName(mappingDefaultName, personDisplayDirectoryName);
string nameWithoutApproximateYears = !isDefaultName ? personDisplayDirectoryName.Split(personCharacters)[zero] : personDisplayDirectoryName;
matches = (from l in personDisplayDirectoryAllFiles where Path.GetFileName(l) == checkFileName select l).ToArray();
Models.PersonName? name;
if (!matches.Any())
name = PersonName.Create(nameWithoutApproximateYears);
else
{
string json = File.ReadAllText(matches[zero]);
name = JsonSerializer.Deserialize<Models.PersonName>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
name ??= PersonName.Create(nameWithoutApproximateYears);
if (name.Last is null || string.IsNullOrEmpty(name.Last.Value))
name = PersonName.Create(nameWithoutApproximateYears);
}
matches = (from l in personDisplayDirectoryAllFiles where !string.IsNullOrEmpty(personKeyFormatted) && l.Contains(personKeyFormatted) select l).ToArray();
if (!string.IsNullOrEmpty(personKeyFormatted) && matches.Any())
{
string? directory = Path.GetDirectoryName(matches[zero]);
if (directory is null)
throw new Exception();
WriteGedComFile(personKeyFormatted, personBirthday, filteredIndividualsLines, name, isDefaultName, directory);
}
result = new(id, personBirthday, name, comments, urls, numbers, emails, addresses);
return result;
}
}