diff --git a/Compare/Compare.cs b/Compare/Compare.cs index c74e55c..2931b86 100644 --- a/Compare/Compare.cs +++ b/Compare/Compare.cs @@ -56,7 +56,7 @@ public class Compare PredictorModel? predictorModel = null; string eResultsFullGroupDirectory = string.Empty; Map.Models.Configuration? mapConfiguration = null; - List personContainers = new(); + Shared.Models.PersonContainer[] personContainers = Array.Empty(); Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, propertyConfiguration, mapConfiguration, outputExtension, ticks, personContainers, eResultsFullGroupDirectory); A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, predictorModel, mapLogic); foreach (string spelling in configuration.Spelling) diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index fa9deb8..e586c5c 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -44,8 +44,8 @@ public partial class DlibDotNet _IsEnvironment = isEnvironment; long ticks = DateTime.Now.Ticks; _Exceptions = new List(); + PersonContainer[] personContainers; _Log = Serilog.Log.ForContext(); - List personContainers; _FileKeyValuePairs = new List>(); _FilePropertiesKeyValuePairs = new Dictionary>>(); Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot); @@ -76,7 +76,7 @@ public partial class DlibDotNet _Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension); } if (_FirstRun || !_ArgZeroIsConfigurationRootDirectory) - personContainers = new(); + personContainers = Array.Empty(); else { int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); @@ -738,7 +738,7 @@ public partial class DlibDotNet return results; } - private void DistanceThenMapLogic(string argZero, long ticks, List personContainers, Container[] containers, string dResultsFullGroupDirectory, string eResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string outputResolution) + private void DistanceThenMapLogic(string argZero, long ticks, PersonContainer[] personContainers, Container[] containers, string dResultsFullGroupDirectory, string eResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string outputResolution) { E_Distance distance = new(); if (string.IsNullOrEmpty(eResultsFullGroupDirectory)) @@ -751,14 +751,15 @@ public partial class DlibDotNet E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, eResultsFullGroupDirectory, sortingContainers); int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces); if (totalNotMapped > 0) - mapLogic.ForceSingleImageThenSaveMapping(_MapConfiguration, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces, sortingContainers, totalNotMapped); + mapLogic.ForceSingleImageThenSaveMapping(dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces, sortingContainers, totalNotMapped); + mapLogic.CopyManualFiles(_Resize.FilenameExtension); if (_MapConfiguration.MappingSaveNotMapped) - mapLogic.SaveNotMappedTicks(_MapConfiguration); + mapLogic.SaveNotMappedTicks(); if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) mapLogic.SaveShortcuts(_Configuration.JuliePhares, distinctFilteredFaces); } - private void Search(long ticks, Model? model, PredictorModel? predictorModel, string argZero, string propertyRoot, List personContainers) + private void Search(long ticks, Model? model, PredictorModel? predictorModel, string argZero, string propertyRoot, PersonContainer[] personContainers) { int j; int f; diff --git a/Instance/Models/_A2_People.cs b/Instance/Models/_A2_People.cs index c04b187..570350e 100644 --- a/Instance/Models/_A2_People.cs +++ b/Instance/Models/_A2_People.cs @@ -44,9 +44,9 @@ internal class A2_People } } - internal static List GetPersonContainers(Configuration configuration, Property.Models.Configuration propertyConfiguration) + internal static PersonContainer[] GetPersonContainers(Configuration configuration, Property.Models.Configuration propertyConfiguration) { - List results; + PersonContainer[] results; string rootDirectory = configuration.PropertyConfiguration.RootDirectory; string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People)); string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory)); diff --git a/Instance/Models/_E_Distance.cs b/Instance/Models/_E_Distance.cs index ab3e8b5..bc8a6df 100644 --- a/Instance/Models/_E_Distance.cs +++ b/Instance/Models/_E_Distance.cs @@ -205,9 +205,9 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People), "{}"); foreach ((string[] personDisplayDirectoryNames, PersonContainer personContainer) in possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) { - if (personContainer.PersonKey is null || personContainer.PersonBirthdays is null || !personContainer.PersonBirthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) continue; - personBirthday = personContainer.PersonBirthdays[zero]; + personBirthday = personContainer.Birthdays[zero]; personDisplayDirectoryName = personDisplayDirectoryNames[^1]; personDisplayDirectory = Path.Combine(personDisplayDirectoryNames); personKeyFormatted = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthdayFormat, personBirthday); diff --git a/Instance/Models/_G2_Identify.cs b/Instance/Models/_G2_Identify.cs index a9d8eee..e44d74f 100644 --- a/Instance/Models/_G2_Identify.cs +++ b/Instance/Models/_G2_Identify.cs @@ -88,7 +88,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify } json = File.ReadAllText(named.FullName); Dictionary resultKeyValuePairs = new(); - List personContainers = A2_People.GetPersonContainers(_Configuration, configuration); + PersonContainer[] personContainers = A2_People.GetPersonContainers(_Configuration, configuration); string[] peopleBirthDates = (from l in personContainers select Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, l.Person.Birthday)).ToArray(); Dictionary sourceKeyValuePairs = JsonSerializer.Deserialize>(json); foreach (KeyValuePair keyValuePair in sourceKeyValuePairs) diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 3af8e98..11940cb 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -30,7 +30,7 @@ public class MapLogic private readonly string _FacesHiddenFilenameExtension; private readonly string _EDistanceContentTicksDirectory; - public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string resizeFilenameExtension, string facesFilenameExtension, string facesHiddenFilenameExtension, string facePartsFilenameExtension, long ticks, List personContainers, string eResultsFullGroupDirectory, List distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? faceDistance) + public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string resizeFilenameExtension, string facesFilenameExtension, string facesHiddenFilenameExtension, string facePartsFilenameExtension, long ticks, PersonContainer[] personContainers, string eResultsFullGroupDirectory, List distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? faceDistance) { _Ticks = ticks; _Configuration = configuration; @@ -66,7 +66,12 @@ public class MapLogic if (!Directory.Exists(eDistanceContentTicksDirectory)) _ = Directory.CreateDirectory(eDistanceContentTicksDirectory); if (configuration is not null && faceDistance is not null) - Stateless.MapLogic.Set(propertyConfiguration, configuration, resizeFilenameExtension, ticks, personContainers, eDistanceContentDirectory, distinctFilteredFaces, faceDistance, personKeyToPersonContainer, personKeyToRanges, notMappedPersonContainers, skipCollection, idThenNormalizedPixelPercentageToPersonContainers); + { + List personContainerCollection = new(personContainers); + Stateless.MapLogic.Set(propertyConfiguration, configuration, resizeFilenameExtension, ticks, personContainerCollection, eDistanceContentDirectory, distinctFilteredFaces, faceDistance, personKeyToPersonContainer, personKeyToRanges, notMappedPersonContainers, skipCollection, idThenNormalizedPixelPercentageToPersonContainers); + if (personContainerCollection.Count == personContainers.Length) + throw new NotSupportedException(); + } foreach (string propertyContentCollectionFile in propertyConfiguration.PropertyContentCollectionFiles) { fullPath = Path.GetFullPath(string.Concat(rootDirectoryParent, propertyContentCollectionFile)); @@ -87,7 +92,7 @@ public class MapLogic _IdThenNormalizedPixelPercentageToPersonContainers = idThenNormalizedPixelPercentageToPersonContainers; } - public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string outputExtension, long ticks, List personContainers, string eResultsFullGroupDirectory) : + public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string outputExtension, long ticks, PersonContainer[] personContainers, string eResultsFullGroupDirectory) : this(maxDegreeOfParallelism, propertyConfiguration, configuration, outputExtension, outputExtension, outputExtension, outputExtension, ticks, personContainers, eResultsFullGroupDirectory, new(), null) { } @@ -102,11 +107,11 @@ public class MapLogic List<(long, long, long, long)> results = new(); foreach (PersonContainer personContainer in personContainers) { - if (personContainer.PersonKey is null) + if (personContainer.Key is null) continue; - if (!_PersonKeyToRanges.ContainsKey(personContainer.PersonKey.Value)) + if (!_PersonKeyToRanges.ContainsKey(personContainer.Key.Value)) continue; - results.Add(_PersonKeyToRanges[personContainer.PersonKey.Value]); + results.Add(_PersonKeyToRanges[personContainer.Key.Value]); } return results; } @@ -193,7 +198,7 @@ public class MapLogic if (personKey is not null && _PersonKeyToPersonContainer.ContainsKey(personKey.Value)) { personContainer = _PersonKeyToPersonContainer[personKey.Value]; - fullName = string.Concat(personContainer.PersonDisplayDirectoryName, ".txt"); + fullName = string.Concat(personContainer.DisplayDirectoryName, ".txt"); File.WriteAllText(Path.Combine(directory, fullName), string.Empty); } } @@ -275,11 +280,11 @@ public class MapLogic } foreach (PersonContainer personContainer in personContainers) { - if (personContainer.PersonKey is null || personContainer.PersonBirthdays is null || !personContainer.PersonBirthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) continue; - personBirthday = personContainer.PersonBirthdays[zero]; + personBirthday = personContainer.Birthdays[zero]; mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, face.Mapping.MappingFromItem); - face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.PersonDisplayDirectoryName, personBirthday, mappingSegmentB); + face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB); } } return result; @@ -341,7 +346,7 @@ public class MapLogic } } - public void SaveNotMappedTicks(Configuration configuration) + public void SaveNotMappedTicks() { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); @@ -354,11 +359,11 @@ public class MapLogic const string facePopulatedKey = nameof(_Sorting); foreach (PersonContainer personContainer in _NotMappedPersonContainers) { - if (personContainer.PersonKey is null || personContainer.PersonBirthdays is null || !personContainer.PersonBirthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) continue; - personBirthday = personContainer.PersonBirthdays[zero]; + personBirthday = personContainer.Birthdays[zero]; personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday); - directory = Path.Combine(_EDistanceContentTicksDirectory, $"{facePopulatedKey}NotMapped", personKeyFormatted, configuration.MappingDefaultName); + directory = Path.Combine(_EDistanceContentTicksDirectory, $"{facePopulatedKey}NotMapped", personKeyFormatted, _Configuration.MappingDefaultName); saveContainer = new(directory); saveContainers.Add(saveContainer); } @@ -414,10 +419,10 @@ public class MapLogic { if (personContainers.Length != 1) break; - if (personContainer.PersonKey is null || personContainer.PersonBirthdays is null || !personContainer.PersonBirthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) continue; - personKey = personContainer.PersonKey.Value; - personBirthday = personContainer.PersonBirthdays[zero]; + personKey = personContainer.Key.Value; + personBirthday = personContainer.Birthdays[zero]; timeSpan = IPersonBirthday.GetTimeSpan(face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromItem.IsWrongYear, personBirthday); if (timeSpan.HasValue) { @@ -490,9 +495,9 @@ public class MapLogic continue; foreach (PersonContainer personContainer in personContainers) { - if (personContainer.PersonKey is null || personContainer.PersonBirthdays is null || !personContainer.PersonBirthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) continue; - personBirthday = personContainer.PersonBirthdays[zero]; + personBirthday = personContainer.Birthdays[zero]; personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday); mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, sortingContainer.Face.Mapping.MappingFromItem); key = string.Concat(personKeyFormatted, '\t', mappingSegmentB); @@ -502,7 +507,7 @@ public class MapLogic if (checkCollection.Count > _Configuration.SortingMaximumPerKey) continue; _ = hashSet.Add(sortingContainer.Sorting.NormalizedPixelPercentage); - sortingContainer.Face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.PersonDisplayDirectoryName, personBirthday, mappingSegmentB); + sortingContainer.Face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB); checkCollection.Add(sortingContainer.Face.Mapping); result += 1; break; @@ -511,14 +516,16 @@ public class MapLogic return result; } - internal void ForceSingleImage(Configuration configuration, IEnumerable distinctFilteredFaces) + internal void ForceSingleImage(IEnumerable distinctFilteredFaces) { + if (_Configuration is null) + throw new NullReferenceException(nameof(_Configuration)); const int zero = 0; string mappingSegmentB; int by = _ForceSingleImage; PersonBirthday personBirthday; List normalizedPixelPercentages; - string displayDirectoryName = configuration.MappingDefaultName; + string displayDirectoryName = _Configuration.MappingDefaultName; Face[] orderedDistinctFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromLocation.Confidence descending select l).ToArray(); foreach (Face face in orderedDistinctFilteredFaces) { @@ -534,11 +541,11 @@ public class MapLogic } foreach (PersonContainer personContainer in _NotMappedPersonContainers) { - if (personContainer.PersonKey is null || personContainer.PersonBirthdays is null || !personContainer.PersonBirthdays.Any()) + if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) continue; - personBirthday = personContainer.PersonBirthdays[zero]; + personBirthday = personContainer.Birthdays[zero]; mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, face.Mapping.MappingFromItem); - face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.PersonDisplayDirectoryName, personBirthday, mappingSegmentB); + face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB); break; } break; @@ -627,22 +634,71 @@ public class MapLogic return results; } - public void ForceSingleImageThenSaveMapping(Configuration configuration, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List distinctFilteredFaces, SortingContainer[] sortingContainers, int totalNotMapped) + public void ForceSingleImageThenSaveMapping(string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List distinctFilteredFaces, SortingContainer[] sortingContainers, int totalNotMapped) { List saveContainers; if (!sortingContainers.Any()) { - ForceSingleImage(configuration, distinctFilteredFaces); + ForceSingleImage(distinctFilteredFaces); saveContainers = GetMappingSaveContainers(dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces); } else { int updated = UpdateFromSortingContainers(sortingContainers); if (totalNotMapped - updated > 0) - ForceSingleImage(configuration, distinctFilteredFaces); + ForceSingleImage(distinctFilteredFaces); saveContainers = GetMappingSaveContainers(dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces); } SaveContainers(saveContainers); } + public void CopyManualFiles(string resizeFilenameExtension) + { + if (_Configuration is null) + throw new NullReferenceException(nameof(_Configuration)); + int? id; + string checkFile; + string directory; + FileInfo fileInfo; + const int zero = 0; + string mappingSegmentB; + string personDirectory; + string personKeyFormatted; + string by = nameof(_Sorting); + PersonBirthday personBirthday; + int? normalizedPixelPercentage; + Dictionary keyValuePairs; + foreach (KeyValuePair keyValuePair in _PersonKeyToPersonContainer) + { + if (keyValuePair.Value.Key is null || keyValuePair.Value.Birthdays is null || !keyValuePair.Value.Birthdays.Any()) + continue; + personBirthday = keyValuePair.Value.Birthdays[zero]; + foreach (string personDisplayDirectoryAllFile in keyValuePair.Value.DisplayDirectoryAllFiles) + { + fileInfo = new(personDisplayDirectoryAllFile); + if (!fileInfo.Exists || !personDisplayDirectoryAllFile.EndsWith(resizeFilenameExtension)) + continue; + (id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(_Configuration.LocationDigits, personDisplayDirectoryAllFile); + if (id is null || normalizedPixelPercentage is null) + continue; + if (_IdThenNormalizedPixelPercentageToPersonContainers.ContainsKey(id.Value)) + { + keyValuePairs = _IdThenNormalizedPixelPercentageToPersonContainers[id.Value]; + if (keyValuePairs.ContainsKey(normalizedPixelPercentage.Value)) + continue; + } + personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday); + mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, keyValuePair.Value.ApproximateYears, fileInfo.CreationTime, isWrongYear: null); + directory = Path.Combine(_EDistanceContentTicksDirectory, by[1..], personKeyFormatted, mappingSegmentB); + personDirectory = Path.Combine(directory, keyValuePair.Value.DisplayDirectoryName, "lnk"); + if (!Directory.Exists(personDirectory)) + _ = Directory.CreateDirectory(personDirectory); + checkFile = Path.Combine(directory, fileInfo.Name); + if (File.Exists(checkFile)) + continue; + File.Copy(personDisplayDirectoryAllFile, checkFile); + } + } + } + } \ No newline at end of file diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index 7b4be25..e3e837f 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -42,7 +42,7 @@ internal abstract class MapLogic string newestPersonKeyFormatted; foreach (PersonContainer personContainer in personContainers) { - foreach (string personDisplayDirectoryAllFile in personContainer.PersonDisplayDirectoryAllFiles) + foreach (string personDisplayDirectoryAllFile in personContainer.DisplayDirectoryAllFiles) { if (Path.GetExtension(personDisplayDirectoryAllFile) != resizeFilenameExtension) continue; @@ -53,20 +53,20 @@ internal abstract class MapLogic skipCollection.Add(id.Value, new()); skipCollection[id.Value].Add(normalizedPixelPercentage.Value); } - if (personContainer.Person is null || personContainer.PersonKey is null || personContainer.PersonBirthdays is null || !personContainer.PersonBirthdays.Any()) + if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) continue; - foreach (PersonBirthday personBirthday in personContainer.PersonBirthdays) + foreach (PersonBirthday personBirthday in personContainer.Birthdays) { personKey = personBirthday.Value.Ticks; personKeys.Add(personKey); } - foreach (PersonBirthday personBirthday in personContainer.PersonBirthdays) + foreach (PersonBirthday personBirthday in personContainer.Birthdays) { personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday); personKeyFormattedCollection.Add(personKeyFormatted); - if (personContainer.PersonBirthdays.Length < 1) + if (personContainer.Birthdays.Length < 1) continue; - newestPersonKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personContainer.PersonKey.Value); + newestPersonKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personContainer.Key.Value); if (!personKeyFormattedToNewestPersonKeyFormatted.ContainsKey(personKeyFormatted)) personKeyFormattedToNewestPersonKeyFormatted.Add(personKeyFormatted, newestPersonKeyFormatted); } @@ -119,8 +119,6 @@ internal abstract class MapLogic foreach (string personKeyDirectory in personKeyDirectories) { personKeyFormatted = Path.GetFileName(personKeyDirectory); - if (personKeyFormatted.Length != configuration.PersonBirthdayFormat.Length) - continue; yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string yearDirectory in yearDirectories) { @@ -147,6 +145,8 @@ internal abstract class MapLogic throw new Exception($"Move personKey directories up one from {nameof(Models.MapLogic.ForceSingleImage)} and delete {nameof(Models.MapLogic.ForceSingleImage)} directory!"); if (personKeyFormatted == nameof(Sorting) && files.Any()) throw new Exception($"Move personKey directories up one from {nameof(Sorting)} and delete {nameof(Sorting)} directory!"); + if (personKeyFormatted.Length != configuration.PersonBirthdayFormat.Length) + continue; foreach (string file in files) { if (file.EndsWith(".lnk") || file.EndsWith(".json")) @@ -207,7 +207,7 @@ internal abstract class MapLogic List distinctCheck = new(); foreach (PersonContainer personContainer in personContainers) { - if (personContainer.PersonKey is null || distinctCheck.Contains(personContainer.PersonKey.Value)) + if (personContainer.Key is null || distinctCheck.Contains(personContainer.Key.Value)) continue; results.Add(personContainer); } @@ -217,24 +217,33 @@ internal abstract class MapLogic private static void SetKeyValuePairs(Configuration configuration, long ticks, List personContainers, List distinctFilteredFaces, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, Dictionary personKeyToPersonContainer, Dictionary> idThenNormalizedPixelPercentageToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, Dictionary> incorrectIdThenNormalizedPixelPercentageToPersonContainers, Dictionary personKeyToRanges) { string check; + const int zero = 0; string rightPadded; PersonBirthday? personBirthday; string newestPersonKeyFormatted; PersonContainer[] distinctPersonContainers; int normalizedPixelPercentageInDecimalForm; Dictionary personKeyFormattedToPersonContainer = new(); + Dictionary> personKeyToPersonContainerCollection = new(); Dictionary>> idThenNormalizedPixelPercentageToPersonContainerCollection = new(); Dictionary>> incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection = new(); foreach (PersonContainer personContainer in personContainers) { - if (personContainer.PersonKey is null) + if (personContainer.Key is null) continue; - if (!personKeyToPersonContainer.ContainsKey(personContainer.PersonKey.Value)) - personKeyToPersonContainer.Add(personContainer.PersonKey.Value, personContainer); - newestPersonKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personContainer.PersonKey.Value); + if (!personKeyToPersonContainerCollection.ContainsKey(personContainer.Key.Value)) + personKeyToPersonContainerCollection.Add(personContainer.Key.Value, new()); + personKeyToPersonContainerCollection[personContainer.Key.Value].Add(personContainer); + newestPersonKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personContainer.Key.Value); if (!personKeyFormattedToPersonContainer.ContainsKey(newestPersonKeyFormatted)) personKeyFormattedToPersonContainer.Add(newestPersonKeyFormatted, personContainer); } + foreach (KeyValuePair> keyValuePair in personKeyToPersonContainerCollection) + { + if (keyValuePair.Value.Count != 1) + throw new NotImplementedException(); + personKeyToPersonContainer.Add(keyValuePair.Key, keyValuePair.Value[zero]); + } if (personKeyFormattedIdThenNormalizedPixelPercentageCollection.Any()) { string personDisplayDirectory; @@ -567,11 +576,11 @@ internal abstract class MapLogic personContainers = keyValuePairs[face.Mapping.MappingFromLocation.NormalizedPixelPercentage]; foreach (PersonContainer personContainer in personContainers) { - if (personContainer.PersonKey is null) + if (personContainer.Key is null) continue; - if (!personTicks.ContainsKey(personContainer.PersonKey.Value)) - personTicks.Add(personContainer.PersonKey.Value, new()); - personTicks[personContainer.PersonKey.Value].Add(face.Mapping.MappingFromItem.MinimumDateTime.Ticks); + if (!personTicks.ContainsKey(personContainer.Key.Value)) + personTicks.Add(personContainer.Key.Value, new()); + personTicks[personContainer.Key.Value].Add(face.Mapping.MappingFromItem.MinimumDateTime.Ticks); } } SetPersonKeysRanges(ticks, personTicks, personKeyToRanges); @@ -584,17 +593,17 @@ internal abstract class MapLogic List notMappedAndWithNamedPersonKeys = new(); foreach (PersonContainer personContainer in personContainers) { - if (personContainer.Person is null || personContainer.PersonKey is null || personContainer.PersonBirthdays is null || !personContainer.PersonBirthdays.Any()) + if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) continue; - if (personKeyCollection.Contains(personContainer.PersonKey.Value)) + if (personKeyCollection.Contains(personContainer.Key.Value)) continue; - else if (string.IsNullOrEmpty(personContainer.PersonDisplayDirectoryName) || personContainer.PersonDisplayDirectoryName == configuration.MappingDefaultName) + else if (string.IsNullOrEmpty(personContainer.DisplayDirectoryName) || personContainer.DisplayDirectoryName == configuration.MappingDefaultName) notMappedAndNotNamedPersonKeys.Add(personContainer); else notMappedAndWithNamedPersonKeys.Add(personContainer); } - results.AddRange(from l in notMappedAndNotNamedPersonKeys orderby l.PersonKey is not null, l.PersonKey select l); - results.AddRange(from l in notMappedAndWithNamedPersonKeys orderby l.PersonKey is not null, l.PersonKey select l); + results.AddRange(from l in notMappedAndNotNamedPersonKeys orderby l.Key is not null, l.Key select l); + results.AddRange(from l in notMappedAndWithNamedPersonKeys orderby l.Key is not null, l.Key select l); return results; } @@ -618,18 +627,18 @@ internal abstract class MapLogic string personDisplayDirectoryName; foreach (PersonContainer personContainer in personContainers) { - if (personContainer.PersonKey is null || !personKeyCollection.Contains(personContainer.PersonKey.Value)) + if (personContainer.Key is null || !personKeyCollection.Contains(personContainer.Key.Value)) continue; - if (personKeyToPersonContainer.ContainsKey(personContainer.PersonKey.Value)) + if (personKeyToPersonContainer.ContainsKey(personContainer.Key.Value)) { - personDisplayDirectoryName = personKeyToPersonContainer[personContainer.PersonKey.Value].PersonDisplayDirectoryName; + personDisplayDirectoryName = personKeyToPersonContainer[personContainer.Key.Value].DisplayDirectoryName; if (string.IsNullOrEmpty(personDisplayDirectoryName)) throw new NotSupportedException(); - if (personDisplayDirectoryName == personContainer.PersonDisplayDirectoryName || (personDisplayDirectoryName[0] == personContainer.PersonDisplayDirectoryName[0] && (personDisplayDirectoryName.Length == 1 || personContainer.PersonDisplayDirectoryName.Length == 1))) + if (personDisplayDirectoryName == personContainer.DisplayDirectoryName || (personDisplayDirectoryName[0] == personContainer.DisplayDirectoryName[0] && (personDisplayDirectoryName.Length == 1 || personContainer.DisplayDirectoryName.Length == 1))) continue; throw new NotImplementedException(); } - personKeyToPersonContainer.Add(personContainer.PersonKey.Value, personContainer); + personKeyToPersonContainer.Add(personContainer.Key.Value, personContainer); } if (personKeyCollection.Any()) { @@ -685,7 +694,7 @@ internal abstract class MapLogic { progressBar.Tick(); foreach (KeyValuePair keyValue in keyValuePair.Value) - nullablePersonKeyCollection.AddRange(from l in keyValue.Value select l.PersonKey); + nullablePersonKeyCollection.AddRange(from l in keyValue.Value select l.Key); } } long[] personKeyCollection = (from l in nullablePersonKeyCollection where l is not null select l.Value).Distinct().ToArray(); diff --git a/Shared/Models/PersonContainer.cs b/Shared/Models/PersonContainer.cs index db89ea0..8fd5863 100644 --- a/Shared/Models/PersonContainer.cs +++ b/Shared/Models/PersonContainer.cs @@ -8,20 +8,20 @@ public class PersonContainer : Properties.IPersonContainer public int? ApproximateYears { init; get; } public Person? Person { init; get; } - public PersonBirthday[]? PersonBirthdays { init; get; } - public string[] PersonDisplayDirectoryAllFiles { init; get; } - public string PersonDisplayDirectoryName { init; get; } - public long? PersonKey { init; get; } + public PersonBirthday[]? Birthdays { init; get; } + public string[] DisplayDirectoryAllFiles { init; get; } + public string DisplayDirectoryName { init; get; } + public long? Key { init; get; } [JsonConstructor] public PersonContainer(int? approximateYears, Person? person, PersonBirthday[]? personBirthdays, string[] personDisplayDirectoryAllFiles, string personDisplayDirectoryName, long? personKey) { ApproximateYears = approximateYears; Person = person; - PersonBirthdays = personBirthdays; - PersonDisplayDirectoryAllFiles = personDisplayDirectoryAllFiles; - PersonDisplayDirectoryName = personDisplayDirectoryName; - PersonKey = personKey; + Birthdays = personBirthdays; + DisplayDirectoryAllFiles = personDisplayDirectoryAllFiles; + DisplayDirectoryName = personDisplayDirectoryName; + Key = personKey; } public PersonContainer(int? approximateYears, string[] personDisplayDirectoryAllFiles, string personDisplayDirectoryName) : diff --git a/Shared/Models/Properties/IPersonContainer.cs b/Shared/Models/Properties/IPersonContainer.cs index 68ecf69..fed6c4e 100644 --- a/Shared/Models/Properties/IPersonContainer.cs +++ b/Shared/Models/Properties/IPersonContainer.cs @@ -5,9 +5,9 @@ public interface IPersonContainer public int? ApproximateYears { init; get; } public Person? Person { init; get; } - public PersonBirthday[]? PersonBirthdays { init; get; } - public string[] PersonDisplayDirectoryAllFiles { init; get; } - public string PersonDisplayDirectoryName { init; get; } - public long? PersonKey { init; get; } + public PersonBirthday[]? Birthdays { init; get; } + public string[] DisplayDirectoryAllFiles { init; get; } + public string DisplayDirectoryName { init; get; } + public long? Key { init; get; } } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/IPersonContainer.cs b/Shared/Models/Stateless/Methods/IPersonContainer.cs index b619e1f..6083ad2 100644 --- a/Shared/Models/Stateless/Methods/IPersonContainer.cs +++ b/Shared/Models/Stateless/Methods/IPersonContainer.cs @@ -5,9 +5,9 @@ public interface IPersonContainer // ... - List TestStatic_GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat) => + Models.PersonContainer[] TestStatic_GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat) => GetPersonContainers(storage, personBirthdayFormat); - static List GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat) => + static Models.PersonContainer[] GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat) => PersonContainer.GetPersonContainers(storage, personBirthdayFormat); } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/PersonContainer.cs b/Shared/Models/Stateless/Methods/PersonContainer.cs index 6e992fb..c4f35c8 100644 --- a/Shared/Models/Stateless/Methods/PersonContainer.cs +++ b/Shared/Models/Stateless/Methods/PersonContainer.cs @@ -3,9 +3,9 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class PersonContainer { - private static List GetPersonContainersCollections(string personBirthdayFormat, char[] chars, string personDisplayDirectory, string personDisplayDirectoryName, string[] personKeyDirectories, int? approximateYears, List collections) + private static List<(long?, Models.PersonContainer)> GetPersonContainersCollections(string personBirthdayFormat, char[] chars, string personDisplayDirectory, string personDisplayDirectoryName, string[] personKeyDirectories, int? approximateYears, List collections) { - List results = new(); + List<(long?, Models.PersonContainer)> results = new(); long personKey; string[] segments; const int zero = 0; @@ -25,7 +25,7 @@ internal abstract class PersonContainer segments = personDisplayDirectoryName.Split(chars); person = IPerson.GetPerson(personKey, segments); personContainer = new(approximateYears, person, personBirthdays, personDisplayDirectoryAllFiles, personDisplayDirectoryName, personKey); - results.Add(personContainer); + results.Add(new(personKey, personContainer)); } return results; } @@ -38,12 +38,13 @@ internal abstract class PersonContainer return result; } - private static List GetPersonContainersGroup(string personBirthdayFormat, char[] chars, string[] personDisplayDirectories) + private static List<(long?, Models.PersonContainer)> GetPersonContainersGroup(string personBirthdayFormat, char[] chars, string[] personDisplayDirectories) { - List results = new(); + List<(long?, Models.PersonContainer)> results = new(); int? approximateYears; string[] personKeyDirectories; string? personDisplayDirectoryName; + Models.PersonContainer personContainer; List collections; foreach (string personDisplayDirectory in personDisplayDirectories) { @@ -53,36 +54,41 @@ internal abstract class PersonContainer approximateYears = Age.GetApproximateYears(personDisplayDirectoryName, chars); personKeyDirectories = Directory.GetDirectories(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly); collections = PersonBirthday.GetPersonBirthdays(personBirthdayFormat, personKeyDirectories, personDisplayDirectory); - if (!collections.Any()) - results.Add(GetPersonContainer(personDisplayDirectory, personDisplayDirectoryName, approximateYears)); - else + if (collections.Any()) results.AddRange(GetPersonContainersCollections(personBirthdayFormat, chars, personDisplayDirectory, personDisplayDirectoryName, personKeyDirectories, approximateYears, collections)); + else + { + personContainer = GetPersonContainer(personDisplayDirectory, personDisplayDirectoryName, approximateYears); + results.Add(new(null, personContainer)); + } } return results; } - private static List GetPersonContainersGroups(string personBirthdayFormat, char[] chars, string[] groupDirectories) + private static Models.PersonContainer[] GetPersonContainersGroups(string personBirthdayFormat, char[] chars, string[] groupDirectories) { - List results = new(); + Models.PersonContainer[] results; const int zero = 0; string groupDirectoryName; string[] personDisplayDirectories; - List personContainers; + List<(long?, Models.PersonContainer)> collection; + List<(long? PersonKey, Models.PersonContainer PersonContainer)> personContainers = new(); foreach (string groupDirectory in groupDirectories) { groupDirectoryName = Path.GetFileName(groupDirectory); if (!chars.Contains(groupDirectoryName[zero])) continue; personDisplayDirectories = Directory.GetDirectories(groupDirectory, "*", SearchOption.TopDirectoryOnly); - personContainers = GetPersonContainersGroup(personBirthdayFormat, chars, personDisplayDirectories); - results.AddRange(personContainers); + collection = GetPersonContainersGroup(personBirthdayFormat, chars, personDisplayDirectories); + personContainers.AddRange(collection); } + results = (from l in personContainers orderby l.PersonKey is not null, l.PersonKey select l.PersonContainer).ToArray(); return results; } - internal static List GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat) + internal static Models.PersonContainer[] GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat) { - List results; + Models.PersonContainer[] results; char[] chars = IAge.GetChars(); string a2PeopleSingletonDirectory = Path.Combine(storage.PeopleRootDirectory, "{}"); if (!Directory.Exists(a2PeopleSingletonDirectory)) @@ -96,7 +102,7 @@ internal abstract class PersonContainer } string[] groupDirectories = Directory.GetDirectories(a2PeopleSingletonDirectory, "*", SearchOption.TopDirectoryOnly); if (!groupDirectories.Any()) - results = new(); + results = Array.Empty(); else results = GetPersonContainersGroups(personBirthdayFormat, chars, groupDirectories); return results;