From 1594783c7dfdfdbac90c830db8367b32bbe12d33 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Sun, 30 Jul 2023 22:53:56 -0700 Subject: [PATCH] Removed VerifyPersonContainersDisplayDirectoryAllFiles, SaveOne, SaveParents, GetRelations, CleanDisplayDirectoryAllFilesAndWriteTicksGed --- .kanbn/index.md | 3 +- ...down-to-genealogical-data-communication.md | 2 +- .kanbn/tasks/ged-as-golden.md | 15 + .vscode/tasks.json | 6 + Instance/DlibDotNet.cs | 49 +-- Map/Models/MapLogic.cs | 11 +- Map/Models/Stateless/MapLogic.cs | 289 ++++++++---------- ...enealogicalDataCommunicationCollections.cs | 19 ++ Shared/Models/PersonContainer.cs | 4 +- .../Methods/GenealogicalDataCommunication.cs | 167 +++------- .../Methods/IGenealogicalDataCommunication.cs | 29 +- Shared/Models/Stateless/Methods/IPerson.cs | 32 ++ .../Stateless/Methods/PersonBirthday.cs | 4 - .../Stateless/Methods/PersonContainer.cs | 49 +-- Tests/UnitTestHardCoded.cs | 17 +- 15 files changed, 312 insertions(+), 384 deletions(-) create mode 100644 .kanbn/tasks/ged-as-golden.md create mode 100644 Shared/Models/GenealogicalDataCommunicationCollections.cs diff --git a/.kanbn/index.md b/.kanbn/index.md index 1243a9d..0660f64 100644 --- a/.kanbn/index.md +++ b/.kanbn/index.md @@ -22,6 +22,7 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g - [image-size-distribution-per-exif-model-directory-when-no-model](tasks/image-size-distribution-per-exif-model-directory-when-no-model.md) - [skip-metadata-load-after-first-each-day](tasks/skip-metadata-load-after-first-each-day.md) - [cluster-questioning](tasks/cluster-questioning.md) +- [console-for-markdown-to-genealogical-data-communication](tasks/console-for-markdown-to-genealogical-data-communication.md) ## Todo @@ -35,7 +36,7 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g - [merge-kristy-files](tasks/merge-kristy-files.md) - [set-date-taken-when-missing](tasks/set-date-taken-when-missing.md) -- [console-for-markdown-to-genealogical-data-communication](tasks/console-for-markdown-to-genealogical-data-communication.md) +- [ged-as-golden](tasks/ged-as-golden.md) ## Done diff --git a/.kanbn/tasks/console-for-markdown-to-genealogical-data-communication.md b/.kanbn/tasks/console-for-markdown-to-genealogical-data-communication.md index 1011a14..2f32b1e 100644 --- a/.kanbn/tasks/console-for-markdown-to-genealogical-data-communication.md +++ b/.kanbn/tasks/console-for-markdown-to-genealogical-data-communication.md @@ -1,6 +1,6 @@ --- created: "2023-07-21T18:26:38.894Z" -updated: "2023-07-22T06:43:30.988Z" +updated: "2023-07-30T04:45:55.208Z" assigned: "" progress: 0 started: "2023-07-21T04:38:02.640Z" diff --git a/.kanbn/tasks/ged-as-golden.md b/.kanbn/tasks/ged-as-golden.md new file mode 100644 index 0000000..bdd46ec --- /dev/null +++ b/.kanbn/tasks/ged-as-golden.md @@ -0,0 +1,15 @@ +--- +created: 2023-07-30T04:46:47.436Z +updated: 2023-07-30T04:46:47.431Z +assigned: "" +progress: 0 +tags: [] +started: 2023-07-30T04:46:47.436Z +--- + +# GED as Golden + +[ ] From directories create one *.pged file to compare +[x] From *.rmtree file export *.ged file +[ ] Read *.ged and write five files +[?] Create directories to compare with current \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 05a6b7d..d0e1772 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -59,6 +59,12 @@ "type": "shell", "command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s M '.kanbn/tasks'", "problemMatcher": [] + }, + { + "label": "File-Folder-Helper AOT s M Self .Kanbn Tasks", + "type": "shell", + "command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s G D:/1-Images-A/Images-dd514b88-Results/A2) People/dd514b88/{} -g D:/1-Images-A/Images-dd514b88-Results/A2) People/dd514b88/([])/Code-638160743318283885/aaa/638160743318283885.ged -d D:/1-Images-A/Images-dd514b88-Results/A2) People/dd514b88/{2}", + "problemMatcher": [] } ] } \ No newline at end of file diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 2dcc6e9..f5b809d 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -40,7 +40,6 @@ public partial class DlibDotNet private readonly Models.Configuration _Configuration; private readonly bool _ArgZeroIsConfigurationRootDirectory; private readonly Map.Models.Configuration _MapConfiguration; - private readonly ReadOnlyDictionary> _FamilyIndexToCollection; public DlibDotNet( List args, @@ -110,10 +109,7 @@ public partial class DlibDotNet _MapConfiguration = Get(configuration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension); _Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, _Configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RangeFaceConfidence, configuration.RectangleIntersectMinimums); if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory) - { personContainers = new(new List()); - _FamilyIndexToCollection = new(new Dictionary>()); - } else { int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); @@ -125,20 +121,19 @@ public partial class DlibDotNet string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People)); string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory)) ?? throw new Exception(); Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory); - _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(peopleRootDirectory, _Configuration.PropertyConfiguration.ResultSingleton)); + _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(peopleRootDirectory, propertyConfiguration.ResultSingleton)); personContainers = new(IPersonContainer.GetPersonContainers(storage, configuration.MappingDefaultName, configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), _Faces.FileNameExtension)); - (string[] headerLines, ReadOnlyDictionary individuals, List familyGroupLines, string[] footerLines, List genealogicalDataCommunicationRelations) = IGenealogicalDataCommunication.GetIndividuals(configuration.PropertyConfiguration.PersonBirthdayFormat, configuration.GenealogicalDataCommunicationFile, personContainers, requireNickName: true); - _FamilyIndexToCollection = IGenealogicalDataCommunication.GetFamilyIndexToCollection(genealogicalDataCommunicationRelations); - VerifyPersonContainersDisplayDirectoryAllFiles(); - if (!string.IsNullOrEmpty(_Configuration.GenealogicalDataCommunicationFile) && headerLines.Any() && individuals.Any() && familyGroupLines.Any() && genealogicalDataCommunicationRelations.Any() && footerLines.Any()) + GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections = IGenealogicalDataCommunication.GetIndividuals(configuration.GenealogicalDataCommunicationFile, requireNickName: true); + if (!string.IsNullOrEmpty(configuration.GenealogicalDataCommunicationFile) && genealogicalDataCommunicationCollections.HeaderLines.Any() && genealogicalDataCommunicationCollections.Individuals.Any() && genealogicalDataCommunicationCollections.FamilyGroupLines.Any() && genealogicalDataCommunicationCollections.FooterLines.Any()) { - string a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])"); + string a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration.PropertyConfiguration, nameof(A2_People), "([])"); TimeSpan a2LastWriteTimeTimeSpan = new(ticks - new DirectoryInfo(a2PeopleContentDirectory).LastWriteTime.Ticks); if (a2LastWriteTimeTimeSpan.TotalDays > 1) { - IGenealogicalDataCommunication.MaybeWriteMarkDownFiles(configuration.MappingDefaultName, configuration.PersonBirthdayFormat, ticks, personContainers, individuals, _FamilyIndexToCollection, a2PeopleContentDirectory); - if (IGenealogicalDataCommunication.CleanDisplayDirectoryAllFilesAndWriteTicksGed(_Configuration.MappingDefaultName, _Configuration.PersonBirthdayFormat, personContainers, headerLines, familyGroupLines, footerLines, ticks, a2PeopleContentDirectory)) - personContainers = new(IPersonContainer.GetPersonContainers(storage, configuration.MappingDefaultName, configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), _Faces.FileNameExtension)); + ReadOnlyDictionary> familyIndexToCollection = IGenealogicalDataCommunication.GetFamilyIndexToCollection(configuration.PersonBirthdayFormat, personContainers, genealogicalDataCommunicationCollections); + if (familyIndexToCollection.Count != 0) + IGenealogicalDataCommunication.MaybeWriteMarkDownFiles(configuration.MappingDefaultName, configuration.PersonBirthdayFormat, ticks, personContainers, genealogicalDataCommunicationCollections.Individuals, familyIndexToCollection, a2PeopleContentDirectory); + Directory.SetLastWriteTime(a2PeopleContentDirectory, new(ticks)); } } } @@ -1042,30 +1037,6 @@ public partial class DlibDotNet return results; } - private void VerifyPersonContainersDisplayDirectoryAllFiles() - { - // WindowsShortcut windowsShortcut; - // foreach (PersonContainer personContainer in personContainersB) - // { - // foreach (string file in personContainer.DisplayDirectoryAllFiles) - // { - // if (!file.EndsWith(".lnk")) - // continue; - // try - // { - // windowsShortcut = WindowsShortcut.Load(file); - // if (windowsShortcut.Path is null) - // continue; - // if (!File.Exists(windowsShortcut.Path)) - // File.Delete(file); - // windowsShortcut.Dispose(); - // } - // catch (Exception) - // { } - // } - // } - } - private static void Verify(string eDistanceContentDirectory, List distinctFilteredItems) { #if VerifyItem @@ -1189,7 +1160,7 @@ public partial class DlibDotNet if (eLastWriteTimeTimeSpan.TotalDays > 1) mapLogic = null; else - mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _FamilyIndexToCollection, personContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory); + mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, personContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory); foreach (string outputResolution in _Configuration.OutputResolutions) { if (outputResolution.Any(l => char.IsNumber(l))) @@ -1262,7 +1233,7 @@ public partial class DlibDotNet } fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory); B_Metadata metadata = new(_Configuration.PropertyConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata, bResultsFullGroupDirectory); - mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _FamilyIndexToCollection, personContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory); + mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, personContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory); containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, _ArgZeroIsConfigurationRootDirectory, argZero, containers); ReadOnlyDictionary>> idToLocationContainers = mapLogic.GetIdToLocationContainers(); FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, fileNameToCollection, idToLocationContainers, mapLogic); diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 64955d8..e160331 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -26,7 +26,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, ReadOnlyDictionary> familyIndexToCollection, ReadOnlyCollection personContainers, long ticks, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) + public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, ReadOnlyCollection personContainers, long ticks, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) { _Ticks = ticks; _Configuration = configuration; @@ -55,7 +55,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic Stateless.MapLogic.Set(maxDegreeOfParallelism, configuration, ticks, - familyIndexToCollection, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, @@ -120,7 +119,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic { foreach (PersonContainer personContainer in wholePercentagesToPersonContainers.Value) { - if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0) continue; if (personContainer.DisplayDirectoryName.Contains(@"{}\~\")) shouldMove.Add(personContainer.DisplayDirectoryName); @@ -180,7 +179,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic } foreach (PersonContainer personContainer in personContainers) { - if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0) continue; personBirthday = personContainer.Birthdays[zero]; personKey = personBirthday.Value.Ticks; @@ -354,7 +353,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic for (int i = _NotMappedPersonContainers.Count - 1; i > 0; i--) { personContainer = _NotMappedPersonContainers[i]; - if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0) continue; personBirthday = personContainer.Birthdays[zero]; mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mappingFromItem); @@ -673,7 +672,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic continue; foreach (PersonContainer personContainer in personContainers) { - if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0) continue; personBirthday = personContainer.Birthdays[zero]; personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday); diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index 48a6a19..56fd868 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -3,7 +3,6 @@ using ShellProgressBar; using System.Collections.ObjectModel; using System.Diagnostics; using System.Drawing; -using System.Text.Json; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Stateless.Methods; using WindowsShortcutFactory; @@ -17,6 +16,12 @@ internal abstract class MapLogic string[] PersonDisplayDirectoryNames, string MappedFaceFile); + private record PersonKeyFormattedIdThenWholePercentages(string PersonKeyFormatted, + string[] PersonDisplayDirectoryNames, + string MappedFaceFile, + int Id, + int WholePercentages); + private static void SetPersonCollections(Configuration configuration, ReadOnlyCollection personContainers, string? a2PeopleSingletonDirectory, Dictionary personKeyFormattedToNewestPersonKeyFormatted, List personKeyFormattedCollection, Dictionary> skipCollection, Dictionary> skipNotSkipCollection) { int? id; @@ -47,7 +52,7 @@ internal abstract class MapLogic skipNotSkipCollection[id.Value].Add(wholePercentages.Value); } } - if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) + if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0) continue; foreach (PersonBirthday personBirthday in personContainer.Birthdays) { @@ -186,14 +191,35 @@ internal abstract class MapLogic } } + private static void MovedToNewestPersonKeyFormatted(string personKeyFormatted, string newestPersonKeyFormatted, string ticksDirectory, string personKeyDirectory) + { + string newestPersonKeyDirectory = Path.Combine(ticksDirectory, newestPersonKeyFormatted); + if (Directory.Exists(newestPersonKeyDirectory)) + MoveFiles(personKeyFormatted, personKeyDirectory, newestPersonKeyFormatted, newestPersonKeyDirectory); + else + Directory.Move(personKeyDirectory, newestPersonKeyDirectory); + } + + private static void RenameUnknown(string[] files) + { + foreach (string file in files) + { + if (file.EndsWith(".unk")) + continue; + File.Move(file, $"{file}.unk"); + } + } + private static List DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, Dictionary personKeyFormattedToNewestPersonKeyFormatted, List personKeyFormattedCollection, string[] ticksDirectories, string message) { List results = new(); int? id; + long ticks; string[] files; string fileName; + bool isNotDefault; + TimeSpan timeSpan; bool check = false; - const int zero = 0; int? wholePercentages; string[] yearDirectories; string personKeyFormatted; @@ -203,7 +229,6 @@ internal abstract class MapLogic List distinct = new(); string[] personKeyDirectories; string[] personNameDirectories; - string newestPersonKeyDirectory; string? newestPersonKeyFormatted; string[] personNameLinkDirectories; string? personFirstInitialDirectory; @@ -216,7 +241,9 @@ internal abstract class MapLogic { progressBar.Tick(); ticksDirectoryName = Path.GetFileName(ticksDirectory); - if (ticksDirectoryName.Length < 3 || ticksDirectoryName[zero] != '(' || ticksDirectoryName[^1] != ')') + if (ticksDirectoryName.Length < 3 || ticksDirectoryName.First() != '(' || ticksDirectoryName[^1] != ')') + continue; + if (!long.TryParse(ticksDirectoryName[1..^1], out ticks)) continue; personKeyDirectories = Directory.GetDirectories(ticksDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string personKeyDirectory in personKeyDirectories) @@ -228,16 +255,12 @@ internal abstract class MapLogic Individually(configuration, ticksDirectory, personKeyDirectory); throw new Exception($"B) Move personKey directories up one from {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} and delete {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} directory!"); } - if (personKeyFormattedToNewestPersonKeyFormatted.TryGetValue(personKeyFormatted, out newestPersonKeyFormatted) && personKeyFormatted != newestPersonKeyFormatted) + _ = personKeyFormattedToNewestPersonKeyFormatted.TryGetValue(personKeyFormatted, out newestPersonKeyFormatted); + if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && newestPersonKeyFormatted is null) { - if (!check) - check = true; - newestPersonKeyDirectory = Path.Combine(ticksDirectory, newestPersonKeyFormatted); - if (Directory.Exists(newestPersonKeyDirectory)) - MoveFiles(personKeyFormatted, personKeyDirectory, newestPersonKeyFormatted, newestPersonKeyDirectory); - else - Directory.Move(personKeyDirectory, newestPersonKeyDirectory); - continue; + timeSpan = new TimeSpan(DateTime.Now.Ticks - ticks); + if (timeSpan.TotalDays > 3) + throw new Exception($"{configuration.MappingDefaultName} are only allowed within x days!"); } yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string yearDirectory in yearDirectories) @@ -251,6 +274,18 @@ internal abstract class MapLogic personDisplayDirectoryNames = IPath.GetDirectoryNames(personNameDirectory); if (!personDisplayDirectoryNames.Any()) continue; + if (personDisplayDirectoryNames[^1] == "Z" && personKeyFormatted.StartsWith("140")) + { + string checkDirectory = Path.Combine(yearDirectory, $"Z]{DateTime.Now.Ticks}"); + if (Directory.Exists(checkDirectory)) + { + files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly); + RenameUnknown(files); + continue; + } + Directory.Move(personNameDirectory, checkDirectory); + continue; + } files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly); if (isReservedDirectoryName && files.Any()) throw new Exception($"Move personKey directories up one from {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} and delete {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} directory!"); @@ -258,19 +293,22 @@ internal abstract class MapLogic throw new Exception($"Move personKey directories up one from {manualCopyHumanized} and delete {manualCopyHumanized} directory!"); if (personKeyFormatted == forceSingleImageHumanized && files.Any()) throw new Exception($"Move personKey directories up one from {forceSingleImageHumanized} and delete {forceSingleImageHumanized} directory!"); - if (newestPersonKeyFormatted is null) + isNotDefault = personDisplayDirectoryNames[^1].First() != 'Z' || !personKeyFormatted.StartsWith("140"); + if (isNotDefault) { - if (!IPerson.IsDefaultName(configuration.MappingDefaultName, personDisplayDirectoryNames[^1])) + if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && newestPersonKeyFormatted is null) + RenameUnknown(files); + else if (newestPersonKeyFormatted is not null && personKeyFormatted != newestPersonKeyFormatted) { - foreach (string file in files) - File.Move(file, $"{file}.unk"); + if (!check) + check = true; + MovedToNewestPersonKeyFormatted(personKeyFormatted, newestPersonKeyFormatted, ticksDirectory, personKeyDirectory); continue; - throw new NotImplementedException("Should this happen?"); } } if (personKeyFormatted.Length != configuration.PersonBirthdayFormat.Length) continue; - if (personDisplayDirectoryNames[^1].Length == 1 || IPerson.IsDefaultName(configuration.MappingDefaultName, personDisplayDirectoryNames[^1]) || !personKeyFormattedCollection.Contains(personKeyFormatted)) + if (personDisplayDirectoryNames[^1].Length == 1 || !isNotDefault || !personKeyFormattedCollection.Contains(personKeyFormatted)) personFirstInitialDirectory = personNameDirectory; else { @@ -347,7 +385,7 @@ internal abstract class MapLogic return results.ToArray(); } - private static void SetKeyValuePairs(Configuration configuration, ReadOnlyCollection personContainers, Dictionary> personKeyToPersonContainerCollection, Dictionary personKeyFormattedToPersonContainer, List<(string, string[], int, int)> personKeyFormattedIdThenWholePercentagesCollection, Dictionary personKeyToPersonContainer, Dictionary> idThenWholePercentagesToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) + private static void SetKeyValuePairsAndAddToCollections(Configuration configuration, ReadOnlyCollection personContainers, Dictionary> personKeyToPersonContainerCollection, Dictionary personKeyFormattedToPersonContainer, List personKeyFormattedIdThenWholePercentagesCollection, Dictionary personKeyToPersonContainer, Dictionary> idThenWholePercentagesToPersonContainers, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) { PersonBirthday? personBirthday; PersonContainer[] distinctPersonContainers; @@ -357,32 +395,36 @@ internal abstract class MapLogic Dictionary>> idThenWholePercentagesToPersonContainerCollection = new(); if (personKeyFormattedIdThenWholePercentagesCollection.Any()) { - string personDisplayDirectory; + string group; + char[] matches; + char status, sex, first; PersonContainer personContainer; + PersonDirectory personDirectory; string personDisplayDirectoryName; - Dictionary personDisplayDirectoryTo = new(); - foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, int id, int wholePercentages) in personKeyFormattedIdThenWholePercentagesCollection) + foreach (PersonKeyFormattedIdThenWholePercentages personKeyFormattedIdThenWholePercentages in personKeyFormattedIdThenWholePercentagesCollection) { - personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormatted); + personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormattedIdThenWholePercentages.PersonKeyFormatted); if (personBirthday is null) continue; - personDisplayDirectoryName = personDisplayDirectoryNames[^1]; - personDisplayDirectory = Path.Combine(personDisplayDirectoryNames); - if (!personKeyFormattedToPersonContainer.ContainsKey(personKeyFormatted)) + if (!personKeyFormattedToPersonContainer.ContainsKey(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted)) { - personContainer = new(configuration.MappingDefaultName, configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName); - personKeyFormattedToPersonContainer.Add(personKeyFormatted, personContainer); + personDisplayDirectoryName = personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryNames[^1]; + matches = configuration.PersonCharacters.Where(l => personDisplayDirectoryName.Contains(l)).ToArray(); + if (matches.Length == 0) + throw new NotSupportedException(); + group = IPerson.GetHourGroup(personDisplayDirectoryName, personBirthday.Value.Hour); + (status, sex, first) = IPerson.GetPersonHour(personDisplayDirectoryName, personBirthday.Value.Hour); + personDirectory = new(matches.First(), group, status, sex, first); + personContainer = new(configuration.MappingDefaultName, configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName, personDirectory); + personKeyFormattedToPersonContainer.Add(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, personContainer); } - if (personDisplayDirectoryName.Length != 1 && personDisplayDirectoryName != configuration.MappingDefaultName && !personDisplayDirectoryTo.ContainsKey(personDisplayDirectory)) - personDisplayDirectoryTo.Add(personDisplayDirectory, new(personDisplayDirectoryNames, personKeyFormattedToPersonContainer[personKeyFormatted])); - if (!idThenWholePercentagesToPersonContainerCollection.ContainsKey(id)) - idThenWholePercentagesToPersonContainerCollection.Add(id, new()); - if (!idThenWholePercentagesToPersonContainerCollection[id].ContainsKey(wholePercentages)) - idThenWholePercentagesToPersonContainerCollection[id].Add(wholePercentages, new()); - idThenWholePercentagesToPersonContainerCollection[id][wholePercentages].Add(personKeyFormattedToPersonContainer[personKeyFormatted]); + if (!idThenWholePercentagesToPersonContainerCollection.ContainsKey(personKeyFormattedIdThenWholePercentages.Id)) + idThenWholePercentagesToPersonContainerCollection.Add(personKeyFormattedIdThenWholePercentages.Id, new()); + if (!idThenWholePercentagesToPersonContainerCollection[personKeyFormattedIdThenWholePercentages.Id].ContainsKey(personKeyFormattedIdThenWholePercentages.WholePercentages)) + idThenWholePercentagesToPersonContainerCollection[personKeyFormattedIdThenWholePercentages.Id].Add(personKeyFormattedIdThenWholePercentages.WholePercentages, new()); + idThenWholePercentagesToPersonContainerCollection[personKeyFormattedIdThenWholePercentages.Id][personKeyFormattedIdThenWholePercentages.WholePercentages].Add(personKeyFormattedToPersonContainer[personKeyFormattedIdThenWholePercentages.PersonKeyFormatted]); + possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Add(new(personKeyFormattedIdThenWholePercentages, personKeyFormattedToPersonContainer[personKeyFormattedIdThenWholePercentages.PersonKeyFormatted])); } - foreach (KeyValuePair keyValuePair in personDisplayDirectoryTo) - possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Add(keyValuePair.Value); } foreach (KeyValuePair>> keyValuePair in idThenWholePercentagesToPersonContainerCollection) { @@ -425,7 +467,7 @@ internal abstract class MapLogic return results; } - private static int SetCollectionsAndGetUnableToConvertCount(Configuration configuration, long ticks, List<(string, string[], int, int)> personKeyFormattedIdThenWholePercentagesCollection, List collection) + private static int SetCollectionsAndGetUnableToConvertCount(Configuration configuration, long ticks, List personKeyFormattedIdThenWholePercentagesCollection, List collection) { int result = 0; int? id; @@ -454,7 +496,7 @@ internal abstract class MapLogic personDisplayDirectoryName = personDisplayDirectoryNames[^1]; if (string.IsNullOrEmpty(personDisplayDirectoryName)) continue; - personKeyFormattedIdThenWholePercentagesCollection.Add(new(personKeyFormatted, personDisplayDirectoryNames, id.Value, wholePercentages.Value)); + personKeyFormattedIdThenWholePercentagesCollection.Add(new(personKeyFormatted, personDisplayDirectoryNames, mappedFaceFile, id.Value, wholePercentages.Value)); } return result; } @@ -467,7 +509,7 @@ internal abstract class MapLogic List personKeys = IPersonContainer.GetPersonKeys(personContainers); foreach (PersonContainer personContainer in personContainers) { - if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) + if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0) continue; if (personKeys.Contains(personContainer.Key.Value)) continue; @@ -527,46 +569,56 @@ internal abstract class MapLogic } } - static void SavePossiblyNewPersonContainers(string personBirthdayFormat, string facesFileNameExtension, string? a2PeopleSingletonDirectory, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) + static void PossiblyRebuildPersonContainers(Configuration configuration, string? a2PeopleSingletonDirectory, Dictionary personKeyFormattedToNewestPersonKeyFormatted, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) { - string json; - string[] files; + bool[] matches; + string fileName; string checkFile; const int zero = 0; string personKeyFormatted; - string personDisplayDirectory; + string[] deleteCollection; + List distinct = new(); PersonBirthday personBirthday; - string personDisplayDirectoryName; - string checkPersonDisplayDirectory; - string checkPersonKeyFormattedDirectory; - JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; - foreach ((string[] personDisplayDirectoryNames, PersonContainer personContainer) in possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) + string personDisplayDirectory; + string personKeyFormattedDirectory; + foreach ((PersonKeyFormattedIdThenWholePercentages personKeyFormattedIdThenWholePercentages, PersonContainer personContainer) in possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) { - if (a2PeopleSingletonDirectory is null || personContainer.Key is null || personContainer.Birthdays is null || personContainer.PersonDirectory is null || !personContainer.Birthdays.Any()) + if (distinct.Contains(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted)) + continue; + if (a2PeopleSingletonDirectory is null || personContainer.Key is null || personContainer.Birthdays is null || personContainer.PersonDirectory is null || personContainer.Birthdays.Length == 0) + continue; + fileName = $"{Path.GetFileName(personKeyFormattedIdThenWholePercentages.MappedFaceFile)}{configuration.FacesHiddenFileNameExtension}"; + matches = (from l in personContainer.DisplayDirectoryAllFiles where l.EndsWith(fileName) select true).ToArray(); + if (matches.Length > 0) + continue; + matches = (from l in personContainer.DisplayDirectoryAllFiles where l.EndsWith(configuration.FacesHiddenFileNameExtension) select true).ToArray(); + if (matches.Length > 0) continue; personBirthday = personContainer.Birthdays[zero]; - personDisplayDirectoryName = personDisplayDirectoryNames[^1]; - personDisplayDirectory = Path.Combine(personDisplayDirectoryNames); - personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personBirthday); - checkPersonDisplayDirectory = Path.Combine(a2PeopleSingletonDirectory, personContainer.PersonDirectory.Char.ToString(), personContainer.PersonDirectory.Group, personDisplayDirectoryName); - checkPersonKeyFormattedDirectory = Path.Combine(checkPersonDisplayDirectory, personKeyFormatted); - if (Directory.Exists(checkPersonKeyFormattedDirectory)) + personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday); + personDisplayDirectory = Path.Combine(a2PeopleSingletonDirectory, personContainer.PersonDirectory.Char.ToString(), personContainer.PersonDirectory.Group, personContainer.DisplayDirectoryName); + personKeyFormattedDirectory = Path.GetFullPath(Path.Combine(personDisplayDirectory, personKeyFormatted)); + deleteCollection = (from l in personContainer.DisplayDirectoryAllFiles where l.StartsWith(personKeyFormattedDirectory) select l).ToArray(); + if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && personContainer.DisplayDirectoryAllFiles.Length != 0 && deleteCollection.Length == 0) + throw new NotSupportedException(); + if (!Directory.Exists(personKeyFormattedDirectory)) + _ = Directory.CreateDirectory(personKeyFormattedDirectory); + if (!File.Exists(personKeyFormattedIdThenWholePercentages.MappedFaceFile)) continue; - _ = Directory.CreateDirectory(checkPersonKeyFormattedDirectory); - checkFile = Path.Combine(checkPersonKeyFormattedDirectory, $"{personKeyFormatted}.json"); - json = JsonSerializer.Serialize(personContainer.Person, jsonSerializerOptions); - _ = IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true); - if (!Directory.Exists(personDisplayDirectory)) + checkFile = Path.Combine(personKeyFormattedDirectory, $"{Path.GetFileName(personKeyFormattedIdThenWholePercentages.MappedFaceFile)}{configuration.FacesHiddenFileNameExtension}"); + if (File.Exists(checkFile)) continue; - files = Directory.GetFiles(personDisplayDirectory, $"*{facesFileNameExtension}", SearchOption.TopDirectoryOnly); - foreach (string file in files) + File.Copy(personKeyFormattedIdThenWholePercentages.MappedFaceFile, checkFile); + foreach (string delete in deleteCollection) { - checkFile = Path.Combine(checkPersonDisplayDirectory, Path.GetFileName(file)); - if (File.Exists(checkFile)) + if (delete.EndsWith(".lnk")) continue; - File.Copy(files[0], checkFile); - break; + if (!File.Exists(delete)) + continue; + File.Delete(delete); } + Directory.SetLastWriteTime(personDisplayDirectory, DateTime.Now); + distinct.Add(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted); } } @@ -713,92 +765,6 @@ internal abstract class MapLogic } } - private static void SaveParents(ReadOnlyDictionary> familyIndexToCollection, List collection, string personKeyFormatted, string[] filteredDisplayDirectoryAllFiles) - { - string? directory; - string checkDirectory; - string? mergeWithLineTwo; - List? relations; - const string wife = IGenealogicalDataCommunication.Wife; - const string child = IGenealogicalDataCommunication.Child; - const string husband = IGenealogicalDataCommunication.Husband; - foreach (GenealogicalDataCommunicationRelation genealogicalDataCommunicationRelation in collection) - { - if (!filteredDisplayDirectoryAllFiles.Any()) - continue; - directory = Path.GetDirectoryName(filteredDisplayDirectoryAllFiles.First()); - if (string.IsNullOrEmpty(directory)) - continue; - if (genealogicalDataCommunicationRelation.Relation != child) - continue; - if (genealogicalDataCommunicationRelation.NickName != personKeyFormatted) - continue; - if (!familyIndexToCollection.TryGetValue(genealogicalDataCommunicationRelation.FamilyIndex, out relations)) - continue; - foreach (GenealogicalDataCommunicationRelation relation in relations) - { - if (relation.FamilyIndex != genealogicalDataCommunicationRelation.FamilyIndex) - continue; - if (relation.Relation is not husband and not wife) - continue; - checkDirectory = Path.Combine(directory, relation.NickName); - if (!Directory.Exists(checkDirectory)) - { - _ = Directory.CreateDirectory(checkDirectory); - mergeWithLineTwo = IGenealogicalDataCommunication.GetMergeWithLineTwo(genealogicalDataCommunicationRelation, relation); - File.WriteAllText(Path.Combine(checkDirectory, $"{mergeWithLineTwo}.rel"), relation.FullName); - } - } - } - } - - private static void SaveOne(Configuration configuration, ReadOnlyDictionary> familyIndexToCollection, List> locationContainers, Dictionary> personKeyToPersonContainerCollection) - { - string checkFile; - string? directory; - string personKeyFormatted; - List distinct = new(); - List? personContainers; - string[] filteredDisplayDirectoryAllFiles; - List? collection; - string checkExtension = $"{configuration.FacesFileNameExtension}{configuration.FacesHiddenFileNameExtension}"; - ReadOnlyDictionary> personKeyToCollection = IGenealogicalDataCommunication.GetCollection(configuration.PersonBirthdayFormat, familyIndexToCollection); - foreach (LocationContainer locationContainer in locationContainers) - { - if (!locationContainer.File.EndsWith(configuration.FacesFileNameExtension)) - continue; - if (distinct.Contains(locationContainer.PersonKey)) - continue; - if (!personKeyToPersonContainerCollection.TryGetValue(locationContainer.PersonKey, out personContainers)) - continue; - foreach (PersonContainer personContainer in personContainers) - { - if (personContainer.Key is null) - continue; - if (personKeyToCollection.TryGetValue(personContainer.Key.Value, out collection)) - { - personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personContainer.Key.Value); - SaveParents(familyIndexToCollection, collection, personKeyFormatted, personContainer.DisplayDirectoryAllFiles.Where(l => l.EndsWith(checkExtension)).ToArray()); - } - if (personContainer.DisplayDirectoryAllFiles.Any(l => l.EndsWith(checkExtension))) - continue; - filteredDisplayDirectoryAllFiles = personContainer.DisplayDirectoryAllFiles.Where(l => l.EndsWith(".pged")).ToArray(); - if (!filteredDisplayDirectoryAllFiles.Any()) - continue; - directory = Path.GetDirectoryName(filteredDisplayDirectoryAllFiles.First()); - if (string.IsNullOrEmpty(directory)) - continue; - checkFile = Path.Combine(directory, $"{Path.GetFileName(locationContainer.File)}{configuration.FacesHiddenFileNameExtension}"); - if (File.Exists(checkFile)) - break; - File.Copy(locationContainer.File, checkFile); - File.Delete(filteredDisplayDirectoryAllFiles.First()); - break; - } - distinct.Add(locationContainer.PersonKey); - } - } - private static void LookForPossibleDuplicates(Configuration configuration, List> locationContainers) { string key; @@ -866,7 +832,7 @@ internal abstract class MapLogic return results; } - internal static void Set(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyDictionary> familyIndexToCollection, ReadOnlyCollection personContainers, string? a2PeopleSingletonDirectory, string eDistanceContentDirectory, Dictionary personKeyToPersonContainer, List notMappedPersonContainers, Dictionary> skipCollection, Dictionary> skipNotSkipCollection, List> locationContainers, Dictionary> idThenWholePercentagesToPersonContainers) + internal static void Set(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection personContainers, string? a2PeopleSingletonDirectory, string eDistanceContentDirectory, Dictionary personKeyToPersonContainer, List notMappedPersonContainers, Dictionary> skipCollection, Dictionary> skipNotSkipCollection, List> locationContainers, Dictionary> idThenWholePercentagesToPersonContainers) { string message; int totalSeconds; @@ -876,15 +842,15 @@ internal abstract class MapLogic Dictionary personKeyFormattedToPersonContainer = new(); Dictionary> personKeyToPersonContainerCollection = new(); string[] ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(eDistanceContentDirectory); - List<(string, string[], int, int)> personKeyFormattedIdThenWholePercentagesCollection = new(); - List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new(); + List personKeyFormattedIdThenWholePercentagesCollection = new(); + List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new(); SetPersonCollections(configuration, personContainers, a2PeopleSingletonDirectory, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, skipCollection, skipNotSkipCollection); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)"; List records = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, ticksDirectories, message); locationContainers.AddRange(GetLocationContainers(maxDegreeOfParallelism, configuration, ticks, personContainers, eDistanceContentDirectory, records)); int unableToMatchCount = SetCollectionsAndGetUnableToConvertCount(configuration, ticks, personKeyFormattedIdThenWholePercentagesCollection, records); - SetKeyValuePairs(configuration, personContainers, personKeyToPersonContainerCollection, personKeyFormattedToPersonContainer, personKeyFormattedIdThenWholePercentagesCollection, personKeyToPersonContainer, idThenWholePercentagesToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); + SetKeyValuePairsAndAddToCollections(configuration, personContainers, personKeyToPersonContainerCollection, personKeyFormattedToPersonContainer, personKeyFormattedIdThenWholePercentagesCollection, personKeyToPersonContainer, idThenWholePercentagesToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); message = $") {records.Count:000} message from ticks Director(ies) - D - {unableToMatchCount} Unable To Match Count / {records.Count} Collection - {totalSeconds} total second(s)"; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; @@ -898,12 +864,9 @@ internal abstract class MapLogic } } long[] personKeyCollection = (from l in nullablePersonKeyCollection where l is not null select l.Value).Distinct().ToArray(); + PossiblyRebuildPersonContainers(configuration, a2PeopleSingletonDirectory, personKeyFormattedToNewestPersonKeyFormatted, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); SetPersonKeyToPersonContainer(configuration, personContainers, personKeyCollection, personKeyToPersonContainer, personKeyToPersonContainerCollection); - ReadOnlyDictionary personKeyFormattedToPersonFullName = IPersonContainer.GetPersonKeyFormattedToPersonFullName(configuration.PersonBirthdayFormat, personContainers); - SaveOne(configuration, familyIndexToCollection, locationContainers, personKeyToPersonContainerCollection); notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, personContainers, personKeyCollection)); - if (possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Any()) - SavePossiblyNewPersonContainers(configuration.PersonBirthdayFormat, configuration.FacesFileNameExtension, a2PeopleSingletonDirectory, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); } private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, long dateTimeOriginalThenMinimumDateTimeTicks, bool? isWrongYear) diff --git a/Shared/Models/GenealogicalDataCommunicationCollections.cs b/Shared/Models/GenealogicalDataCommunicationCollections.cs new file mode 100644 index 0000000..c31a19e --- /dev/null +++ b/Shared/Models/GenealogicalDataCommunicationCollections.cs @@ -0,0 +1,19 @@ +using System.Collections.ObjectModel; +using System.Text.Json; + +namespace View_by_Distance.Shared.Models; + +public record GenealogicalDataCommunicationCollections(string[] HeaderLines, + ReadOnlyDictionary Individuals, + List FamilyGroupLines, + ReadOnlyDictionary IdToNick, + string[] FooterLines) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + return result; + } + +} \ No newline at end of file diff --git a/Shared/Models/PersonContainer.cs b/Shared/Models/PersonContainer.cs index 94da408..8ab7a55 100644 --- a/Shared/Models/PersonContainer.cs +++ b/Shared/Models/PersonContainer.cs @@ -28,8 +28,8 @@ public class PersonContainer : Properties.IPersonContainer KeyIsMaxBirthday = birthdays is null || key is null ? null : key.Value == birthdays.First().Value.Ticks; } - public PersonContainer(string mappingDefaultName, char[] personCharacters, PersonBirthday birthday, string displayDirectoryName) : - this(Stateless.Methods.IAge.GetApproximateYears(personCharacters, displayDirectoryName), new PersonBirthday[] { birthday }, Array.Empty(), displayDirectoryName, birthday.Value.Ticks, Stateless.Methods.IPerson.GetPerson(mappingDefaultName, personCharacters, displayDirectoryName, birthday.Value.Ticks, birthday), null) + public PersonContainer(string mappingDefaultName, char[] personCharacters, PersonBirthday birthday, string displayDirectoryName, PersonDirectory personDirectory) : + this(Stateless.Methods.IAge.GetApproximateYears(personCharacters, displayDirectoryName), new PersonBirthday[] { birthday }, Array.Empty(), displayDirectoryName, birthday.Value.Ticks, Stateless.Methods.IPerson.GetPerson(mappingDefaultName, personCharacters, displayDirectoryName, birthday.Value.Ticks, birthday), personDirectory) { } public PersonContainer(int? approximateYears, PersonBirthday birthdays, string displayDirectoryName, long key) : diff --git a/Shared/Models/Stateless/Methods/GenealogicalDataCommunication.cs b/Shared/Models/Stateless/Methods/GenealogicalDataCommunication.cs index a90212e..f5a35bc 100644 --- a/Shared/Models/Stateless/Methods/GenealogicalDataCommunication.cs +++ b/Shared/Models/Stateless/Methods/GenealogicalDataCommunication.cs @@ -11,6 +11,13 @@ 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 results = new(); @@ -23,39 +30,6 @@ internal abstract class GenealogicalDataCommunication return results.ToArray(); } - private static List GetRelations(string personBirthdayFormat, ReadOnlyDictionary personKeyFormattedToPersonFullName, Dictionary idToNick, List familyGroupLines) - { - List results = new(); - string? nick; - long? personKey; - string relation; - string? fullName; - string[] segments; - string[] familyLines; - Models.PersonBirthday? personBirthday; - for (int i = 0; i < familyGroupLines.Count; i++) - { - familyLines = familyGroupLines[i]; - for (int j = 0; j < familyLines.Length; j++) - { - segments = familyLines[j].Split('@'); - if (segments.First().Length < 3 || segments.Length != 3) - continue; - if (!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; - } - private static ReadOnlyDictionary Convert(Dictionary> keyValuePairs) { Dictionary results = new(); @@ -64,8 +38,9 @@ internal abstract class GenealogicalDataCommunication return new(results); } - internal static (string[], ReadOnlyDictionary, List, string[], List genealogicalDataCommunicationRelations) GetIndividuals(string personBirthdayFormat, string genealogicalDataCommunicationFile, ReadOnlyCollection personContainers, bool requireNickName) + internal static GenealogicalDataCommunicationCollections GetIndividuals(string genealogicalDataCommunicationFile, bool requireNickName) { + GenealogicalDataCommunicationCollections result; ReadOnlyDictionary results; string? nick; string[] segments; @@ -75,7 +50,6 @@ internal abstract class GenealogicalDataCommunication List familyGroupLines = new(); Dictionary idToNick = new(); Dictionary> keyValuePairs = new(); - ReadOnlyDictionary personKeyFormattedToPersonFullName = IPersonContainer.GetPersonKeyFormattedToPersonFullName(personBirthdayFormat, personContainers); string[] sourceLines = string.IsNullOrEmpty(genealogicalDataCommunicationFile) || !File.Exists(genealogicalDataCommunicationFile) ? Array.Empty() : File.ReadAllLines(genealogicalDataCommunicationFile); string[] headerLines = GetHeaderLines(startsWith, sourceLines); for (int i = headerLines.Length; i < sourceLines.Length; i++) @@ -135,18 +109,18 @@ internal abstract class GenealogicalDataCommunication throw new NotSupportedException(); } results = Convert(keyValuePairs); - List genealogicalDataCommunicationRelations = GetRelations(personBirthdayFormat, personKeyFormattedToPersonFullName, idToNick, familyGroupLines); - return (headerLines, results, familyGroupLines, footerLines.ToArray(), genealogicalDataCommunicationRelations); + result = new(headerLines, results, familyGroupLines, new(idToNick), footerLines.ToArray()); + return result; } - internal static List GetMappedLines(string personBirthdayFormat, string genealogicalDataCommunicationFile, ReadOnlyCollection personContainers, bool requireNickName) + internal static List GetMappedLines(string genealogicalDataCommunicationFile, bool requireNickName) { List results = new(); Models.PersonBirthday personBirthday = new(DateTime.Now); GenealogicalDataCommunicationLines genealogicalDataCommunicationLines; - (string[] headerLines, ReadOnlyDictionary individuals, List familyGroupLines, string[] footerLines, _) = GetIndividuals(personBirthdayFormat, genealogicalDataCommunicationFile, personContainers, requireNickName); - results.AddRange(headerLines); - foreach (KeyValuePair keyValuePair in individuals) + GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections = GetIndividuals(genealogicalDataCommunicationFile, requireNickName); + results.AddRange(genealogicalDataCommunicationCollections.HeaderLines); + foreach (KeyValuePair keyValuePair in genealogicalDataCommunicationCollections.Individuals) { genealogicalDataCommunicationLines = GetGenealogicalDataCommunicationLines(personBirthday, keyValuePair.Value); if (!string.IsNullOrEmpty(genealogicalDataCommunicationLines.Id)) @@ -167,9 +141,9 @@ internal abstract class GenealogicalDataCommunication results.AddRange(genealogicalDataCommunicationLines.Death); results.AddRange(genealogicalDataCommunicationLines.Changed); } - for (int i = 0; i < familyGroupLines.Count; i++) - results.AddRange(familyGroupLines[i]); - results.AddRange(footerLines); + for (int i = 0; i < genealogicalDataCommunicationCollections.FamilyGroupLines.Count; i++) + results.AddRange(genealogicalDataCommunicationCollections.FamilyGroupLines[i]); + results.AddRange(genealogicalDataCommunicationCollections.FooterLines); return results; } @@ -301,94 +275,45 @@ internal abstract class GenealogicalDataCommunication return result; } - internal static bool CleanDisplayDirectoryAllFilesAndWriteTicksGed(string mappingDefaultName, string personBirthdayFormat, ReadOnlyCollection personContainers, string[] headerLines, List familyGroupLines, string[] footerLines, long ticks, string a2PeopleContentDirectory) + private static List GetRelations(string personBirthdayFormat, ReadOnlyCollection personContainers, GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections) { - bool result = false; - string directory; - string[] mdFiles; - string[] txtFiles; - const int zero = 0; - string[] jsonFiles; - string[] pGedFiles; - string personKeyFormatted; - List lines = new(); - List distinct = new(); - List individualsLines; - DateTime dateTime = new(ticks); - Models.PersonBirthday personBirthday; - Calendar calendar = new CultureInfo("en-US").Calendar; - string weekOfYear = calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); - lines.AddRange(headerLines); - foreach (Models.PersonContainer personContainer in personContainers) + List results = new(); + string? nick; + long? personKey; + string relation; + string? fullName; + string[] segments; + string[] familyLines; + Models.PersonBirthday? personBirthday; + ReadOnlyDictionary personKeyFormattedToPersonFullName = IPersonContainer.GetPersonKeyFormattedToPersonFullName(personBirthdayFormat, personContainers); + for (int i = 0; i < genealogicalDataCommunicationCollections.FamilyGroupLines.Count; i++) { - 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); - mdFiles = (from l in personContainer.DisplayDirectoryAllFiles where l.EndsWith(".md") select l).ToArray(); - txtFiles = (from l in personContainer.DisplayDirectoryAllFiles where l.EndsWith(".txt") select l).ToArray(); - jsonFiles = (from l in personContainer.DisplayDirectoryAllFiles where l.EndsWith(".json") select l).ToArray(); - pGedFiles = (from l in personContainer.DisplayDirectoryAllFiles where l.EndsWith(".pged") select l).ToArray(); - foreach (string mdFile in mdFiles) + familyLines = genealogicalDataCommunicationCollections.FamilyGroupLines[i]; + for (int j = 0; j < familyLines.Length; j++) { - if (string.IsNullOrEmpty(personKeyFormatted)) + segments = familyLines[j].Split('@'); + if (segments.First().Length < 3 || segments.Length != 3) continue; - if (!mdFile.Contains(personKeyFormatted)) - { - if (!result) - result = true; - File.Delete(mdFile); - } - } - foreach (string pGedFile in pGedFiles) - { - if (string.IsNullOrEmpty(personKeyFormatted)) + if (!genealogicalDataCommunicationCollections.IdToNick.TryGetValue(segments[1], out nick)) continue; - if (!pGedFile.Contains(personKeyFormatted)) - { - if (!result) - result = true; - File.Delete(pGedFile); - continue; - } - individualsLines = File.ReadAllLines(pGedFile).ToList(); - foreach (string jsonFile in jsonFiles) - { - if (!result) - result = true; - File.Delete(jsonFile); - } - foreach (string txtFile in txtFiles) - { - if (new FileInfo(txtFile).Length == 0) - { - if (!result) - result = true; - File.Delete(txtFile); - } - } - lines.AddRange(individualsLines); + 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..])); } } - for (int i = 0; i < familyGroupLines.Count; i++) - lines.AddRange(familyGroupLines[i]); - lines.AddRange(footerLines); - directory = Path.Combine(a2PeopleContentDirectory, $"{dateTime.Year}-GenealogicalDataCommunication", $"{dateTime.Year}-Week-{weekOfYear}"); - if (!Directory.Exists(directory)) - _ = Directory.CreateDirectory(directory); - File.WriteAllLines(Path.Combine(directory, $"{ticks}.ged"), lines); - return result; + return results; } - internal static ReadOnlyDictionary> GetFamilyIndexToCollection(List genealogicalDataCommunicationRelations) + internal static ReadOnlyDictionary> GetFamilyIndexToCollection(string personBirthdayFormat, ReadOnlyCollection personContainers, GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections) { Dictionary> results = new(); List? relations; + List genealogicalDataCommunicationRelations = GetRelations(personBirthdayFormat, personContainers, genealogicalDataCommunicationCollections); foreach (GenealogicalDataCommunicationRelation genealogicalDataCommunicationRelation in genealogicalDataCommunicationRelations) { if (!results.TryGetValue(genealogicalDataCommunicationRelation.FamilyIndex, out relations)) @@ -551,7 +476,7 @@ internal abstract class GenealogicalDataCommunication ReadOnlyDictionary 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.Any()) + 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()); diff --git a/Shared/Models/Stateless/Methods/IGenealogicalDataCommunication.cs b/Shared/Models/Stateless/Methods/IGenealogicalDataCommunication.cs index 43da1d9..50786c0 100644 --- a/Shared/Models/Stateless/Methods/IGenealogicalDataCommunication.cs +++ b/Shared/Models/Stateless/Methods/IGenealogicalDataCommunication.cs @@ -11,10 +11,10 @@ public interface IGenealogicalDataCommunication const string Child = "CHIL"; const string Husband = "HUSB"; - List TestStatic_GetMappedLines(string personBirthdayFormat, string genealogicalDataCommunicationFile, ReadOnlyCollection personContainers, bool requireNickName) => - GetMappedLines(personBirthdayFormat, genealogicalDataCommunicationFile, personContainers, requireNickName); - static List GetMappedLines(string personBirthdayFormat, string genealogicalDataCommunicationFile, ReadOnlyCollection personContainers, bool requireNickName) => - GenealogicalDataCommunication.GetMappedLines(personBirthdayFormat, genealogicalDataCommunicationFile, personContainers, requireNickName); + List TestStatic_GetMappedLines(string genealogicalDataCommunicationFile, bool requireNickName) => + GetMappedLines(genealogicalDataCommunicationFile, requireNickName); + static List GetMappedLines(string genealogicalDataCommunicationFile, bool requireNickName) => + GenealogicalDataCommunication.GetMappedLines(genealogicalDataCommunicationFile, requireNickName); GenealogicalDataCommunicationLines TestStatic_GetGenealogicalDataCommunicationLines(Models.PersonBirthday personBirthday, string[] individualsLines) => GetGenealogicalDataCommunicationLines(individualsLines); @@ -26,15 +26,10 @@ public interface IGenealogicalDataCommunication static Models.GenealogicalDataCommunication GetGenealogicalDataCommunication(bool first, GenealogicalDataCommunicationLines genealogicalDataCommunicationLines) => GenealogicalDataCommunication.GetGenealogicalDataCommunication(first, genealogicalDataCommunicationLines); - (string[], ReadOnlyDictionary, List, string[], List genealogicalDataCommunicationRelations) TestStatic_GetIndividuals(string personBirthdayFormat, string genealogicalDataCommunicationFile, ReadOnlyCollection personContainers, bool requireNickName) => - GetIndividuals(personBirthdayFormat, genealogicalDataCommunicationFile, personContainers, requireNickName); - static (string[], ReadOnlyDictionary, List, string[], List genealogicalDataCommunicationRelations) GetIndividuals(string personBirthdayFormat, string genealogicalDataCommunicationFile, ReadOnlyCollection personContainers, bool requireNickName) => - GenealogicalDataCommunication.GetIndividuals(personBirthdayFormat, genealogicalDataCommunicationFile, personContainers, requireNickName); - - bool TestStatic_CleanDisplayDirectoryAllFilesAndWriteTicksGed(string mappingDefaultName, string personBirthdayFormat, ReadOnlyCollection personContainers, string[] headerLines, List familyGroupLines, string[] footerLines, long ticks, string a2PeopleContentDirectory) => - CleanDisplayDirectoryAllFilesAndWriteTicksGed(mappingDefaultName, personBirthdayFormat, personContainers, headerLines, familyGroupLines, footerLines, ticks, a2PeopleContentDirectory); - static bool CleanDisplayDirectoryAllFilesAndWriteTicksGed(string mappingDefaultName, string personBirthdayFormat, ReadOnlyCollection personContainers, string[] headerLines, List familyGroupLines, string[] footerLines, long ticks, string a2PeopleContentDirectory) => - GenealogicalDataCommunication.CleanDisplayDirectoryAllFilesAndWriteTicksGed(mappingDefaultName, personBirthdayFormat, personContainers, headerLines, familyGroupLines, footerLines, ticks, a2PeopleContentDirectory); + GenealogicalDataCommunicationCollections TestStatic_GetIndividuals(string genealogicalDataCommunicationFile, bool requireNickName) => + GetIndividuals(genealogicalDataCommunicationFile, requireNickName); + static GenealogicalDataCommunicationCollections GetIndividuals(string genealogicalDataCommunicationFile, bool requireNickName) => + GenealogicalDataCommunication.GetIndividuals(genealogicalDataCommunicationFile, requireNickName); ReadOnlyDictionary> TestStatic_GetCollection(string personBirthdayFormat, List genealogicalDataCommunicationRelations) => GetCollection(personBirthdayFormat, genealogicalDataCommunicationRelations); @@ -46,10 +41,10 @@ public interface IGenealogicalDataCommunication static ReadOnlyDictionary> GetCollection(string personBirthdayFormat, ReadOnlyDictionary> familyIndexToCollection) => GenealogicalDataCommunication.GetCollection(personBirthdayFormat, familyIndexToCollection); - ReadOnlyDictionary> TestStatic_GetFamilyIndexToCollection(List genealogicalDataCommunicationRelations) => - GetFamilyIndexToCollection(genealogicalDataCommunicationRelations); - static ReadOnlyDictionary> GetFamilyIndexToCollection(List genealogicalDataCommunicationRelations) => - GenealogicalDataCommunication.GetFamilyIndexToCollection(genealogicalDataCommunicationRelations); + ReadOnlyDictionary> TestStatic_GetFamilyIndexToCollection(string personBirthdayFormat, ReadOnlyCollection personContainers, GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections) => + GetFamilyIndexToCollection(personBirthdayFormat, personContainers, genealogicalDataCommunicationCollections); + static ReadOnlyDictionary> GetFamilyIndexToCollection(string personBirthdayFormat, ReadOnlyCollection personContainers, GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections) => + GenealogicalDataCommunication.GetFamilyIndexToCollection(personBirthdayFormat, personContainers, genealogicalDataCommunicationCollections); string? TestStatic_GetMergeWithLineTwo(GenealogicalDataCommunicationRelation genealogicalDataCommunicationRelation, GenealogicalDataCommunicationRelation relation) => GetMergeWithLineTwo(genealogicalDataCommunicationRelation, relation); diff --git a/Shared/Models/Stateless/Methods/IPerson.cs b/Shared/Models/Stateless/Methods/IPerson.cs index 5205698..b0923e7 100644 --- a/Shared/Models/Stateless/Methods/IPerson.cs +++ b/Shared/Models/Stateless/Methods/IPerson.cs @@ -10,6 +10,38 @@ public interface IPerson static Models.PersonName GetPersonName(string name) => PersonName.GetPersonName(name); + static (char, char, char) 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); + + 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); + bool TestStatic_IsDefaultName(string mappingDefaultName, string value) => IsDefaultName(mappingDefaultName, value); static bool IsDefaultName(string mappingDefaultName, string value) => diff --git a/Shared/Models/Stateless/Methods/PersonBirthday.cs b/Shared/Models/Stateless/Methods/PersonBirthday.cs index a3ccb21..c445bc0 100644 --- a/Shared/Models/Stateless/Methods/PersonBirthday.cs +++ b/Shared/Models/Stateless/Methods/PersonBirthday.cs @@ -110,7 +110,6 @@ internal abstract class PersonBirthday internal static List<(string, Models.PersonBirthday)> GetPersonBirthdays(string personBirthdayFormat, string[] personKeyDirectories, string personDisplayDirectory, string personDisplayDirectoryName) { List<(string, Models.PersonBirthday)> results = new(); - string[] files; string personKeyFormatted; Models.PersonBirthday? personBirthday; foreach (string personKeyDirectory in personKeyDirectories) @@ -124,9 +123,6 @@ internal abstract class PersonBirthday continue; if (!IPersonBirthday.IsCounterPersonBirthday(personBirthday) && ((!personKeyDirectory.Contains('#') && (personDisplayDirectoryName.Contains('~') || personDisplayDirectoryName.Contains('#'))) || (personKeyDirectory.Contains('#') && !personDisplayDirectoryName.Contains('#')))) throw new NotSupportedException(); - files = Directory.GetFiles(personKeyDirectory, "*", SearchOption.TopDirectoryOnly); - if (!files.Any()) - continue; results.Add(new(personKeyFormatted, personBirthday)); } return results; diff --git a/Shared/Models/Stateless/Methods/PersonContainer.cs b/Shared/Models/Stateless/Methods/PersonContainer.cs index ad55b44..58c04aa 100644 --- a/Shared/Models/Stateless/Methods/PersonContainer.cs +++ b/Shared/Models/Stateless/Methods/PersonContainer.cs @@ -5,7 +5,7 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class PersonContainer { - private static string[] GetFiles(string personDisplayDirectory, bool isDefaultName) + private static List GetFiles(string personDisplayDirectory, bool isDefaultName) { List results = new(); string[] files; @@ -58,12 +58,12 @@ internal abstract class PersonContainer results.Add(file); } } - return results.ToArray(); + return results; } - private static string[] GetFiles(string facesFileNameExtension, string personDisplayDirectory, bool isDefaultName) + private static List GetFiles(string facesFileNameExtension, string personDisplayDirectory, bool isDefaultName) { - string[] results; + List results; int? id; string checkFile; int? wholePercentages; @@ -96,11 +96,13 @@ internal abstract class PersonContainer { List results = new(); long personKey; + string[] files; const int zero = 0; Models.Person person; + string personKeyDirectory; Models.PersonContainer personContainer; Models.PersonBirthday[] orderedPersonBirthdays; - string[] personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory, isDefaultName); + List personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory, isDefaultName); foreach ((string personKeyFormatted, Models.PersonBirthday personBirthday) in collection) { orderedPersonBirthdays = (from l in collection where !l.PersonKeyFormatted.Contains(numberSign) orderby l.PersonBirthday.Value.Ticks descending select l.PersonBirthday).ToArray(); @@ -112,8 +114,13 @@ internal abstract class PersonContainer continue; personKey = orderedPersonBirthdays[zero].Value.Ticks; } - person = IPerson.GetPerson(mappingDefaultName, personCharacters, personDisplayDirectoryName, personDisplayDirectoryAllFiles, personKey); - personContainer = new(approximateYears, orderedPersonBirthdays, personDisplayDirectoryAllFiles, personDisplayDirectoryName, personKey, person, personDirectory); + personKeyDirectory = Path.Combine(personDisplayDirectory, personKeyFormatted); + files = Directory.GetFiles(personKeyDirectory, "*", SearchOption.AllDirectories); + if (!files.Any()) + continue; + personDisplayDirectoryAllFiles.AddRange(files.Where(l => l.EndsWith(".rel"))); + person = IPerson.GetPerson(mappingDefaultName, personCharacters, personDisplayDirectoryName, personDisplayDirectoryAllFiles.ToArray(), personKey); + personContainer = new(approximateYears, orderedPersonBirthdays, personDisplayDirectoryAllFiles.ToArray(), personDisplayDirectoryName, personKey, person, personDirectory); results.Add(personContainer); } return results; @@ -161,7 +168,7 @@ internal abstract class PersonContainer string[] personKeyDirectories; string? personDisplayDirectoryName; Models.PersonContainer personContainer; - string[] personDisplayDirectoryAllFiles; + List personDisplayDirectoryAllFiles; List personContainers; List<(string, Models.PersonBirthday)> collection; foreach (string personDisplayDirectory in personDisplayDirectories) @@ -182,7 +189,7 @@ internal abstract class PersonContainer } if (changes.Any(l => l is not null)) continue; - if (collection.Any()) + if (collection.Count > 0) { personContainers = GetPersonContainersCollections(mappingDefaultName, facesFileNameExtension, personCharacters, personDirectory, numberSign, personDisplayDirectory, personDisplayDirectoryName, isDefaultName, approximateYears, collection); results.AddRange(personContainers); @@ -190,7 +197,7 @@ internal abstract class PersonContainer else { personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory, isDefaultName); - personContainer = new(approximateYears, personDisplayDirectoryAllFiles, personDisplayDirectoryName, personDirectory); + personContainer = new(approximateYears, personDisplayDirectoryAllFiles.ToArray(), personDisplayDirectoryName, personDirectory); results.Add(personContainer); } } @@ -247,20 +254,22 @@ internal abstract class PersonContainer private static List GetPersonContainersGroups(string mappingDefaultName, string personBirthdayFormat, string facesFileNameExtension, char[] personCharacters, string[] groupDirectories) { List results; - const int zero = 0; List changes; string groupDirectoryName; List allChanges = new(); List collection; List personContainers = new(); - foreach (string groupDirectory in groupDirectories) + for (int i = 0; i < personCharacters.Length; i++) { - groupDirectoryName = Path.GetFileName(groupDirectory); - if (!personCharacters.Contains(groupDirectoryName[zero])) - continue; - (changes, collection) = GetPersonContainersInnerGroups(mappingDefaultName, personBirthdayFormat, facesFileNameExtension, personCharacters, groupDirectory, groupDirectoryName); - allChanges.AddRange(changes); - personContainers.AddRange(collection); + foreach (string groupDirectory in groupDirectories) + { + groupDirectoryName = Path.GetFileName(groupDirectory); + if (personCharacters[i] != groupDirectoryName.First()) + continue; + (changes, collection) = GetPersonContainersInnerGroups(mappingDefaultName, personBirthdayFormat, facesFileNameExtension, personCharacters, groupDirectory, groupDirectoryName); + allChanges.AddRange(changes); + personContainers.AddRange(collection); + } } if (allChanges.Any(l => l is not null)) throw new NotImplementedException($"A directory was changed restart to look for more! {string.Join(Environment.NewLine, (from l in allChanges where l is not null select l).ToArray())}"); @@ -313,7 +322,7 @@ internal abstract class PersonContainer long personKey; foreach (Models.PersonContainer personContainer in personContainers) { - if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) + if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0) continue; foreach (Models.PersonBirthday personBirthday in personContainer.Birthdays) { @@ -332,7 +341,7 @@ internal abstract class PersonContainer string personKeyFormatted; foreach (Models.PersonContainer personContainer in personContainers) { - if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Person is null || personContainer.PersonDirectory is null || !personContainer.Birthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Person is null || personContainer.PersonDirectory is null || personContainer.Birthdays.Length == 0) continue; personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personContainer.Key.Value); personFullName = PersonName.GetFullName(personContainer.Person.Name); diff --git a/Tests/UnitTestHardCoded.cs b/Tests/UnitTestHardCoded.cs index 5e3bd55..551a6b0 100644 --- a/Tests/UnitTestHardCoded.cs +++ b/Tests/UnitTestHardCoded.cs @@ -2,7 +2,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.VisualStudio.TestTools.UnitTesting; using Phares.Shared; using Serilog; -using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.Reflection; @@ -267,10 +266,9 @@ public partial class UnitTestHardCoded { bool first = true; List mappedLines; - List personContainers = new(); - ReadOnlyDictionary individuals; GenealogicalDataCommunication genealogicalDataCommunication; GenealogicalDataCommunicationLines genealogicalDataCommunicationLines; + GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections; List<(bool, string)> genealogicalDataCommunicationFiles = new() { // new(false, Path.Combine(directory, "Ancestry-Roberts/Roberts Family Tree.ged")), @@ -288,15 +286,15 @@ public partial class UnitTestHardCoded }; foreach ((bool requireNickName, string genealogicalDataCommunicationFile) in genealogicalDataCommunicationFiles) { - (_, individuals, _, _, _) = IGenealogicalDataCommunication.GetIndividuals(_Configuration.PropertyConfiguration.PersonBirthdayFormat, genealogicalDataCommunicationFile, new(personContainers), requireNickName); - foreach (KeyValuePair keyValuePair in individuals) + genealogicalDataCommunicationCollections = IGenealogicalDataCommunication.GetIndividuals(genealogicalDataCommunicationFile, requireNickName); + foreach (KeyValuePair keyValuePair in genealogicalDataCommunicationCollections.Individuals) { genealogicalDataCommunicationLines = IGenealogicalDataCommunication.GetGenealogicalDataCommunicationLines(keyValuePair.Value); Assert.IsNotNull(genealogicalDataCommunicationLines.Name); genealogicalDataCommunication = IGenealogicalDataCommunication.GetGenealogicalDataCommunication(first, genealogicalDataCommunicationLines); Assert.IsNotNull(genealogicalDataCommunication.Name); } - mappedLines = IGenealogicalDataCommunication.GetMappedLines(_Configuration.PropertyConfiguration.PersonBirthdayFormat, genealogicalDataCommunicationFile, new(personContainers), requireNickName); + mappedLines = IGenealogicalDataCommunication.GetMappedLines(genealogicalDataCommunicationFile, requireNickName); if (IPath.WriteAllText($"{genealogicalDataCommunicationFile}.cln", string.Join(Environment.NewLine, mappedLines), updateDateWhenMatches: false, compareBeforeWrite: true)) continue; } @@ -320,10 +318,9 @@ public partial class UnitTestHardCoded PersonName? personName; string personKeyFormatted; // bool isDefaultName = false; - List personContainers = new(); - ReadOnlyDictionary individuals; GenealogicalDataCommunication genealogicalDataCommunication; GenealogicalDataCommunicationLines genealogicalDataCommunicationLines; + GenealogicalDataCommunicationCollections genealogicalDataCommunicationCollections; List<(bool, bool, string)> genealogicalDataCommunicationFiles = new() { // new(false, false, Path.Combine(saveDirectory, "Ancestry-Roberts/Roberts Family Tree.ged.cln")), @@ -342,8 +339,8 @@ public partial class UnitTestHardCoded foreach ((bool verify, bool requireNickName, string genealogicalDataCommunicationFile) in genealogicalDataCommunicationFiles) { fileName = Path.GetFileNameWithoutExtension(genealogicalDataCommunicationFile).Split(' ')[0]; - (_, individuals, _, _, _) = IGenealogicalDataCommunication.GetIndividuals(_Configuration.PropertyConfiguration.PersonBirthdayFormat, genealogicalDataCommunicationFile, new(personContainers), requireNickName); - foreach (KeyValuePair keyValuePair in individuals) + genealogicalDataCommunicationCollections = IGenealogicalDataCommunication.GetIndividuals(genealogicalDataCommunicationFile, requireNickName); + foreach (KeyValuePair keyValuePair in genealogicalDataCommunicationCollections.Individuals) { genealogicalDataCommunicationLines = IGenealogicalDataCommunication.GetGenealogicalDataCommunicationLines(keyValuePair.Value); Assert.IsNotNull(genealogicalDataCommunicationLines.Name);