Genealogical Data Communication but
I still am dependant on directory
This commit is contained in:
parent
03e2a4ecfb
commit
02445261fe
634
Helpers/HelperGenealogicalDataCommunication.cs
Normal file
634
Helpers/HelperGenealogicalDataCommunication.cs
Normal file
@ -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<long, string[]> IndividualsLines,
|
||||
List<string[]> FamilyGroupLines,
|
||||
ReadOnlyDictionary<long, int> 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<string> 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<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<long, string[]> Convert(Dictionary<long, List<string>> keyValuePairs)
|
||||
{
|
||||
Dictionary<long, string[]> results = new();
|
||||
foreach (KeyValuePair<long, List<string>> 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<string> lines = new();
|
||||
const string startsWith = "0 @";
|
||||
List<string> footerLines = new();
|
||||
List<string[]> familyGroupLines = new();
|
||||
Dictionary<long, int> personKeyToId = new();
|
||||
ReadOnlyDictionary<long, string[]> individualsLines;
|
||||
Dictionary<long, List<string>> keyValuePairs = new();
|
||||
int length = appSettings.PersonBirthdayFormat.Length;
|
||||
string[] sourceLines = string.IsNullOrEmpty(input.GenealogicalDataCommunicationFile) || !File.Exists(input.GenealogicalDataCommunicationFile) ? Array.Empty<string>() : 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<string> GetDirectoryNames(string directory)
|
||||
{
|
||||
List<string> 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<PersonDirectory> GetPersonDirectoriesNull(AppSettings appSettings, Input input)
|
||||
{
|
||||
List<PersonDirectory> results = new();
|
||||
DateTime? birthday;
|
||||
string directoryName;
|
||||
string subDirectoryName;
|
||||
List<string> directoryNames;
|
||||
IEnumerable<string> 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<string> GetNotes(PersonDirectory personDirectory)
|
||||
{
|
||||
List<string> 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<PersonDirectory> GetPersonDirectories(AppSettings appSettings, ReadOnlyDictionary<string, List<PersonDirectory>> keyValuePairs)
|
||||
{
|
||||
List<PersonDirectory> results = new();
|
||||
PersonDirectory[] sorted;
|
||||
List<string> notes = new();
|
||||
PersonDirectory personDirectory;
|
||||
List<string> birthdayNotes = new();
|
||||
foreach (KeyValuePair<string, List<PersonDirectory>> 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<string, List<PersonDirectory>> Convert(List<PersonDirectory> collection)
|
||||
{
|
||||
Dictionary<string, List<PersonDirectory>> results = new();
|
||||
string personDisplayDirectoryName;
|
||||
List<PersonDirectory>? 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<PersonDirectory> GetPersonDirectories(AppSettings appSettings, Input input)
|
||||
{
|
||||
List<PersonDirectory> results;
|
||||
string[] segments;
|
||||
PersonName personName;
|
||||
PersonHour? personHour;
|
||||
string personDisplayDirectoryName;
|
||||
List<PersonDirectory> collection = new();
|
||||
List<PersonDirectory> 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<string, List<PersonDirectory>> keyValuePairs = Convert(collection);
|
||||
results = GetPersonDirectories(appSettings, keyValuePairs);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static Dictionary<long, int> GetCopyOfPersonKeyToId(GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections)
|
||||
{
|
||||
Dictionary<long, int> results = new();
|
||||
foreach (KeyValuePair<long, int> keyValuePair in genealogicalDataCommunicationCollections.PersonKeyToId)
|
||||
results.Add(keyValuePair.Key, keyValuePair.Value);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, string[]> GetIndividualsLines(AppSettings appSettings, GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections, ReadOnlyCollection<PersonDirectory> personDirectories)
|
||||
{
|
||||
Dictionary<int, string[]> results = new();
|
||||
int id;
|
||||
string suffix;
|
||||
string segmentsFirst;
|
||||
List<string> lines = new();
|
||||
string personDisplayDirectoryName;
|
||||
Dictionary<long, int> 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<int, string[]> individualsLines)
|
||||
{
|
||||
if (input.GenealogicalDataCommunicationDirectory is not null)
|
||||
{
|
||||
List<string> lines = new();
|
||||
List<string> 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<string> keyValuePair in from l in individualsLines orderby l.Key select l.Value)
|
||||
allLines.AddRange(keyValuePair);
|
||||
}
|
||||
if (genealogicalDataCommunicationCollections.IndividualsLines.Count > 0)
|
||||
{
|
||||
lines.Clear();
|
||||
foreach (KeyValuePair<long, string[]> 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<PersonDirectory> personDirectories, ReadOnlyDictionary<int, string[]> 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<string>();
|
||||
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<string>();
|
||||
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<Worker> logger, List<string> 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<PersonDirectory> personDirectories = GetPersonDirectories(appSettings, input);
|
||||
ReadOnlyDictionary<int, string[]> 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);
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,8 @@ public record AppSettings(string Company,
|
||||
string DefaultNoteType,
|
||||
string[] ExcludeDirectoryNames,
|
||||
string[] ExcludeSchemes,
|
||||
string PersonBirthdayFormat,
|
||||
char[] PersonCharacters,
|
||||
string WorkingDirectoryName)
|
||||
{
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user