334 lines
15 KiB
C#
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;
|
|
}
|
|
|
|
} |