From 2da3db7aa54b9832cee900145b8a7bb20d4bf54d Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Wed, 21 Dec 2022 22:54:50 -0700 Subject: [PATCH] Sorting without ... improvements --- Distance/Models/MapLogicSupport.cs | 2 +- Distance/Models/_E_Distance.cs | 60 +++--- Drag-Drop/Form.cs | 4 +- Drag-Drop/Models/Binder/Configuration.cs | 6 +- Drag-Drop/Models/Configuration.cs | 6 +- Instance/DlibDotNet.cs | 105 +++++++---- Instance/Models/Binder/Configuration.cs | 6 +- Instance/Models/Configuration.cs | 6 +- Map/Models/MapLogic.cs | 174 +++++++++--------- Map/Models/Stateless/MapLogic.cs | 115 ++++-------- Map/Models/Stateless/Methods/IMapLogic.cs | 4 +- Metadata/Models/Stateless/IMetadata.cs | 16 +- Metadata/Models/Stateless/Metadata.cs | 44 ++--- Shared/Models/Mapping.cs | 12 +- {Map => Shared}/Models/Stateless/IMapLogic.cs | 2 +- Shared/Models/Stateless/Methods/IAge.cs | 2 +- Shared/Models/Stateless/Methods/ILocation.cs | 16 +- Shared/Models/Stateless/Methods/IMapping.cs | 11 +- Shared/Models/Stateless/Methods/Location.cs | 75 +++++--- Shared/Models/Stateless/Methods/Mapping.cs | 19 +- .../Stateless/Methods/PersonContainer.cs | 2 +- Tests/Models/Binder/Configuration.cs | 6 +- Tests/Models/Configuration.cs | 6 +- .../Models/Binder/Configuration.cs | 6 +- .../Models/Configuration.cs | 6 +- 25 files changed, 353 insertions(+), 358 deletions(-) rename {Map => Shared}/Models/Stateless/IMapLogic.cs (81%) diff --git a/Distance/Models/MapLogicSupport.cs b/Distance/Models/MapLogicSupport.cs index 9f4ee38..6e1086f 100644 --- a/Distance/Models/MapLogicSupport.cs +++ b/Distance/Models/MapLogicSupport.cs @@ -385,7 +385,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport return result; } - public static void BeforeSaveResizedImagesByPersonKeyFormatted(string[] jLinks, string a2PeopleSingletonDirectory) + public static void BeforeSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleSingletonDirectory) { string[] files; string checkDirectory; diff --git a/Distance/Models/_E_Distance.cs b/Distance/Models/_E_Distance.cs index 7fd1084..32eb9d7 100644 --- a/Distance/Models/_E_Distance.cs +++ b/Distance/Models/_E_Distance.cs @@ -163,8 +163,11 @@ public partial class E_Distance (Face, double?)[] results; List<(Face Face, double? Length)> collection = GetValues(mappingFromItem, filteredFaces, modelsFaceEncoding, normalizedRectangle); results = (from l in collection orderby l.Length select l).Take(1).ToArray(); - (Face _, double? length) = results.First(); - _Debug.Add(length); + if (results.Any()) + { + (Face _, double? length) = results.First(); + _Debug.Add(length); + } return results; } @@ -240,30 +243,33 @@ public partial class E_Distance private static List FilterByIntersect(Face[] faces, int normalizedRectangle) { List results = new(); - results.AddRange(faces); - // double? percent; - // System.Drawing.Rectangle checkRectangle; - // System.Drawing.Rectangle sourceRectangle; - // System.Drawing.Rectangle intersectRectangle; - // string npp = normalizedRectangle.ToString(); - // foreach (Face face in faces) - // { - // if (face.Location is null || face.OutputResolution is null) - // continue; - // sourceRectangle = new(npp, npp, npp, npp); - // checkRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top); - // intersectRectangle = System.Drawing.Rectangle.Intersect(sourceRectangle, checkRectangle); - // if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0) - // continue; - // percent = (double)intersectRectangle.Width * intersectRectangle.Height / (checkRectangle.Width * checkRectangle.Height); - // if (percent < 0.000001) - // continue; - // results.Add(face); - // } + bool useOldWay; + double? percent; + System.Drawing.Rectangle checkRectangle; + System.Drawing.Rectangle sourceRectangle; + System.Drawing.Rectangle intersectRectangle; + foreach (Face face in faces) + { + if (face.Location is null || face.OutputResolution is null) + continue; + checkRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top); + for (int i = 1; i < 3; i++) + { + useOldWay = i == 1; + sourceRectangle = Shared.Models.Stateless.Methods.ILocation.GetRectangle(checkRectangle, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, normalizedRectangle, face.OutputResolution, useOldWay); + intersectRectangle = System.Drawing.Rectangle.Intersect(sourceRectangle, checkRectangle); + if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0) + continue; + percent = (double)intersectRectangle.Width * intersectRectangle.Height / (checkRectangle.Width * checkRectangle.Height); + if (percent < 0.000001) + continue; + results.Add(face); + } + } return results; } - public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, string? eDistanceContentDirectory, MappingFromItem mappingFromItem, List faces, List<(string MappedFaceFile, int normalizedRectangle)> collection) + public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, string? eDistanceContentDirectory, MappingFromItem mappingFromItem, List faces, List<(string MappedFaceFile, int NormalizedRectangle, IReadOnlyList? Directories)> collection) { string? json; string[] matches; @@ -274,15 +280,19 @@ public partial class E_Distance Face[] filteredFaces = (from l in faces where l.FaceEncoding is not null && l.Location is not null && l.OutputResolution is not null select l).ToArray(); if (filteredFaces.Length != faces.Count) checkFaces.Clear(); - foreach ((string mappedFaceFile, int normalizedRectangle) in collection) + foreach ((string mappedFaceFile, int normalizedRectangle, IReadOnlyList? directories) in collection) { if (!filteredFaces.Any()) break; + if (_Renamed.Contains(mappedFaceFile)) + continue; mappedFaceFileName = Path.GetFileName(mappedFaceFile); if (_DuplicateMappedFaceFiles.Contains(mappedFaceFileName)) continue; checkFaces.Clear(); - json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(mappedFaceFile); + if (directories is null) + throw new NullReferenceException(nameof(directories)); + json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(directories); if (json is null) { if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch) diff --git a/Drag-Drop/Form.cs b/Drag-Drop/Form.cs index f43ba5a..28e7405 100644 --- a/Drag-Drop/Form.cs +++ b/Drag-Drop/Form.cs @@ -276,12 +276,14 @@ public partial class Form : System.Windows.Forms.Form // bool isValidImageFormatExtension; List<(string, FaceDistance)> collection = new(); Shared.Models.FaceEncoding? modelsFaceEncoding; + IReadOnlyList directories; FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding; _ProgressBar.Maximum = files.Length; foreach (string file in files) { _ProgressBar.PerformStep(); - json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(file); + directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); + json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(directories); if (json is null) break; modelsFaceEncoding = JsonSerializer.Deserialize(json); diff --git a/Drag-Drop/Models/Binder/Configuration.cs b/Drag-Drop/Models/Binder/Configuration.cs index 70a1671..82e97d9 100644 --- a/Drag-Drop/Models/Binder/Configuration.cs +++ b/Drag-Drop/Models/Binder/Configuration.cs @@ -46,7 +46,7 @@ public class Configuration [Display(Name = "Reverse"), Required] public bool? Reverse { get; set; } [Display(Name = "Save Face Landmark For Output Resolutions"), Required] public string[] SaveFaceLandmarkForOutputResolutions { get; set; } [Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; } - [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveResizedImagesByPersonKeyFormattedForOutputResolutions { get; set; } + [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; } [Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; } [Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; } [Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; } @@ -121,7 +121,7 @@ public class Configuration configuration.SaveFaceLandmarkForOutputResolutions ??= Array.Empty(); if (configuration.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); - configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions ??= Array.Empty(); + configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ??= Array.Empty(); if (configuration.SaveResizedSubfiles is null) throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); configuration.SaveShortcutsForOutputResolutions ??= Array.Empty(); @@ -167,7 +167,7 @@ public class Configuration configuration.Reverse.Value, configuration.SaveFaceLandmarkForOutputResolutions, configuration.SaveFullYearOfRandomFiles.Value, - configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions, + configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions, configuration.SaveShortcutsForOutputResolutions, configuration.SaveResizedSubfiles.Value, configuration.SkipSearch.Value, diff --git a/Drag-Drop/Models/Configuration.cs b/Drag-Drop/Models/Configuration.cs index b84cc67..01480b2 100644 --- a/Drag-Drop/Models/Configuration.cs +++ b/Drag-Drop/Models/Configuration.cs @@ -44,7 +44,7 @@ public class Configuration public bool Reverse { init; get; } public string[] SaveFaceLandmarkForOutputResolutions { init; get; } public bool SaveFullYearOfRandomFiles { init; get; } - public string[] SaveResizedImagesByPersonKeyFormattedForOutputResolutions { init; get; } + public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; } public string[] SaveShortcutsForOutputResolutions { init; get; } public bool SaveResizedSubfiles { init; get; } public bool SkipSearch { init; get; } @@ -88,7 +88,7 @@ public class Configuration bool reverse, string[] saveFaceLandmarkForOutputResolutions, bool saveFullYearOfRandomFiles, - string[] saveResizedImagesByPersonKeyFormattedForOutputResolutions, + string[] saveFilteredOriginalImagesFromJLinksForOutputResolutions, string[] saveShortcutsForOutputResolutions, bool saveResizedSubfiles, bool skipSearch, @@ -131,7 +131,7 @@ public class Configuration Reverse = reverse; SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions; SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles; - SaveResizedImagesByPersonKeyFormattedForOutputResolutions = saveResizedImagesByPersonKeyFormattedForOutputResolutions; + SaveFilteredOriginalImagesFromJLinksForOutputResolutions = saveFilteredOriginalImagesFromJLinksForOutputResolutions; SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions; SaveResizedSubfiles = saveResizedSubfiles; SkipSearch = skipSearch; diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 86b9f8e..bdb5276 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -212,8 +212,8 @@ public partial class DlibDotNet throw new Exception($"One or more {nameof(configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions)} are not in the ValidResolutions list!"); if ((from l in configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) throw new Exception($"One or more {nameof(configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions)} are not in the ValidResolutions list!"); - if ((from l in configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) - throw new Exception($"One or more {nameof(configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions)} are not in the ValidResolutions list!"); + if ((from l in configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) + throw new Exception($"One or more {nameof(configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions)} are not in the ValidResolutions list!"); if ((from l in configuration.SaveShortcutsForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) throw new Exception($"One or more {nameof(configuration.SaveShortcutsForOutputResolutions)} are not in the ValidResolutions list!"); if ((from l in configuration.SaveFaceLandmarkForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) @@ -281,7 +281,7 @@ public partial class DlibDotNet return result; } - private void FullParallelForWork(A_Property propertyLogic, Dictionary> idToMappedFaceFilesCollection, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsDateGroupDirectory, string dResultsFullGroupDirectory, string? eDistanceContentDirectory, List> sourceDirectoryChanges, List propertyFileHolderCollection, List propertyCollection, List>> metadataCollections, List> resizeKeyValuePairs, List> imageFaceCollections, Container container, int index, Item item, DateTime[] containerDateTimes) + private void FullParallelForWork(A_Property propertyLogic, Dictionary?)>> idToMappedFaceFilesWithCollection, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsDateGroupDirectory, string dResultsFullGroupDirectory, string? eDistanceContentDirectory, List> sourceDirectoryChanges, List propertyFileHolderCollection, List propertyCollection, List>> metadataCollections, List> resizeKeyValuePairs, List> imageFaceCollections, Container container, int index, Item item, DateTime[] containerDateTimes) { if (_Log is null) throw new NullReferenceException(nameof(_Log)); @@ -358,7 +358,7 @@ public partial class DlibDotNet faces = new(); else { - List<(string, int)>? collection; + List<(string, int, IReadOnlyList?)>? collection; int[] outputResolutionCollection = imageResizeKeyValuePairs[outputResolution]; int outputResolutionWidth = outputResolutionCollection[0]; int outputResolutionHeight = outputResolutionCollection[1]; @@ -370,9 +370,10 @@ public partial class DlibDotNet bool anyFacesSaved = _Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces); if (_AppSettings.MaxDegreeOfParallelism < 2) ticks = LogDelta(ticks, nameof(D_Face.SaveFaces)); - if (_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) + if ((_Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch) + && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) && !anyFacesSaved && item.Property?.Id is not null - && idToMappedFaceFilesCollection.TryGetValue(item.Property.Id.Value, out collection)) + && idToMappedFaceFilesWithCollection.TryGetValue(item.Property.Id.Value, out collection)) _Distance.LookForMatchFacesAndPossiblyRename(_Faces.FileNameExtension, eDistanceContentDirectory, mappingFromItem, faces, collection); if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution)) { @@ -396,7 +397,7 @@ public partial class DlibDotNet private int FullParallelWork(int maxDegreeOfParallelism, A_Property propertyLogic, - Dictionary> idToMappedFaceFilesCollection, + Dictionary?)>> idToMappedFaceFilesWithCollection, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, @@ -440,7 +441,7 @@ public partial class DlibDotNet { FullParallelForWork( propertyLogic, - idToMappedFaceFilesCollection, + idToMappedFaceFilesWithCollection, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, @@ -626,7 +627,7 @@ public partial class DlibDotNet _Metadata.SetAngleBracketCollection(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, container.SourceDirectory); } - private void FullDoWork(string argZero, string propertyRoot, long ticks, A_Property propertyLogic, int t, Container[] containers, string? eDistanceContentDirectory, Dictionary> idToMappedFaceFilesCollection) + private void FullDoWork(string argZero, string propertyRoot, long ticks, PersonContainer[] personContainers, A_Property propertyLogic, int t, Container[] containers, string? a2PeopleContentDirectory, string eDistanceContentDirectory) { if (_Log is null) throw new NullReferenceException(nameof(_Log)); @@ -650,6 +651,7 @@ public partial class DlibDotNet int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism; List nullablePropertyCollection = new(); List>> metadataCollection = new(); + Dictionary?)>> idToMappedFaceFilesWithCollection = GetCollection(ticks, personContainers, a2PeopleContentDirectory, eDistanceContentDirectory); string dResultsDateGroupDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(D_Face)); foreach (string outputResolution in _Configuration.OutputResolutions) { @@ -682,7 +684,7 @@ public partial class DlibDotNet exceptionCount = FullParallelWork( maxDegreeOfParallelism, propertyLogic, - idToMappedFaceFilesCollection, + idToMappedFaceFilesWithCollection, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, @@ -845,7 +847,7 @@ public partial class DlibDotNet return items; } - private void MapLogic(string argZero, long ticks, PersonContainer[] personContainers, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string eDistanceContentDirectory, string outputResolution) + private void MapLogic(string argZero, long ticks, PersonContainer[] personContainers, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, MapLogicSupport mapLogicSupport, MapLogic mapLogic, string outputResolution) { int? useFiltersCounter = null; SortingContainer[] sortingContainers; @@ -854,22 +856,6 @@ public partial class DlibDotNet Shared.Models.Face[] distinctFilteredFaces = GetFilteredDistinctFaces(argZero, containers); Mapping[] mappingCollection = MapLogicSupport.GetSelectedMappingCollection(distinctFilteredFaces); string dFacesCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne); - MapLogicSupport mapLogicSupport = new( - _Configuration.FaceConfidencePercent, - _Configuration.FaceDistancePermyriad, - _Configuration.RangeDaysDeltaTolerance, - _Configuration.RangeFaceAreaPermilleTolerance, - _Configuration.SortingMaximumPerFaceShouldBeHigh); - MapLogic mapLogic = new( - _AppSettings.MaxDegreeOfParallelism, - _Configuration.PropertyConfiguration, - _MapConfiguration, - ticks, - personContainers, - a2PeopleSingletonDirectory, - eDistanceContentDirectory, - mappingCollection, - mapLogicSupport); (Dictionary personKeyToCount, int totalNotMapped) = mapLogic.AddToMapping(mappingCollection); if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution) || (!string.IsNullOrEmpty(_Configuration.PhotoPrismDirectory) && Directory.Exists(_Configuration.PhotoPrismDirectory))) { @@ -889,10 +875,11 @@ public partial class DlibDotNet mapLogic.CopyNotMappedFaces(_Configuration.RangeFaceAreaPermilleTolerance, dFacesContentDirectory, idToNormalizedRectangleToMapping); if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution)) mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToCount, totalNotMapped); - if (_Configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions.Contains(outputResolution)) - mapLogic.SaveResizedImagesByPersonKeyFormatted(_Configuration.JLinks, a2PeopleSingletonDirectory, personContainers, mappingCollection, personKeyToCount, totalNotMapped); + if (_Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution)) + mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, a2PeopleSingletonDirectory, personContainers, mappingCollection, personKeyToCount, totalNotMapped); if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution)) { + mapLogic.UpdatedPersonKeyToRanges(_MapConfiguration, ticks, mappingCollection); MapLogicSupport.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces); Dictionary> missingIdThenNormalizedRectangleToPersonContainers = mapLogic.GetMissing(idToNormalizedRectangleToMapping); List missingFaceDistanceContainers = _Distance.GetMissingFaceDistanceContainer(_AppSettings.MaxDegreeOfParallelism, ticks, dFacesCollectionDirectory, missingIdThenNormalizedRectangleToPersonContainers); @@ -909,7 +896,7 @@ public partial class DlibDotNet MapLogicSupport.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers); if (totalNotMapped > 0) { - bool saveNullPerson = !personKeyToCount.Any(); + bool saveNullPerson = true; // !personKeyToCount.Any(); int updated = mapLogic.UpdateFromSortingContainers(sortingContainers, saveNullPerson); List saveContainers = mapLogic.GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, useFiltersCounter, saveNullPerson); mapLogic.SaveContainers(totalNotMapped, updated, saveContainers); @@ -1014,6 +1001,48 @@ public partial class DlibDotNet return results; } + private void ParallelForAdd(Dictionary?)>> results, (string PersonKeyFormatted, string[] PersonDisplayDirectoryNames, string MappedFaceFile) value) + { + (int? id, int? normalizedRectangle) = Shared.Models.Stateless.Methods.IMapping.GetConverted(_Faces.FileNameExtension, value.MappedFaceFile); + if (id is null || normalizedRectangle is null || !results.TryGetValue(id.Value, out List<(string, int, IReadOnlyList?)>? collection)) + return; + IReadOnlyList directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(value.MappedFaceFile); + lock (collection) + collection.Add(new(value.MappedFaceFile, normalizedRectangle.Value, directories)); + } + + private Dictionary?)>> GetCollection(long ticks, PersonContainer[] personContainers, string? a2PeopleContentDirectory, string? eDistanceContentDirectory) + { + Dictionary?)>> results = new(); + int? id; + int? normalizedRectangle; + List<(string, string[], string)> collection = Map.Models.Stateless.Methods.IMapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(_MapConfiguration, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers); + foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string mappedFaceFile) in collection) + { + (id, normalizedRectangle) = Shared.Models.Stateless.Methods.IMapping.GetConverted(_Faces.FileNameExtension, mappedFaceFile); + if (id is null || normalizedRectangle is null) + continue; + if (!results.ContainsKey(id.Value)) + results.Add(id.Value, new()); + if (!_Configuration.DistanceMoveUnableToMatch && !_Configuration.DistanceRenameToMatch) + results[id.Value].Add(new(mappedFaceFile, normalizedRectangle.Value, null)); + } + if (results.Any() && (_Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch)) + { + int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); + string message = $") Building Mapped Face Files Collection - {totalSeconds} total second(s)"; + ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism }; + ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; + using ProgressBar progressBar = new(collection.Count, message, options); + _ = Parallel.For(0, collection.Count, parallelOptions, (i, state) => + { + ParallelForAdd(results, collection[i]); + progressBar.Tick(); + }); + } + return results; + } + private void Search(long ticks, string argZero, string propertyRoot, PersonContainer[] personContainers) { int j; @@ -1047,7 +1076,9 @@ public partial class DlibDotNet { string resultsGroupDirectory; a2PeopleContentDirectory = null; - eDistanceContentDirectory = null; + eDistanceContentDirectory = Path.GetPathRoot(argZero); + if (eDistanceContentDirectory is null) + throw new NullReferenceException(nameof(eDistanceContentDirectory)); string? newRootDirectory = SaveUrlAndGetNewRootDirectory(container); for (int i = 1; i < 10; i++) { @@ -1059,17 +1090,19 @@ public partial class DlibDotNet propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), create: false); propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse); } - Dictionary> idToMappedFaceFilesCollection = Map.Models.Stateless.Methods.IMapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(_MapConfiguration, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers); containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, _ArgZeroIsConfigurationRootDirectory, argZero, containers); - FullDoWork(argZero, propertyRoot, ticks, propertyLogic, t, containers, eDistanceContentDirectory, idToMappedFaceFilesCollection); + MapLogicSupport mapLogicSupport = new(_Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeFaceAreaPermilleTolerance, _Configuration.SortingMaximumPerFaceShouldBeHigh); + MapLogic? mapLogic = _Configuration.DistanceMoveUnableToMatch ? null : new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, mapLogicSupport); + FullDoWork(argZero, propertyRoot, ticks, personContainers, propertyLogic, t, containers, a2PeopleContentDirectory, eDistanceContentDirectory); _Distance.Clear(); + mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, mapLogicSupport); foreach (string outputResolution in _Configuration.OutputResolutions) { if (_PropertyRootExistedBefore || container is not null) break; (aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution); - if (_Configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions.Contains(outputResolution)) - MapLogicSupport.BeforeSaveResizedImagesByPersonKeyFormatted(_Configuration.JLinks, a2PeopleSingletonDirectory); + if (_Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution)) + MapLogicSupport.BeforeSaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, a2PeopleSingletonDirectory); if (_ArgZeroIsConfigurationRootDirectory && _Configuration.SaveResizedSubfiles && outputResolution == _Configuration.OutputResolutions[0] @@ -1080,7 +1113,7 @@ public partial class DlibDotNet if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any()) break; SetMapping(argZero, containers); - MapLogic(argZero, ticks, personContainers, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eDistanceContentDirectory, outputResolution); + MapLogic(argZero, ticks, personContainers, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, mapLogicSupport, mapLogic, outputResolution); if (_IsEnvironment.Development) continue; List mappingFromItemCollection = GetMappingFromItemCollection(containers); diff --git a/Instance/Models/Binder/Configuration.cs b/Instance/Models/Binder/Configuration.cs index 731bca2..fd8a2af 100644 --- a/Instance/Models/Binder/Configuration.cs +++ b/Instance/Models/Binder/Configuration.cs @@ -69,7 +69,7 @@ public class Configuration [Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; } [Display(Name = "Save Mapped"), Required] public string[] SaveMappedForOutputResolutions { get; set; } [Display(Name = "Save Not Mapped"), Required] public string[] SaveNotMappedForOutputResolutions { get; set; } - [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveResizedImagesByPersonKeyFormattedForOutputResolutions { get; set; } + [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; } [Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; } [Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; } [Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; } @@ -190,7 +190,7 @@ public class Configuration throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); configuration.SaveMappedForOutputResolutions ??= Array.Empty(); configuration.SaveNotMappedForOutputResolutions ??= Array.Empty(); - configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions ??= Array.Empty(); + configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ??= Array.Empty(); if (configuration.SaveResizedSubfiles is null) throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); configuration.SaveShortcutsForOutputResolutions ??= Array.Empty(); @@ -265,7 +265,7 @@ public class Configuration configuration.SaveFullYearOfRandomFiles.Value, configuration.SaveMappedForOutputResolutions, configuration.SaveNotMappedForOutputResolutions, - configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions, + configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions, configuration.SaveResizedSubfiles.Value, configuration.SaveShortcutsForOutputResolutions, configuration.SkipSearch.Value, diff --git a/Instance/Models/Configuration.cs b/Instance/Models/Configuration.cs index e7da88a..a627186 100644 --- a/Instance/Models/Configuration.cs +++ b/Instance/Models/Configuration.cs @@ -65,7 +65,7 @@ public class Configuration public bool SaveFullYearOfRandomFiles { init; get; } public string[] SaveMappedForOutputResolutions { init; get; } public string[] SaveNotMappedForOutputResolutions { init; get; } - public string[] SaveResizedImagesByPersonKeyFormattedForOutputResolutions { init; get; } + public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; } public bool SaveResizedSubfiles { init; get; } public string[] SaveShortcutsForOutputResolutions { init; get; } public bool SkipSearch { init; get; } @@ -133,7 +133,7 @@ public class Configuration bool saveFullYearOfRandomFiles, string[] saveMappedForOutputResolutions, string[] saveNotMappedForOutputResolutions, - string[] saveResizedImagesByPersonKeyFormattedForOutputResolutions, + string[] saveFilteredOriginalImagesFromJLinksForOutputResolutions, bool saveResizedSubfiles, string[] saveShortcutsForOutputResolutions, bool skipSearch, @@ -200,7 +200,7 @@ public class Configuration SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles; SaveMappedForOutputResolutions = saveMappedForOutputResolutions; SaveNotMappedForOutputResolutions = saveNotMappedForOutputResolutions; - SaveResizedImagesByPersonKeyFormattedForOutputResolutions = saveResizedImagesByPersonKeyFormattedForOutputResolutions; + SaveFilteredOriginalImagesFromJLinksForOutputResolutions = saveFilteredOriginalImagesFromJLinksForOutputResolutions; SaveResizedSubfiles = saveResizedSubfiles; SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions; SkipSearch = skipSearch; diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 385cf93..ed0452f 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -2,7 +2,6 @@ using Humanizer; using ShellProgressBar; using System.Text; using System.Text.Json; -using View_by_Distance.Map.Models.Stateless; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Stateless.Methods; using WindowsShortcutFactory; @@ -15,7 +14,7 @@ public class MapLogic protected readonly Dictionary> _SkipCollection; protected readonly List _NotMappedPersonContainers; protected readonly Dictionary _PersonKeyToPersonContainer; - protected readonly Dictionary _PersonKeyToRanges; + protected Dictionary? _PersonKeyToRanges; protected readonly Dictionary> _IdThenNormalizedRectangleToPersonContainers; public Dictionary KeyValuePairs => throw new NotImplementedException(); @@ -29,7 +28,7 @@ public class MapLogic private readonly Shared.Models.Methods.IMapLogicSupport? _MapLogicSupport; private readonly Shared.Models.Properties.IPropertyConfiguration _PropertyConfiguration; - public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, Mapping[] mappingCollection, Shared.Models.Methods.IMapLogicSupport? mapLogicSupport) + public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, Shared.Models.Methods.IMapLogicSupport? mapLogicSupport) { _Ticks = ticks; _Configuration = configuration; @@ -50,7 +49,6 @@ public class MapLogic List notMappedPersonContainers = new(); Dictionary personKeyToPersonContainer = new(); string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory); - Dictionary personKeyToRanges = new(); string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})"); Dictionary> idThenNormalizedRectangleToPersonContainers = new(); for (int i = 1; i < 5; i++) @@ -71,10 +69,8 @@ public class MapLogic personContainerCollection, a2PeopleSingletonDirectory, eDistanceContentDirectory, - mappingCollection, mapLogicSupport, personKeyToPersonContainer, - personKeyToRanges, notMappedPersonContainers, skipCollection, idThenNormalizedRectangleToPersonContainers); @@ -94,17 +90,12 @@ public class MapLogic throw new NullReferenceException(nameof(collection)); } _SkipCollection = skipCollection; - _PersonKeyToRanges = personKeyToRanges; - _NotMappedPersonContainers = notMappedPersonContainers; _PersonKeyToPersonContainer = personKeyToPersonContainer; _EDistanceContentTicksDirectory = eDistanceContentTicksDirectory; _IdThenNormalizedRectangleToPersonContainers = idThenNormalizedRectangleToPersonContainers; + _NotMappedPersonContainers = notMappedPersonContainers.OrderByDescending(l => l.Key).ToList(); } - public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) : - this(maxDegreeOfParallelism, propertyConfiguration, configuration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, Array.Empty(), null) - { } - public override string ToString() { string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); @@ -119,7 +110,6 @@ public class MapLogic long personKey; const int zero = 0; string mappingSegmentB; - int by = IMapLogic.Mapping; PersonBirthday personBirthday; PersonContainer[]? collection; List personContainers = new(); @@ -147,7 +137,7 @@ public class MapLogic personKeyToCount.Add(personKey, 0); personKeyToCount[personKey] += 1; mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem); - mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB); + mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB); } } return new(personKeyToCount, result); @@ -309,23 +299,23 @@ public class MapLogic { isByMapping = false; isBySorting = false; - by = $"{nameof(IMapLogic.Mapping)}Null"; + by = $"{nameof(Shared.Models.Stateless.IMapLogic.Mapping)}Null"; } else { - isByMapping = mapping.By == IMapLogic.Mapping; - isBySorting = mapping.By == IMapLogic.Sorting; + isByMapping = mapping.By == Shared.Models.Stateless.IMapLogic.Mapping; + isBySorting = mapping.By == Shared.Models.Stateless.IMapLogic.Sorting; if (isBySorting && mapping.MappingFromPerson is null) - by = $"{nameof(IMapLogic.Sorting)} Without Person"; + by = $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Without Person"; else if (isBySorting && useFiltersCounter.HasValue) - by = $"{nameof(IMapLogic.Sorting)} Modified Filters - {useFiltersCounter.Value}"; + by = $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Modified Filters - {useFiltersCounter.Value}"; else { by = mapping.By.Value switch { - IMapLogic.Mapping => nameof(IMapLogic.Mapping), - IMapLogic.Sorting => nameof(IMapLogic.Sorting), - IMapLogic.ForceSingleImage => forceSingleImageHumanized, + Shared.Models.Stateless.IMapLogic.Mapping => nameof(Shared.Models.Stateless.IMapLogic.Mapping), + Shared.Models.Stateless.IMapLogic.Sorting => nameof(Shared.Models.Stateless.IMapLogic.Sorting), + Shared.Models.Stateless.IMapLogic.ForceSingleImage => forceSingleImageHumanized, _ => throw new NotImplementedException() }; } @@ -344,7 +334,7 @@ public class MapLogic PersonBirthday personBirthday; PersonContainer personContainer; result = Path.Combine(_EDistanceContentTicksDirectory, by, sortingContainer.Sorting.Id.ToString(), sortingContainer.Sorting.NormalizedRectangle.ToString()); - for (int i = 0; i < _NotMappedPersonContainers.Count; i++) + for (int i = _NotMappedPersonContainers.Count - 1; i > 0; i--) { personContainer = _NotMappedPersonContainers[i]; if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) @@ -376,12 +366,13 @@ public class MapLogic string? facesDirectory; FileHolder faceFileHolder; string personKeyFormatted; + List distinct = new(); string? facePartsDirectory; SaveContainer? saveContainer; FileHolder facePartsFileHolder; FileHolder hiddenFaceFileHolder; Dictionary? normalizedRectangleToMapping; - string forceSingleImageHumanized = nameof(IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); + string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); foreach (Mapping mapping in mappingCollection) { directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath); @@ -396,8 +387,14 @@ public class MapLogic continue; if (mapping.SortingContainer is null) continue; + if (distinct.Contains(mapping.MappingFromItem.Id)) + continue; + if (distinct.Contains(mapping.SortingContainer.Sorting.Id)) + continue; directory = GetDirectory(by, mapping.MappingFromItem, mapping.SortingContainer); - personDirectory = Path.Combine(directory, _Configuration.MappingDefaultName); + personDirectory = Path.Combine(directory, $"Z]{DateTime.Now.Ticks}"); + distinct.Add(mapping.MappingFromItem.Id); + distinct.Add(mapping.SortingContainer.Sorting.Id); } else { @@ -441,10 +438,10 @@ public class MapLogic facePartsDirectory = GetFacePartsDirectory(d2FacePartsContentDirectory, mapping.MappingFromItem); if (facePartsDirectory is null) continue; - if (!isBySorting || mapping.MappingFromPerson is not null) - checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); - else - checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}-Source{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); + // if (!isBySorting || mapping.MappingFromPerson is not null) + checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); + // else + // checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}-Source{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); shortcutFile = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk"); hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}")); facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}")); @@ -488,7 +485,7 @@ public class MapLogic bool saveMapped = true; bool saveNullPerson = false; int? useFiltersCounter = null; - string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(IMapLogic.Mapping)); + string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping)); List saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToCount, useFiltersCounter, saveNullPerson, saveMapped); SaveContainers(totalNotMapped, updated, saveContainers); if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory)) @@ -497,6 +494,8 @@ public class MapLogic private List<(long, long, long, long)> GetPersonKeysRangesCollection(PersonContainer[] personContainers) { + if (_PersonKeyToRanges is null) + throw new NullReferenceException(nameof(_PersonKeyToRanges)); List<(long, long, long, long)> results = new(); (long, long, long, long) singleton; foreach (PersonContainer personContainer in personContainers) @@ -576,7 +575,7 @@ public class MapLogic if (sorting.Id == faceDistanceEncoding.Id) { if (sorting.NormalizedRectangle == faceDistanceEncoding.NormalizedRectangle.Value) - throw new NotSupportedException(); + continue; continue; } results.Add(sorting); @@ -599,12 +598,11 @@ public class MapLogic string mappingSegmentB; string personKeyFormatted; PersonBirthday personBirthday; - const int by = IMapLogic.Sorting; - PersonContainer[] personContainers; + PersonContainer[]? personContainers; Dictionary keyToCount = new(); - Dictionary keyToSegmentC = new(); List normalizedRectangleCollectionForA; List normalizedRectangleCollectionForB; + Dictionary keyToSegmentC = new(); Dictionary> idToNormalizedRectangleCollectionForA = new(); Dictionary> idToNormalizedRectangleCollectionForB = new(); Dictionary? normalizedRectangleToPersonContainers; @@ -623,22 +621,13 @@ public class MapLogic if (!idToNormalizedRectangleCollectionForB.ContainsKey(sortingContainer.Mapping.MappingFromItem.Id)) idToNormalizedRectangleCollectionForB.Add(sortingContainer.Mapping.MappingFromItem.Id, new()); normalizedRectangleCollectionForB = idToNormalizedRectangleCollectionForB[sortingContainer.Mapping.MappingFromItem.Id]; - if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(sortingContainer.Sorting.Id, out normalizedRectangleToPersonContainers)) + if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(sortingContainer.Sorting.Id, out normalizedRectangleToPersonContainers) || !normalizedRectangleToPersonContainers.TryGetValue(sortingContainer.Sorting.NormalizedRectangle, out personContainers)) { if (!saveNullPerson) continue; - personContainers = Array.Empty(); if (normalizedRectangleCollectionForA.Contains(sortingContainer.Mapping.MappingFromLocation.NormalizedRectangle)) continue; - key = string.Concat(sortingContainer.Mapping.MappingFromItem.Id, '\t', sortingContainer.Mapping.MappingFromLocation.NormalizedRectangle); - if (!keyToCount.ContainsKey(key)) - keyToCount.Add(key, 0); - if (!keyToSegmentC.ContainsKey(key)) - keyToSegmentC.Add(key, string.Empty); - keyToCount[key]++; - if (keyToCount[key] > _Configuration.SortingMaximumPerKey) - continue; - sortingContainer.Mapping.UpdateMappingFromUnknownPerson(by, sortingContainer); + sortingContainer.Mapping.UpdateMappingFromUnknownPerson(sortingContainer); normalizedRectangleCollectionForA.Add(sortingContainer.Mapping.MappingFromLocation.NormalizedRectangle); result += 1; } @@ -646,10 +635,6 @@ public class MapLogic { if (normalizedRectangleCollectionForB.Contains(sortingContainer.Mapping.MappingFromLocation.NormalizedRectangle)) continue; - if (!normalizedRectangleToPersonContainers.ContainsKey(sortingContainer.Sorting.NormalizedRectangle)) - personContainers = Array.Empty(); - else - personContainers = normalizedRectangleToPersonContainers[sortingContainer.Sorting.NormalizedRectangle]; foreach (PersonContainer personContainer in personContainers) { if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) @@ -670,7 +655,7 @@ public class MapLogic keyToCount[key] = 0; keyToSegmentC[key] = sortingContainer.Sorting.DistancePermyriad.ToString(); } - sortingContainer.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB, keyToSegmentC[key], sortingContainer); + sortingContainer.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB, keyToSegmentC[key], sortingContainer); normalizedRectangleCollectionForB.Add(sortingContainer.Mapping.MappingFromLocation.NormalizedRectangle); result += 1; break; @@ -703,10 +688,10 @@ public class MapLogic string? personDisplayDirectory; int? normalizedRectangle; WindowsShortcut windowsShortcut; - string by = nameof(IMapLogic.ManualCopy); Dictionary? normalizedRectangleToMapping; + string by = nameof(Shared.Models.Stateless.IMapLogic.ManualCopy); Dictionary? normalizedRectangleToPeronContainerCollection; - string successfull = $"_ {nameof(IMapLogic.ManualCopy).Humanize(LetterCasing.Title)} Successfull"; + string successfull = $"_ {nameof(Shared.Models.Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title)} Successfull"; foreach (KeyValuePair keyValuePair in _PersonKeyToPersonContainer) { if (keyValuePair.Value.Key is null || keyValuePair.Value.Birthdays is null || !keyValuePair.Value.Birthdays.Any()) @@ -718,7 +703,7 @@ public class MapLogic continue; if (!personDisplayDirectoryAllFile.EndsWith(_Configuration.FacesFileNameExtension)) continue; - (id, normalizedRectangle, _) = IMapping.GetConverted(_Configuration.FacesFileNameExtension, personDisplayDirectoryAllFile); + (id, normalizedRectangle) = IMapping.GetConverted(_Configuration.FacesFileNameExtension, personDisplayDirectoryAllFile); if (id is null || normalizedRectangle is null) continue; fileInfo = new(personDisplayDirectoryAllFile); @@ -790,7 +775,7 @@ public class MapLogic SaveContainer saveContainer; PersonBirthday personBirthday; List saveContainers = new(); - const string facePopulatedKey = nameof(IMapLogic.Sorting); + const string facePopulatedKey = nameof(Shared.Models.Stateless.IMapLogic.Sorting); foreach (PersonContainer personContainer in _NotMappedPersonContainers) { if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) @@ -804,13 +789,12 @@ public class MapLogic SaveContainers(totalNotMapped, updated, saveContainers); } - private (string, PersonBirthday?) GetPersonBirthday(string windowsShortcutPath) + private (string, PersonBirthday?) GetPersonBirthday(string[] directoryNames) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); PersonBirthday? personBirthday = null; string personKeyFormatted = string.Empty; - string[] directoryNames = IPath.GetDirectoryNames(windowsShortcutPath); foreach (string directoryName in directoryNames) { personBirthday = IPersonBirthday.GetPersonBirthday(_Configuration.PersonBirthdayFormat, directoryName); @@ -823,6 +807,26 @@ public class MapLogic return new(personKeyFormatted, personBirthday); } + private (string, PersonBirthday?) GetPersonBirthday(string windowsShortcutPath) + { + if (_Configuration is null) + throw new NullReferenceException(nameof(_Configuration)); + string[] directoryNames = IPath.GetDirectoryNames(windowsShortcutPath); + (string personKeyFormatted, PersonBirthday? personBirthday) = GetPersonBirthday(directoryNames); + if (personBirthday is null) + { + string[] directories = Directory.GetDirectories(windowsShortcutPath, "*", SearchOption.TopDirectoryOnly); + foreach (string directory in directories) + { + directoryNames = IPath.GetDirectoryNames(directory); + (personKeyFormatted, personBirthday) = GetPersonBirthday(directoryNames); + if (personBirthday is not null) + break; + } + } + return new(personKeyFormatted, personBirthday); + } + private List GetPersonKeyFormattedCollection(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, Dictionary personKeyToCount) { if (_Configuration is null) @@ -831,7 +835,6 @@ public class MapLogic throw new NullReferenceException(nameof(_MapLogicSupport)); List results = new(); string[] files; - string[] directories; string checkDirectory; string[] checkDirectories; string personKeyFormatted; @@ -861,30 +864,12 @@ public class MapLogic continue; } (personKeyFormatted, personBirthday) = GetPersonBirthday(windowsShortcut.Path); - if (personBirthday is not null) - { - if (!personKeyToCount.ContainsKey(personBirthday.Value.Ticks)) - collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension))); - else - collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{personKeyToCount[personBirthday.Value.Ticks]} Face(s)"))); - } - else - { - directories = Directory.GetDirectories(windowsShortcut.Path, "*", SearchOption.TopDirectoryOnly); - foreach (string directory in directories) - { - personKeyFormatted = Path.GetFileName(directory); - personBirthday = IPersonBirthday.GetPersonBirthday(_Configuration.PersonBirthdayFormat, personKeyFormatted); - if (personBirthday is null) - continue; - if (!personKeyToCount.ContainsKey(personBirthday.Value.Ticks)) - collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension))); - else - collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{personKeyToCount[personBirthday.Value.Ticks]} Face(s)"))); - } - } - if (!collection.Any()) + if (personBirthday is null) throw new NotSupportedException(fileNameWithoutExtension); + if (!personKeyToCount.ContainsKey(personBirthday.Value.Ticks)) + collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension))); + else + collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{personKeyToCount[personBirthday.Value.Ticks]} Face(s)"))); foreach ((long personKey, string displayDirectoryName) in collection) { matches = (from l in personContainers where l.Key == personKey && l.ApproximateYears.HasValue select l).ToArray(); @@ -902,7 +887,7 @@ public class MapLogic return results; } - private (int, FileHolder, int, string, string, string, string)[] GetCollectionForSaveResizedImagesByPersonKeyFormatted(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, Mapping[] mappingCollection, Dictionary personKeyToCount) + private (int, FileHolder, int, string, string, string, string)[] GetCollectionForSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, Mapping[] mappingCollection, Dictionary personKeyToCount) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); @@ -914,13 +899,13 @@ public class MapLogic string personKeyFormatted; bool usePersonKeyAndDeterministicHashCodeKey = false; List personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleSingletonDirectory, personContainers, personKeyToCount); - List<(int Id, FileHolder ResizedFileHolder, int ApproximateYears, string PersonKeyFormatted, string CheckFile, string Directory, string PersonDirectory)> collection = new(); + List<(int Id, FileHolder ImageFileHolder, int ApproximateYears, string PersonKeyFormatted, string CheckFile, string Directory, string PersonDirectory)> collection = new(); foreach (Mapping mapping in mappingCollection) { directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath); if (directoryName is null) throw new NotSupportedException(); - if (mapping.By is null or IMapLogic.Sorting) + if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting) continue; if (mapping.MappingFromPerson?.ApproximateYears is null) continue; @@ -945,28 +930,28 @@ public class MapLogic personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName); checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); } - collection.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.ResizedFileHolder, mapping.MappingFromPerson.ApproximateYears.Value, personKeyFormatted, directory, personDirectory, checkFile)); + collection.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.ImageFileHolder, mapping.MappingFromPerson.ApproximateYears.Value, personKeyFormatted, directory, personDirectory, checkFile)); } results = (from l in collection orderby l.ApproximateYears descending, l.PersonKeyFormatted descending select l).ToArray(); return results; } - public void SaveResizedImagesByPersonKeyFormatted(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, Mapping[] mappingCollection, Dictionary personKeyToCount, int totalNotMapped) + public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, Mapping[] mappingCollection, Dictionary personKeyToCount, int totalNotMapped) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); SaveContainer? saveContainer; List distinctCollection = new(); List saveContainers = new(); - (int, FileHolder, int, string, string, string, string)[] collection = GetCollectionForSaveResizedImagesByPersonKeyFormatted(jLinks, a2PeopleSingletonDirectory, personContainers, mappingCollection, personKeyToCount); - foreach ((int id, FileHolder resizedFileHolder, int approximateYears, string personKeyFormatted, string directory, string personDirectory, string checkFile) in collection) + (int, FileHolder, int, string, string, string, string)[] collection = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleSingletonDirectory, personContainers, mappingCollection, personKeyToCount); + foreach ((int id, FileHolder imageFileHolder, int approximateYears, string personKeyFormatted, string directory, string personDirectory, string checkFile) in collection) { if (distinctCollection.Contains(id)) continue; distinctCollection.Add(id); saveContainer = new(personDirectory); saveContainers.Add(saveContainer); - saveContainer = new(resizedFileHolder, checkFile, directory); + saveContainer = new(imageFileHolder, checkFile, directory); saveContainers.Add(saveContainer); } SaveContainers(totalNotMapped, null, saveContainers); @@ -1013,7 +998,7 @@ public class MapLogic { if (mapping.MappingFromItem.ResizedFileHolder.DirectoryName is null || !mapping.MappingFromItem.ResizedFileHolder.Exists) continue; - if (mapping.By is null or IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null) + if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null) continue; if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB)) throw new NotSupportedException(); @@ -1028,7 +1013,7 @@ public class MapLogic throw new NotSupportedException(); if (mapping.MappingFromItem.ResizedFileHolder.DirectoryName is null || !mapping.MappingFromItem.ResizedFileHolder.Exists) continue; - if (mapping.By is null or IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null) + if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null) { if (mapping.MappingFromItem.ContainerDateTimes.Any() && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName)) { @@ -1115,7 +1100,7 @@ public class MapLogic string? facesDirectory; FileHolder faceFileHolder; List? normalizedRectangles; - string by = nameof(IMapLogic.CopyNotMappedFaces); + string by = nameof(Shared.Models.Stateless.IMapLogic.CopyNotMappedFaces); Dictionary? normalizedRectangleToPersonContainers; foreach (KeyValuePair> keyValuePair in idToNormalizedRectangleToMapping) { @@ -1409,4 +1394,11 @@ public class MapLogic return results; } + public void UpdatedPersonKeyToRanges(Configuration configuration, long ticks, Mapping[] mappingCollection) + { + Dictionary personKeyToRanges = new(); + Stateless.MapLogic.SetPersonTicks(configuration, ticks, mappingCollection, personKeyToRanges, _IdThenNormalizedRectangleToPersonContainers); + _PersonKeyToRanges = personKeyToRanges; + } + } \ No newline at end of file diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index cb2025d..d74c548 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -9,7 +9,7 @@ namespace View_by_Distance.Map.Models.Stateless; internal abstract class MapLogic { - private static List AddToPersonKeysThenGetNonSpecificPeopleCollection(Configuration configuration, List personKeys) + private static List GetNonSpecificPeopleCollection(Configuration configuration, long ticks, List personKeys) { List results = new(); Person person; @@ -19,13 +19,14 @@ internal abstract class MapLogic PersonContainer personContainer; string[] personDisplayDirectoryAllFiles = Array.Empty(); DateTime incrementDate = new(configuration.PersonBirthdayFirstYear, 1, 1); - for (int i = 0; i < 500; i++) + for (int i = 0; i < int.MaxValue; i++) { personKey = incrementDate.Ticks; incrementDate = incrementDate.AddDays(1); + if (incrementDate.Ticks > ticks) + break; if (personKeys.Contains(personKey)) continue; - personKeys.Add(personKey); personBirthday = IPersonBirthday.GetPersonBirthday(personKey); person = IPerson.GetPerson(configuration.MappingDefaultName, personKey, personBirthday); personContainer = new(approximateYears, person, new PersonBirthday[] { personBirthday }, personDisplayDirectoryAllFiles, configuration.MappingDefaultName, personKey, partialKeyFormatted: null); @@ -47,7 +48,7 @@ internal abstract class MapLogic { if (!personDisplayDirectoryAllFile.EndsWith(configuration.FacesFileNameExtension)) continue; - (id, normalizedRectangle, _) = IMapping.GetConverted(configuration.FacesFileNameExtension, personDisplayDirectoryAllFile); + (id, normalizedRectangle) = IMapping.GetConverted(configuration.FacesFileNameExtension, personDisplayDirectoryAllFile); if (id is null || normalizedRectangle is null) continue; if (!skipCollection.ContainsKey(id.Value)) @@ -91,8 +92,8 @@ internal abstract class MapLogic string[] personNameLinkDirectories; string? personFirstInitialDirectory; string[] personDisplayDirectoryNames; - string manualCopyHumanized = nameof(IMapLogic.ManualCopy).Humanize(LetterCasing.Title); - string forceSingleImageHumanized = nameof(IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); + string manualCopyHumanized = nameof(Shared.Models.Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title); + string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; using ProgressBar progressBar = new(ticksDirectories.Length, message, options); foreach (string ticksDirectory in ticksDirectories) @@ -128,8 +129,8 @@ internal abstract class MapLogic if (!personDisplayDirectoryNames.Any()) continue; files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly); - if (personKeyFormatted == nameof(IMapLogic.Sorting) && files.Any()) - throw new Exception($"Move personKey directories up one from {nameof(IMapLogic.Sorting)} and delete {nameof(IMapLogic.Sorting)} directory!"); + if (personKeyFormatted == nameof(Shared.Models.Stateless.IMapLogic.Sorting) && 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!"); if (personKeyFormatted == manualCopyHumanized && files.Any()) throw new Exception($"Move personKey directories up one from {manualCopyHumanized} and delete {manualCopyHumanized} directory!"); if (personKeyFormatted == forceSingleImageHumanized && files.Any()) @@ -159,7 +160,7 @@ internal abstract class MapLogic { if (file.EndsWith(".lnk") || file.EndsWith(".json")) continue; - (id, normalizedRectangle, _) = IMapping.GetConverted(configuration.FacesFileNameExtension, file); + (id, normalizedRectangle) = IMapping.GetConverted(configuration.FacesFileNameExtension, file); if (id is null || normalizedRectangle is null) continue; results.Add(new(personKeyFormatted, personDisplayDirectoryNames, file)); @@ -188,26 +189,9 @@ internal abstract class MapLogic return results; } - public static Dictionary> GetIdToCollection(Configuration configuration, List<(string, string[], string)> collection) + internal static List<(string, string[], string)> DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, PersonContainer[] personContainers) { - Dictionary> results = new(); - int? id; - int? normalizedRectangle; - foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string mappedFaceFile) in collection) - { - (id, normalizedRectangle, _) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFaceFile); - if (id is null || normalizedRectangle is null) - continue; - if (!results.ContainsKey(id.Value)) - results.Add(id.Value, new()); - results[id.Value].Add(new(mappedFaceFile, normalizedRectangle.Value)); - } - return results; - } - - internal static Dictionary> DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, PersonContainer[] personContainers) - { - Dictionary> results; + List<(string, string[], string)> results; string personKeyFormatted; List personKeyFormattedCollection = new(); List<(long? PersonKey, string Line)> lines = new(); @@ -242,8 +226,7 @@ internal abstract class MapLogic } if (!string.IsNullOrEmpty(a2PeopleContentDirectory)) File.WriteAllLines(Path.Combine(a2PeopleContentDirectory, "People - C.tsv"), from l in lines select l.Line); - List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message); - results = GetIdToCollection(configuration, collection); + results = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message); return results; } @@ -260,7 +243,7 @@ internal abstract class MapLogic return results.ToArray(); } - private static void SetKeyValuePairs(Configuration configuration, long ticks, List personContainers, Mapping[] mappingCollection, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, Dictionary personKeyToPersonContainer, Dictionary> idThenNormalizedRectangleToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, Dictionary> incorrectIdThenNormalizedRectangleToPersonContainers, Dictionary personKeyToRanges) + private static void SetKeyValuePairs(Configuration configuration, List personContainers, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, Dictionary personKeyToPersonContainer, Dictionary> idThenNormalizedRectangleToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, Dictionary> incorrectIdThenNormalizedRectangleToPersonContainers) { PersonBirthday? personBirthday; PersonContainer[] distinctPersonContainers; @@ -308,7 +291,6 @@ internal abstract class MapLogic idThenNormalizedRectangleToPersonContainers[keyValuePair.Key].Add(innerKeyValuePair.Key, distinctPersonContainers); } }; - SetPersonTicks(configuration, ticks, mappingCollection, personKeyToRanges, idThenNormalizedRectangleToPersonContainers); if (incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection.Any()) { PersonContainer personContainer; @@ -366,18 +348,15 @@ internal abstract class MapLogic return results; } - private static (int, int) SetCollectionsAndGetUnableToMatchCount(Configuration configuration, long ticks, Dictionary> idToMappingCollection, Dictionary personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, List<(string, string[], string)> collection) + private static (int, int) SetCollectionsAndGetUnableToConvertCount(Configuration configuration, long ticks, Dictionary personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, List<(string, string[], string)> collection) { int result = 0; int? id; int? normalizedRectangle; - string newestPersonKeyFormatted; - List? mappingCollection; - string personDisplayDirectoryName; List normalizedRectangles; - List checkMappingCollection = new(); + string newestPersonKeyFormatted; + string personDisplayDirectoryName; List duplicateMappedFaceFiles = new(); - bool idToMappingCollectionAny = idToMappingCollection.Any(); Dictionary> idToNormalizedRectangles = new(); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); string message = $") {collection.Count:000} join from ticks Director(ies) - C - {totalSeconds} total second(s)"; @@ -386,7 +365,7 @@ internal abstract class MapLogic foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string mappedFaceFile) in collection) { progressBar.Tick(); - (id, normalizedRectangle, mappingCollection) = IMapping.GetConverted(configuration.FacesFileNameExtension, idToMappingCollectionAny, idToMappingCollection, mappedFaceFile); + (id, normalizedRectangle) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFaceFile); if (id is null || normalizedRectangle is null) { result++; @@ -395,31 +374,6 @@ internal abstract class MapLogic if (!idToNormalizedRectangles.ContainsKey(id.Value)) idToNormalizedRectangles.Add(id.Value, new()); normalizedRectangles = idToNormalizedRectangles[id.Value]; - checkMappingCollection.Clear(); - if (mappingCollection is not null) - { - foreach (Mapping mapping in mappingCollection) - { - if (normalizedRectangle.Value != mapping.MappingFromLocation.NormalizedRectangle) - continue; - if (normalizedRectangles.Contains(mapping.MappingFromLocation.NormalizedRectangle)) - { - duplicateMappedFaceFiles.Add(mappedFaceFile); - continue; - } - checkMappingCollection.Add(mapping); - } - if (!checkMappingCollection.Any()) - { - result++; - continue; - } - if (checkMappingCollection.Count != 1) - { - result++; - continue; - } - } normalizedRectangles.Add(normalizedRectangle.Value); idToNormalizedRectangles[id.Value].Add(normalizedRectangle.Value); if (!personKeyFormattedToNewestPersonKeyFormatted.ContainsKey(personKeyFormatted)) @@ -495,8 +449,8 @@ internal abstract class MapLogic else average = (sumCollection.Sum() / collection.Length) + minimum; standardDeviation = GetStandardDeviation(collection, average); - ucl = (long)(average + (standardDeviation * IMapLogic.Sigma)); - lcl = (long)(average - (standardDeviation * IMapLogic.Sigma)); + ucl = (long)(average + (standardDeviation * Shared.Models.Stateless.IMapLogic.Sigma)); + lcl = (long)(average - (standardDeviation * Shared.Models.Stateless.IMapLogic.Sigma)); if (lcl < 0) lcl = 0; if (ucl > 0) @@ -506,7 +460,7 @@ internal abstract class MapLogic } } - private static void SetPersonTicks(Configuration configuration, long ticks, Mapping[] mappingCollection, Dictionary personKeyToRanges, Dictionary> idThenNormalizedRectangleToPersonContainers) + internal static void SetPersonTicks(Configuration configuration, long ticks, Mapping[] mappingCollection, Dictionary personKeyToRanges, Dictionary> idThenNormalizedRectangleToPersonContainers) { PersonContainer[]? personContainers; Dictionary? keyValuePairs; @@ -534,7 +488,7 @@ internal abstract class MapLogic SetPersonKeysRanges(configuration, ticks, personKeyToMinimumDateTimeTicks, personKeyToRanges); } - private static List GetNotMappedPersonContainers(Configuration configuration, List personContainers, long[] personKeyCollection) + private static List GetNotMappedPersonContainers(Configuration configuration, List personContainers, List personKeys, long[] personKeyCollection) { List results = new(); List notMappedAndNotNamedPersonKeys = new(); @@ -543,15 +497,17 @@ internal abstract class MapLogic { if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) continue; + if (personKeys.Contains(personContainer.Key.Value)) + continue; if (personKeyCollection.Contains(personContainer.Key.Value)) continue; - else if (string.IsNullOrEmpty(personContainer.DisplayDirectoryName) || personContainer.DisplayDirectoryName == configuration.MappingDefaultName) + if (string.IsNullOrEmpty(personContainer.DisplayDirectoryName) || personContainer.DisplayDirectoryName == configuration.MappingDefaultName) notMappedAndNotNamedPersonKeys.Add(personContainer); else notMappedAndWithNamedPersonKeys.Add(personContainer); } - 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); + results.AddRange(notMappedAndNotNamedPersonKeys); + // results.AddRange(notMappedAndWithNamedPersonKeys); return results; } @@ -612,7 +568,7 @@ internal abstract class MapLogic } } - internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, List personContainers, string? a2PeopleContentDirectory, string eDistanceContentDirectory, Mapping[] mappingCollection, Shared.Models.Methods.IMapLogicSupport mapLogicSupport, Dictionary personKeyToPersonContainer, Dictionary personKeyToRanges, List notMappedPersonContainers, Dictionary> skipCollection, Dictionary> idThenNormalizedRectangleToPersonContainers) + internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, List personContainers, string? a2PeopleContentDirectory, string eDistanceContentDirectory, Shared.Models.Methods.IMapLogicSupport mapLogicSupport, Dictionary personKeyToPersonContainer, List notMappedPersonContainers, Dictionary> skipCollection, Dictionary> idThenNormalizedRectangleToPersonContainers) { if (configuration is null) throw new NullReferenceException(nameof(configuration)); @@ -621,26 +577,19 @@ internal abstract class MapLogic List personKeys = new(); List nullablePersonKeyCollection = new(); List personKeyFormattedCollection = new(); - Dictionary> idToMappingCollection = new(); Dictionary personKeyFormattedToNewestPersonKeyFormatted = new(); List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new(); List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection = new(); List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection = new(); Dictionary> incorrectIdThenNormalizedRectangleToPersonContainers = new(); SetPersonCollections(configuration, personContainers, personKeys, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, skipCollection); - personContainers.AddRange(AddToPersonKeysThenGetNonSpecificPeopleCollection(configuration, personKeys)); - foreach (Mapping mapping in mappingCollection) - { - if (!idToMappingCollection.ContainsKey(mapping.MappingFromItem.Id)) - idToMappingCollection.Add(mapping.MappingFromItem.Id, new()); - idToMappingCollection[mapping.MappingFromItem.Id].Add(mapping); - } + personContainers.AddRange(GetNonSpecificPeopleCollection(configuration, ticks, personKeys)); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly); message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)"; List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message); - (int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(configuration, ticks, idToMappingCollection, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedRectangleCollection, incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, collection); - SetKeyValuePairs(configuration, ticks, personContainers, mappingCollection, personKeyFormattedIdThenNormalizedRectangleCollection, incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, personKeyToPersonContainer, idThenNormalizedRectangleToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, incorrectIdThenNormalizedRectangleToPersonContainers, personKeyToRanges); + (int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToConvertCount(configuration, ticks, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedRectangleCollection, incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, collection); + SetKeyValuePairs(configuration, personContainers, personKeyFormattedIdThenNormalizedRectangleCollection, incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, personKeyToPersonContainer, idThenNormalizedRectangleToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, incorrectIdThenNormalizedRectangleToPersonContainers); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); message = $") {collection.Count:000} message from ticks Director(ies) - D - {duplicateCount} Duplicate Count {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)"; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; @@ -655,7 +604,7 @@ internal abstract class MapLogic } long[] personKeyCollection = (from l in nullablePersonKeyCollection where l is not null select l.Value).Distinct().ToArray(); SetPersonKeyToPersonContainer(configuration, personContainers, personKeyCollection, personKeyToPersonContainer); - notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, personContainers, personKeyCollection)); + notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, personContainers, personKeys, personKeyCollection)); AppendToSkipCollection(skipCollection, idThenNormalizedRectangleToPersonContainers, incorrectIdThenNormalizedRectangleToPersonContainers); if (possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Any()) mapLogicSupport.SavePossiblyNewPersonContainers(propertyConfiguration, configuration.PersonBirthdayFormat, configuration.FacesFileNameExtension, a2PeopleContentDirectory, personKeyToPersonContainer, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); diff --git a/Map/Models/Stateless/Methods/IMapLogic.cs b/Map/Models/Stateless/Methods/IMapLogic.cs index 8ae6ccf..515e30e 100644 --- a/Map/Models/Stateless/Methods/IMapLogic.cs +++ b/Map/Models/Stateless/Methods/IMapLogic.cs @@ -3,9 +3,9 @@ namespace View_by_Distance.Map.Models.Stateless.Methods; public interface IMapLogic { // ... - Dictionary> TestStatic_DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) => + List<(string, string[], string)> TestStatic_DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) => DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers); - static Dictionary> DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) => + static List<(string, string[], string)> DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) => MapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers); } \ No newline at end of file diff --git a/Metadata/Models/Stateless/IMetadata.cs b/Metadata/Models/Stateless/IMetadata.cs index 211bf0a..128b4d4 100644 --- a/Metadata/Models/Stateless/IMetadata.cs +++ b/Metadata/Models/Stateless/IMetadata.cs @@ -3,14 +3,14 @@ namespace View_by_Distance.Metadata.Models.Stateless; public interface IMetadata { - string? TestStatic_GetFaceEncoding(string file) => - GetFaceEncoding(file); - static string? GetFaceEncoding(string file) => - Metadata.GetFaceEncoding(file); + string? TestStatic_GetFaceEncoding(IReadOnlyList directories) => + GetFaceEncoding(directories); + static string? GetFaceEncoding(IReadOnlyList directories) => + Metadata.GetFaceEncoding(directories); - string? TestStatic_GetFaceX(string file) => - GetFaceX(file); - static string? GetFaceX(string file) => - Metadata.GetFaceX(file); + string? TestStatic_GetFaceX(IReadOnlyList directories) => + GetFaceX(directories); + static string? GetFaceX(IReadOnlyList directories) => + Metadata.GetFaceX(directories); } \ No newline at end of file diff --git a/Metadata/Models/Stateless/Metadata.cs b/Metadata/Models/Stateless/Metadata.cs index a43ea01..c20b1a4 100644 --- a/Metadata/Models/Stateless/Metadata.cs +++ b/Metadata/Models/Stateless/Metadata.cs @@ -3,52 +3,44 @@ namespace View_by_Distance.Metadata.Models.Stateless; internal class Metadata { - internal static string? GetFaceEncoding(string file) + internal static string? GetFaceEncoding(IReadOnlyList directories) { string? result; List results = new(); const string comment = "Comment: "; - if (File.Exists(file)) + foreach (MetadataExtractor.Directory directory in directories) { - IReadOnlyList directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); - foreach (MetadataExtractor.Directory directory in directories) + if (directory.Name != "PNG-tEXt") + continue; + foreach (MetadataExtractor.Tag tag in directory.Tags) { - if (directory.Name != "PNG-tEXt") + if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) continue; - foreach (MetadataExtractor.Tag tag in directory.Tags) - { - if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) - continue; - if (!tag.Description.StartsWith(comment)) - continue; - results.Add(tag.Description); - } + if (!tag.Description.StartsWith(comment)) + continue; + results.Add(tag.Description); } } result = results.Any() ? results[0][comment.Length..] : null; return result; } - internal static string? GetFaceX(string file) + internal static string? GetFaceX(IReadOnlyList directories) { string? result; List results = new(); const string artist = "Artist: "; - if (File.Exists(file)) + foreach (MetadataExtractor.Directory directory in directories) { - IReadOnlyList directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); - foreach (MetadataExtractor.Directory directory in directories) + if (directory.Name != "PNG-tEXt") + continue; + foreach (MetadataExtractor.Tag tag in directory.Tags) { - if (directory.Name != "PNG-tEXt") + if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) continue; - foreach (MetadataExtractor.Tag tag in directory.Tags) - { - if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) - continue; - if (!tag.Description.StartsWith(artist)) - continue; - results.Add(tag.Description); - } + if (!tag.Description.StartsWith(artist)) + continue; + results.Add(tag.Description); } } result = results.Any() ? results[0][artist.Length..] : null; diff --git a/Shared/Models/Mapping.cs b/Shared/Models/Mapping.cs index db2edde..40906cb 100644 --- a/Shared/Models/Mapping.cs +++ b/Shared/Models/Mapping.cs @@ -134,23 +134,23 @@ public class Mapping : Properties.IMapping return result; } - public void UpdateMappingFromUnknownPerson(int? by, SortingContainer sortingContainer) + public void UpdateMappingFromUnknownPerson(SortingContainer sortingContainer) { - _By = by; + _By = Stateless.IMapLogic.Sorting; _SortingContainer = sortingContainer; } - public void UpdateMappingFromPerson(int? approximateYears, int? by, string displayDirectoryName, PersonBirthday personBirthday, string segmentB) + public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB) { - _By = by; _SortingContainer = null; + _By = Stateless.IMapLogic.Mapping; _MappingFromPerson = new(approximateYears, displayDirectoryName, personBirthday, segmentB); } - public void UpdateMappingFromPerson(int? approximateYears, int? by, string displayDirectoryName, PersonBirthday personBirthday, string segmentB, string segmentC, SortingContainer sortingContainer) + public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB, string segmentC, SortingContainer sortingContainer) { - _By = by; _SegmentC = segmentC; + _By = Stateless.IMapLogic.Sorting; _SortingContainer = sortingContainer; _MappingFromPerson = new(approximateYears, displayDirectoryName, personBirthday, segmentB); } diff --git a/Map/Models/Stateless/IMapLogic.cs b/Shared/Models/Stateless/IMapLogic.cs similarity index 81% rename from Map/Models/Stateless/IMapLogic.cs rename to Shared/Models/Stateless/IMapLogic.cs index 57869c4..863d30d 100644 --- a/Map/Models/Stateless/IMapLogic.cs +++ b/Shared/Models/Stateless/IMapLogic.cs @@ -1,4 +1,4 @@ -namespace View_by_Distance.Map.Models.Stateless; +namespace View_by_Distance.Shared.Models.Stateless; public interface IMapLogic { // ... diff --git a/Shared/Models/Stateless/Methods/IAge.cs b/Shared/Models/Stateless/Methods/IAge.cs index 33e59de..2e5f6be 100644 --- a/Shared/Models/Stateless/Methods/IAge.cs +++ b/Shared/Models/Stateless/Methods/IAge.cs @@ -21,7 +21,7 @@ public interface IAge char[] TestStatic_GetChars() => GetChars(); static char[] GetChars() => - new char[] { '!', '#', '^', '_', '`', '~', '+' }; + new char[] { '!', '#', ']', '^', '_', '`', '~', '+' }; int? TestStatic_GetApproximateYears(string personDisplayDirectoryName, char[] chars) => GetApproximateYears(personDisplayDirectoryName, chars); diff --git a/Shared/Models/Stateless/Methods/ILocation.cs b/Shared/Models/Stateless/Methods/ILocation.cs index 33edb18..73b808a 100644 --- a/Shared/Models/Stateless/Methods/ILocation.cs +++ b/Shared/Models/Stateless/Methods/ILocation.cs @@ -1,8 +1,15 @@ +using System.Drawing; + namespace View_by_Distance.Shared.Models.Stateless.Methods; public interface ILocation { // ... + Rectangle TestStatic_GetRectangle(Rectangle checkRectangle, int locationDigits, int locationFactor, int normalizedRectangle, Models.OutputResolution outputResolution, bool useOldWay) => + GetRectangle(checkRectangle, locationDigits, locationFactor, normalizedRectangle, outputResolution, useOldWay); + static Rectangle GetRectangle(Rectangle checkRectangle, int locationDigits, int locationFactor, int normalizedRectangle, Models.OutputResolution outputResolution, bool useOldWay) => + Location.GetRectangle(checkRectangle, locationDigits, locationFactor, normalizedRectangle, OutputResolution.Get(outputResolution).Height, OutputResolution.Get(outputResolution).Width, useOldWay); + string TestStatic_GetLeftPadded(int locationDigits, string value) => GetLeftPadded(locationDigits, value); static string GetLeftPadded(int locationDigits, string value) => @@ -33,11 +40,6 @@ public interface ILocation static Models.Location? GetLocation(int factor, Models.Location? location, int locationDigits, int locationFactor, int height, int width, int zCount) => location is null ? null : new(location.Confidence, factor, height, location, locationDigits, locationFactor, width, zCount); - (int?, int?) TestStatic_GetCenterRoundedXY(int bottom, int height, int left, int locationFactor, int right, int top, int width) => - GetCenterRoundedXY(bottom, height, left, locationFactor, right, top, width); - static (int?, int?) GetCenterRoundedXY(int bottom, int height, int left, int locationFactor, int right, int top, int width) => - Location.GetCenterRoundedXY(bottom, height, left, locationFactor, right, top, width, zCount: 1); - (decimal?, decimal?, decimal?, decimal?) TestStatic_GetHeightLeftTopWidth(int bottom, int height, int left, int right, int top, int width) => GetHeightLeftTopWidth(bottom, height, left, right, top, width); static (decimal?, decimal?, decimal?, decimal?) GetHeightLeftTopWidth(int bottom, int height, int left, int right, int top, int width) => @@ -63,9 +65,9 @@ public interface ILocation static int GetNormalizedRectangle(int bottom, int height, int left, int locationDigits, int right, int top, int width) => Location.GetNormalizedRectangle(bottom, height, left, locationDigits, right, top, width, zCount: 1); - Models.Location TestStatic_GetTrimBound(double detectionConfidence, System.Drawing.Rectangle rectangle, int width, int height, int facesCount) => + Models.Location TestStatic_GetTrimBound(double detectionConfidence, Rectangle rectangle, int width, int height, int facesCount) => TrimBound(detectionConfidence, rectangle, width, height, facesCount); - static Models.Location TrimBound(double detectionConfidence, System.Drawing.Rectangle rectangle, int width, int height, int facesCount) => + static Models.Location TrimBound(double detectionConfidence, Rectangle rectangle, int width, int height, int facesCount) => new(Math.Min(rectangle.Bottom, height), detectionConfidence, height, diff --git a/Shared/Models/Stateless/Methods/IMapping.cs b/Shared/Models/Stateless/Methods/IMapping.cs index e687a5d..c05463f 100644 --- a/Shared/Models/Stateless/Methods/IMapping.cs +++ b/Shared/Models/Stateless/Methods/IMapping.cs @@ -28,14 +28,9 @@ public interface IMapping static string GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, Models.OutputResolution outputResolution) => $"{id}.{ILocation.GetLeftPadded(locationDigits, ILocation.GetNormalizedRectangle(location, locationDigits, outputResolution))}"; - (int?, int?, List?) TestStatic_GetConverted(string facesFileNameExtension, string file) => + (int?, int?) TestStatic_GetConverted(string facesFileNameExtension, string file) => GetConverted(facesFileNameExtension, file); - static (int?, int?, List?) GetConverted(string facesFileNameExtension, string file) => - Mapping.GetConverted(facesFileNameExtension, false, new(), file); - - (int?, int?, List?) TestStatic_GetConverted(string facesFileNameExtension, bool idToMappingCollectionAny, Dictionary> idToMappingCollection, string file) => - GetConverted(facesFileNameExtension, idToMappingCollectionAny, idToMappingCollection, file); - static (int?, int?, List?) GetConverted(string facesFileNameExtension, bool idToMappingCollectionAny, Dictionary> idToMappingCollection, string file) => - Mapping.GetConverted(facesFileNameExtension, idToMappingCollectionAny, idToMappingCollection, file); + static (int?, int?) GetConverted(string facesFileNameExtension, string file) => + Mapping.GetConverted(facesFileNameExtension, file); } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/Location.cs b/Shared/Models/Stateless/Methods/Location.cs index 46a05eb..e586c40 100644 --- a/Shared/Models/Stateless/Methods/Location.cs +++ b/Shared/Models/Stateless/Methods/Location.cs @@ -1,3 +1,5 @@ +using System.Drawing; + namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class Location @@ -76,29 +78,6 @@ internal abstract class Location return result; } - internal static (int?, int?) GetCenterRoundedXY(int bottom, int height, int left, int locationFactor, int right, int top, int width, int zCount) - { - (int?, int?) result; - bool verified = Check(bottom, height, left, right, top, width, zCount, throwException: false); - decimal center = 2m; - decimal factor = locationFactor; - decimal xCenterValue = (left + right) / center; - decimal yCenterValue = (top + bottom) / center; - if (xCenterValue < left || xCenterValue > right) - throw new Exception(); - if (yCenterValue < top || yCenterValue > bottom) - throw new Exception(); - decimal xCenterPercentageFactored = xCenterValue / width * factor; - decimal yCenterPercentageFactored = yCenterValue / height * factor; - int xCenterRounded = (int)Math.Round(xCenterPercentageFactored, 0); - int yCenterRounded = (int)Math.Round(yCenterPercentageFactored, 0); - if (!verified) - result = new(null, null); - else - result = new(xCenterRounded, yCenterRounded); - return result; - } - internal static int GetNormalizedRectangle(int bottom, int height, int left, int locationDigits, int right, int top, int width, int zCount) { int result; @@ -160,4 +139,54 @@ internal abstract class Location int result = (int)(confidence / rangeFaceConfidence[1] * faceConfidencePercent); return result; } + + private static Rectangle? GetRectangle(int locationDigits, int height, string normalizedRectangle, int width) + { + Rectangle? result; + int length = (locationDigits - 1) / 4; + string[] segments = new string[] + { + normalizedRectangle[..1], + normalizedRectangle.Substring(1, length), + normalizedRectangle.Substring(3, length), + normalizedRectangle.Substring(5, length), + normalizedRectangle.Substring(7, length) + }; + if (string.Join(string.Empty, segments) != normalizedRectangle) + result = null; + else + { + if (!int.TryParse(segments[1], out int xNormalized) || !int.TryParse(segments[2], out int yNormalized) || !int.TryParse(segments[3], out int wNormalized) || !int.TryParse(segments[4], out int hNormalized)) + result = null; + else + { + decimal factor = 100; + result = new((int)(xNormalized / factor * width), (int)(yNormalized / factor * height), (int)(wNormalized / factor * width), (int)(hNormalized / factor * height)); + } + } + return result; + } + + internal static Rectangle GetRectangle(Rectangle checkRectangle, int locationDigits, int locationFactor, int normalizedRectangleValue, int height, int width, bool useOldWay) + { + Rectangle? result; + string normalizedRectangle = normalizedRectangleValue.ToString(); + if (normalizedRectangle.Length != locationDigits) + throw new NotImplementedException(); + if (!useOldWay) + { + result = GetRectangle(locationDigits, height, normalizedRectangle, width); + if (result is null) + throw new NullReferenceException(nameof(result)); + } + else + { + (int? x, int? y) = GetXY(locationDigits, locationFactor, width, height, normalizedRectangle); + if (x is null || y is null) + throw new Exception(); + result = new(x.Value - (checkRectangle.Width / 2), y.Value - (checkRectangle.Height / 2), checkRectangle.Width, checkRectangle.Height); + } + return result.Value; + } + } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/Mapping.cs b/Shared/Models/Stateless/Methods/Mapping.cs index b6fc7ef..a5807bc 100644 --- a/Shared/Models/Stateless/Methods/Mapping.cs +++ b/Shared/Models/Stateless/Methods/Mapping.cs @@ -27,51 +27,42 @@ internal abstract class Mapping return new(id, normalizedRectangle, extensionLowered, needsFacesFileNameExtension); } - private static (int?, int?, List?) GetConvertedsFromSegments(string facesFileNameExtension, bool idToMappingCollectionAny, Dictionary> idToMappingCollection, string fileName) + private static (int?, int?) GetConvertedFromSegments(string facesFileNameExtension, string fileName) { int? id; int? normalizedRectangle; - List? mappingCollection; (string? Id, string? NormalizedRectangle, string? ExtensionLowered, bool? Check) segments = GetSegments(facesFileNameExtension, fileName); if (string.IsNullOrEmpty(segments.Id) || string.IsNullOrEmpty(segments.NormalizedRectangle) || string.IsNullOrEmpty(segments.ExtensionLowered) || segments.Check is null) { id = null; - mappingCollection = null; normalizedRectangle = null; } else if (!int.TryParse(segments.Id, out int idValue) || !int.TryParse(segments.NormalizedRectangle, out int normalizedRectangleValue)) { id = null; - mappingCollection = null; normalizedRectangle = null; } else { id = idValue; normalizedRectangle = normalizedRectangleValue; - if (!idToMappingCollectionAny || !idToMappingCollection.ContainsKey(idValue)) - mappingCollection = null; - else - mappingCollection = idToMappingCollection[idValue]; } - return new(id, normalizedRectangle, mappingCollection); + return new(id, normalizedRectangle); } - internal static (int?, int?, List?) GetConverted(string facesFileNameExtension, bool idToMappingCollectionAny, Dictionary> idToMappingCollection, string file) + internal static (int?, int?) GetConverted(string facesFileNameExtension, string file) { int? id; int? normalizedRectangle; - List? mappingCollection; string fileName = Path.GetFileName(file); if (fileName.Length >= 2 && !fileName[1..].Contains('-')) - (id, normalizedRectangle, mappingCollection) = GetConvertedsFromSegments(facesFileNameExtension, idToMappingCollectionAny, idToMappingCollection, fileName); + (id, normalizedRectangle) = GetConvertedFromSegments(facesFileNameExtension, fileName); else { id = null; - mappingCollection = null; normalizedRectangle = null; } - return new(id, normalizedRectangle, mappingCollection); + return new(id, normalizedRectangle); } internal static int GetAreaPermille(int faceAreaPermille, int bottom, int height, int left, int right, int top, int width) diff --git a/Shared/Models/Stateless/Methods/PersonContainer.cs b/Shared/Models/Stateless/Methods/PersonContainer.cs index 2257602..fc736c1 100644 --- a/Shared/Models/Stateless/Methods/PersonContainer.cs +++ b/Shared/Models/Stateless/Methods/PersonContainer.cs @@ -14,7 +14,7 @@ internal abstract class PersonContainer { if (personDisplayDirectoryAllFile.EndsWith(".lnk")) continue; - (id, normalizedRectangle, _) = IMapping.GetConverted(facesFileNameExtension, personDisplayDirectoryAllFile); + (id, normalizedRectangle) = IMapping.GetConverted(facesFileNameExtension, personDisplayDirectoryAllFile); if (id is not null && normalizedRectangle is not null && !personDisplayDirectoryAllFile.EndsWith(".json")) continue; checkDirectory = Path.GetDirectoryName(personDisplayDirectoryAllFile); diff --git a/Tests/Models/Binder/Configuration.cs b/Tests/Models/Binder/Configuration.cs index 8acfc8e..e7692c7 100644 --- a/Tests/Models/Binder/Configuration.cs +++ b/Tests/Models/Binder/Configuration.cs @@ -45,7 +45,7 @@ public class Configuration [Display(Name = "Reverse"), Required] public bool? Reverse { get; set; } [Display(Name = "Save Face Landmark For Output Resolutions"), Required] public string[] SaveFaceLandmarkForOutputResolutions { get; set; } [Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; } - [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveResizedImagesByPersonKeyFormattedForOutputResolutions { get; set; } + [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; } [Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; } [Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; } [Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; } @@ -118,7 +118,7 @@ public class Configuration configuration.SaveFaceLandmarkForOutputResolutions ??= Array.Empty(); if (configuration.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); - configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions ??= Array.Empty(); + configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ??= Array.Empty(); if (configuration.SaveResizedSubfiles is null) throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); configuration.SaveShortcutsForOutputResolutions ??= Array.Empty(); @@ -163,7 +163,7 @@ public class Configuration configuration.Reverse.Value, configuration.SaveFaceLandmarkForOutputResolutions, configuration.SaveFullYearOfRandomFiles.Value, - configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions, + configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions, configuration.SaveShortcutsForOutputResolutions, configuration.SaveResizedSubfiles.Value, configuration.SkipSearch.Value, diff --git a/Tests/Models/Configuration.cs b/Tests/Models/Configuration.cs index af5c742..4ef6376 100644 --- a/Tests/Models/Configuration.cs +++ b/Tests/Models/Configuration.cs @@ -43,7 +43,7 @@ public class Configuration public bool Reverse { init; get; } public string[] SaveFaceLandmarkForOutputResolutions { init; get; } public bool SaveFullYearOfRandomFiles { init; get; } - public string[] SaveResizedImagesByPersonKeyFormattedForOutputResolutions { init; get; } + public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; } public string[] SaveShortcutsForOutputResolutions { init; get; } public bool SaveResizedSubfiles { init; get; } public bool SkipSearch { init; get; } @@ -86,7 +86,7 @@ public class Configuration bool reverse, string[] saveFaceLandmarkForOutputResolutions, bool saveFullYearOfRandomFiles, - string[] saveResizedImagesByPersonKeyFormattedForOutputResolutions, + string[] saveFilteredOriginalImagesFromJLinksForOutputResolutions, string[] saveShortcutsForOutputResolutions, bool saveResizedSubfiles, bool skipSearch, @@ -128,7 +128,7 @@ public class Configuration Reverse = reverse; SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions; SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles; - SaveResizedImagesByPersonKeyFormattedForOutputResolutions = saveResizedImagesByPersonKeyFormattedForOutputResolutions; + SaveFilteredOriginalImagesFromJLinksForOutputResolutions = saveFilteredOriginalImagesFromJLinksForOutputResolutions; SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions; SaveResizedSubfiles = saveResizedSubfiles; SkipSearch = skipSearch; diff --git a/TestsWithFaceRecognitionDotNet/Models/Binder/Configuration.cs b/TestsWithFaceRecognitionDotNet/Models/Binder/Configuration.cs index d3acd6e..fc2feae 100644 --- a/TestsWithFaceRecognitionDotNet/Models/Binder/Configuration.cs +++ b/TestsWithFaceRecognitionDotNet/Models/Binder/Configuration.cs @@ -64,7 +64,7 @@ public class Configuration [Display(Name = "Reverse"), Required] public bool? Reverse { get; set; } [Display(Name = "Save Face Landmark For Output Resolutions"), Required] public string[] SaveFaceLandmarkForOutputResolutions { get; set; } [Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; } - [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveResizedImagesByPersonKeyFormattedForOutputResolutions { get; set; } + [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; } [Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; } [Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; } [Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; } @@ -178,7 +178,7 @@ public class Configuration configuration.SaveFaceLandmarkForOutputResolutions ??= Array.Empty(); if (configuration.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); - configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions ??= Array.Empty(); + configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ??= Array.Empty(); if (configuration.SaveResizedSubfiles is null) throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); configuration.SaveShortcutsForOutputResolutions ??= Array.Empty(); @@ -249,7 +249,7 @@ public class Configuration configuration.Reverse.Value, configuration.SaveFaceLandmarkForOutputResolutions, configuration.SaveFullYearOfRandomFiles.Value, - configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions, + configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions, configuration.SaveResizedSubfiles.Value, configuration.SaveShortcutsForOutputResolutions, configuration.SkipSearch.Value, diff --git a/TestsWithFaceRecognitionDotNet/Models/Configuration.cs b/TestsWithFaceRecognitionDotNet/Models/Configuration.cs index 52163d8..0dbefcb 100644 --- a/TestsWithFaceRecognitionDotNet/Models/Configuration.cs +++ b/TestsWithFaceRecognitionDotNet/Models/Configuration.cs @@ -62,7 +62,7 @@ public class Configuration public bool Reverse { init; get; } public string[] SaveFaceLandmarkForOutputResolutions { init; get; } public bool SaveFullYearOfRandomFiles { init; get; } - public string[] SaveResizedImagesByPersonKeyFormattedForOutputResolutions { init; get; } + public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; } public bool SaveResizedSubfiles { init; get; } public string[] SaveShortcutsForOutputResolutions { init; get; } public bool SkipSearch { init; get; } @@ -127,7 +127,7 @@ public class Configuration bool reverse, string[] saveFaceLandmarkForOutputResolutions, bool saveFullYearOfRandomFiles, - string[] saveResizedImagesByPersonKeyFormattedForOutputResolutions, + string[] saveFilteredOriginalImagesFromJLinksForOutputResolutions, bool saveResizedSubfiles, string[] saveShortcutsForOutputResolutions, bool skipSearch, @@ -191,7 +191,7 @@ public class Configuration Reverse = reverse; SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions; SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles; - SaveResizedImagesByPersonKeyFormattedForOutputResolutions = saveResizedImagesByPersonKeyFormattedForOutputResolutions; + SaveFilteredOriginalImagesFromJLinksForOutputResolutions = saveFilteredOriginalImagesFromJLinksForOutputResolutions; SaveResizedSubfiles = saveResizedSubfiles; SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions; SkipSearch = skipSearch;