diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 7b98f0d..2170311 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -971,7 +971,7 @@ public partial class DlibDotNet string file; List<(long PersonKey, string File)> collection = new(); List> results = new(); - collection.AddRange(Map.Models.Stateless.Methods.IMapLogic.GetDisplayDirectoryAllFiles(_PersonContainers)); + collection.AddRange(Map.Models.Stateless.Methods.IMapLogic.GetDisplayDirectoryAllFiles(_Faces.FileNameExtension, _PersonContainers)); collection.AddRange(Map.Models.Stateless.Methods.IMapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(_MapConfiguration, _PersonContainers, ticks, a2PeopleContentDirectory, eDistanceContentDirectory)); for (int i = 0; i < collection.Count; i++) { @@ -1043,6 +1043,66 @@ public partial class DlibDotNet } } + private void CreateTree(PersonContainer[] personContainers, long ticks, string a2PeopleContentDirectory, Dictionary> personKeyToIds) + { + string by; + string directory; + string[] matches; + string[] segments; + const int zero = 0; + string[] pGedFiles; + string personKeyFormatted; + List distinct = new(); + PersonBirthday personBirthday; + string rootDirectory = Path.Combine(a2PeopleContentDirectory, $"{ticks}-Tree"); + List lines = new() + { + "0 HEAD", + "1 SOUR DlibDotNet", + $"1 FILE {ticks}", + $"1 DATE {new DateTime(ticks):dd MMM yyyy}", + "1 DEST ANSTFILE", + "1 GEDC", + "2 VERS 5.5.1", + "2 FORM LINEAGE-LINKED", + "1 SUBM @1980-01-17_00@", + "2 NAME Mike Phares Jr", + "1 SUBN", + }; + foreach (PersonContainer personContainer in personContainers) + { + if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Person is null || !personContainer.Birthdays.Any()) + continue; + if (personContainer.DisplayDirectoryName == _Configuration.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 = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday); + by = Shared.Models.Stateless.Methods.IPersonBirthday.IsCounterPersonBirthday(personBirthday) ? _Configuration.PropertyConfiguration.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; + lines.AddRange(File.ReadAllLines(pGedFiles[0])); + 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.Add("0 TRLR"); + File.WriteAllLines(Path.Combine(a2PeopleContentDirectory, $"{ticks}.ged"), lines); + } + private void Search(long ticks, string argZero, string propertyRoot) { int t; @@ -1099,8 +1159,10 @@ public partial class DlibDotNet propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory); } containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, _ArgZeroIsConfigurationRootDirectory, argZero, containers); - MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, _PersonContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory); + MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _PersonContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory); personKeyToIds = mapLogic.GetPersonKeyToIds(); + if (a2PeopleContentDirectory is not null) + CreateTree(_PersonContainers, ticks, a2PeopleContentDirectory, personKeyToIds); fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory); Dictionary>> idToLocationContainers = GetDictionary(ticks, a2PeopleContentDirectory, eDistanceContentDirectory); FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, eDistanceContentDirectory, fileNameToCollection, idToLocationContainers, mapLogic); @@ -1113,8 +1175,6 @@ public partial class DlibDotNet int totalNotMapped = mapLogic.UpdateMappingFromPerson(mappingCollection); string json = System.Text.Json.JsonSerializer.Serialize(mappingCollection); File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json); - if (a2PeopleContentDirectory is not null && false) - mapLogic.CreateTree(ticks, a2PeopleContentDirectory); foreach (string outputResolution in _Configuration.OutputResolutions) { if (_PropertyRootExistedBefore || container is not null) diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 7b60440..e5cb31c 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -28,7 +28,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic private readonly string _EDistanceContentTicksDirectory; private readonly Shared.Models.Properties.IPropertyConfiguration _PropertyConfiguration; - public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) + public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, PersonContainer[] personContainers, long ticks, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) { _Ticks = ticks; _Configuration = configuration; @@ -102,37 +102,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic return result; } - public void CreateTree(long ticks, string a2PeopleContentDirectory) - { - if (_Configuration is null) - throw new NullReferenceException(nameof(_Configuration)); - string by; - string directory; - string[] segments; - const int zero = 0; - string personKeyFormatted; - PersonBirthday personBirthday; - string rootDirectory = Path.Combine(a2PeopleContentDirectory, $"{ticks}-Tree"); - foreach (KeyValuePair personKeyToPersonContainer in _PersonKeyToPersonContainer) - { - if (personKeyToPersonContainer.Value.Key is null || personKeyToPersonContainer.Value.Birthdays is null || !personKeyToPersonContainer.Value.Birthdays.Any()) - continue; - if (personKeyToPersonContainer.Value.DisplayDirectoryName == _Configuration.MappingDefaultName) - continue; - personBirthday = personKeyToPersonContainer.Value.Birthdays[zero]; - personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday); - by = IPersonBirthday.IsCounterPersonBirthday(personBirthday) ? _PropertyConfiguration.ResultAllInOne : "People"; - segments = personKeyToPersonContainer.Value.DisplayDirectoryName.Split(_Configuration.PersonCharacters.ToArray()); - if (segments.Length < 2) - directory = Path.Combine(rootDirectory, $"000 {personKeyFormatted} {personKeyToPersonContainer.Value.DisplayDirectoryName}"); - else - directory = Path.Combine(rootDirectory, $"{segments[1].PadLeft(3, '0')} {personKeyFormatted} {personKeyToPersonContainer.Value.DisplayDirectoryName}"); - if (Directory.Exists(directory)) - continue; - _ = Directory.CreateDirectory(directory); - } - } - public Dictionary> GetPersonKeyToIds() { Dictionary> results = new(); diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index b58dc95..1437e35 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -172,7 +172,7 @@ internal abstract class MapLogic } foreach (string file in files) { - if (file.EndsWith(".lnk") || file.EndsWith(".json")) + if (file.EndsWith(".lnk")) continue; (id, normalizedRectangle) = IMapping.GetConverted(configuration.FacesFileNameExtension, file); if (id is null || normalizedRectangle is null) @@ -281,7 +281,7 @@ internal abstract class MapLogic { PersonBirthday? personBirthday; PersonContainer[] distinctPersonContainers; - List<(long, PersonContainer)> collection = GetDistinctCollection(configuration, personContainers, personKeyToPersonContainerCollection, personKeyFormattedToPersonContainer); + (long, PersonContainer)[] collection = GetDistinctCollection(configuration, personContainers, personKeyToPersonContainerCollection, personKeyFormattedToPersonContainer); foreach ((long personKey, PersonContainer personContainer) in collection) personKeyToPersonContainer.Add(personKey, personContainer); Dictionary>> idThenNormalizedRectangleToPersonContainerCollection = new(); @@ -325,11 +325,12 @@ internal abstract class MapLogic }; } - private static List<(long, PersonContainer)> GetDistinctCollection(Configuration configuration, IEnumerable personContainers, Dictionary> personKeyToPersonContainerCollection, Dictionary personKeyFormattedToPersonContainer) + private static (long, PersonContainer)[] GetDistinctCollection(Configuration configuration, IEnumerable personContainers, Dictionary> personKeyToPersonContainerCollection, Dictionary personKeyFormattedToPersonContainer) { - List<(long, PersonContainer)> results = new(); + (long, PersonContainer)[] results; const int zero = 0; string newestPersonKeyFormatted; + List<(long PersonKey, PersonContainer PersonContainer)> collection = new(); foreach (PersonContainer personContainer in personContainers) { if (personContainer.Key is null) @@ -345,8 +346,9 @@ internal abstract class MapLogic { if (keyValuePair.Value.Count != 1 && (from l in keyValuePair.Value select l.DisplayDirectoryName).Distinct().Count() != 1) throw new NotSupportedException(keyValuePair.Value[zero].DisplayDirectoryName); - results.Add(new(keyValuePair.Key, keyValuePair.Value[zero])); + collection.Add(new(keyValuePair.Key, keyValuePair.Value[zero])); } + results = (from l in collection orderby l.PersonKey descending select (l.PersonKey, l.PersonContainer)).ToArray(); return results; } @@ -694,7 +696,7 @@ internal abstract class MapLogic } } - internal static List<(long, string)> GetDisplayDirectoryAllFiles(PersonContainer[] personContainers) + internal static List<(long, string)> GetDisplayDirectoryAllFiles(string fileNameExtension, PersonContainer[] personContainers) { List<(long, string)> results = new(); List distinct = new(); @@ -704,7 +706,7 @@ internal abstract class MapLogic continue; foreach (string displayDirectoryAllFile in personContainer.DisplayDirectoryAllFiles) { - if (displayDirectoryAllFile.EndsWith(".json")) + if (!displayDirectoryAllFile.EndsWith(fileNameExtension)) continue; if (distinct.Contains(displayDirectoryAllFile)) continue; diff --git a/Map/Models/Stateless/Methods/IMapLogic.cs b/Map/Models/Stateless/Methods/IMapLogic.cs index 0c37ecb..e43d041 100644 --- a/Map/Models/Stateless/Methods/IMapLogic.cs +++ b/Map/Models/Stateless/Methods/IMapLogic.cs @@ -8,10 +8,10 @@ public interface IMapLogic static Dictionary> GetIdToPersonKeys(Dictionary> personKeyToIds) => MapLogic.GetIdToPersonKeys(personKeyToIds); - List<(long, string)> TestStatic_GetDisplayDirectoryAllFiles(Shared.Models.PersonContainer[] personContainers) => - GetDisplayDirectoryAllFiles(personContainers); - static List<(long, string)> GetDisplayDirectoryAllFiles(Shared.Models.PersonContainer[] personContainers) => - MapLogic.GetDisplayDirectoryAllFiles(personContainers); + List<(long, string)> TestStatic_GetDisplayDirectoryAllFiles(string fileNameExtension, Shared.Models.PersonContainer[] personContainers) => + GetDisplayDirectoryAllFiles(fileNameExtension, personContainers); + static List<(long, string)> GetDisplayDirectoryAllFiles(string fileNameExtension, Shared.Models.PersonContainer[] personContainers) => + MapLogic.GetDisplayDirectoryAllFiles(fileNameExtension, personContainers); Shared.Models.Mapping[] TestStatic_GetSelectedMappingCollection(List distinctFilteredFaces) => GetSelectedMappingCollection(distinctFilteredFaces); diff --git a/Shared/Models/Stateless/Methods/IPerson.cs b/Shared/Models/Stateless/Methods/IPerson.cs index a6b01dd..6cecc7f 100644 --- a/Shared/Models/Stateless/Methods/IPerson.cs +++ b/Shared/Models/Stateless/Methods/IPerson.cs @@ -13,11 +13,11 @@ public interface IPerson Models.Person TestStatic_GetPerson(char[] personCharacters, string personDisplayDirectoryName, long personKey, Models.PersonBirthday personBirthday) => GetPerson(personCharacters, personDisplayDirectoryName, personKey, personBirthday); static Models.Person GetPerson(char[] personCharacters, string personDisplayDirectoryName, long personKey, Models.PersonBirthday personBirthday) => - Person.GetPerson(personKey, personBirthday, personDisplayDirectoryName.Split(personCharacters)); + Person.GetPerson(Array.Empty(), null, personKey, personBirthday, personDisplayDirectoryName.Split(personCharacters)); - Models.Person TestStatic_GetPerson(long personKey, string[] segments) => - GetPerson(personKey, segments); - static Models.Person GetPerson(long personKey, string[] segments) => - Person.GetPerson(personKey, IPersonBirthday.GetPersonBirthday(personKey), segments); + Models.Person TestStatic_GetPerson(string[] personDisplayDirectoryAllFiles, string personKeyFormatted, long personKey, string[] segments) => + GetPerson(personDisplayDirectoryAllFiles, personKeyFormatted, personKey, segments); + static Models.Person GetPerson(string[] personDisplayDirectoryAllFiles, string personKeyFormatted, long personKey, string[] segments) => + Person.GetPerson(personDisplayDirectoryAllFiles, personKeyFormatted, personKey, IPersonBirthday.GetPersonBirthday(personKey), segments); } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/Person.cs b/Shared/Models/Stateless/Methods/Person.cs index e1f76b0..5452e00 100644 --- a/Shared/Models/Stateless/Methods/Person.cs +++ b/Shared/Models/Stateless/Methods/Person.cs @@ -1,3 +1,5 @@ +using System.Text; + namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class Person @@ -15,7 +17,42 @@ internal abstract class Person return new(personBirthday, personKeyFormatted); } - internal static Models.Person GetPerson(long personKey, Models.PersonBirthday personBirthday, string[] segments) + private static void WriteGedFile(string? personKeyFormatted, Models.PersonBirthday personBirthday, Models.PersonName name, string[] matches) + { + string[] pGedFiles = (from l in matches where l.EndsWith(".pged") select l).ToArray(); + if (!pGedFiles.Any()) + { + StringBuilder stringBuilder = new(); + _ = stringBuilder.Append("0 @I").Append(personKeyFormatted).AppendLine("@ INDI"); + _ = stringBuilder.Append("1 NAME ").Append(name.First.Value).Append(" /").Append(name.Last.Value).AppendLine("/"); + if (!string.IsNullOrEmpty(name.First.Value)) + _ = stringBuilder.Append("2 GIVN ").AppendLine(name.First.Value); + if (!string.IsNullOrEmpty(name.Last.Value)) + _ = stringBuilder.Append("2 SURN ").AppendLine(name.Last.Value); + if (!string.IsNullOrEmpty(name.Alias.Value)) + { + _ = stringBuilder.Append("2 NICK ").AppendLine(name.Alias.Value); + if (name.Alias.Value.Contains(" Jr")) + _ = stringBuilder.Append("2 NSFX ").AppendLine("Jr"); + else if (name.Alias.Value.Contains(" Sr")) + _ = stringBuilder.Append("2 NSFX ").AppendLine("Sr"); + } + _ = stringBuilder.AppendLine("1 SEX U"); + if (!IPersonBirthday.IsCounterPersonBirthday(personBirthday)) + { + _ = stringBuilder.AppendLine("1 BIRT"); + _ = stringBuilder.Append("2 DATE ").AppendLine(personBirthday.Value.ToString("dd MMM yyyy")); + } + string? directory = Path.GetDirectoryName(matches[0]); + if (directory is null) + throw new Exception(); + if (!Directory.Exists(directory)) + _ = Directory.CreateDirectory(directory); + File.WriteAllText(Path.Combine(directory, $"{personKeyFormatted}.pged"), stringBuilder.ToString()); + } + } + + internal static Models.Person GetPerson(string[] personDisplayDirectoryAllFiles, string? personKeyFormatted, long personKey, Models.PersonBirthday personBirthday, string[] segments) { Models.Person result; const int zero = 0; @@ -26,6 +63,9 @@ internal abstract class Person 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 (matches.Any()) + WriteGedFile(personKeyFormatted, personBirthday, name, matches); result = new(id, personBirthday, name, comments, urls, numbers, emails, addresses); return result; } diff --git a/Shared/Models/Stateless/Methods/PersonBirthday.cs b/Shared/Models/Stateless/Methods/PersonBirthday.cs index 47dd7a3..f1d083a 100644 --- a/Shared/Models/Stateless/Methods/PersonBirthday.cs +++ b/Shared/Models/Stateless/Methods/PersonBirthday.cs @@ -27,7 +27,7 @@ internal abstract class PersonBirthday internal static bool IsCounterPersonBirthday(Models.PersonBirthday personBirthday) { bool result; - if (personBirthday.Value.Year < 1826) + if (personBirthday.Value.Year < 1809) result = true; else result = false; diff --git a/Shared/Models/Stateless/Methods/PersonContainer.cs b/Shared/Models/Stateless/Methods/PersonContainer.cs index 242dabb..e4bf9e2 100644 --- a/Shared/Models/Stateless/Methods/PersonContainer.cs +++ b/Shared/Models/Stateless/Methods/PersonContainer.cs @@ -15,7 +15,7 @@ internal abstract class PersonContainer if (personDisplayDirectoryAllFile.EndsWith(".lnk")) continue; (id, normalizedRectangle) = IMapping.GetConverted(facesFileNameExtension, personDisplayDirectoryAllFile); - if (id is not null && normalizedRectangle is not null && !personDisplayDirectoryAllFile.EndsWith(".json")) + if (id is not null && normalizedRectangle is not null) continue; checkDirectory = Path.GetDirectoryName(personDisplayDirectoryAllFile); if (string.IsNullOrEmpty(checkDirectory)) @@ -55,7 +55,7 @@ internal abstract class PersonContainer continue; personKey = orderedPersonBirthdays[zero].Value.Ticks; } - person = IPerson.GetPerson(personKey, segments); + person = IPerson.GetPerson(personDisplayDirectoryAllFiles, personKeyFormatted, personKey, segments); personContainer = new(approximateYears, @char, person, orderedPersonBirthdays, personDisplayDirectoryAllFiles, personDisplayDirectoryName, personKey); results.Add(new(personKey, personContainer)); }