VerifyPersonContainersDisplayDirectoryAllFiles, SaveOne, SaveParents, GetRelations, CleanDisplayDirectoryAllFilesAndWriteTicksGed
520 lines
29 KiB
C#
520 lines
29 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
|
|
|
internal abstract class GenealogicalDataCommunication
|
|
{
|
|
|
|
// ...
|
|
|
|
private record Record(Models.PersonContainer PersonContainer,
|
|
string PersonKeyFormatted,
|
|
string File,
|
|
string RelationPersonKeyFormatted,
|
|
string MergeWithLineTwo,
|
|
string? RelationFullName);
|
|
|
|
private static string[] GetHeaderLines(string startsWith, string[] sourceLines)
|
|
{
|
|
List<string> 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<string, string[]> Convert(Dictionary<string, List<string>> keyValuePairs)
|
|
{
|
|
Dictionary<string, string[]> results = new();
|
|
foreach (KeyValuePair<string, List<string>> keyValuePair in keyValuePairs)
|
|
results.Add(keyValuePair.Key, keyValuePair.Value.ToArray());
|
|
return new(results);
|
|
}
|
|
|
|
internal static GenealogicalDataCommunicationCollections GetIndividuals(string genealogicalDataCommunicationFile, bool requireNickName)
|
|
{
|
|
GenealogicalDataCommunicationCollections result;
|
|
ReadOnlyDictionary<string, string[]> results;
|
|
string? nick;
|
|
string[] segments;
|
|
List<string> lines = new();
|
|
const string startsWith = "0 @";
|
|
List<string> footerLines = new();
|
|
List<string[]> familyGroupLines = new();
|
|
Dictionary<string, string> idToNick = new();
|
|
Dictionary<string, List<string>> keyValuePairs = new();
|
|
string[] sourceLines = string.IsNullOrEmpty(genealogicalDataCommunicationFile) || !File.Exists(genealogicalDataCommunicationFile) ? Array.Empty<string>() : File.ReadAllLines(genealogicalDataCommunicationFile);
|
|
string[] headerLines = GetHeaderLines(startsWith, sourceLines);
|
|
for (int i = headerLines.Length; i < sourceLines.Length; i++)
|
|
{
|
|
if (!sourceLines[i].StartsWith(startsWith))
|
|
continue;
|
|
nick = null;
|
|
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"))
|
|
{
|
|
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 "))
|
|
continue;
|
|
nick = sourceLines[j][7..];
|
|
if (segments.Length == 3)
|
|
idToNick.Add(segments[1], nick);
|
|
}
|
|
if (requireNickName && string.IsNullOrEmpty(nick))
|
|
throw new Exception(string.Join(Environment.NewLine, lines));
|
|
nick ??= Guid.NewGuid().ToString();
|
|
keyValuePairs.Add(nick, new());
|
|
if (!lines.Any())
|
|
continue;
|
|
keyValuePairs[nick].AddRange(lines);
|
|
lines.Clear();
|
|
}
|
|
else
|
|
throw new NotSupportedException();
|
|
}
|
|
results = Convert(keyValuePairs);
|
|
result = new(headerLines, results, familyGroupLines, new(idToNick), footerLines.ToArray());
|
|
return result;
|
|
}
|
|
|
|
internal static List<string> GetMappedLines(string genealogicalDataCommunicationFile, bool requireNickName)
|
|
{
|
|
List<string> results = new();
|
|
Models.PersonBirthday personBirthday = new(DateTime.Now);
|
|
GenealogicalDataCommunicationLines genealogicalDataCommunicationLines;
|
|
GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections = GetIndividuals(genealogicalDataCommunicationFile, requireNickName);
|
|
results.AddRange(genealogicalDataCommunicationCollections.HeaderLines);
|
|
foreach (KeyValuePair<string, string[]> keyValuePair in genealogicalDataCommunicationCollections.Individuals)
|
|
{
|
|
genealogicalDataCommunicationLines = GetGenealogicalDataCommunicationLines(personBirthday, keyValuePair.Value);
|
|
if (!string.IsNullOrEmpty(genealogicalDataCommunicationLines.Id))
|
|
results.Add(genealogicalDataCommunicationLines.Id);
|
|
if (!string.IsNullOrEmpty(genealogicalDataCommunicationLines.UId))
|
|
results.Add(genealogicalDataCommunicationLines.UId);
|
|
if (!string.IsNullOrEmpty(genealogicalDataCommunicationLines.Name))
|
|
results.Add(genealogicalDataCommunicationLines.Name);
|
|
if (!string.IsNullOrEmpty(genealogicalDataCommunicationLines.GivenName))
|
|
results.Add(genealogicalDataCommunicationLines.GivenName);
|
|
if (!string.IsNullOrEmpty(genealogicalDataCommunicationLines.SurName))
|
|
results.Add(genealogicalDataCommunicationLines.SurName);
|
|
if (!string.IsNullOrEmpty(genealogicalDataCommunicationLines.NickName))
|
|
results.Add(genealogicalDataCommunicationLines.NickName);
|
|
if (!string.IsNullOrEmpty(genealogicalDataCommunicationLines.Sex))
|
|
results.Add(genealogicalDataCommunicationLines.Sex);
|
|
results.AddRange(genealogicalDataCommunicationLines.Birth);
|
|
results.AddRange(genealogicalDataCommunicationLines.Death);
|
|
results.AddRange(genealogicalDataCommunicationLines.Changed);
|
|
}
|
|
for (int i = 0; i < genealogicalDataCommunicationCollections.FamilyGroupLines.Count; i++)
|
|
results.AddRange(genealogicalDataCommunicationCollections.FamilyGroupLines[i]);
|
|
results.AddRange(genealogicalDataCommunicationCollections.FooterLines);
|
|
return results;
|
|
}
|
|
|
|
internal static GenealogicalDataCommunicationLines GetGenealogicalDataCommunicationLines(Models.PersonBirthday personBirthday, string[] individualsLines)
|
|
{
|
|
GenealogicalDataCommunicationLines result;
|
|
string? idLine = null;
|
|
string? sexLine = null;
|
|
string? uIdLine = null;
|
|
string? nameLine = null;
|
|
string? suffixLine = null;
|
|
string? surNameLine = null;
|
|
string? nickNameLine = null;
|
|
string? givenNameLine = null;
|
|
List<string> birthLines = new();
|
|
List<string> deathLines = new();
|
|
List<string> changedLines = new();
|
|
for (int i = 0; i < individualsLines.Length; i++)
|
|
{
|
|
if (idLine is null && individualsLines[i].EndsWith("@ INDI"))
|
|
idLine = individualsLines[i];
|
|
else if (uIdLine is null && individualsLines[i].StartsWith("1 _UID"))
|
|
uIdLine = individualsLines[i];
|
|
else if (nameLine is null && individualsLines[i].StartsWith("1 NAME"))
|
|
nameLine = individualsLines[i];
|
|
else if (givenNameLine is null && individualsLines[i].StartsWith("2 GIVN"))
|
|
givenNameLine = individualsLines[i];
|
|
else if (surNameLine is null && individualsLines[i].StartsWith("2 SURN"))
|
|
surNameLine = individualsLines[i];
|
|
else if (suffixLine is null && individualsLines[i].StartsWith("2 NSFX"))
|
|
suffixLine = individualsLines[i];
|
|
else if (nickNameLine is null && individualsLines[i].StartsWith("2 NICK"))
|
|
nickNameLine = individualsLines[i];
|
|
else if (sexLine is null && individualsLines[i].StartsWith("1 SEX"))
|
|
sexLine = individualsLines[i];
|
|
else if (!birthLines.Any() && individualsLines[i] == "1 BIRT")
|
|
{
|
|
birthLines.Add(individualsLines[i]);
|
|
if (individualsLines.Length > i + 1 && individualsLines[i + 1].StartsWith("2 DATE"))
|
|
{
|
|
i += 1;
|
|
birthLines.Add(individualsLines[i]);
|
|
}
|
|
}
|
|
else if (!deathLines.Any() && individualsLines[i].StartsWith("1 DEAT"))
|
|
{
|
|
deathLines.Add(individualsLines[i]);
|
|
if (individualsLines.Length > i + 1 && individualsLines[i + 1].StartsWith("2 DATE"))
|
|
{
|
|
i += 1;
|
|
deathLines.Add(individualsLines[i]);
|
|
}
|
|
}
|
|
else if (!changedLines.Any() && individualsLines[i] == "1 CHAN")
|
|
{
|
|
changedLines.Add(individualsLines[i]);
|
|
if (individualsLines.Length > i + 1 && individualsLines[i + 1].StartsWith("2 DATE"))
|
|
{
|
|
i += 1;
|
|
changedLines.Add(individualsLines[i]);
|
|
}
|
|
}
|
|
}
|
|
if (!birthLines.Any())
|
|
{
|
|
birthLines.Add("1 BIRT");
|
|
birthLines.Add($"2 DATE {personBirthday.Value:dd MMM yyyy}");
|
|
}
|
|
result = new(idLine, uIdLine, nameLine, givenNameLine, surNameLine, suffixLine, nickNameLine, sexLine, birthLines, deathLines, changedLines);
|
|
return result;
|
|
}
|
|
|
|
internal static Models.GenealogicalDataCommunication GetGenealogicalDataCommunication(bool first, GenealogicalDataCommunicationLines genealogicalDataCommunicationLines)
|
|
{
|
|
Models.GenealogicalDataCommunication result;
|
|
DateTime? birth;
|
|
DateTime? death;
|
|
DateTime? changed;
|
|
string? uId = string.IsNullOrEmpty(genealogicalDataCommunicationLines.UId) || !genealogicalDataCommunicationLines.UId.Contains("1 _UID ") ? null : genealogicalDataCommunicationLines.UId.Split("1 _UID ")[1];
|
|
char sex = string.IsNullOrEmpty(genealogicalDataCommunicationLines.Sex) || !genealogicalDataCommunicationLines.Sex.Contains("1 SEX ") ? 'U' : genealogicalDataCommunicationLines.Sex.Split("1 SEX ")[1].First();
|
|
string? name = string.IsNullOrEmpty(genealogicalDataCommunicationLines.Name) || !genealogicalDataCommunicationLines.Name.Contains("1 NAME ") ? null : genealogicalDataCommunicationLines.Name.Split("1 NAME ")[1];
|
|
string? suffix = string.IsNullOrEmpty(genealogicalDataCommunicationLines.Suffix) || !genealogicalDataCommunicationLines.Suffix.Contains("2 NSFX ") ? null : genealogicalDataCommunicationLines.Suffix.Split("2 NSFX ")[1];
|
|
string? surName = string.IsNullOrEmpty(genealogicalDataCommunicationLines.SurName) || !genealogicalDataCommunicationLines.SurName.Contains("2 SURN ") ? null : genealogicalDataCommunicationLines.SurName.Split("2 SURN ")[1];
|
|
string nickName = string.IsNullOrEmpty(genealogicalDataCommunicationLines.NickName) || !genealogicalDataCommunicationLines.NickName.Contains("2 NICK ") ? throw new NotSupportedException() : genealogicalDataCommunicationLines.NickName.Split("2 NICK ")[1];
|
|
string? givenName = string.IsNullOrEmpty(genealogicalDataCommunicationLines.GivenName) || !genealogicalDataCommunicationLines.GivenName.Contains("2 GIVN ") ? null : genealogicalDataCommunicationLines.GivenName.Split("2 GIVN ")[1];
|
|
string? id = string.IsNullOrEmpty(genealogicalDataCommunicationLines.Id) || !genealogicalDataCommunicationLines.Id.Contains("0 @I") || !genealogicalDataCommunicationLines.Id.Contains("@ INDI") ? null : genealogicalDataCommunicationLines.Id.Split('@')[1][1..];
|
|
string[] birthLines = (from l in genealogicalDataCommunicationLines.Birth where l.Contains("2 DATE ") select l.Split("2 DATE ")[1]).ToArray();
|
|
string[] deathLines = (from l in genealogicalDataCommunicationLines.Death where l.Contains("2 DATE ") select l.Split("2 DATE ")[1]).ToArray();
|
|
string[] changedLines = (from l in genealogicalDataCommunicationLines.Changed where l.Contains("2 DATE ") select l.Split("2 DATE ")[1]).ToArray();
|
|
if (!birthLines.Any() || !DateTime.TryParse(birthLines[0], out DateTime parseBirth))
|
|
birth = null;
|
|
else
|
|
birth = parseBirth;
|
|
if (!deathLines.Any() || !DateTime.TryParse(deathLines[0], out DateTime parseDeath))
|
|
death = null;
|
|
else
|
|
death = parseDeath;
|
|
if (!changedLines.Any() || !DateTime.TryParse(changedLines[0], out DateTime parseChanged))
|
|
changed = null;
|
|
else
|
|
changed = parseChanged;
|
|
if (birth is not null)
|
|
{
|
|
bool alive = death is null && !genealogicalDataCommunicationLines.Death.Any(l => l == "1 DEAT Y");
|
|
(int age, _) = IAge.GetAge(DateTime.Now.Ticks, birth.Value.Ticks);
|
|
int hours = IPersonBirthday.GetHour(alive, sex);
|
|
if (!first)
|
|
hours += 2;
|
|
if (death == birth)
|
|
death = death.Value.AddHours(hours);
|
|
birth = birth.Value.AddHours(hours);
|
|
if (age < 1)
|
|
birth = null;
|
|
if (birth is not null && death is null && (!alive || (age > 110 && !IPersonBirthday.IsCounterPersonBirthday(new(birth.Value)))))
|
|
death = birth;
|
|
}
|
|
death ??= !genealogicalDataCommunicationLines.Death.Any(l => l == "1 DEAT Y") ? null : birth;
|
|
result = new(birth,
|
|
changed,
|
|
death,
|
|
givenName,
|
|
id,
|
|
name,
|
|
nickName,
|
|
sex,
|
|
suffix,
|
|
surName,
|
|
uId);
|
|
return result;
|
|
}
|
|
|
|
private static List<GenealogicalDataCommunicationRelation> GetRelations(string personBirthdayFormat, ReadOnlyCollection<Models.PersonContainer> personContainers, GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections)
|
|
{
|
|
List<GenealogicalDataCommunicationRelation> results = new();
|
|
string? nick;
|
|
long? personKey;
|
|
string relation;
|
|
string? fullName;
|
|
string[] segments;
|
|
string[] familyLines;
|
|
Models.PersonBirthday? personBirthday;
|
|
ReadOnlyDictionary<string, string> personKeyFormattedToPersonFullName = IPersonContainer.GetPersonKeyFormattedToPersonFullName(personBirthdayFormat, personContainers);
|
|
for (int i = 0; i < genealogicalDataCommunicationCollections.FamilyGroupLines.Count; i++)
|
|
{
|
|
familyLines = genealogicalDataCommunicationCollections.FamilyGroupLines[i];
|
|
for (int j = 0; j < familyLines.Length; j++)
|
|
{
|
|
segments = familyLines[j].Split('@');
|
|
if (segments.First().Length < 3 || segments.Length != 3)
|
|
continue;
|
|
if (!genealogicalDataCommunicationCollections.IdToNick.TryGetValue(segments[1], out nick))
|
|
continue;
|
|
relation = segments.First()[2..].Trim();
|
|
personBirthday = IPersonBirthday.GetPersonBirthday(personBirthdayFormat, nick);
|
|
personKey = personBirthday?.Value.Ticks;
|
|
fullName = personKeyFormattedToPersonFullName.GetValueOrDefault(nick);
|
|
if (j + 1 >= familyLines.Length || familyLines[j + 1].Length < 3 || familyLines[j + 1][..3] != "2 _")
|
|
results.Add(new(i, relation, segments[1], nick, personKey, fullName, null));
|
|
else
|
|
results.Add(new(i, relation, segments[1], nick, personKey, fullName, familyLines[j + 1][2..]));
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
internal static ReadOnlyDictionary<int, List<GenealogicalDataCommunicationRelation>> GetFamilyIndexToCollection(string personBirthdayFormat, ReadOnlyCollection<Models.PersonContainer> personContainers, GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections)
|
|
{
|
|
Dictionary<int, List<GenealogicalDataCommunicationRelation>> results = new();
|
|
List<GenealogicalDataCommunicationRelation>? relations;
|
|
List<GenealogicalDataCommunicationRelation> genealogicalDataCommunicationRelations = GetRelations(personBirthdayFormat, personContainers, genealogicalDataCommunicationCollections);
|
|
foreach (GenealogicalDataCommunicationRelation genealogicalDataCommunicationRelation in genealogicalDataCommunicationRelations)
|
|
{
|
|
if (!results.TryGetValue(genealogicalDataCommunicationRelation.FamilyIndex, out relations))
|
|
{
|
|
results.Add(genealogicalDataCommunicationRelation.FamilyIndex, new());
|
|
if (!results.TryGetValue(genealogicalDataCommunicationRelation.FamilyIndex, out relations))
|
|
throw new NotSupportedException();
|
|
}
|
|
relations.Add(genealogicalDataCommunicationRelation);
|
|
}
|
|
return new(results);
|
|
}
|
|
|
|
internal static ReadOnlyDictionary<long, List<GenealogicalDataCommunicationRelation>> GetCollection(string personBirthdayFormat, List<GenealogicalDataCommunicationRelation> genealogicalDataCommunicationRelations)
|
|
{
|
|
Dictionary<long, List<GenealogicalDataCommunicationRelation>> results = new();
|
|
long personKey;
|
|
string personKeyFormatted;
|
|
Models.PersonBirthday? personBirthday;
|
|
List<GenealogicalDataCommunicationRelation>? collection;
|
|
foreach (GenealogicalDataCommunicationRelation genealogicalDataCommunicationRelation in genealogicalDataCommunicationRelations)
|
|
{
|
|
personKeyFormatted = genealogicalDataCommunicationRelation.NickName;
|
|
personBirthday = IPersonBirthday.GetPersonBirthday(personBirthdayFormat, personKeyFormatted);
|
|
if (personBirthday is null)
|
|
continue;
|
|
personKey = personBirthday.Value.Ticks;
|
|
if (!results.TryGetValue(personKey, out collection))
|
|
{
|
|
results.Add(personKey, new());
|
|
if (!results.TryGetValue(personKey, out collection))
|
|
throw new NotSupportedException();
|
|
}
|
|
collection.Add(genealogicalDataCommunicationRelation);
|
|
}
|
|
return new(results);
|
|
}
|
|
|
|
internal static ReadOnlyDictionary<long, List<GenealogicalDataCommunicationRelation>> GetCollection(string personBirthdayFormat, ReadOnlyDictionary<int, List<GenealogicalDataCommunicationRelation>> familyIndexToCollection)
|
|
{
|
|
Dictionary<long, List<GenealogicalDataCommunicationRelation>> results = new();
|
|
long personKey;
|
|
string personKeyFormatted;
|
|
Models.PersonBirthday? personBirthday;
|
|
List<GenealogicalDataCommunicationRelation>? collection;
|
|
foreach (KeyValuePair<int, List<GenealogicalDataCommunicationRelation>> keyValuePair in familyIndexToCollection)
|
|
{
|
|
foreach (GenealogicalDataCommunicationRelation genealogicalDataCommunicationRelation in keyValuePair.Value)
|
|
{
|
|
personKeyFormatted = genealogicalDataCommunicationRelation.NickName;
|
|
personBirthday = IPersonBirthday.GetPersonBirthday(personBirthdayFormat, personKeyFormatted);
|
|
if (personBirthday is null)
|
|
continue;
|
|
personKey = personBirthday.Value.Ticks;
|
|
if (!results.TryGetValue(personKey, out collection))
|
|
{
|
|
results.Add(personKey, new());
|
|
if (!results.TryGetValue(personKey, out collection))
|
|
throw new NotSupportedException();
|
|
}
|
|
collection.Add(genealogicalDataCommunicationRelation);
|
|
}
|
|
}
|
|
return new(results);
|
|
}
|
|
|
|
internal static string GetMergeWithLineTwo(GenealogicalDataCommunicationRelation genealogicalDataCommunicationRelation, GenealogicalDataCommunicationRelation relation)
|
|
{
|
|
string result;
|
|
const char father = 'F';
|
|
const char mother = 'M';
|
|
string wife = IGenealogicalDataCommunication.Wife;
|
|
string husband = IGenealogicalDataCommunication.Husband;
|
|
if (string.IsNullOrEmpty(genealogicalDataCommunicationRelation.LineTwo))
|
|
{
|
|
if (relation.Relation == wife)
|
|
result = nameof(mother);
|
|
else if (relation.Relation == husband)
|
|
result = nameof(father);
|
|
else
|
|
result = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
StringBuilder stringBuilder = new();
|
|
if (genealogicalDataCommunicationRelation.LineTwo[1] == father)
|
|
{
|
|
if (relation.Relation == wife)
|
|
_ = stringBuilder.Append(nameof(mother));
|
|
else if (relation.Relation == husband)
|
|
_ = stringBuilder.Append(genealogicalDataCommunicationRelation.LineTwo.Split(' ').Last()).Append(' ').Append(nameof(father));
|
|
}
|
|
else if (genealogicalDataCommunicationRelation.LineTwo[1] == mother)
|
|
{
|
|
if (relation.Relation == husband)
|
|
_ = stringBuilder.Append(nameof(father));
|
|
else if (relation.Relation == wife)
|
|
_ = stringBuilder.Append(genealogicalDataCommunicationRelation.LineTwo.Split(' ').Last()).Append(' ').Append(nameof(mother));
|
|
}
|
|
result = stringBuilder.ToString();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static void WriteAll(long ticks, string a2PeopleContentDirectory, List<string[]> frontMatterLinesCollections, string weekOfYear)
|
|
{
|
|
string json;
|
|
string[] segments;
|
|
string? directory;
|
|
string frontMatterLastLine;
|
|
DateTime dateTime = new(ticks);
|
|
List<string> allFrontMatterLines = new();
|
|
foreach (string[] frontMatterLines in frontMatterLinesCollections)
|
|
{
|
|
allFrontMatterLines.Add("{");
|
|
frontMatterLastLine = frontMatterLines.Last();
|
|
foreach (string frontMatterLine in frontMatterLines)
|
|
{
|
|
segments = frontMatterLine.Split(": ");
|
|
if (segments.Length != 2)
|
|
continue;
|
|
if (frontMatterLine == frontMatterLastLine)
|
|
allFrontMatterLines.Add($"\"{string.Join("\": ", segments)}");
|
|
else
|
|
allFrontMatterLines.Add($"\"{string.Join("\": ", segments)},");
|
|
}
|
|
allFrontMatterLines.Add("},");
|
|
}
|
|
directory = Path.Combine(a2PeopleContentDirectory, $"{dateTime.Year}-Markdown", $"{dateTime.Year}-Week-{weekOfYear}", ticks.ToString());
|
|
if (!Directory.Exists(directory))
|
|
_ = Directory.CreateDirectory(directory);
|
|
json = $"[{string.Join(Environment.NewLine, allFrontMatterLines.ToArray(), 0, allFrontMatterLines.Count - 1)}{allFrontMatterLines.Last()[..^1]}]";
|
|
Models.GenealogicalDataCommunication[]? genealogicalDataCommunications = JsonSerializer.Deserialize(json, GenealogicalDataCommunicationSourceCollectionGenerationContext.Default.GenealogicalDataCommunicationArray);
|
|
if (genealogicalDataCommunications is null)
|
|
throw new NullReferenceException(nameof(genealogicalDataCommunications));
|
|
json = JsonSerializer.Serialize(genealogicalDataCommunications, GenealogicalDataCommunicationSourceCollectionGenerationContext.Default.GenealogicalDataCommunicationArray);
|
|
_ = IPath.WriteAllText(Path.Combine(directory, $"{ticks}.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
|
}
|
|
|
|
internal static void MaybeWriteMarkDownFiles(string mappingDefaultName, string personBirthdayFormat, long ticks, ReadOnlyCollection<Models.PersonContainer> personContainers, ReadOnlyDictionary<string, string[]> individuals, ReadOnlyDictionary<int, List<GenealogicalDataCommunicationRelation>> familyIndexToCollection, string a2PeopleContentDirectory)
|
|
{
|
|
bool? male;
|
|
bool? first;
|
|
string fullName;
|
|
string[]? lines;
|
|
string[] matches;
|
|
string? directory;
|
|
bool isDefaultName;
|
|
const int zero = 0;
|
|
string personKeyFormatted;
|
|
string lowerHyphenFullName;
|
|
List<string> frontMatterLines;
|
|
string pattern = "[^a-z0-9-]";
|
|
DateTime dateTime = new(ticks);
|
|
Calendar calendar = new CultureInfo("en-US").Calendar;
|
|
List<(string? Id, string[] FrontMatterLines)> collection = new();
|
|
Models.GenealogicalDataCommunication genealogicalDataCommunication;
|
|
GenealogicalDataCommunicationLines? genealogicalDataCommunicationLines;
|
|
string weekOfYear = calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
|
|
ReadOnlyDictionary<string, string> personKeyFormattedToPersonFullName = IPersonContainer.GetPersonKeyFormattedToPersonFullName(personBirthdayFormat, personContainers);
|
|
foreach (Models.PersonContainer personContainer in personContainers.OrderByDescending(l => l.Key))
|
|
{
|
|
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Person is null || personContainer.PersonDirectory is null || personContainer.Birthdays.Length == 0)
|
|
continue;
|
|
male = personContainer.PersonDirectory.Sex == 'U' ? null : personContainer.PersonDirectory.Sex == 'M' || (personContainer.PersonDirectory.Sex == 'F' ? false : throw new Exception());
|
|
first = personContainer.PersonDirectory.First == 'U' ? null : personContainer.PersonDirectory.First == 'Y' || (personContainer.PersonDirectory.First == 'N' ? false : throw new Exception());
|
|
if (first is null)
|
|
continue;
|
|
isDefaultName = IPerson.IsDefaultName(mappingDefaultName, personContainer.DisplayDirectoryName);
|
|
personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personContainer.Key.Value);
|
|
matches = (from l in personContainer.DisplayDirectoryAllFiles where l.Contains(personKeyFormatted) select l).ToArray();
|
|
if (!matches.Any())
|
|
continue;
|
|
directory = Path.GetDirectoryName(matches[zero]);
|
|
if (directory is null)
|
|
continue;
|
|
if (!individuals.TryGetValue(personKeyFormatted, out lines))
|
|
continue;
|
|
genealogicalDataCommunicationLines = lines is null ? null : GetGenealogicalDataCommunicationLines(personContainer.Birthdays[zero], lines);
|
|
if (genealogicalDataCommunicationLines is null)
|
|
continue;
|
|
genealogicalDataCommunication = GetGenealogicalDataCommunication(first.Value, genealogicalDataCommunicationLines);
|
|
if (genealogicalDataCommunication.Sex != personContainer.PersonDirectory.Sex)
|
|
continue;
|
|
if (genealogicalDataCommunication.Birth is not null && !directory.EndsWith(genealogicalDataCommunication.Birth.Value.Hour.ToString()))
|
|
continue;
|
|
if (genealogicalDataCommunication.Death is null && personContainer.PersonDirectory.Status == 'D' || genealogicalDataCommunication.Death is not null && personContainer.PersonDirectory.Status == 'A')
|
|
continue;
|
|
fullName = PersonName.GetFullName(personContainer.Person.Name);
|
|
lowerHyphenFullName = $"{Regex.Replace(fullName.ToLower(), pattern, "-")}";
|
|
frontMatterLines = MarkDown.GetFrontMatterLines(ticks, fullName, lowerHyphenFullName, genealogicalDataCommunication);
|
|
if (!frontMatterLines.Any())
|
|
continue;
|
|
collection.Add((genealogicalDataCommunication.Id, frontMatterLines.ToArray()));
|
|
MarkDown.WriteFile(personKeyFormatted, ticks, a2PeopleContentDirectory, calendar, pattern, personKeyFormattedToPersonFullName, familyIndexToCollection, genealogicalDataCommunication, fullName, lowerHyphenFullName, frontMatterLines);
|
|
}
|
|
if (collection.Any())
|
|
{
|
|
List<string[]> frontMatterLinesCollections = (from l in collection orderby l.Id.Length, l.Id where l.Id is not null select l.FrontMatterLines).ToList();
|
|
WriteAll(ticks, a2PeopleContentDirectory, frontMatterLinesCollections, weekOfYear);
|
|
}
|
|
}
|
|
|
|
} |