From 004017b9ddc981f5e4133d0e098729f7e7be70f0 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Sun, 14 Aug 2022 19:52:30 -0700 Subject: [PATCH] Closest is usable with NamedDeterministicHashCodeIdAndFaceLocationIndex --- Instance/DlibDotNet.cs | 64 +++--- Instance/Models/_D2_FaceLandmark.cs | 3 +- Instance/Models/_D_Face.cs | 22 +-- Instance/Models/_E_Distance.cs | 183 ++++++++++++------ Metadata/Models/B_Metadata.cs | 24 +-- Property/Models/Closest.cs | 6 +- Property/Models/Item.cs | 8 +- Property/Models/PropertyLogic.cs | 77 +++++++- Property/Models/Stateless/IResult.cs | 26 ++- Property/Models/Stateless/Result.cs | 76 ++------ Resize/Models/_C_Resize.cs | 26 +-- Tests/UnitTestResize.cs | 9 +- .../UnitTestFace.cs | 9 +- 13 files changed, 325 insertions(+), 208 deletions(-) diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 8ddae9c..418dc4e 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -418,7 +418,7 @@ public class DlibDotNet } } int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); - string message = $"{container.R + 1:000}.{container.G} / {containersCount:000}) {filteredItems.Length:000} file(s) - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}"; + string message = $"{container.R:000}.{container.G} / {containersCount:000}) {filteredItems.Length:000} file(s) - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}"; using (ProgressBar progressBar = new(filteredItems.Length, message, options)) { _ = Parallel.For(0, filteredItems.Length, parallelOptions, i => @@ -438,15 +438,6 @@ public class DlibDotNet } }); } -#pragma warning disable - int[] ids = (from l in filteredItems where l.Property?.Id is not null select l.Property.Id.Value).ToArray(); -#pragma warning restore - bool hasDuplicateId = ids.Length != ids.Distinct().Count(); - if (hasDuplicateId) - { - if (hasDuplicateId) - { } - } return result; } @@ -575,6 +566,10 @@ public class DlibDotNet throw new NullReferenceException(nameof(_Log)); if (_AppSettings.MaxDegreeOfParallelism is null) throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); + if (_Configuration.SaveResizedSubfiles is null) + throw new NullReferenceException(nameof(_Configuration.SaveResizedSubfiles)); + int[] ids; + int distinctCount; int exceptionCount; Item[] filteredItems; long ticks = DateTime.Now.Ticks; @@ -617,7 +612,7 @@ public class DlibDotNet continue; if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero)) continue; - filteredItems = (from l in container.Items where l.ImageFileHolder is not null && l.ValidImageFormatExtension && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray(); + filteredItems = (from l in container.Items where l.ImageFileHolder is not null && (l.Abandoned is null || !l.Abandoned.Value) && l.ValidImageFormatExtension && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray(); if (!filteredItems.Any()) continue; faceCollections.Clear(); @@ -635,27 +630,37 @@ public class DlibDotNet aResultsFullGroupDirectory, contentDescription: string.Empty, singletonDescription: "Properties for each image", - collectionDescription: string.Empty)); + collectionDescription: string.Empty, + converted: false)); _Metadata.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, container.SourceDirectory, bResultsFullGroupDirectory, contentDescription: string.Empty, singletonDescription: "Metadata as key value pairs", - collectionDescription: string.Empty)); + collectionDescription: string.Empty, + converted: true)); _Resize.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, container.SourceDirectory, cResultsFullGroupDirectory, contentDescription: "Resized image", singletonDescription: "Resize dimensions for each resolution", - collectionDescription: string.Empty)); + collectionDescription: string.Empty, + converted: true)); if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution)) _Faces.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, container.SourceDirectory, dResultsFullGroupDirectory, contentDescription: "n png file(s) for each face found", singletonDescription: string.Empty, - collectionDescription: "For each image a json file with all faces found")); + collectionDescription: "For each image a json file with all faces found", + converted: true)); exceptionCount = FullParallelWork(ticks, propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, containers.Count, container, filteredItems); +#pragma warning disable + ids = (from l in filteredItems where l.Property?.Id is not null select l.Property.Id.Value).ToArray(); +#pragma warning restore + distinctCount = ids.Distinct().Count(); + if (ids.Length != distinctCount) + _Log.Information($"{ids.Length} != {distinctCount} <{container.SourceDirectory}>"); if (metadataCollection.Count != filteredItems.Length || propertyCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || faceCollections.Count != filteredItems.Length) throw new Exception("Counts don't match!"); if (exceptionCount != 0) @@ -664,7 +669,7 @@ public class DlibDotNet WriteGroup(configuration, propertyLogic, propertyCollection, metadataCollection, faceCollections, resizeKeyValuePairs, container.SourceDirectory, outputResolution, filteredItems); if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0 && outputResolution == _Configuration.OutputResolutions[0]) propertyLogic.AddToPropertyLogicAllCollection(filteredItems); - if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0 && propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.Any()) + if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0 && propertyLogic.NamedFaceInfoDeterministicHashCodeIds.Any()) { if (outputResolution == _Configuration.OutputResolutions[0] || _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) { @@ -674,6 +679,10 @@ public class DlibDotNet // break; // if (isSilent && container.SourceDirectory.EndsWith("zzz =2014.4 Winter Tracy Pictures")) // 30#.2 // break; + // if (isSilent && container.SourceDirectory.EndsWith("=2009.0 Winter Logan Michael")) //34#.2 + // break; + // if (isSilent && container.SourceDirectory.EndsWith("Animal Kingdom")) //35#.3 + // break; // if (isSilent && container.SourceDirectory.EndsWith("Texas 2015")) //46#.4 // break; for (int i = 0; i < faceCollections.Count; i++) @@ -685,10 +694,6 @@ public class DlibDotNet } if (exceptionCount == 0 && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)) _Distance.LoadOrCreateThenSaveDistanceResultsForOutputResolutions(configuration, eResultsFullGroupDirectory, container.SourceDirectory, outputResolution, sourceDirectoryChanges, filteredItems, faceCollections); - if (_Resize.AngleBracketCollection.Any()) - _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(_Resize.AngleBracketCollection[0].Replace("<>", "()")); - if (_Faces.AngleBracketCollection.Any()) - _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(_Faces.AngleBracketCollection[0].Replace("<>", "()")); if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any()) { for (int y = 0; y < int.MaxValue; y++) @@ -700,10 +705,21 @@ public class DlibDotNet _Log.Information(". . ."); } } + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}")); + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, "{}")); + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}")); + if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution)) + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, "[]")); + if (_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)) + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]")); + if (_Configuration.LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions.Contains(outputResolution)) + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]")); + if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution)) + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(d2ResultsFullGroupDirectory, "[]")); if (_ArgZeroIsConfigurationRootDirectory && outputResolution == _Configuration.OutputResolutions[0]) { propertyLogic.SaveAllCollection(); - if (propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.Any()) + if (_Configuration.SaveResizedSubfiles.Value && propertyLogic.NamedFaceInfoDeterministicHashCodeIds.Any()) { string dFacesContentDirectory; string eDistanceContentDirectory; @@ -715,9 +731,13 @@ public class DlibDotNet eDistanceCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, $"[{ticks}]"); List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection; collection = E_Distance.ParallelWork(_AppSettings.MaxDegreeOfParallelism.Value, argZero, containers); + _ = LogDelta(ticks, nameof(E_Distance.ParallelWork)); E_Distance.SavePropertyHolders(argZero, containers, zPropertyHolderSingletonDirectory); + _ = LogDelta(ticks, nameof(E_Distance.SavePropertyHolders)); E_Distance.SaveThreeSigmaFaceEncodings(collection, peopleCollection, eDistanceCollectionDirectory); - E_Distance.SaveClosest(argZero, containers, peopleCollection, eDistanceContentDirectory, dFacesContentDirectory); + _ = LogDelta(ticks, nameof(E_Distance.SaveThreeSigmaFaceEncodings)); + E_Distance.SaveClosest(argZero, containers, peopleCollection, propertyLogic, eDistanceContentDirectory, dFacesContentDirectory); + _ = LogDelta(ticks, nameof(E_Distance.SaveClosest)); } if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any()) break; diff --git a/Instance/Models/_D2_FaceLandmark.cs b/Instance/Models/_D2_FaceLandmark.cs index db93dce..3b18223 100644 --- a/Instance/Models/_D2_FaceLandmark.cs +++ b/Instance/Models/_D2_FaceLandmark.cs @@ -128,7 +128,8 @@ internal class D2_FaceLandmarks d2ResultsFullGroupDirectory, contentDescription: "n x 2 png file(s) for each face found", singletonDescription: string.Empty, - collectionDescription: string.Empty)); + collectionDescription: string.Empty, + converted: false)); string facesDirectory = Path.Combine(angleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension); string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) }; List dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); diff --git a/Instance/Models/_D_Face.cs b/Instance/Models/_D_Face.cs index 79debb3..221d085 100644 --- a/Instance/Models/_D_Face.cs +++ b/Instance/Models/_D_Face.cs @@ -429,21 +429,17 @@ public class D_Face : Shared.Models.Properties.IFace, IFace string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) }; List dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension); - FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json")); - string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", "_ _ _", $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json"); - if (fileInfo.Exists) + string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json"); + string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json"); + FileInfo fileInfo = new(dCollectionFile); + if (!fileInfo.Exists) { - if (!File.Exists(dCollectionFile)) + if (File.Exists(usingRelativePath)) { - fileInfo.MoveTo(dCollectionFile); - fileInfo = new(dCollectionFile); + File.Move(usingRelativePath, fileInfo.FullName); + fileInfo.Refresh(); } - } - else - { - if (File.Exists(dCollectionFile)) - fileInfo = new(dCollectionFile); - else + if (!fileInfo.Exists) { if (fileInfo.Directory?.Parent is null) throw new Exception(); @@ -516,8 +512,6 @@ public class D_Face : Shared.Models.Properties.IFace, IFace throw new NullReferenceException(nameof(item.ImageFileHolder)); if (item.ResizedFileHolder is null) throw new NullReferenceException(nameof(item.ResizedFileHolder)); - if (string.IsNullOrEmpty(dResultsFullGroupDirectory)) - throw new NullReferenceException(nameof(dResultsFullGroupDirectory)); FileInfo fileInfo; bool check = false; string parentCheck; diff --git a/Instance/Models/_E_Distance.cs b/Instance/Models/_E_Distance.cs index 5b04b3e..57e9b58 100644 --- a/Instance/Models/_E_Distance.cs +++ b/Instance/Models/_E_Distance.cs @@ -6,6 +6,7 @@ using View_by_Distance.Metadata.Models; using View_by_Distance.Property.Models; using View_by_Distance.Resize.Models; using View_by_Distance.Shared.Models.Stateless; +using WindowsShortcutFactory; namespace View_by_Distance.Instance.Models; @@ -198,11 +199,13 @@ internal class E_Distance throw new NullReferenceException(nameof(_Configuration.CheckJsonForDistanceResults)); if (_Configuration.PropertiesChangedForDistance is null) throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForDistance)); + Item item; string json; bool check = false; string parentCheck; - FileHolder? fileHolder; + string usingRelativePath; DateTime? dateTime = null; + string dCollectionDirectory; FileInfo[] fileInfoCollection; bool updateDateWhenMatches = false; List directories = new(); @@ -216,26 +219,37 @@ internal class E_Distance eResultsFullGroupDirectory, contentDescription: ".tvs File", singletonDescription: string.Empty, - collectionDescription: "n json file(s) for each face found (one to many)"); + collectionDescription: "n json file(s) for each face found (one to many)", + converted: true); for (int i = 0; i < filteredItems.Length; i++) { - fileHolder = filteredItems[i].ImageFileHolder; - if (fileHolder is null) + item = filteredItems[i]; + if (item.ImageFileHolder is null || item.Property?.Id is null) continue; - directoryInfo = new System.IO.DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), fileHolder.NameWithoutExtension)); + usingRelativePath = Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), item.ImageFileHolder.NameWithoutExtension); + dCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, "[]", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}"); + directoryInfo = new System.IO.DirectoryInfo(dCollectionDirectory); if (!directoryInfo.Exists) { - if (directoryInfo.Parent?.Parent is null) - throw new Exception(); - parentCheck = Path.Combine(directoryInfo.Parent.Parent.FullName, directoryInfo.Name); - if (Directory.Exists(parentCheck)) + if (Directory.Exists(usingRelativePath)) { - foreach (string file in Directory.GetFiles(parentCheck)) - File.Delete(file); - Directory.Delete(parentCheck); + Directory.Move(usingRelativePath, directoryInfo.FullName); + directoryInfo.Refresh(); + } + if (!Directory.Exists(dCollectionDirectory)) + { + if (directoryInfo.Parent?.Parent is null) + throw new Exception(); + parentCheck = Path.Combine(directoryInfo.Parent.Parent.FullName, directoryInfo.Name); + if (Directory.Exists(parentCheck)) + { + foreach (string file in Directory.GetFiles(parentCheck)) + File.Delete(file); + Directory.Delete(parentCheck); + } } } - tvsDirectoryInfo = new System.IO.DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "()"), fileHolder.NameWithoutExtension)); + tvsDirectoryInfo = new System.IO.DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension)); directories.Add(new string[] { directoryInfo.FullName, tvsDirectoryInfo.FullName }); if (_Configuration.CheckJsonForDistanceResults.Value && directoryInfo.Exists) { @@ -517,7 +531,7 @@ internal class E_Distance return results; } - private static Closest? GetClosestParallelFor(float maxMinimum, DateTime minimumDateTime, bool? isWrongYear, Shared.Models.Properties.IFace face, FaceEncoding faceEncoding, (DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, FaceEncoding[] FaceEncodings) tuple) + private static Closest? GetClosestParallelFor(DateTime minimumDateTime, bool? isWrongYear, Shared.Models.Properties.IFace face, FaceEncoding faceEncoding, (DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, FaceEncoding[] FaceEncodings) tuple) { Closest? result; if (isWrongYear.HasValue && !isWrongYear.Value && minimumDateTime < tuple.PersonBirthday.Value) @@ -526,19 +540,20 @@ internal class E_Distance { List faceDistances = FaceRecognition.FaceDistances(tuple.FaceEncodings, faceEncoding); result = new(face.LocationIndex, tuple.MinimumDateTime, tuple.IsWrongYear, tuple.PersonBirthday, faceDistances); - if (result.Minimum > maxMinimum) + if (result.Minimum > Closest.MaximumMinimum) result = null; } return result; } - private static List GetClosestCollection(int maxDegreeOfParallelism, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, float maxMinimum, DateTime itemMinimumDateTime, bool? itemIsWrongYear, Shared.Models.Properties.IFace face) + private static Closest[] GetClosestCollection(int maxDegreeOfParallelism, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, DateTime itemMinimumDateTime, bool? itemIsWrongYear, Shared.Models.Properties.IFace face) { - List results; + Closest[] results; + List closestCollection; FaceEncoding faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); if (maxDegreeOfParallelism == 1) { - results = new(); + closestCollection = new(); Closest closest; List faceDistances; foreach ((DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday, FaceEncoding[] faceEncodings) in collection) @@ -547,35 +562,36 @@ internal class E_Distance continue; faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncoding); closest = new(face.LocationIndex, minimumDateTime, isWrongYear, personBirthday, faceDistances); - if (closest.Minimum > maxMinimum) + if (closest.Minimum > Closest.MaximumMinimum) continue; - results.Add(closest); + closestCollection.Add(closest); } } else { - results = new(); + closestCollection = new(); ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; _ = Parallel.For(0, collection.Count, parallelOptions, i => { - Closest? closest = GetClosestParallelFor(maxMinimum, itemMinimumDateTime, itemIsWrongYear, face, faceEncoding, collection[i]); + Closest? closest = GetClosestParallelFor(itemMinimumDateTime, itemIsWrongYear, face, faceEncoding, collection[i]); if (closest is not null) { - lock (results) - results.Add(closest); + lock (closestCollection) + closestCollection.Add(closest); } }); } + results = Closest.Get(closestCollection); return results; } - private static void AddClosest(int maxDegreeOfParallelism, string argZero, List containers, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, bool skipIsWrongYear, int maxPer, float maxMinimum) + private static void AddClosest(int maxDegreeOfParallelism, string argZero, List containers, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection) { string key; Closest closest; bool? itemIsWrongYear; + Closest[] closestCollection; DateTime? itemMinimumDateTime; - List closestCollection; Shared.Models.Properties.IFace face; Dictionary results = new(); foreach (Container container in containers) @@ -592,7 +608,7 @@ internal class E_Distance if (itemMinimumDateTime is null) continue; (itemIsWrongYear, _) = item.IsWrongYear(); - if (skipIsWrongYear && itemIsWrongYear.HasValue && itemIsWrongYear.Value) + if (Closest.SkipIsWrongYear && itemIsWrongYear.HasValue && itemIsWrongYear.Value) continue; item.Closest.Clear(); for (int i = 0; i < item.Faces.Count; i++) @@ -602,19 +618,21 @@ internal class E_Distance item.Closest.Add(closest); if (!face.Populated) continue; - closestCollection = GetClosestCollection(maxDegreeOfParallelism, collection, maxMinimum, itemMinimumDateTime.Value, itemIsWrongYear, face); - if (!closestCollection.Any()) - continue; - closest = Closest.Get(closestCollection); - if (closest.PersonBirthday is null) - continue; - key = Item.GetKey(closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday); - if (!results.ContainsKey(key)) - results.Add(key, 0); - else if (results[key] > maxPer) - continue; - results[key] += 1; - item.Closest[0] = closest; + closestCollection = GetClosestCollection(maxDegreeOfParallelism, collection, itemMinimumDateTime.Value, itemIsWrongYear, face); + for (int j = 0; j < closestCollection.Length; j++) + { + closest = closestCollection[j]; + if (closest.PersonBirthday is null) + continue; + key = Item.GetKey(closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday); + if (!results.ContainsKey(key)) + results.Add(key, 0); + else if (results[key] > Closest.MaximumPer) + continue; + results[key] += 1; + item.Closest[0] = closest; + break; + } } } } @@ -623,12 +641,9 @@ internal class E_Distance internal static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> ParallelWork(int maxDegreeOfParallelism, string argZero, List containers) { List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> results; - const int maxPer = 5; - const float maxMinimum = 0.50f; - const bool skipIsWrongYear = true; Dictionary> keyValuePairs = Item.GetKeyValuePairs(argZero, containers); results = GetThreeSigmaFaceEncodings(maxDegreeOfParallelism, keyValuePairs); - AddClosest(maxDegreeOfParallelism, argZero, containers, results, skipIsWrongYear, maxPer, maxMinimum); + AddClosest(maxDegreeOfParallelism, argZero, containers, results); return results; } @@ -692,17 +707,21 @@ internal class E_Distance } } - internal static void SaveClosest(string argZero, List containers, Dictionary> peopleCollection, string eDistanceContentDirectory, string dFacesContentDirectory) + internal static List<(FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> GetClosest(string argZero, List containers, Dictionary> peopleCollection, PropertyLogic propertyLogic, string eDistanceContentDirectory, string dFacesContentDirectory) { - string copyFile; + List<(FileHolder?, string, FileInfo?, string, string)> results = new(); string checkFile; string directory; string personKey; + string personName; + string shortcutFile; + FileInfo faceFileInfo; string? directoryName; string facesDirectory; - string faceFullFileName; + string personDirectory; Shared.Models.Person person; const string facePopulatedKey = "Closest"; + string deterministicHashCodeIdAndFaceLocationIndex; const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]"; foreach (Container container in containers) { @@ -723,31 +742,73 @@ internal class E_Distance { if (closest.Average is null || closest.FaceLocationIndex is null || closest.PersonBirthday is null) continue; + deterministicHashCodeIdAndFaceLocationIndex = $"{closest.FaceLocationIndex.Value} - {item.Property.Id.Value}"; + if (propertyLogic.NamedDeterministicHashCodeIdAndFaceLocationIndex.Contains(deterministicHashCodeIdAndFaceLocationIndex)) + continue; personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.PersonBirthday); directory = Item.GetDirectory(eDistanceContentDirectory, facePopulatedKey, closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday, personKey); - if (!Directory.Exists(directory)) - _ = Directory.CreateDirectory(directory); // checkFile = Path.Combine(directory, item.ImageFileHolder.Name); - checkFile = Path.Combine(directory, $"{closest.FaceLocationIndex.Value} - {item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}"); - if (peopleCollection.ContainsKey(personKey)) + if (!peopleCollection.ContainsKey(personKey)) + personDirectory = string.Empty; + else { person = peopleCollection[personKey][0]; - directory = Path.Combine(directory, Regex.Replace(Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name), pattern, string.Empty)); - if (!Directory.Exists(directory)) - _ = Directory.CreateDirectory(directory); + personName = Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name); + personDirectory = Path.Combine(directory, Regex.Replace(personName, pattern, string.Empty)); + results.Add(new(null, personDirectory, null, string.Empty, string.Empty)); } facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension)); - faceFullFileName = Path.Combine(facesDirectory, $"{closest.FaceLocationIndex.Value} - {item.ImageFileHolder.NameWithoutExtension}.png"); - if (Directory.Exists(facesDirectory) && File.Exists(faceFullFileName)) - copyFile = faceFullFileName; + faceFileInfo = new(Path.Combine(facesDirectory, $"{closest.FaceLocationIndex.Value} - {item.ImageFileHolder.NameWithoutExtension}.png")); + checkFile = Path.Combine(directory, $"{deterministicHashCodeIdAndFaceLocationIndex}{item.ImageFileHolder.ExtensionLowered}"); + if (string.IsNullOrEmpty(personDirectory)) + shortcutFile = string.Empty; else - copyFile = item.ResizedFileHolder.FullName; - if (File.Exists(checkFile)) - continue; - File.Copy(copyFile, checkFile); + shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeIdAndFaceLocationIndex}{item.ImageFileHolder.ExtensionLowered}.lnk"); + results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile)); } } } + return results; + } + + internal static void SaveClosest(string argZero, List containers, Dictionary> peopleCollection, PropertyLogic propertyLogic, string eDistanceContentDirectory, string dFacesContentDirectory) + { + WindowsShortcut windowsShortcut; + List<(FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> collection = GetClosest(argZero, containers, peopleCollection, propertyLogic, eDistanceContentDirectory, dFacesContentDirectory); + string[] directories = (from l in collection select l.directory).Distinct().ToArray(); + foreach (string directory in directories) + { + if (string.IsNullOrEmpty(directory)) + continue; + if (!Directory.Exists(directory)) + _ = Directory.CreateDirectory(directory); + } + foreach ((FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile) in collection) + { + if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null || faceFileInfo is null) + continue; + if (File.Exists(checkFile)) + continue; + if (faceFileInfo.Directory is not null && faceFileInfo.Directory.Exists && faceFileInfo.Exists) + File.Copy(faceFileInfo.FullName, checkFile); + else + File.Copy(resizedFileHolder.FullName, checkFile); + } + foreach ((FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile) in collection) + { + if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null || faceFileInfo is null) + continue; + if (string.IsNullOrEmpty(shortcutFile)) + continue; + try + { + windowsShortcut = new() { Path = resizedFileHolder.FullName }; + windowsShortcut.Save(shortcutFile); + windowsShortcut.Dispose(); + } + catch (Exception) + { } + } } } \ No newline at end of file diff --git a/Metadata/Models/B_Metadata.cs b/Metadata/Models/B_Metadata.cs index 44db077..1af9e1d 100644 --- a/Metadata/Models/B_Metadata.cs +++ b/Metadata/Models/B_Metadata.cs @@ -85,27 +85,21 @@ public class B_Metadata throw new NullReferenceException(nameof(item.Property.Id)); if (item.ImageFileHolder is null) throw new NullReferenceException(nameof(item.ImageFileHolder)); - if (string.IsNullOrEmpty(bResultsFullGroupDirectory)) - throw new NullReferenceException(nameof(bResultsFullGroupDirectory)); - Dictionary>>? dictionary; string json = string.Empty; string[] changesFrom = Array.Empty(); + Dictionary>>? dictionary; List dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); - FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "{}"), string.Concat(item.ImageFileHolder.NameWithoutExtension, ".json"))); - string bMetadataSingletonFile = Path.Combine(bResultsFullGroupDirectory, "{}", "_ _ _", $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json"); - if (fileInfo.Exists) + string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "{}"), string.Concat(item.ImageFileHolder.NameWithoutExtension, ".json")); + string bMetadataSingletonFile = Path.Combine(bResultsFullGroupDirectory, "{}", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json"); + FileInfo fileInfo = new(bMetadataSingletonFile); + if (!fileInfo.Exists) { - if (!File.Exists(bMetadataSingletonFile)) + if (File.Exists(usingRelativePath)) { - fileInfo.MoveTo(bMetadataSingletonFile); - fileInfo = new(bMetadataSingletonFile); + File.Move(usingRelativePath, fileInfo.FullName); + fileInfo.Refresh(); } - } - else - { - if (File.Exists(bMetadataSingletonFile)) - fileInfo = new(bMetadataSingletonFile); - else + if (!fileInfo.Exists) { if (fileInfo.Directory?.Parent is null) throw new Exception(); diff --git a/Property/Models/Closest.cs b/Property/Models/Closest.cs index b6b22f5..7c8b31d 100644 --- a/Property/Models/Closest.cs +++ b/Property/Models/Closest.cs @@ -5,6 +5,10 @@ namespace View_by_Distance.Property.Models; public class Closest { + public const int MaximumPer = 50; + public const float MaximumMinimum = 0.50f; + public const bool SkipIsWrongYear = true; + public const float MinimumMinimum = 0.05f; protected readonly double? _Average; protected readonly int? _FaceLocationIndex; @@ -40,6 +44,6 @@ public class Closest { } - public static Closest Get(List collection) => (from l in collection orderby l.Minimum < 0.05, l.Average select l).First(); + public static Closest[] Get(List collection) => (from l in collection orderby l.Minimum < MinimumMinimum, l.Average select l).ToArray(); } \ No newline at end of file diff --git a/Property/Models/Item.cs b/Property/Models/Item.cs index a3b8861..28bb160 100644 --- a/Property/Models/Item.cs +++ b/Property/Models/Item.cs @@ -106,10 +106,10 @@ public class Item continue; if (item.Property?.Id is null || item.ResizedFileHolder is null) continue; - if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(item.Property.Id.Value)) + if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIds.ContainsKey(item.Property.Id.Value)) continue; minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property); - personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[item.Property.Id.Value]; + personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIds[item.Property.Id.Value]; (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime); for (int j = 0; j < personKeys.Length; j++) { @@ -163,7 +163,7 @@ public class Item if (item.Property?.Id is null || item.ResizedFileHolder is null) continue; collection = new(); - if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(item.Property.Id.Value)) + if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIds.ContainsKey(item.Property.Id.Value)) { faceCollection = new(); directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}"); @@ -171,7 +171,7 @@ public class Item else { faceCollection = item.Faces; - keys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[item.Property.Id.Value]; + keys = propertyLogic.NamedFaceInfoDeterministicHashCodeIds[item.Property.Id.Value]; minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property); if (minimumDateTime is null) continue; diff --git a/Property/Models/PropertyLogic.cs b/Property/Models/PropertyLogic.cs index c7b0bc9..aac479f 100644 --- a/Property/Models/PropertyLogic.cs +++ b/Property/Models/PropertyLogic.cs @@ -19,14 +19,16 @@ public class PropertyLogic protected readonly Dictionary _KeyValuePairs; protected readonly Dictionary _IndicesFromNew; protected readonly Dictionary _SixCharacterNamedFaceInfo; - protected readonly Dictionary _NamedFaceInfoDeterministicHashCodeIndices; + protected readonly List _NamedDeterministicHashCodeIdAndFaceLocationIndex; + protected readonly Dictionary _NamedFaceInfoDeterministicHashCodeIds; public bool Reverse { get; } public List AngleBracketCollection { get; } public Dictionary KeyValuePairs => _KeyValuePairs; public Dictionary IndicesFromNew => _IndicesFromNew; public List ExceptionsDirectories => _ExceptionsDirectories; - public Dictionary NamedFaceInfoDeterministicHashCodeIndices => _NamedFaceInfoDeterministicHashCodeIndices; + public Dictionary NamedFaceInfoDeterministicHashCodeIds => _NamedFaceInfoDeterministicHashCodeIds; + public List NamedDeterministicHashCodeIdAndFaceLocationIndex => _NamedDeterministicHashCodeIdAndFaceLocationIndex; private readonly Model? _Model; private readonly Serilog.ILogger? _Log; @@ -57,6 +59,7 @@ public class PropertyLogic string json; string[] files; string fullPath; + List namedDeterministicHashCodeIdAndFaceLocationIndex = new(); Dictionary? keyValuePairs; List>? collection; Dictionary indicesFromNew = new(); @@ -75,7 +78,20 @@ public class PropertyLogic throw new NullReferenceException(nameof(namedFaceInfoDeterministicHashCodeIndices)); } if (namedFaceInfoDeterministicHashCodeIndices.Any()) + { sixCharacterNamedFaceInfo = new(); + string[] directories = Directory.GetDirectories(rootDirectoryParent, "*DeterministicHashCode*", SearchOption.TopDirectoryOnly); + if (directories.Any()) + { + Dictionary ticksKeyValuePairs = GetKeyValuePairs(namedDeterministicHashCodeIdAndFaceLocationIndex, directories[0]); + foreach (KeyValuePair keyValuePair in ticksKeyValuePairs) + { + if (namedFaceInfoDeterministicHashCodeIndices.ContainsKey(keyValuePair.Key)) + continue; + namedFaceInfoDeterministicHashCodeIndices.Add(keyValuePair.Key, keyValuePair.Value); + } + } + } else { files = Directory.GetFiles(rootDirectoryParent, "*SixCharacter*.json", SearchOption.TopDirectoryOnly); @@ -117,10 +133,63 @@ public class PropertyLogic indicesFromNew.Add(keyValuePair.Key, keyValuePair.Value); } } + _NamedDeterministicHashCodeIdAndFaceLocationIndex = namedDeterministicHashCodeIdAndFaceLocationIndex; _KeyValuePairs = keyValuePairs; _IndicesFromNew = indicesFromNew; _SixCharacterNamedFaceInfo = sixCharacterNamedFaceInfo; - _NamedFaceInfoDeterministicHashCodeIndices = namedFaceInfoDeterministicHashCodeIndices; + _NamedFaceInfoDeterministicHashCodeIds = namedFaceInfoDeterministicHashCodeIndices; + } + + private static Dictionary GetKeyValuePairs(List namedDeterministicHashCodeIdAndFaceLocationIndex, string rootDirectory) + { + Dictionary results = new(); + string id; + string[] files; + string personKey; + string[] segments; + string faceLocationIndex; + string[] yearDirectories; + string[] personKeyDirectories; + string[] personNameDirectories; + string fileNameWithoutExtension; + string[] ticksDirectories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string ticksDirectory in ticksDirectories) + { + if (!ticksDirectory.EndsWith(')')) + continue; + personKeyDirectories = Directory.GetDirectories(ticksDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string personKeyDirectory in personKeyDirectories) + { + personKey = Path.GetFileName(personKeyDirectory); + yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string yearDirectory in yearDirectories) + { + personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string personNameDirectory in personNameDirectories) + { + files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string file in files) + { + if (file.EndsWith(".lnk")) + continue; + fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file); + segments = fileNameWithoutExtension.Split(' '); + if (segments.Length < 2) + continue; + id = segments[2]; + faceLocationIndex = segments[0]; + if (!int.TryParse(id, out int idValue)) + continue; + namedDeterministicHashCodeIdAndFaceLocationIndex.Add(fileNameWithoutExtension); + if (results.ContainsKey(idValue)) + continue; + results.Add(idValue, new string[] { personKey }); + } + } + } + } + } + return results; } public override string ToString() @@ -640,7 +709,7 @@ public class PropertyLogic List> filteredSourceDirectoryFileTuples = new(); ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; - string message = $"{container.R + 1:000}.{container.G} / {containersCount:000}) {filteredItems.Length:000} file(s) - {totalSeconds} total second(s) - {container.SourceDirectory}"; + string message = $"{container.R:000}.{container.G} / {containersCount:000}) {filteredItems.Length:000} file(s) - {totalSeconds} total second(s) - {container.SourceDirectory}"; using ProgressBar progressBar = new(filteredItems.Length, message, options); _ = Parallel.For(0, filteredItems.Length, parallelOptions, i => { diff --git a/Property/Models/Stateless/IResult.cs b/Property/Models/Stateless/IResult.cs index 0590926..789900b 100644 --- a/Property/Models/Stateless/IResult.cs +++ b/Property/Models/Stateless/IResult.cs @@ -5,25 +5,37 @@ namespace View_by_Distance.Property.Models.Stateless; public interface IResult { + public const string Content = "()"; + public const string Singleton = "{}"; + public const string Collection = "[]"; + public const string AllInOne = "_ _ _"; + string TestStatic_GetRelativePath(Models.Configuration configuration, string path); - static string GetRelativePath(Models.Configuration configuration, string path) => Result.GetRelativePath(configuration, path); + static string GetRelativePath(Models.Configuration configuration, string path) + => Result.GetRelativePath(configuration, path); string TestStatic_GetResultsGroupDirectory(Models.Configuration configuration, string description); - static string GetResultsGroupDirectory(Models.Configuration configuration, string description) => Result.GetResultsGroupDirectory(configuration, description); + static string GetResultsGroupDirectory(Models.Configuration configuration, string description) + => Result.GetResultsGroupDirectory(configuration, description); string TestStatic_GetResultsDateGroupDirectory(Models.Configuration configuration, string description); - static string GetResultsDateGroupDirectory(Models.Configuration configuration, string description) => Result.GetResultsDateGroupDirectory(configuration, description); + static string GetResultsDateGroupDirectory(Models.Configuration configuration, string description) + => Result.GetResultsDateGroupDirectory(configuration, description); string TestStatic_GetResultsDateGroupDirectory(Models.Configuration configuration, string description, string jsonGroup); - static string GetResultsDateGroupDirectory(Models.Configuration configuration, string description, string jsonGroup) => Result.GetResultsDateGroupDirectory(configuration, description, jsonGroup); + static string GetResultsDateGroupDirectory(Models.Configuration configuration, string description, string jsonGroup) + => Result.GetResultsDateGroupDirectory(configuration, description, jsonGroup); List TestStatic_GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription); - static List GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription) => Result.GetDirectoryInfoCollection(configuration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription); + static List GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted) + => Result.GetDirectoryInfoCollection(configuration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted); string TestStatic_GetResultsFullGroupDirectory(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel); - static string GetResultsFullGroupDirectory(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) => Result.GetResultsFullGroupDirectory(configuration, model, predictorModel, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel); + static string GetResultsFullGroupDirectory(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) + => Result.GetResultsFullGroupDirectory(configuration, model, predictorModel, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel); List TestStatic_GetDirectoryInfoCollection(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription); - static List GetDirectoryInfoCollection(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) => Result.GetDirectoryInfoCollection(configuration, model, predictorModel, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription); + static List GetDirectoryInfoCollection(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) + => Result.GetDirectoryInfoCollection(configuration, model, predictorModel, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription); } \ No newline at end of file diff --git a/Property/Models/Stateless/Result.cs b/Property/Models/Stateless/Result.cs index 692a4fa..3a8429c 100644 --- a/Property/Models/Stateless/Result.cs +++ b/Property/Models/Stateless/Result.cs @@ -64,20 +64,18 @@ internal class Result return result; } - internal static List GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription) + internal static List GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted) { List results = new(); - string result = string.Empty; string checkDirectory; - const string allInOne = "_ _ _"; string sourceDirectorySegment = GetRelativePath(configuration, sourceDirectory); + string result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment); if (!string.IsNullOrEmpty(contentDescription)) { - checkDirectory = Path.Combine(dateGroupDirectory, "()", allInOne); + checkDirectory = Path.Combine(dateGroupDirectory, IResult.Content, IResult.AllInOne); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); - result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment); - string contentDirectory = new(result.Replace("<>", "()")); + string contentDirectory = new(result.Replace("<>", IResult.Content)); if (!Directory.Exists(contentDirectory)) _ = Directory.CreateDirectory(contentDirectory); checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("() - ", contentDescription)); @@ -86,76 +84,44 @@ internal class Result } if (!string.IsNullOrEmpty(singletonDescription)) { - checkDirectory = Path.Combine(dateGroupDirectory, "{}", allInOne); + checkDirectory = Path.Combine(dateGroupDirectory, IResult.Singleton, IResult.AllInOne); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); - result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment); - string singletonDirectory = new(result.Replace("<>", "{}")); - if (!Directory.Exists(singletonDirectory)) - _ = Directory.CreateDirectory(singletonDirectory); + if (!converted) + { + string singletonDirectory = new(result.Replace("<>", IResult.Singleton)); + if (!Directory.Exists(singletonDirectory)) + _ = Directory.CreateDirectory(singletonDirectory); + } checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("{} - ", singletonDescription)); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); } if (!string.IsNullOrEmpty(collectionDescription)) { - checkDirectory = Path.Combine(dateGroupDirectory, "[]", allInOne); + checkDirectory = Path.Combine(dateGroupDirectory, IResult.Collection, IResult.AllInOne); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); - result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment); - string collectionDirectory = new(result.Replace("<>", "[]")); - if (!Directory.Exists(collectionDirectory)) - _ = Directory.CreateDirectory(collectionDirectory); + if (!converted) + { + string collectionDirectory = new(result.Replace("<>", IResult.Collection)); + if (!Directory.Exists(collectionDirectory)) + _ = Directory.CreateDirectory(collectionDirectory); + } checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("[] - ", collectionDescription)); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); } - if (string.IsNullOrEmpty(result)) - throw new Exception(); results.Add(result); return results; } internal static List GetDirectoryInfoCollection(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) { - List results = new(); - string result = string.Empty; - string checkDirectory; - string sourceDirectorySegment = GetRelativePath(configuration, sourceDirectory); + List results; + bool converted = false; string dateGroupDirectory = GetResultsFullGroupDirectory(configuration, model, predictorModel, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel); - if (!string.IsNullOrEmpty(contentDescription)) - { - result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment); - System.IO.DirectoryInfo contentDirectoryInfo = new(result.Replace("<>", "()")); - if (!contentDirectoryInfo.Exists) - contentDirectoryInfo.Create(); - checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("() - ", contentDescription)); - if (!Directory.Exists(checkDirectory)) - _ = Directory.CreateDirectory(checkDirectory); - } - if (!string.IsNullOrEmpty(singletonDescription)) - { - result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment); - System.IO.DirectoryInfo singletonDirectoryInfo = new(result.Replace("<>", "{}")); - if (!singletonDirectoryInfo.Exists) - singletonDirectoryInfo.Create(); - checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("{} - ", singletonDescription)); - if (!Directory.Exists(checkDirectory)) - _ = Directory.CreateDirectory(checkDirectory); - } - if (!string.IsNullOrEmpty(collectionDescription)) - { - result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment); - System.IO.DirectoryInfo collectionDirectoryInfo = new(result.Replace("<>", "[]")); - if (!collectionDirectoryInfo.Exists) - collectionDirectoryInfo.Create(); - checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("[] - ", collectionDescription)); - if (!Directory.Exists(checkDirectory)) - _ = Directory.CreateDirectory(checkDirectory); - } - if (string.IsNullOrEmpty(result)) - throw new Exception(); - results.Add(result); + results = GetDirectoryInfoCollection(configuration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted); return results; } diff --git a/Resize/Models/_C_Resize.cs b/Resize/Models/_C_Resize.cs index c9bc61c..f8c6a4d 100644 --- a/Resize/Models/_C_Resize.cs +++ b/Resize/Models/_C_Resize.cs @@ -291,8 +291,6 @@ public class C_Resize throw new NullReferenceException(nameof(item.ImageFileHolder)); if (!imageResizes.ContainsKey(outputResolution)) throw new Exception(); - if (string.IsNullOrEmpty(cResultsFullGroupDirectory)) - throw new NullReferenceException(nameof(cResultsFullGroupDirectory)); int[] resize = imageResizes[outputResolution]; int outputResolutionWidth = resize[_OutputResolutionWidthIndex]; int outputResolutionHeight = resize[_OutputResolutionHeightIndex]; @@ -308,8 +306,6 @@ public class C_Resize throw new NullReferenceException(nameof(item.ImageFileHolder)); if (item.ResizedFileHolder is null) throw new NullReferenceException(nameof(item.ResizedFileHolder)); - if (string.IsNullOrEmpty(cResultsFullGroupDirectory)) - throw new NullReferenceException(nameof(cResultsFullGroupDirectory)); FileHolder fileHolder = item.ResizedFileHolder; if (!imageResizes.ContainsKey(outputResolution)) throw new Exception(); @@ -433,26 +429,20 @@ public class C_Resize throw new NullReferenceException(nameof(item.Property.Id)); if (item.ImageFileHolder is null) throw new NullReferenceException(nameof(item.ImageFileHolder)); - if (string.IsNullOrEmpty(cResultsFullGroupDirectory)) - throw new NullReferenceException(nameof(cResultsFullGroupDirectory)); string json; string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata) }; List dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); - FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "{}"), string.Concat(item.ImageFileHolder.NameWithoutExtension, ".json"))); - string cResizeSingletonFile = Path.Combine(cResultsFullGroupDirectory, "{}", "_ _ _", $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json"); - if (fileInfo.Exists) + string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "{}"), string.Concat(item.ImageFileHolder.NameWithoutExtension, ".json")); + string cResizeSingletonFile = Path.Combine(cResultsFullGroupDirectory, "{}", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json"); + FileInfo fileInfo = new(cResizeSingletonFile); + if (!fileInfo.Exists) { - if (!File.Exists(cResizeSingletonFile)) + if (File.Exists(usingRelativePath)) { - fileInfo.MoveTo(cResizeSingletonFile); - fileInfo = new(cResizeSingletonFile); + File.Move(usingRelativePath, fileInfo.FullName); + fileInfo.Refresh(); } - } - else - { - if (File.Exists(cResizeSingletonFile)) - fileInfo = new(cResizeSingletonFile); - else + if (!fileInfo.Exists) { if (fileInfo.Directory?.Parent is null) throw new Exception(); diff --git a/Tests/UnitTestResize.cs b/Tests/UnitTestResize.cs index 4089ef5..8709879 100644 --- a/Tests/UnitTestResize.cs +++ b/Tests/UnitTestResize.cs @@ -137,21 +137,24 @@ public class UnitTestResize aResultsFullGroupDirectory, contentDescription: string.Empty, singletonDescription: "Properties for each image", - collectionDescription: string.Empty)); + collectionDescription: string.Empty, + converted: false)); metadata.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection( _PropertyConfiguration, sourceDirectory, bResultsFullGroupDirectory, contentDescription: string.Empty, singletonDescription: "Metadata as key value pairs", - collectionDescription: string.Empty)); + collectionDescription: string.Empty, + converted: true)); resize.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection( _PropertyConfiguration, sourceDirectory, cResultsFullGroupDirectory, contentDescription: "Resized image", singletonDescription: "Resize dimensions for each resolution", - collectionDescription: string.Empty)); + collectionDescription: string.Empty, + converted: true)); string sourceDirectoryFile = ".json"; Property.Models.FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName)); string relativePath = Property.Models.Stateless.IPath.GetRelativePath(fileHolder.FullName, length); diff --git a/TestsWithFaceRecognitionDotNet/UnitTestFace.cs b/TestsWithFaceRecognitionDotNet/UnitTestFace.cs index b87a568..ab2d4d1 100644 --- a/TestsWithFaceRecognitionDotNet/UnitTestFace.cs +++ b/TestsWithFaceRecognitionDotNet/UnitTestFace.cs @@ -199,21 +199,24 @@ public class UnitTestFace aResultsFullGroupDirectory, contentDescription: string.Empty, singletonDescription: "Properties for each image", - collectionDescription: string.Empty)); + collectionDescription: string.Empty, + converted: false)); metadata.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection( _PropertyConfiguration, sourceDirectory, bResultsFullGroupDirectory, contentDescription: string.Empty, singletonDescription: "Metadata as key value pairs", - collectionDescription: string.Empty)); + collectionDescription: string.Empty, + converted: true)); resize.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection( _PropertyConfiguration, sourceDirectory, cResultsFullGroupDirectory, contentDescription: "Resized image", singletonDescription: "Resize dimensions for each resolution", - collectionDescription: string.Empty)); + collectionDescription: string.Empty, + converted: true)); string sourceDirectoryFile = ".json"; Property.Models.FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName)); string relativePath = Property.Models.Stateless.IPath.GetRelativePath(fileHolder.FullName, length);