diff --git a/Compare/Compare.cs b/Compare/Compare.cs index 118b733..41aedd4 100644 --- a/Compare/Compare.cs +++ b/Compare/Compare.cs @@ -35,7 +35,7 @@ public class Compare string[] segments; _AppSettings = appSettings; if (appSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); _RenameFindReplace = new(); _RenameBFindReplace = new(); _RenameCFindReplace = new(); @@ -55,8 +55,9 @@ public class Compare bool reverse = false; Model? model = null; PredictorModel? predictorModel = null; + PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel); if (propertyConfiguration.PopulatePropertyId is null) - throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId)); + throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId)); foreach (string spelling in configuration.Spelling) { segments = spelling.Split('|'); @@ -104,10 +105,10 @@ public class Compare throw new Exception("Change configuration!"); _RenameCFindReplace.Add(new(renameFrom, renameTo)); } - groupCollection = Property.Models.Stateless.A_Property.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories, reverse: false); + groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories); if (appSettings.MaxDegreeOfParallelism.Value < 2) - ticks = LogDelta(ticks, nameof(Property.Models.Stateless.A_Property.GetGroupCollection)); - _Log.Information($"{nameof(Property.Models.Stateless.A_Property.GetGroupCollection)} has finished"); + ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection)); + _Log.Information($"{nameof(Property.Models.Stateless.Container.GetGroupCollection)} has finished"); _Configuration = configuration; List missingVerifyToSeasonCollection = GetMissingVerifyToSeasonCollection(topDirectories, groupCollection); if (missingVerifyToSeasonCollection.Any()) @@ -116,36 +117,36 @@ public class Compare { topDirectories.Clear(); _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); - groupCollection = Property.Models.Stateless.A_Property.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories, reverse: false); + groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories); if (appSettings.MaxDegreeOfParallelism.Value < 2) - ticks = LogDelta(ticks, nameof(Property.Models.Stateless.A_Property.GetGroupCollection)); + ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection)); } _Log.Information($"{nameof(PossiblyRename)} has finished"); if (PossiblyRenameB(topDirectories, groupCollection)) { topDirectories.Clear(); _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); - groupCollection = Property.Models.Stateless.A_Property.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories, reverse: false); + groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories); if (appSettings.MaxDegreeOfParallelism.Value < 2) - ticks = LogDelta(ticks, nameof(Property.Models.Stateless.A_Property.GetGroupCollection)); + ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection)); } _Log.Information($"{nameof(PossiblyRenameB)} has finished"); if (PossiblyRenameC(topDirectories, groupCollection)) { topDirectories.Clear(); _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); - groupCollection = Property.Models.Stateless.A_Property.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories, reverse: false); + groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories); if (appSettings.MaxDegreeOfParallelism.Value < 2) - ticks = LogDelta(ticks, nameof(Property.Models.Stateless.A_Property.GetGroupCollection)); + ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection)); } _Log.Information($"{nameof(PossiblyRenameC)} has finished"); if (PossiblyCorrect(topDirectories, groupCollection)) { topDirectories.Clear(); _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); - groupCollection = Property.Models.Stateless.A_Property.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories, reverse: false); + groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories); if (appSettings.MaxDegreeOfParallelism.Value < 2) - ticks = LogDelta(ticks, nameof(Property.Models.Stateless.A_Property.GetGroupCollection)); + ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection)); } _Log.Information($"{nameof(PossiblyCorrect)} has finished"); string[] dbFiles = Directory.GetFiles(propertyConfiguration.RootDirectory, "*.db", SearchOption.AllDirectories); @@ -156,14 +157,13 @@ public class Compare { topDirectories.Clear(); _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); - groupCollection = Property.Models.Stateless.A_Property.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories, reverse: false); + groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories); if (appSettings.MaxDegreeOfParallelism.Value < 2) - ticks = LogDelta(ticks, nameof(Property.Models.Stateless.A_Property.GetGroupCollection)); + ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection)); } - PropertyLogic propertyLogic = GetPropertyLogic(); if (_IsEnvironment.Development && propertyConfiguration.PopulatePropertyId.Value && !propertyLogic.KeyValuePairs.Any()) throw new Exception("Copy keyValuePairs-####.json file"); - List propertyHolderCollections = Property.Models.Stateless.A_Property.Get(propertyConfiguration, reverse, model, predictorModel, propertyLogic); + List containers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic); if (!isSilent) { _Log.Information("First pass completed"); @@ -205,7 +205,7 @@ public class Compare _Log.Information(". . ."); } string aPropertyContentCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A_Property), "[()]"); - ThirdPassToMove(propertyConfiguration, model, predictorModel, propertyLogic, propertyHolderCollections, aPropertyContentCollectionDirectory); + ThirdPassToMove(propertyConfiguration, model, predictorModel, propertyLogic, containers, aPropertyContentCollectionDirectory); if (!isSilent) { _Log.Information("Third pass completed"); @@ -217,7 +217,7 @@ public class Compare } _Log.Information(". . ."); } - FourthPassCreateWindowsShortcuts(propertyConfiguration, model, predictorModel, propertyLogic, propertyHolderCollections, saveToCollection: false, keepAll: false); + FourthPassCreateWindowsShortcuts(propertyConfiguration, model, predictorModel, propertyLogic, containers, saveToCollection: false, keepAll: false); if (!isSilent) { _Log.Information("Fourth pass completed"); @@ -372,28 +372,28 @@ public class Compare private static void Verify(Models.Configuration configuration) { if (configuration.Spelling is null || !configuration.Spelling.Any()) - throw new ArgumentNullException(nameof(configuration.Spelling)); + throw new NullReferenceException(nameof(configuration.Spelling)); } private long LogDelta(long ticks, string methodName) { long result; if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); result = DateTime.Now.Ticks; return result; } - private PropertyLogic GetPropertyLogic() + private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel) { PropertyLogic result; if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); - result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); + result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel); string fromPrepareForOld = "34720-637858334555170379.tsv"; string fromPrepareForOldFile = Path.Combine(_Configuration.PropertyConfiguration.RootDirectory, fromPrepareForOld); if (File.Exists(fromPrepareForOldFile)) @@ -432,11 +432,11 @@ public class Compare private void SaveDiffFilesOrSaveLogAndMoveFiles(Property.Models.Configuration configuration) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}"); _Log.Information(aPropertySingletonDirectory); _Log.Information("to"); @@ -510,14 +510,14 @@ public class Compare private void ChangeExtensionFromDeleteToJson(string aPropertySingletonDirectory) { if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); string searchPattern = "*.delete"; long ticks = DateTime.Now.Ticks; List topDirectories = new(); List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection; - groupCollection = Property.Models.Stateless.A_Property.GetGroupCollection(aPropertySingletonDirectory, searchPattern, topDirectories); + groupCollection = Property.Models.Stateless.Container.GetGroupCollection(aPropertySingletonDirectory, searchPattern, topDirectories); if (_AppSettings.MaxDegreeOfParallelism.Value < 2) - ticks = LogDelta(ticks, nameof(Property.Models.Stateless.A_Property.GetGroupCollection)); + ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection)); foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in groupCollection) { if (!topDirectories.Any()) @@ -647,7 +647,7 @@ public class Compare private bool PossiblyCorrect(List topDirectories, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection) { if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); bool result = false; string corrected; string correctedMoveTo; @@ -695,7 +695,7 @@ public class Compare private List GetMissingVerifyToSeasonCollection(List _, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection) { if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); List results = new(); string check; foreach ((int _, string sourceDirectory, string[] _, int _) in groupCollection) @@ -715,7 +715,7 @@ public class Compare private void CreateWindowsShortcuts((long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] collection, bool keepAll) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); int z = 0; string fileName; WindowsShortcut windowsShortcut; @@ -750,12 +750,12 @@ public class Compare } } - private void ThirdPassToMove(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List propertyHolderCollections, string aPropertyContentCollectionDirectory) + private void ThirdPassToMove(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List containers, string aPropertyContentCollectionDirectory) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); int stay = 0; string fileName; string id = " - Id"; @@ -769,7 +769,7 @@ public class Compare List distinctDirectories = new(); List> valueCollection = new(); List directoryInfoCollection = new(); - propertyLogic.ParallelWork(configuration, model, predictorModel, ticks, propertyHolderCollections, firstPass: false); + propertyLogic.ParallelWork(ticks, containers, firstPass: false); if (propertyLogic.ExceptionsDirectories.Any()) throw new Exception(); foreach (Property.Models.DirectoryInfo group in directoryInfoCollection) @@ -828,10 +828,10 @@ public class Compare } } - private void FourthPassCreateWindowsShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List propertyHolderCollections, bool saveToCollection, bool keepAll) + private void FourthPassCreateWindowsShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List containers, bool saveToCollection, bool keepAll) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); int stay = 0; A_Property? property; ConsoleKey? consoleKey = null; @@ -841,7 +841,7 @@ public class Compare List> valueCollection = new(); (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] collection; List directoryInfoCollection = new(); - propertyLogic.ParallelWork(configuration, model, predictorModel, ticks, propertyHolderCollections, firstPass: false); + propertyLogic.ParallelWork(ticks, containers, firstPass: false); if (propertyLogic.ExceptionsDirectories.Any()) throw new Exception(); foreach (Property.Models.DirectoryInfo group in directoryInfoCollection) @@ -859,7 +859,7 @@ public class Compare fileMoveCollection.Add(filteredSourceDirectoryFile); } } - collection = propertyLogic.GetPropertyIds(configuration, model, predictorModel, directoryInfoCollection, saveToCollection); + collection = propertyLogic.GetPropertyIds(directoryInfoCollection, saveToCollection); _Log.Information($"{stay} file(s) are staying and {fileMoveCollection.Count} file(s) will be moved"); for (int x = 0; x < int.MaxValue; x++) { diff --git a/Date-Group/DateGroup.cs b/Date-Group/DateGroup.cs index a085fee..295da4d 100644 --- a/Date-Group/DateGroup.cs +++ b/Date-Group/DateGroup.cs @@ -31,7 +31,7 @@ public class DateGroup { } _AppSettings = appSettings; if (appSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); _IsEnvironment = isEnvironment; _Exceptions = new List(); _Log = Serilog.Log.ForContext(); @@ -46,15 +46,15 @@ public class DateGroup PredictorModel? predictorModel = null; _Configuration = configuration; if (configuration.ByHash is null) - throw new ArgumentNullException(nameof(configuration.ByHash)); + throw new NullReferenceException(nameof(configuration.ByHash)); if (configuration.ByCreateDateShortcut is null) - throw new ArgumentNullException(nameof(configuration.ByCreateDateShortcut)); + throw new NullReferenceException(nameof(configuration.ByCreateDateShortcut)); if (propertyConfiguration.PopulatePropertyId is null) - throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId)); + throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId)); if (!_IsEnvironment.Development) throw new Exception("This program only allows development environments!"); long ticks = DateTime.Now.Ticks; - PropertyLogic propertyLogic = GetPropertyLogic(); + PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel); string[] dbFiles = Directory.GetFiles(propertyConfiguration.RootDirectory, "*.db", SearchOption.AllDirectories); foreach (string dbFile in dbFiles) File.Delete(dbFile); @@ -64,22 +64,22 @@ public class DateGroup _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); if (true || appSettings.MaxDegreeOfParallelism.Value < 2) ticks = LogDelta(ticks, nameof(Property.Models.Stateless.IPath.DeleteEmptyDirectories)); - List propertyHolderCollections = Property.Models.Stateless.A_Property.Get(propertyConfiguration, reverse, model, predictorModel, propertyLogic); + List containers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic); if (configuration.ByCreateDateShortcut.HasValue && configuration.ByCreateDateShortcut.Value) - CreateDateShortcut(propertyConfiguration, propertyHolderCollections); + CreateDateShortcut(propertyConfiguration, containers); else { List topDirectories = new(); List directoryInfoCollection = new(); - propertyLogic.ParallelWork(propertyConfiguration, model, predictorModel, ticks, propertyHolderCollections, firstPass: true); + propertyLogic.ParallelWork(ticks, containers, firstPass: true); if (appSettings.MaxDegreeOfParallelism.Value < 2) ticks = LogDelta(ticks, nameof(PropertyLogic.ParallelWork)); if (propertyLogic.ExceptionsDirectories.Any()) throw new Exception(); if (propertyConfiguration.PopulatePropertyId.Value && (configuration.ByCreateDateShortcut.Value || configuration.ByHash.Value)) { - if (Property.Models.Stateless.A_Property.Any(propertyHolderCollections)) - propertyLogic.ParallelWork(propertyConfiguration, model, predictorModel, ticks, propertyHolderCollections, firstPass: false); + if (Property.Models.Stateless.A_Property.Any(containers)) + propertyLogic.ParallelWork(ticks, containers, firstPass: false); if (appSettings.MaxDegreeOfParallelism.Value < 2) ticks = LogDelta(ticks, nameof(PropertyLogic.ParallelWork)); if (propertyLogic.ExceptionsDirectories.Any()) @@ -94,21 +94,21 @@ public class DateGroup private static void Verify(Models.Configuration configuration) { if (configuration.ByCreateDateShortcut is null) - throw new ArgumentNullException(nameof(configuration.ByCreateDateShortcut)); + throw new NullReferenceException(nameof(configuration.ByCreateDateShortcut)); if (configuration.ByDay is null) - throw new ArgumentNullException(nameof(configuration.ByDay)); + throw new NullReferenceException(nameof(configuration.ByDay)); if (configuration.ByHash is null) - throw new ArgumentNullException(nameof(configuration.ByHash)); + throw new NullReferenceException(nameof(configuration.ByHash)); if (configuration.BySeason is null) - throw new ArgumentNullException(nameof(configuration.BySeason)); + throw new NullReferenceException(nameof(configuration.BySeason)); if (configuration.ByWeek is null) - throw new ArgumentNullException(nameof(configuration.ByWeek)); + throw new NullReferenceException(nameof(configuration.ByWeek)); if (!configuration.ByCreateDateShortcut.Value && !configuration.ByDay.Value && !configuration.ByWeek.Value && !configuration.BySeason.Value && !configuration.ByHash.Value) throw new Exception("Change configuration!"); if (configuration.KeepFullPath is null) - throw new ArgumentNullException(nameof(configuration.KeepFullPath)); + throw new NullReferenceException(nameof(configuration.KeepFullPath)); if (configuration?.PropertyConfiguration?.PopulatePropertyId is null) - throw new ArgumentNullException(nameof(configuration.PropertyConfiguration.PopulatePropertyId)); + throw new NullReferenceException(nameof(configuration.PropertyConfiguration.PopulatePropertyId)); if (configuration.PropertyConfiguration.PopulatePropertyId.Value && !configuration.ByCreateDateShortcut.Value && !configuration.ByHash.Value) throw new Exception("Change configuration!"); if (!configuration.PropertyConfiguration.PopulatePropertyId.Value && configuration.ByHash.Value) @@ -153,7 +153,7 @@ public class DateGroup { long result; if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); result = DateTime.Now.Ticks; @@ -164,17 +164,17 @@ public class DateGroup { List<(string Source, string[] Destination)> results = new(); if (_Configuration.ByCreateDateShortcut is null) - throw new ArgumentNullException(nameof(_Configuration.ByCreateDateShortcut)); + throw new NullReferenceException(nameof(_Configuration.ByCreateDateShortcut)); if (_Configuration.ByDay is null) - throw new ArgumentNullException(nameof(_Configuration.ByDay)); + throw new NullReferenceException(nameof(_Configuration.ByDay)); if (_Configuration.ByHash is null) - throw new ArgumentNullException(nameof(_Configuration.ByHash)); + throw new NullReferenceException(nameof(_Configuration.ByHash)); if (_Configuration.BySeason is null) - throw new ArgumentNullException(nameof(_Configuration.BySeason)); + throw new NullReferenceException(nameof(_Configuration.BySeason)); if (_Configuration.ByWeek is null) - throw new ArgumentNullException(nameof(_Configuration.ByWeek)); + throw new NullReferenceException(nameof(_Configuration.ByWeek)); if (_Configuration.KeepFullPath is null) - throw new ArgumentNullException(nameof(_Configuration.KeepFullPath)); + throw new NullReferenceException(nameof(_Configuration.KeepFullPath)); char flag; string day; int season; @@ -319,7 +319,7 @@ public class DateGroup if (!_Configuration.ByHash.Value || property.Id is null) fileName = filteredSourceDirectoryFileHolder.Name; else - fileName = $"{property.Id.Value}{filteredSourceDirectoryFileHolder.Extension.ToLower()}"; + fileName = $"{property.Id.Value}{filteredSourceDirectoryFileHolder.ExtensionLowered}"; destinationCollection.Add(destinationDirectory); destinationCollection.AddRange(directoryNames); destinationCollection.Add(fileName); @@ -328,14 +328,14 @@ public class DateGroup return results; } - private PropertyLogic GetPropertyLogic() + private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel) { PropertyLogic result; if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); - result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); + result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel); return result; } @@ -343,9 +343,9 @@ public class DateGroup { List<(string Source, string[] Destination)> results = new(); if (_Configuration.KeepFullPath is null) - throw new ArgumentNullException(nameof(_Configuration.KeepFullPath)); + throw new NullReferenceException(nameof(_Configuration.KeepFullPath)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string? topDirectory; string? checkDirectory; string sourceDirectory; @@ -380,9 +380,9 @@ public class DateGroup private void MoveFiles(List topDirectories, List groupCollection) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string directoryName; List distinct = new(); List<(string Source, string[] Destination)> fileMoveCollectionAll = GetFileMoveCollectionAll(topDirectories, groupCollection); @@ -434,44 +434,48 @@ public class DateGroup _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory); } - private static void CreateDateShortcut(Property.Models.Configuration configuration, List propertyHolderCollections) + private static void CreateDateShortcut(Property.Models.Configuration configuration, List containers) { string path; string fileName; string directory; int selectedTotal; const int minimum = 3; + List selectedItems; List dateTimes; + DateTime? minimumDateTime; const int maximumHours = 24; string? relativePathDirectory; WindowsShortcut windowsShortcut; TimeSpan threeStandardDeviationHigh; - List selectedPropertyHolderCollection; string aPropertyContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "()"); - foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections) + foreach (Container container in containers) { - if (!propertyHolderCollection.Any()) + if (!container.Items.Any()) continue; selectedTotal = 0; - threeStandardDeviationHigh = Property.Models.Stateless.A_Property.GetThreeStandardDeviationHigh(minimum, propertyHolderCollection); + threeStandardDeviationHigh = Property.Models.Stateless.A_Property.GetThreeStandardDeviationHigh(minimum, container); if (threeStandardDeviationHigh.TotalHours > maximumHours) threeStandardDeviationHigh = new(maximumHours, 0, 0); - for (int i = 0; i < propertyHolderCollection.Length; i++) + for (int i = 0; i < container.Items.Count; i++) { - (i, dateTimes, selectedPropertyHolderCollection) = Property.Models.Stateless.A_Property.Get(propertyHolderCollection, threeStandardDeviationHigh, i); - selectedTotal += selectedPropertyHolderCollection.Count; - foreach (PropertyHolder propertyHolder in selectedPropertyHolderCollection) + (i, dateTimes, selectedItems) = Property.Models.Stateless.A_Property.Get(container, threeStandardDeviationHigh, i); + selectedTotal += selectedItems.Count; + foreach (Item item in selectedItems) { - if (propertyHolder.Property is null || propertyHolder.MinimumDateTime is null) + if (item.Property is null) continue; - relativePathDirectory = Path.GetDirectoryName(propertyHolder.RelativePath); + relativePathDirectory = Path.GetDirectoryName(item.RelativePath); if (string.IsNullOrEmpty(relativePathDirectory)) continue; - path = Path.GetFullPath($"{configuration.RootDirectory}{propertyHolder.RelativePath[..^5]}"); + minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(item.Property); + if (minimumDateTime is null) + continue; + path = Path.GetFullPath($"{configuration.RootDirectory}{item.RelativePath[..^5]}"); directory = Path.Combine($"{aPropertyContentDirectory}{relativePathDirectory}", $"{dateTimes.Min():yyyy-MM-dd_HH-mm-ss}---{dateTimes.Max():yyyy-MM-dd_HH-mm-ss}"); if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); - fileName = Path.Combine(directory, $"{Path.GetFileName(propertyHolder.RelativePath[..^5])}.lnk"); + fileName = Path.Combine(directory, $"{Path.GetFileName(item.RelativePath[..^5])}.lnk"); if (File.Exists(fileName)) continue; windowsShortcut = new() { Path = path }; @@ -479,10 +483,10 @@ public class DateGroup windowsShortcut.Dispose(); if (!File.Exists(fileName)) continue; - File.SetLastWriteTime(fileName, propertyHolder.MinimumDateTime.Value); + File.SetLastWriteTime(fileName, minimumDateTime.Value); } } - if (selectedTotal < propertyHolderCollection.Length && selectedTotal < (from l in propertyHolderCollection where l.Property is not null && l.MinimumDateTime.HasValue select true).Count()) + if (selectedTotal < container.Items.Count && selectedTotal < (from l in container.Items where l.Property is not null select true).Count()) continue; } } diff --git a/FaceRecognitionDotNet/Dlib/Python/SimpleObjectDetector.cs b/FaceRecognitionDotNet/Dlib/Python/SimpleObjectDetector.cs index 57f36d2..75d96e7 100644 --- a/FaceRecognitionDotNet/Dlib/Python/SimpleObjectDetector.cs +++ b/FaceRecognitionDotNet/Dlib/Python/SimpleObjectDetector.cs @@ -120,9 +120,9 @@ internal sealed class SimpleObjectDetector uint upsamplingAmount) { if (detector == null) - throw new ArgumentNullException(nameof(detector)); + throw new NullReferenceException(nameof(detector)); if (image == null) - throw new ArgumentNullException(nameof(image)); + throw new NullReferenceException(nameof(image)); detector.ThrowIfDisposed(); image.ThrowIfDisposed(); diff --git a/FaceRecognitionDotNet/FaceEncoding.cs b/FaceRecognitionDotNet/FaceEncoding.cs index 031076e..fad24b3 100644 --- a/FaceRecognitionDotNet/FaceEncoding.cs +++ b/FaceRecognitionDotNet/FaceEncoding.cs @@ -24,15 +24,15 @@ public sealed class FaceEncoding : DisposableObject, ISerializable private FaceEncoding(SerializationInfo info, StreamingContext context) { if (info == null) - throw new ArgumentNullException(nameof(info)); + throw new NullReferenceException(nameof(info)); double[]? array = info.GetValue(nameof(_Encoding), typeof(double[])) as double[]; int? row = (int?)info.GetValue(nameof(_Encoding.Rows), typeof(int)); int? column = (int?)info.GetValue(nameof(_Encoding.Columns), typeof(int)); if (row is null) - throw new ArgumentNullException(nameof(row)); + throw new NullReferenceException(nameof(row)); if (column is null) - throw new ArgumentNullException(nameof(column)); + throw new NullReferenceException(nameof(column)); _Encoding = new Matrix(array, row.Value, column.Value); } diff --git a/FaceRecognitionDotNet/FaceRecognition.cs b/FaceRecognitionDotNet/FaceRecognition.cs index a0d3574..dfd8fea 100644 --- a/FaceRecognitionDotNet/FaceRecognition.cs +++ b/FaceRecognitionDotNet/FaceRecognition.cs @@ -80,12 +80,12 @@ public sealed class FaceRecognition : DisposableObject /// Initializes a new instance of the class with the instance that contains model binary datum. /// /// The instance that contains model binary datum. - /// is null. + /// is null. /// The model data is null. private FaceRecognition(ModelParameter parameter) { if (parameter == null) - throw new ArgumentNullException(nameof(parameter)); + throw new NullReferenceException(nameof(parameter)); if (parameter.PosePredictor5FaceLandmarksModel == null) throw new NullReferenceException(nameof(parameter.PosePredictor5FaceLandmarksModel)); @@ -149,11 +149,11 @@ public sealed class FaceRecognition : DisposableObject /// The number of image looking for faces. Higher numbers find smaller faces. /// The number of images to include in each GPU processing batch. /// An enumerable collection of array of found face locations. - /// is null. + /// is null. public IEnumerable BatchFaceLocations(IEnumerable images, int numberOfTimesToUpsample, int batchSize = 128) { if (images == null) - throw new ArgumentNullException(nameof(images)); + throw new NullReferenceException(nameof(images)); List? results = new(); @@ -183,14 +183,14 @@ public sealed class FaceRecognition : DisposableObject /// A single face encoding to compare against a known face encoding. /// The distance between faces to consider it a match. Lower is more strict. The default value is 0.6. /// A True/False value indicating which known a face encoding matches the face encoding to check. - /// or is null. + /// or is null. /// or . public static bool CompareFace(FaceEncoding knownFaceEncoding, FaceEncoding faceEncodingToCheck, double tolerance = 0.6d) { if (knownFaceEncoding == null) - throw new ArgumentNullException(nameof(knownFaceEncoding)); + throw new NullReferenceException(nameof(knownFaceEncoding)); if (faceEncodingToCheck == null) - throw new ArgumentNullException(nameof(faceEncodingToCheck)); + throw new NullReferenceException(nameof(faceEncodingToCheck)); knownFaceEncoding.ThrowIfDisposed(); faceEncodingToCheck.ThrowIfDisposed(); @@ -205,14 +205,14 @@ public sealed class FaceRecognition : DisposableObject /// A single face encoding to compare against the enumerable collection. /// The distance between faces to consider it a match. Lower is more strict. The default value is 0.6. /// An enumerable collection of True/False values indicating which known face encodings match the face encoding to check. - /// or is null. + /// or is null. /// is disposed. Or contains disposed object. public static IEnumerable CompareFaces(IEnumerable knownFaceEncodings, FaceEncoding faceEncodingToCheck, double tolerance = 0.6d) { if (knownFaceEncodings == null) - throw new ArgumentNullException(nameof(knownFaceEncodings)); + throw new NullReferenceException(nameof(knownFaceEncodings)); if (faceEncodingToCheck == null) - throw new ArgumentNullException(nameof(faceEncodingToCheck)); + throw new NullReferenceException(nameof(faceEncodingToCheck)); faceEncodingToCheck.ThrowIfDisposed(); @@ -242,7 +242,7 @@ public sealed class FaceRecognition : DisposableObject /// Create a new instance of the class. /// /// The instance that contains model binary datum. - /// is null. + /// is null. /// The model data is null. public static FaceRecognition Create(ModelParameter parameter) => new(parameter); @@ -252,14 +252,14 @@ public sealed class FaceRecognition : DisposableObject /// The image contains a face. /// The enumerable collection of location rectangle for faces. /// - /// or is null. + /// or is null. /// is disposed. public static IEnumerable CropFaces(Image image, IEnumerable locations) { if (image == null) - throw new ArgumentNullException(nameof(image)); + throw new NullReferenceException(nameof(image)); if (locations == null) - throw new ArgumentNullException(nameof(locations)); + throw new NullReferenceException(nameof(locations)); image.ThrowIfDisposed(); @@ -302,14 +302,14 @@ public sealed class FaceRecognition : DisposableObject /// The face encoding to compare. /// The face encoding to compare against. /// The euclidean distance for comparison face. If 0, faces are completely equal. - /// or is null. + /// or is null. /// or is disposed. public static double FaceDistance(FaceEncoding faceEncoding, FaceEncoding faceToCompare) { if (faceEncoding == null) - throw new ArgumentNullException(nameof(faceEncoding)); + throw new NullReferenceException(nameof(faceEncoding)); if (faceToCompare == null) - throw new ArgumentNullException(nameof(faceToCompare)); + throw new NullReferenceException(nameof(faceToCompare)); faceEncoding.ThrowIfDisposed(); faceToCompare.ThrowIfDisposed(); @@ -327,14 +327,14 @@ public sealed class FaceRecognition : DisposableObject /// The enumerable collection of face encoding to compare. /// The face encoding to compare against. /// The enumerable collection of euclidean distance for comparison face. If 0, faces are completely equal. - /// or is null. + /// or is null. /// is disposed. Or contains disposed object. public static List FaceDistances(IEnumerable faceEncodings, FaceEncoding faceToCompare) { if (faceEncodings == null) - throw new ArgumentNullException(nameof(faceEncodings)); + throw new NullReferenceException(nameof(faceEncodings)); if (faceToCompare == null) - throw new ArgumentNullException(nameof(faceToCompare)); + throw new NullReferenceException(nameof(faceToCompare)); faceToCompare.ThrowIfDisposed(); @@ -362,14 +362,14 @@ public sealed class FaceRecognition : DisposableObject /// The dimension of vector which be returned from detector. /// The model of face detector to detect in image. If is not null, this value is ignored. /// An enumerable collection of face feature data corresponds to all faces in specified image. - /// is null. + /// is null. /// contains no elements. /// or this object or custom face landmark detector is disposed. /// is not supported. public List FaceEncodings(Image image, int numberOfTimesToUpsample, IEnumerable? knownFaceLocation, int numberOfJitters, PredictorModel predictorModel, Model model) { if (image == null) - throw new ArgumentNullException(nameof(image)); + throw new NullReferenceException(nameof(image)); if (predictorModel == PredictorModel.Custom) throw new NotSupportedException("FaceRecognition.PredictorModel.Custom is not supported."); @@ -408,7 +408,7 @@ public sealed class FaceRecognition : DisposableObject /// The dimension of vector which be returned from detector. /// The model of face detector to detect in image. If is not null, this value is ignored. /// An enumerable collection of dictionary of face parts locations (eyes, nose, etc). - /// is null. + /// is null. /// contains no elements. /// or this object or custom face landmark detector is disposed. /// The custom face landmark detector is not ready. @@ -416,7 +416,7 @@ public sealed class FaceRecognition : DisposableObject { List<(FacePart, FacePoint[])[]> results = new(); if (faceImage == null) - throw new ArgumentNullException(nameof(faceImage)); + throw new NullReferenceException(nameof(faceImage)); if (faceLocations != null && !faceLocations.Any()) throw new InvalidOperationException($"{nameof(faceLocations)} contains no elements."); faceImage.ThrowIfDisposed(); @@ -469,12 +469,12 @@ public sealed class FaceRecognition : DisposableObject /// The number of times to up-sample the image when finding faces. /// The model of face detector to detect in image. /// An enumerable collection of face location correspond to all faces in specified image. - /// is null. + /// is null. /// or this object is disposed. public List FaceLocations(Model model, Image image, int numberOfTimesToUpsample, bool sortByPixelPercentage) { if (image == null) - throw new ArgumentNullException(nameof(image)); + throw new NullReferenceException(nameof(image)); image.ThrowIfDisposed(); ThrowIfDisposed(); @@ -497,12 +497,12 @@ public sealed class FaceRecognition : DisposableObject /// /// The array contains face encoding data. /// The this method creates. - /// is null. + /// is null. /// must be 128. public static FaceEncoding LoadFaceEncoding(double[] encoding) { if (encoding == null) - throw new ArgumentNullException(nameof(encoding)); + throw new NullReferenceException(nameof(encoding)); if (encoding.Length != 128) { string message = $"{nameof(encoding)}.{nameof(encoding.Length)} must be 128."; @@ -523,7 +523,7 @@ public sealed class FaceRecognition : DisposableObject /// /// The from which to create the new . /// The this method creates. - /// is null. + /// is null. /// The specified is not supported. public static Image? LoadImage(Bitmap bitmap) { @@ -635,7 +635,7 @@ public sealed class FaceRecognition : DisposableObject /// The stride width in bytes. /// A image color mode. /// The this method creates. - /// is null. + /// is null. /// is less than 0. /// is less than 0. /// is less than 0. @@ -644,7 +644,7 @@ public sealed class FaceRecognition : DisposableObject public static Image? LoadImage(byte[] array, int row, int column, int stride, Mode mode) { if (array == null) - throw new ArgumentNullException(nameof(array)); + throw new NullReferenceException(nameof(array)); if (row < 0) throw new ArgumentOutOfRangeException($"{nameof(row)}", $"{nameof(row)} is less than 0."); if (column < 0) @@ -757,7 +757,7 @@ public sealed class FaceRecognition : DisposableObject if (predictorModel == PredictorModel.Custom) { if (CustomFaceLandmarkDetector is null) - throw new ArgumentNullException(nameof(CustomFaceLandmarkDetector)); + throw new NullReferenceException(nameof(CustomFaceLandmarkDetector)); foreach (Location? rect in locations) { FullObjectDetection? ret = CustomFaceLandmarkDetector.Detect(faceImage, rect); diff --git a/FaceRecognitionDotNet/Image.cs b/FaceRecognitionDotNet/Image.cs index ff99c72..5d29653 100644 --- a/FaceRecognitionDotNet/Image.cs +++ b/FaceRecognitionDotNet/Image.cs @@ -66,12 +66,12 @@ public sealed class Image : DisposableObject /// /// A string that contains the name of the file to which to save this . /// The for this . - /// is null. + /// is null. /// This object is disposed. public void Save(string filename, ImageFormat format) { if (filename == null) - throw new ArgumentNullException(nameof(filename)); + throw new NullReferenceException(nameof(filename)); ThrowIfDisposed(); diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 863ef41..c425967 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -41,7 +41,7 @@ public class DlibDotNet Person[] people; _AppSettings = appSettings; if (appSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); _IsEnvironment = isEnvironment; _Exceptions = new List(); _Log = Serilog.Log.ForContext(); @@ -61,21 +61,21 @@ public class DlibDotNet _Distance = new E_Distance(configuration); _FaceLandmarks = new D2_FaceLandmarks(configuration); if (configuration.ForceMetadataLastWriteTimeToCreationTime is null) - throw new ArgumentNullException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)); + throw new NullReferenceException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)); if (configuration.ForceResizeLastWriteTimeToCreationTime is null) - throw new ArgumentNullException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime)); + throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime)); if (configuration.IgnoreExtensions is null) - throw new ArgumentNullException(nameof(configuration.IgnoreExtensions)); + throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.OutputQuality is null) - throw new ArgumentNullException(nameof(configuration.OutputQuality)); + throw new NullReferenceException(nameof(configuration.OutputQuality)); if (configuration.OverrideForResizeImages is null) - throw new ArgumentNullException(nameof(configuration.OverrideForResizeImages)); + throw new NullReferenceException(nameof(configuration.OverrideForResizeImages)); if (configuration.PropertiesChangedForMetadata is null) - throw new ArgumentNullException(nameof(configuration.PropertiesChangedForMetadata)); + throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata)); if (configuration.PropertiesChangedForResize is null) - throw new ArgumentNullException(nameof(configuration.PropertiesChangedForResize)); + throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize)); if (configuration.Reverse is null) - throw new ArgumentNullException(nameof(configuration.Reverse)); + throw new NullReferenceException(nameof(configuration.Reverse)); _Metadata = new(configuration.ForceMetadataLastWriteTimeToCreationTime.Value, configuration.PropertiesChangedForMetadata.Value); if (args.Count > 0) argZero = Path.GetFullPath(args[0]); @@ -88,7 +88,7 @@ public class DlibDotNet (Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(configuration); _Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel); if (configuration.SkipSearch is null) - throw new ArgumentNullException(nameof(configuration.SkipSearch)); + throw new NullReferenceException(nameof(configuration.SkipSearch)); if (!_ArgZeroIsConfigurationRootDirectory) people = Array.Empty(); else @@ -134,7 +134,7 @@ public class DlibDotNet { long result; if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); result = DateTime.Now.Ticks; @@ -188,7 +188,7 @@ public class DlibDotNet private void Verify(Models.Configuration configuration) { if (!configuration.OutputResolutions.Any() || string.IsNullOrEmpty(configuration.OutputResolutions[0]) || !configuration.ValidResolutions.Contains(configuration.OutputResolutions[0])) - throw new ArgumentNullException(nameof(configuration.OutputResolutions), "must be a valid outputResolution!"); + throw new NullReferenceException($"{nameof(configuration.OutputResolutions)} must be a valid outputResolution!"); if ((from l in configuration.OutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) throw new Exception($"One or more {nameof(configuration.OutputResolutions)} are not in the ValidResolutions list!"); if ((from l in configuration.LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) @@ -202,81 +202,81 @@ public class DlibDotNet if ((from l in configuration.SaveFaceLandmarkForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) throw new Exception($"One or more {nameof(configuration.SaveFaceLandmarkForOutputResolutions)} are not in the ValidResolutions list!"); if (configuration.CheckJsonForDistanceResults is null) - throw new ArgumentNullException(nameof(configuration.CheckJsonForDistanceResults)); + throw new NullReferenceException(nameof(configuration.CheckJsonForDistanceResults)); if (configuration.CrossDirectoryMaxItemsInDistanceCollection is null) - throw new ArgumentNullException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection)); + throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection)); if (configuration.DistanceFactor is null) - throw new ArgumentNullException(nameof(configuration.DistanceFactor)); + throw new NullReferenceException(nameof(configuration.DistanceFactor)); if (configuration.ForceMetadataLastWriteTimeToCreationTime is null) - throw new ArgumentNullException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)); + throw new NullReferenceException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)); if (configuration.ForceResizeLastWriteTimeToCreationTime is null) - throw new ArgumentNullException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime)); + throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime)); if (configuration.IgnoreExtensions is null) - throw new ArgumentNullException(nameof(configuration.IgnoreExtensions)); + throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.IgnoreRelativePaths is null) - throw new ArgumentNullException(nameof(configuration.IgnoreRelativePaths)); + throw new NullReferenceException(nameof(configuration.IgnoreRelativePaths)); if (configuration.LoadOrCreateThenSaveIndex is null) - throw new ArgumentNullException(nameof(configuration.LoadOrCreateThenSaveIndex)); + throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveIndex)); if (configuration.LocationConfidenceFactor is null) - throw new ArgumentNullException(nameof(configuration.LocationConfidenceFactor)); + throw new NullReferenceException(nameof(configuration.LocationConfidenceFactor)); if (configuration.MappedMaxIndex is null) - throw new ArgumentNullException(nameof(configuration.MappedMaxIndex)); + throw new NullReferenceException(nameof(configuration.MappedMaxIndex)); if (configuration.MappedMaxIndex.HasValue && configuration.LoadOrCreateThenSaveIndex.Value && !_IsEnvironment.DebuggerWasAttachedDuringConstructor) - throw new ArgumentNullException(nameof(configuration.MappedMaxIndex)); + throw new NullReferenceException(nameof(configuration.MappedMaxIndex)); if (configuration.MaxItemsInDistanceCollection is null) - throw new ArgumentNullException(nameof(configuration.MaxItemsInDistanceCollection)); + throw new NullReferenceException(nameof(configuration.MaxItemsInDistanceCollection)); if (configuration.MixedYearRelativePaths is null) - throw new ArgumentNullException(nameof(configuration.MixedYearRelativePaths)); + throw new NullReferenceException(nameof(configuration.MixedYearRelativePaths)); if (configuration.NumberOfJitters is null) - throw new ArgumentNullException(nameof(configuration.NumberOfJitters)); + throw new NullReferenceException(nameof(configuration.NumberOfJitters)); if (configuration.NumberOfTimesToUpsample is null) - throw new ArgumentNullException(nameof(configuration.NumberOfTimesToUpsample)); + throw new NullReferenceException(nameof(configuration.NumberOfTimesToUpsample)); if (configuration.OutputQuality is null) - throw new ArgumentNullException(nameof(configuration.OutputQuality)); + throw new NullReferenceException(nameof(configuration.OutputQuality)); if (configuration.OutputResolutions is null) - throw new ArgumentNullException(nameof(configuration.OutputResolutions)); + throw new NullReferenceException(nameof(configuration.OutputResolutions)); if (configuration.OverrideForFaceImages is null) - throw new ArgumentNullException(nameof(configuration.OverrideForFaceImages)); + throw new NullReferenceException(nameof(configuration.OverrideForFaceImages)); if (configuration.OverrideForFaceLandmarkImages is null) - throw new ArgumentNullException(nameof(configuration.OverrideForFaceLandmarkImages)); + throw new NullReferenceException(nameof(configuration.OverrideForFaceLandmarkImages)); if (configuration.OverrideForResizeImages is null) - throw new ArgumentNullException(nameof(configuration.OverrideForResizeImages)); + throw new NullReferenceException(nameof(configuration.OverrideForResizeImages)); if (configuration.PaddingLoops is null) - throw new ArgumentNullException(nameof(configuration.PaddingLoops)); + throw new NullReferenceException(nameof(configuration.PaddingLoops)); if (configuration.PropertiesChangedForDistance is null) - throw new ArgumentNullException(nameof(configuration.PropertiesChangedForDistance)); + throw new NullReferenceException(nameof(configuration.PropertiesChangedForDistance)); if (configuration.PropertiesChangedForFaces is null) - throw new ArgumentNullException(nameof(configuration.PropertiesChangedForFaces)); + throw new NullReferenceException(nameof(configuration.PropertiesChangedForFaces)); if (configuration.PropertiesChangedForIndex is null) - throw new ArgumentNullException(nameof(configuration.PropertiesChangedForIndex)); + throw new NullReferenceException(nameof(configuration.PropertiesChangedForIndex)); if (configuration.PropertiesChangedForMetadata is null) - throw new ArgumentNullException(nameof(configuration.PropertiesChangedForMetadata)); + throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata)); if (configuration.PropertiesChangedForResize is null) - throw new ArgumentNullException(nameof(configuration.PropertiesChangedForResize)); + throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize)); if (configuration.Reverse is null) - throw new ArgumentNullException(nameof(configuration.Reverse)); + throw new NullReferenceException(nameof(configuration.Reverse)); if (configuration.SaveFaceLandmarkForOutputResolutions is null) - throw new ArgumentNullException(nameof(configuration.SaveFaceLandmarkForOutputResolutions)); + throw new NullReferenceException(nameof(configuration.SaveFaceLandmarkForOutputResolutions)); if (configuration.SaveFullYearOfRandomFiles is null) - throw new ArgumentNullException(nameof(configuration.SaveFullYearOfRandomFiles)); + throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); if (configuration.SaveResizedSubfiles is null) - throw new ArgumentNullException(nameof(configuration.SaveResizedSubfiles)); + throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); if (configuration.SkipSearch is null) - throw new ArgumentNullException(nameof(configuration.SkipSearch)); + throw new NullReferenceException(nameof(configuration.SkipSearch)); if (configuration.TestDistanceResults is null) - throw new ArgumentNullException(nameof(configuration.TestDistanceResults)); + throw new NullReferenceException(nameof(configuration.TestDistanceResults)); if (configuration.ValidResolutions is null) - throw new ArgumentNullException(nameof(configuration.ValidResolutions)); + throw new NullReferenceException(nameof(configuration.ValidResolutions)); if (string.IsNullOrEmpty(configuration.ModelDirectory) || !Directory.Exists(configuration.ModelDirectory)) - throw new ArgumentNullException(nameof(configuration.ModelDirectory)); + throw new NullReferenceException(nameof(configuration.ModelDirectory)); if (string.IsNullOrEmpty(configuration.ModelName)) - throw new ArgumentNullException(nameof(configuration.ModelName)); + throw new NullReferenceException(nameof(configuration.ModelName)); if (string.IsNullOrEmpty(configuration.OutputExtension)) - throw new ArgumentNullException(nameof(configuration.OutputExtension)); + throw new NullReferenceException(nameof(configuration.OutputExtension)); if (string.IsNullOrEmpty(configuration.PredictorModelName)) - throw new ArgumentNullException(nameof(configuration.PredictorModelName)); + throw new NullReferenceException(nameof(configuration.PredictorModelName)); if (configuration.DistanceFactor.Value + configuration.LocationConfidenceFactor.Value != 10) - throw new ArgumentNullException(nameof(configuration.DistanceFactor)); + throw new NullReferenceException(nameof(configuration.DistanceFactor)); } private void VerifyExtra(List args, Property.Models.Configuration propertyConfiguration, Models.Configuration configuration) @@ -305,18 +305,18 @@ public class DlibDotNet throw new Exception("Input directory should be the source and not a resized directory!"); } - private void FullParallelForWork(PropertyLogic propertyLogic, string outputResolution, List> sourceDirectoryChanges, List propertyFileHolderCollection, List propertyCollection, List>> metadataCollections, List> resizeKeyValuePairs, List> imageFaceCollections, string sourceDirectory, int index, PropertyHolder propertyHolder) + private void FullParallelForWork(PropertyLogic propertyLogic, string outputResolution, List> sourceDirectoryChanges, List propertyFileHolderCollection, List propertyCollection, List>> metadataCollections, List> resizeKeyValuePairs, List> imageFaceCollections, string sourceDirectory, int index, Item item) { - if (propertyHolder.ImageFileHolder is null) - throw new ArgumentNullException(nameof(propertyHolder.ImageFileHolder)); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration.SaveResizedSubfiles is null) - throw new ArgumentNullException(nameof(_Configuration.SaveResizedSubfiles)); + throw new NullReferenceException(nameof(_Configuration.SaveResizedSubfiles)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); if (_Configuration.PropertyConfiguration.WriteBitmapDataBytes is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration.WriteBitmapDataBytes)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration.WriteBitmapDataBytes)); A_Property property; List faceCollection; string original = "Original"; @@ -326,40 +326,44 @@ public class DlibDotNet Dictionary imageResizeKeyValuePairs; List> subFileTuples = new(); List> metadataCollection; - if (propertyHolder.Property is null) + if (item.Property is null) { - lock (sourceDirectoryChanges) - sourceDirectoryChanges.Add(new Tuple(nameof(A_Property), DateTime.Now)); - property = propertyLogic.GetProperty(propertyLogic.AngleBracketCollection[0], propertyHolder, subFileTuples, parseExceptions); - propertyHolder.Update(property); + property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions); + item.Update(property); + if (subFileTuples.Any()) + { + lock (sourceDirectoryChanges) + sourceDirectoryChanges.Add(new Tuple(nameof(A_Property), (from l in subFileTuples select l.Item2).Max())); + } } else { - property = propertyHolder.Property; - if (propertyHolder.Changed.HasValue && propertyHolder.Changed.Value) + property = item.Property; + if (item.Changed.HasValue && item.Changed.Value) { - lock (sourceDirectoryChanges) - sourceDirectoryChanges.Add(new Tuple(nameof(A_Property), DateTime.Now)); + // lock (sourceDirectoryChanges) + // sourceDirectoryChanges.Add(new Tuple(nameof(A_Property), DateTime.Now)); + throw new NotImplementedException(); } } - (int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection(subFileTuples, parseExceptions, propertyHolder); + (int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection(subFileTuples, parseExceptions, item); if (_AppSettings.MaxDegreeOfParallelism.Value < 2) ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection)); - FileHolder resizedFileHolder = new(Path.Combine(_Resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(propertyHolder.ImageFileHolder.FullName))); - propertyHolder.SetResizedFileHolder(resizedFileHolder); - imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, propertyHolder); + FileHolder resizedFileHolder = new(Path.Combine(_Resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName))); + item.SetResizedFileHolder(resizedFileHolder); + imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, item); if (_AppSettings.MaxDegreeOfParallelism.Value < 2) ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs)); if (_Configuration.SaveResizedSubfiles.Value) { - _Resize.SaveResizedSubfile(outputResolution, subFileTuples, propertyHolder, original, property, imageResizeKeyValuePairs); + _Resize.SaveResizedSubfile(outputResolution, subFileTuples, item, original, property, imageResizeKeyValuePairs); if (_AppSettings.MaxDegreeOfParallelism.Value < 2) ticks = LogDelta(ticks, nameof(C_Resize.SaveResizedSubfile)); - propertyHolder.SetResizedFileHolder(FileHolder.Refresh(resizedFileHolder)); + item.SetResizedFileHolder(FileHolder.Refresh(resizedFileHolder)); } else if (outputResolution == _Configuration.OutputResolutions[0] && false) { - byte[] bytes = _Resize.GetResizedBytes(outputResolution, subFileTuples, propertyHolder, property, imageResizeKeyValuePairs); + byte[] bytes = _Resize.GetResizedBytes(outputResolution, subFileTuples, item, property, imageResizeKeyValuePairs); if (_AppSettings.MaxDegreeOfParallelism.Value < 2) ticks = LogDelta(ticks, nameof(C_Resize.GetResizedBytes)); string path = Path.Combine(resizedFileHolder.DirectoryName, resizedFileHolder.NameWithoutExtension); @@ -373,15 +377,15 @@ public class DlibDotNet int outputResolutionWidth = outputResolutionCollection[0]; int outputResolutionHeight = outputResolutionCollection[1]; int outputResolutionOrientation = outputResolutionCollection[2]; - faceCollection = _Faces.GetFaces(_Configuration.PropertyConfiguration, outputResolution, subFileTuples, parseExceptions, propertyHolder, property, resizedFileHolder, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation); + faceCollection = _Faces.GetFaces(_Configuration.PropertyConfiguration, outputResolution, subFileTuples, parseExceptions, item, property, resizedFileHolder, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation); if (_AppSettings.MaxDegreeOfParallelism.Value < 2) ticks = LogDelta(ticks, nameof(D_Face.GetFaces)); - _Faces.SaveFaces(_Configuration.PropertyConfiguration, subFileTuples, parseExceptions, propertyHolder, faceCollection); + _Faces.SaveFaces(_Configuration.PropertyConfiguration, subFileTuples, parseExceptions, item, faceCollection); if (_AppSettings.MaxDegreeOfParallelism.Value < 2) ticks = LogDelta(ticks, nameof(D_Face.SaveFaces)); if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution)) { - _FaceLandmarks.SaveFaceLandmarkImages(subFileTuples, parseExceptions, propertyHolder, faceCollection); + _FaceLandmarks.SaveFaceLandmarkImages(subFileTuples, parseExceptions, item, faceCollection); if (_AppSettings.MaxDegreeOfParallelism.Value < 2) ticks = LogDelta(ticks, nameof(D2_FaceLandmarks.SaveFaceLandmarkImages)); } @@ -392,23 +396,23 @@ public class DlibDotNet imageFaceCollections[index] = faceCollection; metadataCollections[index] = metadataCollection; resizeKeyValuePairs[index] = imageResizeKeyValuePairs; - propertyFileHolderCollection[index] = propertyHolder.ImageFileHolder; + propertyFileHolderCollection[index] = item.ImageFileHolder; sourceDirectoryChanges.AddRange(from l in subFileTuples where l.Item2 > dateTime select l); } } - private int FullParallelWork(long ticks, PropertyLogic propertyLogic, string outputResolution, List> sourceDirectoryChanges, List propertyFileHolderCollection, List propertyCollection, List>> metadataCollection, List> resizeKeyValuePairs, List> faceCollections, int propertyHolderCollectionsCount, int g, string sourceDirectory, int r, PropertyHolder[] filteredPropertyHolderCollection) + private int FullParallelWork(long ticks, PropertyLogic propertyLogic, string outputResolution, List> sourceDirectoryChanges, List propertyFileHolderCollection, List propertyCollection, List>> metadataCollection, List> resizeKeyValuePairs, List> faceCollections, int containersCount, Container container, Item[] filteredItems) { int result = 0; if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(AppSettings.MaxDegreeOfParallelism)); ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism.Value }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; - if (faceCollections.Count != filteredPropertyHolderCollection.Length || metadataCollection.Count != filteredPropertyHolderCollection.Length || resizeKeyValuePairs.Count != filteredPropertyHolderCollection.Length || propertyCollection.Count != filteredPropertyHolderCollection.Length) + if (faceCollections.Count != filteredItems.Length || metadataCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || propertyCollection.Count != filteredItems.Length) { - for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) + for (int i = 0; i < filteredItems.Length; i++) { faceCollections.Add(new()); metadataCollection.Add(new()); @@ -418,23 +422,23 @@ public class DlibDotNet } } int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); - string message = $"{r + 1:000}.{g} / {propertyHolderCollectionsCount:000}) {filteredPropertyHolderCollection.Length:000} file(s) - {totalSeconds} total second(s) - {outputResolution} - {sourceDirectory}"; - using (ProgressBar progressBar = new(filteredPropertyHolderCollection.Length, message, options)) + string message = $"{container.R + 1: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, filteredPropertyHolderCollection.Length, parallelOptions, i => + _ = Parallel.For(0, filteredItems.Length, parallelOptions, i => { try { - FullParallelForWork(propertyLogic, outputResolution, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, sourceDirectory, index: i, filteredPropertyHolderCollection[i]); + FullParallelForWork(propertyLogic, outputResolution, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, container.SourceDirectory, index: i, filteredItems[i]); if (i == 0 || sourceDirectoryChanges.Any()) progressBar.Tick(); } catch (Exception ex) { result += 1; - _Log.Error(string.Concat(sourceDirectory, Environment.NewLine, ex.Message, Environment.NewLine, ex.StackTrace), ex); - if (result == filteredPropertyHolderCollection.Length) - throw new Exception(string.Concat("All in [", sourceDirectory, "] failed!")); + _Log.Error(string.Concat(container.SourceDirectory, Environment.NewLine, ex.Message, Environment.NewLine, ex.StackTrace), ex); + if (result == filteredItems.Length) + throw new Exception(string.Concat("All in [", container.SourceDirectory, "] failed!")); } }); } @@ -476,20 +480,20 @@ public class DlibDotNet } } - private void WriteGroup(Property.Models.Configuration configuration, PropertyLogic propertyLogic, List propertyCollection, List>> metadataCollection, List> faceCollections, List> resizeKeyValuePairs, string sourceDirectory, string outputResolution, PropertyHolder[] filteredPropertyHolderCollection) + private void WriteGroup(Property.Models.Configuration configuration, PropertyLogic propertyLogic, List propertyCollection, List>> metadataCollection, List> faceCollections, List> resizeKeyValuePairs, string sourceDirectory, string outputResolution, Item[] filteredItems) { if (_Configuration.PropertiesChangedForMetadata is null) - throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata)); + throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForMetadata)); if (configuration.PropertiesChangedForProperty is null) - throw new ArgumentNullException(nameof(configuration.PropertiesChangedForProperty)); + throw new NullReferenceException(nameof(configuration.PropertiesChangedForProperty)); if (_Configuration.PropertiesChangedForResize is null) - throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize)); + throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForResize)); if (_Configuration.PropertiesChangedForFaces is null) - throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForFaces)); + throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForFaces)); + Item item; string key; string json; string checkFile; - PropertyHolder propertyHolder; int sourceDirectoryLength = sourceDirectory.Length; _FilePropertiesKeyValuePairs.Add(sourceDirectory, new List>()); JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false }; @@ -502,14 +506,14 @@ public class DlibDotNet List>>> metadataCollectionKeyValuePairs = new(); (int level, List directories) = Property.Models.Stateless.IPath.Get(configuration.RootDirectory, sourceDirectory); string fileName = string.Concat(string.Join(configuration.FileNameDirectorySeparator, directories), ".json"); - for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) + for (int i = 0; i < filteredItems.Length; i++) { - propertyHolder = filteredPropertyHolderCollection[i]; - if (propertyHolder.Property is null) + item = filteredItems[i]; + if (item.Property is null) continue; - if (propertyHolder.ImageFileHolder is null) + if (item.ImageFileHolder is null) continue; - key = Property.Models.Stateless.IPath.GetRelativePath(propertyHolder.ImageFileHolder.FullName, sourceDirectoryLength); + key = Property.Models.Stateless.IPath.GetRelativePath(item.ImageFileHolder.FullName, sourceDirectoryLength); _FileKeyValuePairs.Add(new KeyValuePair(sourceDirectory, key)); _FilePropertiesKeyValuePairs[sourceDirectory].Add(new Tuple(key, propertyCollection[i])); faceCollectionsKeyValuePairs.Add(new KeyValuePair>(key, faceCollections[i])); @@ -560,41 +564,35 @@ public class DlibDotNet } } - private void FullDoWork(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, Dictionary> peopleCollection, PropertyLogic propertyLogic, List propertyHolderCollections) + private void FullDoWork(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, Dictionary> peopleCollection, PropertyLogic propertyLogic, List containers) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); - int g; - int r; + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); int exceptionCount; - string sourceDirectory; + Item[] filteredItems; long ticks = DateTime.Now.Ticks; - string eDistanceCollectionDirectory; List> faceCollections = new(); List propertyCollection = new(); - PropertyHolder[] filteredPropertyHolderCollection; List propertyFileHolderCollection = new(); List> resizeKeyValuePairs = new(); List> sourceDirectoryChanges = new(); List>> metadataCollection = new(); - List<(string[], PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection; string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}"); string propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(A_Property)); foreach (string outputResolution in _Configuration.OutputResolutions) { _FileKeyValuePairs.Clear(); _FilePropertiesKeyValuePairs.Clear(); - eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), $"[{ticks}]"); - foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections) + foreach (Container container in containers) { - if (!propertyHolderCollection.Any()) + if (!container.Items.Any()) continue; - if (!_ArgZeroIsConfigurationRootDirectory && !propertyHolderCollection[0].SourceDirectory.StartsWith(argZero)) + if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero)) continue; - filteredPropertyHolderCollection = (from l in propertyHolderCollection where l.ImageFileHolder is not null && l.Property is not null && l.ValidImageFormatExtension.HasValue && l.ValidImageFormatExtension.Value && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.Extension) select l).ToArray(); - if (!filteredPropertyHolderCollection.Any()) + filteredItems = (from l in container.Items where l.ImageFileHolder is not null && l.ValidImageFormatExtension && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray(); + if (!filteredItems.Any()) continue; faceCollections.Clear(); metadataCollection.Clear(); @@ -605,15 +603,12 @@ public class DlibDotNet _Faces.AngleBracketCollection.Clear(); _Resize.AngleBracketCollection.Clear(); _Metadata.AngleBracketCollection.Clear(); - g = filteredPropertyHolderCollection[0].G; - r = filteredPropertyHolderCollection[0].R; propertyLogic.AngleBracketCollection.Clear(); _FaceLandmarks.AngleBracketCollection.Clear(); - sourceDirectory = filteredPropertyHolderCollection[0].SourceDirectory; propertyLogic.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, - sourceDirectory, + container.SourceDirectory, nameof(A_Property), outputResolution, includeResizeGroup: false, @@ -625,7 +620,7 @@ public class DlibDotNet _Metadata.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, - sourceDirectory, + container.SourceDirectory, nameof(B_Metadata), outputResolution, includeResizeGroup: false, @@ -637,7 +632,7 @@ public class DlibDotNet _Resize.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, - sourceDirectory, + container.SourceDirectory, nameof(C_Resize), outputResolution, includeResizeGroup: true, @@ -650,7 +645,7 @@ public class DlibDotNet _Faces.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, - sourceDirectory, + container.SourceDirectory, nameof(D_Face), outputResolution, includeResizeGroup: true, @@ -663,7 +658,7 @@ public class DlibDotNet _FaceLandmarks.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, - sourceDirectory, + container.SourceDirectory, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, @@ -672,28 +667,28 @@ public class DlibDotNet contentDescription: "n x 2 png file(s) for each face found", singletonDescription: string.Empty, collectionDescription: string.Empty)); - exceptionCount = FullParallelWork(ticks, propertyLogic, outputResolution, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, propertyHolderCollections.Count, g, sourceDirectory, r, filteredPropertyHolderCollection); - if (metadataCollection.Count != filteredPropertyHolderCollection.Length || propertyCollection.Count != filteredPropertyHolderCollection.Length || resizeKeyValuePairs.Count != filteredPropertyHolderCollection.Length || faceCollections.Count != filteredPropertyHolderCollection.Length) + exceptionCount = FullParallelWork(ticks, propertyLogic, outputResolution, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, containers.Count, container, filteredItems); + 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) - _Exceptions.Add(sourceDirectory); + _Exceptions.Add(container.SourceDirectory); if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0) - WriteGroup(configuration, propertyLogic, propertyCollection, metadataCollection, faceCollections, resizeKeyValuePairs, sourceDirectory, outputResolution, filteredPropertyHolderCollection); + WriteGroup(configuration, propertyLogic, propertyCollection, metadataCollection, faceCollections, resizeKeyValuePairs, container.SourceDirectory, outputResolution, filteredItems); if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0 && outputResolution == _Configuration.OutputResolutions[0]) - propertyLogic.AddToPropertyLogicAllCollection(filteredPropertyHolderCollection); + propertyLogic.AddToPropertyLogicAllCollection(filteredItems); if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0 && propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.Any()) { if (outputResolution == _Configuration.OutputResolutions[0] || _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) { for (int i = 0; i < faceCollections.Count; i++) - filteredPropertyHolderCollection[i].Faces.AddRange(from l in faceCollections[i] select l); - PropertyHolder.AddToNamed(propertyLogic, filteredPropertyHolderCollection); + filteredItems[i].Faces.AddRange(from l in faceCollections[i] select l); + Item.AddToNamed(propertyLogic, filteredItems); if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) - D_Face.SaveShortcuts(configuration, model, predictorModel, _Configuration.JuliePhares, ticks, peopleCollection, propertyLogic, outputResolution, filteredPropertyHolderCollection); + D_Face.SaveShortcuts(configuration, model, predictorModel, _Configuration.JuliePhares, ticks, peopleCollection, propertyLogic, outputResolution, filteredItems); } } if (exceptionCount == 0 && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)) - _Distance.LoadOrCreateThenSaveDistanceResultsForOutputResolutions(configuration, model, predictorModel, sourceDirectory, outputResolution, sourceDirectoryChanges, filteredPropertyHolderCollection, faceCollections); + _Distance.LoadOrCreateThenSaveDistanceResultsForOutputResolutions(configuration, model, predictorModel, container.SourceDirectory, outputResolution, sourceDirectoryChanges, filteredItems, faceCollections); if (_Resize.AngleBracketCollection.Any()) _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(_Resize.AngleBracketCollection[0].Replace("<>", "()")); if (_Faces.AngleBracketCollection.Any()) @@ -716,9 +711,22 @@ public class DlibDotNet propertyLogic.SaveAllCollection(); if (propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.Any()) { - collection = E_Distance.GetGroupedFaceEncodings(argZero, propertyHolderCollections); - E_Distance.SaveGroupedFaceEncodings(collection, peopleCollection, eDistanceCollectionDirectory); - E_Distance.GetClosest(argZero, propertyHolderCollections, collection, peopleCollection, eDistanceCollectionDirectory); + const int maxPer = 5; + const bool skipIsWrongYear = true; + string dFacesContentDirectory; + string eDistanceContentDirectory; + string eDistanceCollectionDirectory; + string zPropertyHolderSingletonDirectory; + List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection; + dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()"); + eDistanceContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), $"({ticks})"); + eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), $"[{ticks}]"); + zPropertyHolderSingletonDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, $"Z_{nameof(Item)}", outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "{}"); + collection = E_Distance.GetThreeSigmaFaceEncodings(argZero, containers); + E_Distance.AddClosest(argZero, containers, collection, skipIsWrongYear, maxPer); + E_Distance.SavePropertyHolders(argZero, containers, zPropertyHolderSingletonDirectory); + E_Distance.SaveClosest(argZero, containers, eDistanceContentDirectory, dFacesContentDirectory); + E_Distance.SaveThreeSigmaFaceEncodings(collection, peopleCollection, eDistanceCollectionDirectory); } if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any()) break; @@ -739,23 +747,27 @@ public class DlibDotNet } } - private PropertyLogic GetPropertyLogic() + private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel) { PropertyLogic result; if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); - result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); + result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel); return result; } private void Search(Property.Models.Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel, string argZero, Person[] people) { - PropertyLogic propertyLogic = GetPropertyLogic(); + List containers; Dictionary> peopleCollection = A2_People.Convert(people); - List propertyHolderCollections = Property.Models.Stateless.A_Property.Get(configuration, reverse, model, predictorModel, propertyLogic); - FullDoWork(configuration, model, predictorModel, argZero, peopleCollection, propertyLogic, propertyHolderCollections); + PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel); + if (string.IsNullOrEmpty(configuration.RootDirectory)) + containers = Property.Models.Stateless.A_Property.Get(configuration, propertyLogic); + else + containers = Property.Models.Stateless.Container.GetContainers(configuration, propertyLogic); + FullDoWork(configuration, model, predictorModel, argZero, peopleCollection, propertyLogic, containers); } internal void RenameQueue(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel) => _Rename.RenameQueue(configuration, model, predictorModel); diff --git a/Instance/Models/_A2_People.cs b/Instance/Models/_A2_People.cs index 0eaca2c..71cabfa 100644 --- a/Instance/Models/_A2_People.cs +++ b/Instance/Models/_A2_People.cs @@ -65,7 +65,7 @@ internal class A2_People { Person[] results; if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory; string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People)); string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory)); diff --git a/Instance/Models/_D2_FaceLandmark.cs b/Instance/Models/_D2_FaceLandmark.cs index 3d597b8..25f1b86 100644 --- a/Instance/Models/_D2_FaceLandmark.cs +++ b/Instance/Models/_D2_FaceLandmark.cs @@ -107,10 +107,12 @@ internal class D2_FaceLandmarks #pragma warning restore CA1416 - internal void SaveFaceLandmarkImages(List> subFileTuples, List parseExceptions, PropertyHolder propertyHolder, List faceCollections) + internal void SaveFaceLandmarkImages(List> subFileTuples, List parseExceptions, Item item, List faceCollections) { - if (propertyHolder.ResizedFileHolder is null) - throw new Exception($"{propertyHolder.ResizedFileHolder} is null!"); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); + if (item.ResizedFileHolder is null) + throw new NullReferenceException(nameof(item.ResizedFileHolder)); FileInfo fileInfo; bool check = false; string parentCheck; @@ -120,7 +122,7 @@ internal class D2_FaceLandmarks long ticks = DateTime.Now.Ticks; List imageFiles = new(); bool updateDateWhenMatches = false; - string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), propertyHolder.ImageFileNameWithoutExtension); + 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(); if (!Directory.Exists(facesDirectory)) @@ -132,7 +134,7 @@ internal class D2_FaceLandmarks imageFiles.Add(Array.Empty()); continue; } - fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {propertyHolder.ImageFileNameWithoutExtension}.png")); + fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {item.ImageFileHolder.NameWithoutExtension}.png")); if (!fileInfo.Exists) { if (fileInfo.Directory?.Parent is null) @@ -164,7 +166,7 @@ internal class D2_FaceLandmarks } } if (check) - SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, propertyHolder.ResizedFileHolder); + SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, item.ResizedFileHolder); } } \ No newline at end of file diff --git a/Instance/Models/_D_Face.cs b/Instance/Models/_D_Face.cs index 528f393..fbed239 100644 --- a/Instance/Models/_D_Face.cs +++ b/Instance/Models/_D_Face.cs @@ -251,15 +251,17 @@ public class D_Face : Shared.Models.Properties.IFace, IFace } } - private List GetFaces(FileHolder resizedFileHolder, PropertyHolder propertyHolder, A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string facesDirectory) + private List GetFaces(FileHolder resizedFileHolder, Item item, A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string facesDirectory) { List results = new(); if (_Configuration.PaddingLoops is null) throw new Exception(); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); if (_Configuration.NumberOfJitters is null) - throw new ArgumentNullException(nameof(_Configuration.NumberOfJitters)); + throw new NullReferenceException(nameof(_Configuration.NumberOfJitters)); if (_Configuration.NumberOfTimesToUpsample is null) - throw new ArgumentNullException(nameof(_Configuration.NumberOfTimesToUpsample)); + throw new NullReferenceException(nameof(_Configuration.NumberOfTimesToUpsample)); List locations; FaceRecognitionDotNet.Image? unknownImage = null; if (resizedFileHolder.Exists) @@ -269,13 +271,13 @@ public class D_Face : Shared.Models.Properties.IFace, IFace catch (Exception) { } } if (unknownImage is null) - results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i: null, location: null)); + results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null)); else { FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter); locations = faceRecognition.FaceLocations(_Model, unknownImage, _Configuration.NumberOfTimesToUpsample.Value, sortByPixelPercentage: true); if (!locations.Any()) - results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i: null, location: null)); + results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null)); else { double? α; @@ -312,7 +314,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace locations[i].Top - (padding * p), source.Width, source.Height); - face = new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i, location); + face = new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i, location); width = location.Right - location.Left; height = location.Bottom - location.Top; rectangle = new Rectangle(location.Left, location.Top, width, height); @@ -329,7 +331,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace using (knownImage = FaceRecognition.LoadImage(preRotated)) { if (knownImage is null || knownImage.IsDisposed) - throw new ArgumentNullException(nameof(knownImage)); + throw new NullReferenceException(nameof(knownImage)); facesLandmarks = faceRecognition.GetFaceLandmarkCollection(knownImage, _Configuration.NumberOfTimesToUpsample.Value, faceLocations: null, _PredictorModel, _Model); } if (facesLandmarks.Count == 0 && p < _Configuration.PaddingLoops.Value) @@ -361,7 +363,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace using (rotatedImage = FaceRecognition.LoadImage(rotated)) { if (rotatedImage is null || rotatedImage.IsDisposed) - throw new ArgumentNullException(nameof(rotatedImage)); + throw new NullReferenceException(nameof(rotatedImage)); faceEncodings = faceRecognition.FaceEncodings(rotatedImage, _Configuration.NumberOfTimesToUpsample.Value, knownFaceLocation: null, _Configuration.NumberOfJitters.Value, _PredictorModel, _Model); } if (faceEncodings.Count == 0 && p < _Configuration.PaddingLoops.Value) @@ -372,7 +374,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace faceEncoding = new(rawEncoding, faceEncodings[0].Size); face.Update(α, faceEncoding, populated: true); } - faceFile = Path.Combine(facesDirectory, $"{i} - {propertyHolder.ImageFileNameWithoutExtension}.png"); + faceFile = Path.Combine(facesDirectory, $"{i} - {item.ImageFileHolder.NameWithoutExtension}.png"); preRotated.Save(faceFile, System.Drawing.Imaging.ImageFormat.Png); results.Add(face); } @@ -388,7 +390,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace locations[i].Top, source.Width, source.Height); - face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i, location); + face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i, location); results.Add(face); } } @@ -410,18 +412,20 @@ public class D_Face : Shared.Models.Properties.IFace, IFace _Populated = populated; } - internal List GetFaces(Property.Models.Configuration configuration, string outputResolution, List> subFileTuples, List parseExceptions, PropertyHolder propertyHolder, A_Property property, FileHolder resizedFileHolder, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) + internal List GetFaces(Property.Models.Configuration configuration, string outputResolution, List> subFileTuples, List parseExceptions, Item item, A_Property property, FileHolder resizedFileHolder, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) { List? results; if (_Configuration.PropertiesChangedForFaces is null) throw new Exception(); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); string json; D_Face face; bool checkForOutputResolutionChange = false; 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("<>", "()"), propertyHolder.ImageFileNameWithoutExtension); - FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{propertyHolder.ImageFileNameWithoutExtension}.json")); + string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension); + FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json")); if (!fileInfo.Exists) { if (fileInfo.Directory?.Parent is null) @@ -445,7 +449,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace { results = JsonSerializer.Deserialize>(json); if (results is null) - throw new ArgumentNullException(nameof(results)); + throw new NullReferenceException(nameof(results)); for (int i = 0; i < results.Count; i++) { face = results[i]; @@ -473,7 +477,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace } else if (results is null) { - results = GetFaces(resizedFileHolder, propertyHolder, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, facesDirectory); + results = GetFaces(resizedFileHolder, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, facesDirectory); json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions); bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime; DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max(); @@ -483,18 +487,20 @@ public class D_Face : Shared.Models.Properties.IFace, IFace return results; } - internal void SaveFaces(Property.Models.Configuration configuration, List> subFileTuples, List parseExceptions, PropertyHolder propertyHolder, List faceCollection) + internal void SaveFaces(Property.Models.Configuration configuration, List> subFileTuples, List parseExceptions, Item item, List faceCollection) { if (_Configuration.OverrideForFaceImages is null) throw new Exception(); - if (propertyHolder.ResizedFileHolder is null) - throw new Exception($"{propertyHolder.ResizedFileHolder} is null!"); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); + if (item.ResizedFileHolder is null) + throw new NullReferenceException(nameof(item.ResizedFileHolder)); FileInfo fileInfo; bool check = false; string parentCheck; List imageFiles = new(); string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) }; - string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), propertyHolder.ImageFileNameWithoutExtension); + string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension); List dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); bool facesDirectoryExisted = Directory.Exists(facesDirectory); if (!facesDirectoryExisted) @@ -506,7 +512,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace imageFiles.Add(string.Empty); continue; } - fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {propertyHolder.ImageFileNameWithoutExtension}.png")); + fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {item.ImageFileHolder.NameWithoutExtension}.png")); if (!fileInfo.Exists) { if (fileInfo.Directory?.Parent is null) @@ -524,19 +530,20 @@ public class D_Face : Shared.Models.Properties.IFace, IFace check = true; } if (check) - SaveFaces(faceCollection, propertyHolder.ResizedFileHolder, imageFiles); + SaveFaces(faceCollection, item.ResizedFileHolder, imageFiles); } - internal static void SaveShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string[] juliePhares, long ticks, Dictionary> peopleCollection, PropertyLogic propertyLogic, string outputResolution, PropertyHolder[] filteredPropertyHolderCollection) + internal static void SaveShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string[] juliePhares, long ticks, Dictionary> peopleCollection, PropertyLogic propertyLogic, string outputResolution, Item[] filteredItems) { Person person; string fileName; string fullName; + DateTime? minimumDateTime; WindowsShortcut windowsShortcut; const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]"; string dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), $"({ticks})"); - List<(PropertyHolder, (string, Shared.Models.Properties.IFace?, (string, string, string, string))[])> collections = PropertyHolder.GetCollection(propertyLogic, filteredPropertyHolderCollection, dFacesContentDirectory); - foreach ((PropertyHolder propertyHolder, (string personKey, Shared.Models.Properties.IFace? _, (string, string, string, string))[] collection) in collections) + List<(Item, (string, Shared.Models.Properties.IFace?, (string, string, string, string))[])> collections = Item.GetCollection(propertyLogic, filteredItems, dFacesContentDirectory); + foreach ((Item item, (string personKey, Shared.Models.Properties.IFace? _, (string, string, string, string))[] collection) in collections) { if (collection.Length != 1) continue; @@ -544,7 +551,10 @@ public class D_Face : Shared.Models.Properties.IFace, IFace { if (string.IsNullOrEmpty(personKey)) continue; - if (propertyHolder.Property?.Id is null || propertyHolder.ImageFileHolder is null || propertyHolder.MinimumDateTime is null || propertyHolder.ResizedFileHolder is null) + if (item.Property?.Id is null || item.ImageFileHolder is null || item.ResizedFileHolder is null) + continue; + minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(item.Property); + if (minimumDateTime is null) continue; if (!Directory.Exists(directory)) { @@ -560,19 +570,19 @@ public class D_Face : Shared.Models.Properties.IFace, IFace { if (!Directory.Exists(copyDirectory)) _ = Directory.CreateDirectory(copyDirectory); - fileName = Path.Combine(copyDirectory, $"{propertyHolder.Property.Id.Value}{propertyHolder.ResizedFileHolder.Extension}"); + fileName = Path.Combine(copyDirectory, $"{item.Property.Id.Value}{item.ResizedFileHolder.ExtensionLowered}"); if (!File.Exists(fileName)) - File.Copy(propertyHolder.ResizedFileHolder.FullName, fileName); + File.Copy(item.ResizedFileHolder.FullName, fileName); } - fileName = Path.Combine(directory, $"{propertyHolder.Property.Id.Value}.lnk"); + fileName = Path.Combine(directory, $"{item.Property.Id.Value}.lnk"); if (File.Exists(fileName)) continue; - windowsShortcut = new() { Path = propertyHolder.ImageFileHolder.FullName }; + windowsShortcut = new() { Path = item.ImageFileHolder.FullName }; windowsShortcut.Save(fileName); windowsShortcut.Dispose(); if (!File.Exists(fileName)) continue; - File.SetLastWriteTime(fileName, propertyHolder.MinimumDateTime.Value); + File.SetLastWriteTime(fileName, minimumDateTime.Value); } } } diff --git a/Instance/Models/_E2_Navigate.cs b/Instance/Models/_E2_Navigate.cs index dfc7460..4c33b79 100644 --- a/Instance/Models/_E2_Navigate.cs +++ b/Instance/Models/_E2_Navigate.cs @@ -38,7 +38,7 @@ internal class E2_Navigate private void DisplayTags(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string[] directories, Dictionary directoryKeyValuePairs, string[] files, Dictionary fileKeyValuePairs) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); bool all = false; FileSystem fileSystem; string requestPath = "/RootResultsDirectory"; @@ -71,7 +71,7 @@ internal class E2_Navigate private void DisplayFaces(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string selectedFileFullName) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); string requestPath = "/RootResultsDirectory"; string? rootResultsDirectory = Path.GetDirectoryName(Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(B_Metadata))); if (string.IsNullOrEmpty(rootResultsDirectory)) @@ -95,9 +95,9 @@ internal class E2_Navigate { string result; if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); _Log.Warn(string.Concat("What is the new name for [", Path.GetFileName(subSourceDirectory), "]<", subSourceDirectory, ">?")); string? newDirectoryName = _Console.ReadLine(); _Log.Warn("Are you sure y[es] || n[o]?"); @@ -135,7 +135,7 @@ internal class E2_Navigate internal void Navigate(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); string[] subFiles; ConsoleKey consoleKey; string[] subDirectories; diff --git a/Instance/Models/_E3_Rename.cs b/Instance/Models/_E3_Rename.cs index ccb171b..b79db59 100644 --- a/Instance/Models/_E3_Rename.cs +++ b/Instance/Models/_E3_Rename.cs @@ -115,7 +115,7 @@ internal class E3_Rename { List results = new(); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); bool add; string to; bool exists; @@ -230,7 +230,7 @@ internal class E3_Rename internal void DirectoryRename(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string relativePath, string newDirectoryName) { if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string json; FileInfo current; FileInfo fileInfo; diff --git a/Instance/Models/_E_Distance.cs b/Instance/Models/_E_Distance.cs index 2899372..e9bb776 100644 --- a/Instance/Models/_E_Distance.cs +++ b/Instance/Models/_E_Distance.cs @@ -33,11 +33,11 @@ internal class E_Distance return result; } - private static void LoadFaceEncodingCollections(PropertyHolder[] filteredPropertyHolderCollection, List> faceCollections, List locationIndicesCollection, List faceEncodingCollection, List> faceEncodingCollections) + private static void LoadFaceEncodingCollections(Item[] filteredItems, List> faceCollections, List locationIndicesCollection, List faceEncodingCollection, List> faceEncodingCollections) { List faceCollection; FaceEncoding faceEncoding; - for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) + for (int i = 0; i < filteredItems.Length; i++) { faceCollection = faceCollections[i]; if (!faceCollection.Any()) @@ -171,28 +171,28 @@ internal class E_Distance } } - private void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, PropertyHolder[] filteredPropertyHolderCollection, List> faceCollections, List directories, bool updateDateWhenMatches, DateTime? updateToWhenMatches) + private void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, Item[] filteredItems, List> faceCollections, List directories, bool updateDateWhenMatches, DateTime? updateToWhenMatches) { FileHolder? fileHolder; List locationIndicesCollection = new(); List> subFileTuples = new(); List faceEncodingCollection = new(); List> faceEncodingCollections = new(); - LoadFaceEncodingCollections(filteredPropertyHolderCollection, faceCollections, locationIndicesCollection, faceEncodingCollection, faceEncodingCollections); + LoadFaceEncodingCollections(filteredItems, faceCollections, locationIndicesCollection, faceEncodingCollection, faceEncodingCollections); if (faceEncodingCollections.Count != faceCollections.Count) throw new Exception(); if (locationIndicesCollection.Count != faceEncodingCollection.Count) throw new Exception(); - for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) + for (int i = 0; i < filteredItems.Length; i++) { - fileHolder = filteredPropertyHolderCollection[i].ImageFileHolder; + fileHolder = filteredItems[i].ImageFileHolder; if (fileHolder is null) continue; - LoadOrCreateThenSaveDistanceResultsForOutputResolutionsLoop(configuration, faceCollections, filteredPropertyHolderCollection.Length, i, faceCollections[i], locationIndicesCollection, subFileTuples, faceEncodingCollection, faceEncodingCollections[i], fileHolder.NameWithoutExtension, directories[i][0], directories[i][1], updateDateWhenMatches, updateToWhenMatches); + LoadOrCreateThenSaveDistanceResultsForOutputResolutionsLoop(configuration, faceCollections, filteredItems.Length, i, faceCollections[i], locationIndicesCollection, subFileTuples, faceEncodingCollection, faceEncodingCollections[i], fileHolder.NameWithoutExtension, directories[i][0], directories[i][1], updateDateWhenMatches, updateToWhenMatches); } } - internal void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string outputResolution, List> sourceDirectoryChanges, PropertyHolder[] filteredPropertyHolderCollection, List> faceCollections) + internal void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string outputResolution, List> sourceDirectoryChanges, Item[] filteredItems, List> faceCollections) { if (_Configuration.CheckJsonForDistanceResults is null) throw new Exception(); @@ -222,9 +222,9 @@ internal class E_Distance contentDescription: ".tvs File", singletonDescription: string.Empty, collectionDescription: "n json file(s) for each face found (one to many)"); - for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) + for (int i = 0; i < filteredItems.Length; i++) { - fileHolder = filteredPropertyHolderCollection[i].ImageFileHolder; + fileHolder = filteredItems[i].ImageFileHolder; if (fileHolder is null) continue; directoryInfo = new System.IO.DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), fileHolder.NameWithoutExtension)); @@ -269,7 +269,7 @@ internal class E_Distance } } if (check) - LoadOrCreateThenSaveDistanceResultsForOutputResolutions(configuration, filteredPropertyHolderCollection, faceCollections, directories, updateDateWhenMatches, updateToWhenMatches: dateTime); + LoadOrCreateThenSaveDistanceResultsForOutputResolutions(configuration, filteredItems, faceCollections, directories, updateDateWhenMatches, updateToWhenMatches: dateTime); _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()")); } @@ -353,7 +353,7 @@ internal class E_Distance internal void LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); string? relativePath; Shared.Models.Face face; ParallelOptions parallelOptions = new(); @@ -414,9 +414,9 @@ internal class E_Distance return result; } - internal static List<(string[], Shared.Models.PersonBirthday, FaceEncoding[])> GetGroupedFaceEncodings(string argZero, List propertyHolderCollections) + internal static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> GetThreeSigmaFaceEncodings(string argZero, List containers) { - List<(string[], Shared.Models.PersonBirthday, FaceEncoding[])> results = new(); + List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> results = new(); double lcl; double ucl; double sum; @@ -428,13 +428,13 @@ internal class E_Distance FaceEncoding faceEncoding; List faceDistances; List faceEncodings; - Dictionary> keyValuePairs = PropertyHolder.GetKeyValuePairs(argZero, propertyHolderCollections); - foreach (KeyValuePair> keyValuePair in keyValuePairs) + Dictionary> keyValuePairs = Item.GetKeyValuePairs(argZero, containers); + foreach (KeyValuePair> keyValuePair in keyValuePairs) { lowestIndex = 0; faceEncodings = new(); lowestSum = double.MaxValue; - foreach ((string[] directories, Shared.Models.PersonBirthday personBirthday, Shared.Models.Properties.IFace face) in keyValuePair.Value) + foreach ((DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday, Shared.Models.Properties.IFace face) in keyValuePair.Value) { if (!face.Populated) continue; @@ -462,17 +462,17 @@ internal class E_Distance standardDeviation = GetStandardDeviation(faceDistances, average); lcl = average - (standardDeviation * 3); ucl = average + (standardDeviation * 3); - for (int i = faceEncodings.Count; i > -1; i--) + for (int i = faceEncodings.Count - 1; i > -1; i--) { if (faceDistances[i] < lcl || faceDistances[i] > ucl) faceEncodings.RemoveAt(i); } - results.Add(new(keyValuePair.Value[zero].Directories, keyValuePair.Value[zero].PersonBirthday, faceEncodings.ToArray())); + results.Add(new(keyValuePair.Value[zero].MinimumDateTime, keyValuePair.Value[zero].IsWrongYear, keyValuePair.Value[zero].PersonBirthday, faceEncodings.ToArray())); } return results; } - internal static void SaveGroupedFaceEncodings(List<(string[], Shared.Models.PersonBirthday, FaceEncoding[])> collection, Dictionary> peopleCollection, string eDistanceCollectionDirectory) + internal static void SaveThreeSigmaFaceEncodings(List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, Dictionary> peopleCollection, string eDistanceCollectionDirectory) { string json; string checkFile; @@ -480,14 +480,14 @@ internal class E_Distance string directory; List rawEncodings; Shared.Models.Person person; + const string facePopulatedKey = "ThreeSigma"; const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]"; - foreach ((string[] directories, Shared.Models.PersonBirthday personBirthday, FaceEncoding[] faceEncodings) in collection) + foreach ((DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday, FaceEncoding[] faceEncodings) in collection) { - directories[0] = eDistanceCollectionDirectory; rawEncodings = new(); checkFile = string.Empty; - directory = Path.Combine(directories); personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday); + directory = Item.GetDirectory(eDistanceCollectionDirectory, facePopulatedKey, minimumDateTime, isWrongYear, personBirthday, personKey); person = peopleCollection[personKey][0]; checkFile = string.Concat(directory, " - ", Regex.Replace(Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name), pattern, string.Empty), ".json"); if (string.IsNullOrEmpty(checkFile)) @@ -501,81 +501,150 @@ internal class E_Distance } } - public static void GetKeyValuePairs(string argZero, List propertyHolderCollections, List<(string[], Shared.Models.PersonBirthday, FaceEncoding[])> collection) + public static void AddClosest(string argZero, List containers, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, bool skipIsWrongYear, int maxPer) { + string key; double average; - string personKey; - bool? isWrongYear; - TimeSpan? timeSpan; double lowestAverage; - string[] directories; - string isWrongYearFlag; + bool? itemIsWrongYear; + bool? lowestIsWrongYear; FaceEncoding faceEncoding; List faceDistances; - const string facePopulatedKey = "MatchImages"; + DateTime? itemMinimumDateTime; + DateTime? lowestMinimumDateTime; + Shared.Models.Properties.IFace face; + Dictionary results = new(); Shared.Models.PersonBirthday? lowestPersonBirthday; - foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections) + foreach (Container container in containers) { + lowestIsWrongYear = null; lowestPersonBirthday = null; + lowestMinimumDateTime = null; lowestAverage = double.MaxValue; - if (!propertyHolderCollection.Any()) + if (!container.Items.Any()) continue; - if (!propertyHolderCollection[0].SourceDirectory.StartsWith(argZero)) + if (!container.SourceDirectory.StartsWith(argZero)) continue; - foreach (PropertyHolder propertyHolder in propertyHolderCollection) + foreach (Item item in container.Items) { - if (propertyHolder.ImageFileHolder is null || propertyHolder.Property is null || propertyHolder.Named.Any()) + if (item.ImageFileHolder is null || item.Property is null || item.Named.Any()) continue; - if (propertyHolder.MinimumDateTime is null) + itemMinimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(item.Property); + if (itemMinimumDateTime is null) continue; - (isWrongYear, _) = propertyHolder.IsWrongYear(); - foreach (Shared.Models.Properties.IFace face in propertyHolder.Faces) + (itemIsWrongYear, _) = item.IsWrongYear(); + if (skipIsWrongYear && itemIsWrongYear.HasValue && itemIsWrongYear.Value) + continue; + item.Closest.Clear(); + for (int i = 0; i < item.Faces.Count; i++) { + face = item.Faces[i]; + item.Closest.Add(new(face.LocationIndex, itemMinimumDateTime.Value, itemIsWrongYear, null, null)); if (!face.Populated) continue; faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); - foreach ((string[] _, Shared.Models.PersonBirthday personBirthday, FaceEncoding[] faceEncodings) in collection) + foreach ((DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday, FaceEncoding[] faceEncodings) in collection) { + if (itemIsWrongYear.HasValue && !itemIsWrongYear.Value && itemMinimumDateTime.Value < personBirthday.Value) + continue; faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncoding); average = faceDistances.Average(); - if (average < lowestAverage) + if (average > lowestAverage) continue; + lowestAverage = average; + lowestIsWrongYear = isWrongYear; lowestPersonBirthday = personBirthday; + lowestMinimumDateTime = minimumDateTime; } - if (lowestPersonBirthday is null) + if (lowestPersonBirthday is null || lowestMinimumDateTime is null) continue; - personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(lowestPersonBirthday); - timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(propertyHolder.MinimumDateTime.Value, isWrongYear, lowestPersonBirthday); - if (timeSpan.HasValue && timeSpan.Value.Ticks < 0) - directories = new string[] { string.Empty, facePopulatedKey, personKey, "!---" }; - else if (timeSpan.HasValue) - directories = new string[] { string.Empty, facePopulatedKey, personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}" }; - else - { - isWrongYearFlag = PropertyHolder.GetWrongYearFlag(isWrongYear); - directories = new string[] { string.Empty, facePopulatedKey, personKey, $"{isWrongYearFlag}{propertyHolder.MinimumDateTime.Value:yyyy}" }; - } + key = Item.GetKey(lowestMinimumDateTime.Value, lowestIsWrongYear, lowestPersonBirthday); + if (!results.ContainsKey(key)) + results.Add(key, 0); + else if (results[key] > maxPer) + continue; + results[key] += 1; + item.Closest[0] = new(face.LocationIndex, lowestMinimumDateTime.Value, lowestIsWrongYear, lowestPersonBirthday, lowestAverage); } - } } } - internal static void GetClosest(string argZero, List propertyHolderCollections, List<(string[], Shared.Models.PersonBirthday, FaceEncoding[])> collection, Dictionary> peopleCollection, string eDistanceCollectionDirectory) + public static void SavePropertyHolders(string argZero, List containers, string zPropertyHolderSingletonDirectory) { - GetKeyValuePairs(argZero, propertyHolderCollections, collection); - if (peopleCollection is null) - { } - if (string.IsNullOrEmpty(eDistanceCollectionDirectory)) - { } - // foreach (KeyValuePair> keyValuePair in keyValuePairs) - // { - // foreach ((string[] directories, Shared.Models.PersonBirthday personBirthday, Shared.Models.Properties.IFace face) in keyValuePair.Value) - // { - // if (face.Populated) - // continue; - // } - // } + string json; + FileInfo fileInfo; + bool updateDateWhenMatches = false; + JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; + foreach (Container container in containers) + { + if (!container.Items.Any()) + continue; + if (!container.SourceDirectory.StartsWith(argZero)) + continue; + foreach (Item item in container.Items) + { + if (item.ImageFileHolder is null || item.Property is null || !item.Faces.Any() || !item.Closest.Any()) + continue; + if (!(from l in item.Closest where l.Average.HasValue select true).Any()) + continue; + json = JsonSerializer.Serialize(item, jsonSerializerOptions); + fileInfo = new(string.Concat(zPropertyHolderSingletonDirectory, item.RelativePath, ".json")); + if (fileInfo.Directory is null) + continue; + if (!fileInfo.Directory.Exists) + fileInfo.Directory.Create(); + _ = Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true); + } + } + } + + internal static void SaveClosest(string argZero, List containers, string eDistanceContentDirectory, string dFacesContentDirectory) + { + string copyFile; + string checkFile; + string directory; + string personKey; + string? directoryName; + string facesDirectory; + string faceFullFileName; + const string facePopulatedKey = "Closet"; + foreach (Container container in containers) + { + if (!container.Items.Any()) + continue; + if (!container.SourceDirectory.StartsWith(argZero)) + continue; + foreach (Item item in container.Items) + { + if (item.ImageFileHolder is null || item.Property is null || item.ResizedFileHolder is null || item.Named.Any()) + continue; + if (!item.Closest.Any()) + continue; + directoryName = Path.GetDirectoryName(item.RelativePath); + if (directoryName is null) + throw new Exception(); + foreach (Closest closest in item.Closest) + { + if (closest.Average is null || closest.FaceLocationIndex is null || closest.PersonBirthday is null) + continue; + personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.PersonBirthday); + directory = Item.GetDirectory(eDistanceContentDirectory, facePopulatedKey, closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday, personKey); + checkFile = Path.Combine(directory, item.ImageFileHolder.Name); + if (!Directory.Exists(directory)) + _ = Directory.CreateDirectory(directory); + 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; + else + copyFile = item.ResizedFileHolder.FullName; + if (File.Exists(checkFile)) + continue; + File.Copy(copyFile, checkFile); + } + } + } } } \ No newline at end of file diff --git a/Instance/Models/_F_Random.cs b/Instance/Models/_F_Random.cs index ff66d3f..4156cd2 100644 --- a/Instance/Models/_F_Random.cs +++ b/Instance/Models/_F_Random.cs @@ -29,7 +29,7 @@ internal class F_Random { bool result = false; if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string? checkDirectory = Path.GetFullPath(directory); for (int i = 0; i < int.MaxValue; i++) { diff --git a/Metadata/Models/B_Metadata.cs b/Metadata/Models/B_Metadata.cs index 9922103..399aef6 100644 --- a/Metadata/Models/B_Metadata.cs +++ b/Metadata/Models/B_Metadata.cs @@ -39,7 +39,7 @@ public class B_Metadata { Dictionary>> results = new(); if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); try { object? @object; @@ -78,16 +78,16 @@ public class B_Metadata return results; } - public (int, List>) GetMetadataCollection(List> subFileTuples, List parseExceptions, Property.Models.PropertyHolder propertyHolder) + public (int, List>) GetMetadataCollection(List> subFileTuples, List parseExceptions, Property.Models.Item item) { List> results = new(); - if (propertyHolder.ImageFileHolder is null) - throw new Exception($"{propertyHolder.ImageFileHolder} is null!"); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); Dictionary>>? dictionary; string json = string.Empty; string[] changesFrom = Array.Empty(); 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(propertyHolder.ImageFileNameWithoutExtension, ".json"))); + FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "{}"), string.Concat(item.ImageFileHolder.NameWithoutExtension, ".json"))); if (!fileInfo.Exists) { if (fileInfo.Directory?.Parent is null) @@ -135,7 +135,7 @@ public class B_Metadata } if (dictionary is null || !dictionary.Any()) { - dictionary = GetMetadataCollection(propertyHolder.ImageFileHolder.FullName); + dictionary = GetMetadataCollection(item.ImageFileHolder.FullName); json = JsonSerializer.Serialize(dictionary, _WriteIndentedJsonSerializerOptions); bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime; DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max(); diff --git a/Not-Copy-Copy/Not-Copy-Copy.cs b/Not-Copy-Copy/Not-Copy-Copy.cs index ae56472..6f614d3 100644 --- a/Not-Copy-Copy/Not-Copy-Copy.cs +++ b/Not-Copy-Copy/Not-Copy-Copy.cs @@ -28,7 +28,7 @@ public class NotCopyCopy { } _AppSettings = appSettings; if (appSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); _IsEnvironment = isEnvironment; _Exceptions = new List(); _Log = Serilog.Log.ForContext(); @@ -43,15 +43,15 @@ public class NotCopyCopy PredictorModel? predictorModel = null; _Configuration = configuration; if (propertyConfiguration.PopulatePropertyId is null) - throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId)); + throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId)); if (!_IsEnvironment.Development) throw new Exception("This program only allows development environments!"); - PropertyLogic propertyLogic = GetPropertyLogic(); + PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel); propertyConfiguration.ChangeRootDirectory(configuration.CompareSource); - List comparePropertyHolderCollections = Property.Models.Stateless.A_Property.Get(propertyConfiguration, reverse, model, predictorModel, propertyLogic); + List compareContainers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic); propertyConfiguration.ChangeRootDirectory(configuration.SelectedSource); - List selectedPropertyHolderCollections = Property.Models.Stateless.A_Property.Get(propertyConfiguration, reverse, model, predictorModel, propertyLogic); - if (comparePropertyHolderCollections.Count == selectedPropertyHolderCollections.Count) + List selectedContainers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic); + if (compareContainers.Count == selectedContainers.Count) throw new Exception(); string directoryName; List distinct = new(); @@ -100,36 +100,36 @@ public class NotCopyCopy private static void Verify(Models.Configuration configuration) { if (Path.GetPathRoot(configuration.SelectedSource) == configuration.SelectedSource) - throw new ArgumentNullException(nameof(configuration.SelectedSource)); + throw new NullReferenceException(nameof(configuration.SelectedSource)); if (string.IsNullOrEmpty(configuration.CompareSource) || !Directory.Exists(configuration.CompareSource)) - throw new ArgumentNullException(nameof(configuration.CompareSource)); + throw new NullReferenceException(nameof(configuration.CompareSource)); if (string.IsNullOrEmpty(configuration.EmptyDestination) || Directory.Exists(configuration.EmptyDestination)) - throw new ArgumentNullException(nameof(configuration.EmptyDestination)); + throw new NullReferenceException(nameof(configuration.EmptyDestination)); if (string.IsNullOrEmpty(configuration.SelectedSource) || !Directory.Exists(configuration.SelectedSource)) - throw new ArgumentNullException(nameof(configuration.SelectedSource)); + throw new NullReferenceException(nameof(configuration.SelectedSource)); if (configuration.SelectedSource.Length != configuration.CompareSource.Length) - throw new ArgumentNullException(nameof(configuration.SelectedSource)); + throw new NullReferenceException(nameof(configuration.SelectedSource)); } private long LogDelta(long ticks, string methodName) { long result; if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); result = DateTime.Now.Ticks; return result; } - private PropertyLogic GetPropertyLogic() + private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel) { PropertyLogic result; if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); - result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); + result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel); return result; } @@ -137,7 +137,7 @@ public class NotCopyCopy { List<(string Source, string[] Destination)> results = new(); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string key; string fileName; A_Property? property; diff --git a/PrepareForOld/PrepareForOld.cs b/PrepareForOld/PrepareForOld.cs index 0bca0c7..62bb60a 100644 --- a/PrepareForOld/PrepareForOld.cs +++ b/PrepareForOld/PrepareForOld.cs @@ -30,7 +30,7 @@ public class PrepareForOld string spellingB; _AppSettings = appSettings; if (appSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); _SpellingFindReplace = new(); _IsEnvironment = isEnvironment; _Exceptions = new List(); @@ -42,7 +42,7 @@ public class PrepareForOld Models.Configuration configuration = Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory, propertyConfiguration); Verify(configuration); if (propertyConfiguration.IgnoreExtensions is null) - throw new ArgumentNullException(nameof(propertyConfiguration.IgnoreExtensions)); + throw new NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions)); for (int i = 0; i < configuration.Spelling.Length; i++) { spellingA = configuration.Spelling[i]; @@ -109,7 +109,7 @@ public class PrepareForOld private static void Verify(Models.Configuration configuration) { if (configuration.Spelling is null || !configuration.Spelling.Any()) - throw new ArgumentNullException(nameof(configuration.Spelling)); + throw new NullReferenceException(nameof(configuration.Spelling)); } private static List GetExifCollection(string infoDirectory, string infoDirectoryExtra, bool checkDistinct) @@ -141,7 +141,7 @@ public class PrepareForOld { List<(int Index, long Ticks, string RelativeDirectory, string FileNameWithoutExtension, string Extension, string RegexResult)> results = new(); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); long ticks; string json; string extension; @@ -224,14 +224,14 @@ public class PrepareForOld private void SaveTabSeparatedValues(Property.Models.Configuration configuration, string aPropertySingletonDirectory) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); if (string.IsNullOrEmpty(rootDirectoryParent)) - throw new ArgumentNullException(nameof(rootDirectoryParent)); + throw new NullReferenceException(nameof(rootDirectoryParent)); int z = 0; int mappedIndex; int? propertyId; @@ -414,7 +414,7 @@ public class PrepareForOld JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; Dictionary? source = JsonSerializer.Deserialize>(json); if (source is null) - throw new ArgumentNullException(nameof(source)); + throw new NullReferenceException(nameof(source)); { int propertyId; foreach (KeyValuePair keyValuePair in source) @@ -469,12 +469,12 @@ public class PrepareForOld private void ReSaveJsonFiles() { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); if (string.IsNullOrEmpty(rootDirectoryParent)) - throw new ArgumentNullException(nameof(rootDirectoryParent)); + throw new NullReferenceException(nameof(rootDirectoryParent)); int z = 0; int propertyId; List missingIndices = new(); @@ -523,14 +523,14 @@ public class PrepareForOld private void CopyMissingImagesLogs() { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); if (string.IsNullOrEmpty(rootDirectoryParent)) - throw new ArgumentNullException(nameof(rootDirectoryParent)); + throw new NullReferenceException(nameof(rootDirectoryParent)); int z = 0; int propertyId; Dictionary findReplace = new(); @@ -591,14 +591,14 @@ public class PrepareForOld private void VerifyAgainstIndexInfoJsonFiles(Property.Models.Configuration configuration, string aPropertySingletonDirectory) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); if (string.IsNullOrEmpty(rootDirectoryParent)) - throw new ArgumentNullException(nameof(rootDirectoryParent)); + throw new NullReferenceException(nameof(rootDirectoryParent)); int z = 0; int? propertyId; long? propertyTicks; diff --git a/Property-Compare/Models/PropertyCompareLogic.cs b/Property-Compare/Models/PropertyCompareLogic.cs index 6e45e5f..c1124f8 100644 --- a/Property-Compare/Models/PropertyCompareLogic.cs +++ b/Property-Compare/Models/PropertyCompareLogic.cs @@ -33,7 +33,7 @@ public class PropertyCompareLogic { List results = new(); if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); int index; string value; long[] distinctNumberValues; @@ -81,7 +81,7 @@ public class PropertyCompareLogic { List fromThenToCollection = new(); if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); int z = 0; string to; string from; @@ -177,7 +177,7 @@ public class PropertyCompareLogic string json = File.ReadAllText(jsonFile); A_Property? property = JsonSerializer.Deserialize(json); if (property?.Id is null) - throw new ArgumentNullException(nameof(property)); + throw new NullReferenceException(nameof(property)); DateTime minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(property); corrected = string.Concat(relativeDirectory, jsonFileNameWithoutExtension); if (_SpellingFindReplace is not null && (from l in _SpellingFindReplace where corrected.Contains(l.Find) select true).Any()) @@ -251,7 +251,7 @@ public class PropertyCompareLogic { List results = new(); if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); string[] files; int totalSeconds; string directory; @@ -274,7 +274,7 @@ public class PropertyCompareLogic List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; - groupCollection = Property.Models.Stateless.A_Property.GetGroupCollection(aPropertySingletonDirectory, searchPattern, topDirectories); + groupCollection = Property.Models.Stateless.Container.GetGroupCollection(aPropertySingletonDirectory, searchPattern, topDirectories); foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in groupCollection) { if (!topDirectories.Any()) @@ -319,7 +319,7 @@ public class PropertyCompareLogic private void MoveFiles(string[] directories, List fromThenToCollection) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); int z; string to; string from; @@ -406,7 +406,7 @@ public class PropertyCompareLogic public void SaveDiffFiles(string aPropertyCollectionDirectory, int loadLessThan, PropertyCompare[] propertyCompares, PropertyCompare[]? diffPropertyCompares) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); string text; string[] lines; string fileName; @@ -459,7 +459,7 @@ public class PropertyCompareLogic public void SaveLogAndMoveFiles(string aPropertyCollectionDirectory, int loadLessThan, PropertyCompare[] propertyCompares, PropertyCompare[]? diffPropertyCompares, int i) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); List lines; string checkDirectory; string[] toDirectories; @@ -498,7 +498,7 @@ public class PropertyCompareLogic public void WithSubdirectory(string propertyDirectory, bool subDirectoriesAny, string fileName, bool renameCompare, bool deleteArg) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); List fileCollection = new(); if (renameCompare && deleteArg) throw new Exception(); diff --git a/Property/Models/Closest.cs b/Property/Models/Closest.cs new file mode 100644 index 0000000..e58370a --- /dev/null +++ b/Property/Models/Closest.cs @@ -0,0 +1,40 @@ +using System.Text.Json.Serialization; +using View_by_Distance.Shared.Models; + +namespace View_by_Distance.Property.Models; + +public class Closest +{ + + protected readonly double? _Average; + protected readonly int? _FaceLocationIndex; + protected readonly bool? _IsWrongYear; + protected readonly DateTime _MinimumDateTime; + protected readonly PersonBirthday? _PersonBirthday; + + public double? Average => _Average; + public int? FaceLocationIndex => _FaceLocationIndex; + public bool? IsWrongYear => _IsWrongYear; + public DateTime MinimumDateTime => _MinimumDateTime; + public PersonBirthday? PersonBirthday => _PersonBirthday; + + [JsonConstructor] + public Closest(double? average, int? faceLocationIndex, bool? isWrongYear, DateTime minimumDateTime, PersonBirthday? personBirthday) + { + _Average = average; + _FaceLocationIndex = faceLocationIndex; + _IsWrongYear = isWrongYear; + _MinimumDateTime = minimumDateTime; + _PersonBirthday = personBirthday; + } + + public Closest(int? faceLocationIndex, DateTime minimumDateTime, bool? isWrongYear, PersonBirthday? personBirthday, double? average) + { + _Average = average; + _FaceLocationIndex = faceLocationIndex; + _IsWrongYear = isWrongYear; + _MinimumDateTime = minimumDateTime; + _PersonBirthday = personBirthday; + } + +} \ No newline at end of file diff --git a/Property/Models/Configuration.cs b/Property/Models/Configuration.cs index 90f7588..44ff705 100644 --- a/Property/Models/Configuration.cs +++ b/Property/Models/Configuration.cs @@ -65,37 +65,37 @@ public class Configuration public static void Verify(Configuration? propertyConfiguration) { if (propertyConfiguration is null) - throw new ArgumentNullException(nameof(propertyConfiguration)); + throw new NullReferenceException(nameof(propertyConfiguration)); if (propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime is null) - throw new ArgumentNullException(nameof(propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime)); + throw new NullReferenceException(nameof(propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime)); if (propertyConfiguration.IgnoreExtensions is null || !propertyConfiguration.IgnoreExtensions.Any()) - throw new ArgumentNullException(nameof(propertyConfiguration.IgnoreExtensions)); + throw new NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions)); if (propertyConfiguration.PopulatePropertyId is null) - throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId)); + throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId)); if (propertyConfiguration.PropertiesChangedForProperty is null) - throw new ArgumentNullException(nameof(propertyConfiguration.PropertiesChangedForProperty)); + throw new NullReferenceException(nameof(propertyConfiguration.PropertiesChangedForProperty)); if (propertyConfiguration.PropertyContentCollectionFiles is null) - throw new ArgumentNullException(nameof(propertyConfiguration.PropertyContentCollectionFiles)); + throw new NullReferenceException(nameof(propertyConfiguration.PropertyContentCollectionFiles)); if (propertyConfiguration.ValidImageFormatExtensions is null || !propertyConfiguration.ValidImageFormatExtensions.Any()) - throw new ArgumentNullException(nameof(propertyConfiguration.ValidImageFormatExtensions)); + throw new NullReferenceException(nameof(propertyConfiguration.ValidImageFormatExtensions)); if (propertyConfiguration.ValidMetadataExtensions is null || !propertyConfiguration.ValidMetadataExtensions.Any()) - throw new ArgumentNullException(nameof(propertyConfiguration.ValidMetadataExtensions)); + throw new NullReferenceException(nameof(propertyConfiguration.ValidMetadataExtensions)); if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any()) - throw new ArgumentNullException(nameof(propertyConfiguration.VerifyToSeason)); + throw new NullReferenceException(nameof(propertyConfiguration.VerifyToSeason)); if (propertyConfiguration.WriteBitmapDataBytes is null) - throw new ArgumentNullException(nameof(propertyConfiguration.WriteBitmapDataBytes)); + throw new NullReferenceException(nameof(propertyConfiguration.WriteBitmapDataBytes)); if (Path.GetPathRoot(propertyConfiguration.RootDirectory) == propertyConfiguration.RootDirectory) - throw new ArgumentNullException(nameof(propertyConfiguration.RootDirectory)); + throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory)); if (propertyConfiguration is null) - throw new ArgumentNullException(nameof(propertyConfiguration)); + throw new NullReferenceException(nameof(propertyConfiguration)); if (string.IsNullOrEmpty(propertyConfiguration.DateGroup)) - throw new ArgumentNullException(nameof(propertyConfiguration.DateGroup)); + throw new NullReferenceException(nameof(propertyConfiguration.DateGroup)); if (string.IsNullOrEmpty(propertyConfiguration.FileNameDirectorySeparator)) - throw new ArgumentNullException(nameof(propertyConfiguration.FileNameDirectorySeparator)); + throw new NullReferenceException(nameof(propertyConfiguration.FileNameDirectorySeparator)); if (string.IsNullOrEmpty(propertyConfiguration.Pattern)) - throw new ArgumentNullException(nameof(propertyConfiguration.Pattern)); + throw new NullReferenceException(nameof(propertyConfiguration.Pattern)); if (string.IsNullOrEmpty(propertyConfiguration.RootDirectory) || !Directory.Exists(propertyConfiguration.RootDirectory)) - throw new ArgumentNullException(nameof(propertyConfiguration.RootDirectory)); + throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory)); } public void ChangeRootDirectory(string rootDirectory) => _RootDirectory = rootDirectory; diff --git a/Property/Models/Container.cs b/Property/Models/Container.cs new file mode 100644 index 0000000..305d3fa --- /dev/null +++ b/Property/Models/Container.cs @@ -0,0 +1,34 @@ +using System.Text.Json.Serialization; + +namespace View_by_Distance.Property.Models; + +public class Container +{ + + protected readonly int _G; + protected readonly int _R; + protected readonly List _Items; + protected readonly string _SourceDirectory; + public int G => _G; + public List Items => _Items; + public int R => _R; + public string SourceDirectory => _SourceDirectory; + + [JsonConstructor] + public Container(int g, int r, List items, string sourceDirectory) + { + _G = g; + _R = r; + _Items = items; + _SourceDirectory = sourceDirectory; + } + + public Container(int g, int r, string sourceDirectory) + { + _G = g; + _R = r; + _Items = new(); + _SourceDirectory = sourceDirectory; + } + +} \ No newline at end of file diff --git a/Property/Models/FileHolder.cs b/Property/Models/FileHolder.cs index bdf126b..4ef5257 100644 --- a/Property/Models/FileHolder.cs +++ b/Property/Models/FileHolder.cs @@ -5,7 +5,7 @@ public class FileHolder protected readonly DateTime _CreationTime; protected readonly string? _DirectoryName; protected readonly bool _Exists; - protected readonly string _Extension; + protected readonly string _ExtensionLowered; protected readonly string _FullName; protected readonly DateTime _LastWriteTime; protected readonly long? _Length; @@ -14,19 +14,19 @@ public class FileHolder public DateTime CreationTime => _CreationTime; public string? DirectoryName => _DirectoryName; public bool Exists => _Exists; - public string Extension => _Extension; + public string ExtensionLowered => _ExtensionLowered; public string FullName => _FullName; public DateTime LastWriteTime => _LastWriteTime; public long? Length => _Length; public string Name => _Name; public string NameWithoutExtension => _NameWithoutExtension; - public FileHolder(DateTime creationTime, string? directoryName, bool exists, string extension, string fullName, DateTime lastWriteTime, long? length, string name, string nameWithoutExtension) + public FileHolder(DateTime creationTime, string? directoryName, bool exists, string extensionLowered, string fullName, DateTime lastWriteTime, long? length, string name, string nameWithoutExtension) { _CreationTime = creationTime; _DirectoryName = directoryName; _Exists = exists; - _Extension = extension; + _ExtensionLowered = extensionLowered; _FullName = fullName; _LastWriteTime = lastWriteTime; _Length = length; @@ -41,7 +41,7 @@ public class FileHolder _CreationTime = fileInfo.CreationTime; _DirectoryName = fileInfo.DirectoryName; _Exists = fileInfo.Exists; - _Extension = fileInfo.Extension; + _ExtensionLowered = fileInfo.Extension.ToLower(); _FullName = fileInfo.FullName; _LastWriteTime = fileInfo.LastWriteTime; if (fileInfo.Exists) @@ -56,7 +56,7 @@ public class FileHolder _CreationTime = fileInfo.CreationTime; _DirectoryName = fileInfo.DirectoryName; _Exists = fileInfo.Exists; - _Extension = fileInfo.Extension; + _ExtensionLowered = fileInfo.Extension.ToLower(); _FullName = fileInfo.FullName; _LastWriteTime = fileInfo.LastWriteTime; if (fileInfo.Exists) diff --git a/Property/Models/PropertyHolder.cs b/Property/Models/Item.cs similarity index 51% rename from Property/Models/PropertyHolder.cs rename to Property/Models/Item.cs index f3b7829..a3b8861 100644 --- a/Property/Models/PropertyHolder.cs +++ b/Property/Models/Item.cs @@ -4,86 +4,72 @@ using View_by_Distance.Shared.Models.Properties; namespace View_by_Distance.Property.Models; -public class PropertyHolder +public class Item { protected readonly bool? _Abandoned; protected readonly bool? _Changed; + protected List _Closest; protected List _Faces; protected readonly FileHolder? _ImageFileHolder; - protected readonly string _ImageFileNameWithoutExtension; - protected readonly int _G; - protected DateTime? _MinimumDateTime; protected bool? _Moved; - protected List<(bool?, DateTime, PersonBirthday, double?)> _Named; + protected List _Named; protected readonly bool? _NoJson; protected A_Property? _Property; - protected readonly int _R; protected readonly string _RelativePath; protected FileHolder? _ResizedFileHolder; - protected readonly string _SourceDirectory; protected readonly string _SourceDirectoryFile; - protected bool? _ValidImageFormatExtension; + protected bool _ValidImageFormatExtension; public bool? Abandoned => _Abandoned; public bool? Changed => _Changed; + public List Closest => _Closest; public List Faces => _Faces; public FileHolder? ImageFileHolder => _ImageFileHolder; - public string ImageFileNameWithoutExtension => _ImageFileNameWithoutExtension; - public int G => _G; - public DateTime? MinimumDateTime => _MinimumDateTime; public bool? Moved => _Moved; public bool? NoJson => _NoJson; - public List<(bool? isWrongYear, DateTime minimumDateTime, PersonBirthday personBirthday, double? pixelPercentage)> Named => _Named; + public List Named => _Named; public A_Property? Property => _Property; - public int R => _R; public string RelativePath => _RelativePath; public FileHolder? ResizedFileHolder => _ResizedFileHolder; - public string SourceDirectory => _SourceDirectory; public string SourceDirectoryFile => _SourceDirectoryFile; - public bool? ValidImageFormatExtension => _ValidImageFormatExtension; - - public PropertyHolder() - { - _G = -1; - _R = -1; - _Faces = new(); - _Named = new(); - _RelativePath = string.Empty; - _SourceDirectory = string.Empty; - _SourceDirectoryFile = string.Empty; - _ImageFileNameWithoutExtension = string.Empty; - } + public bool ValidImageFormatExtension => _ValidImageFormatExtension; [JsonConstructor] - public PropertyHolder(int g, string sourceDirectory, string sourceDirectoryFile, string relativePath, int r, FileHolder? imageFileInfo, A_Property? property, bool? abandoned, bool? changed, bool? moved, bool? validImageFormatExtension) + public Item(bool? abandoned, bool? changed, List closest, List faces, FileHolder? imageFileHolder, bool? moved, List named, bool? noJson, A_Property? property, string relativePath, FileHolder? resizedFileHolder, string sourceDirectoryFile, bool validImageFormatExtension) { - _G = g; - _R = r; - _Faces = new(); - _Moved = moved; - _Named = new(); + _Abandoned = abandoned; _Changed = changed; + _Closest = closest; + _Faces = faces; + _ImageFileHolder = imageFileHolder; + _Moved = moved; + _Named = named; + _NoJson = noJson; _Property = property; + _RelativePath = relativePath; + _ResizedFileHolder = resizedFileHolder; + _SourceDirectoryFile = sourceDirectoryFile; + _ValidImageFormatExtension = validImageFormatExtension; + } + + public Item(string sourceDirectoryFile, string relativePath, FileHolder? imageFileInfo, bool isValidImageFormatExtension, A_Property? property, bool? abandoned, bool? changed) + { + _Faces = new(); + _Named = new(); + _Closest = new(); + _Changed = changed; _Abandoned = abandoned; _NoJson = abandoned is null; _RelativePath = relativePath; _ImageFileHolder = imageFileInfo; - _SourceDirectory = sourceDirectory; _SourceDirectoryFile = sourceDirectoryFile; - _ValidImageFormatExtension = validImageFormatExtension; - _MinimumDateTime = Stateless.A_Property.GetMinimumDateTime(property); - if (imageFileInfo is null) - _ImageFileNameWithoutExtension = string.Empty; - else - _ImageFileNameWithoutExtension = Path.GetFileNameWithoutExtension(imageFileInfo.FullName); - if (imageFileInfo is not null && imageFileInfo.Extension is ".json") + _ValidImageFormatExtension = isValidImageFormatExtension; + if (relativePath.EndsWith(".json")) + throw new ArgumentException("Can not be a *.json file!"); + if (imageFileInfo is not null && imageFileInfo.ExtensionLowered is ".json") throw new ArgumentException("Can not be a *.json file!"); - if (!sourceDirectoryFile.EndsWith(".json") && !sourceDirectoryFile.EndsWith(".old")) - throw new ArgumentException("Must be a *.json or *.old file!"); } - internal void SetValidImageFormatExtension(bool isValidImageFormatExtension) => _ValidImageFormatExtension = isValidImageFormatExtension; - internal void SetMoved(bool moved) => _Moved = moved; public static string GetWrongYearFlag(bool? isWrongYear) => isWrongYear is null ? "#" : isWrongYear.Value ? "~" : "="; @@ -92,42 +78,39 @@ public class PropertyHolder public bool Any() => (_Abandoned.HasValue && _Abandoned.Value) || (_Changed.HasValue && _Changed.Value) || (_Moved.HasValue && _Moved.Value) || (_NoJson.HasValue && _NoJson.Value); - public void Update(A_Property property) - { - _Property = property; - _MinimumDateTime = Stateless.A_Property.GetMinimumDateTime(property); - } + public void Update(A_Property property) => _Property = property; public (bool?, string[]) IsWrongYear() { (bool?, string[]) result; if (_Property is null || _ImageFileHolder is null) - throw new ArgumentNullException(); - result = _Property.IsWrongYear(_ImageFileHolder.FullName, _MinimumDateTime); + throw new NullReferenceException(); + DateTime? minimumDateTime = Stateless.A_Property.GetMinimumDateTime(_Property); + result = _Property.IsWrongYear(_ImageFileHolder.FullName, minimumDateTime); return result; } - public static void AddToNamed(PropertyLogic propertyLogic, PropertyHolder[] filteredPropertyHolderCollection) + public static void AddToNamed(PropertyLogic propertyLogic, Item[] filteredItems) { + Item item; bool? isWrongYear; string[] segments; string[] personKeys; double? pixelPercentage; DateTime minimumDateTime; - PropertyHolder propertyHolder; PersonBirthday? personBirthday; - for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) + for (int i = 0; i < filteredItems.Length; i++) { - propertyHolder = filteredPropertyHolderCollection[i]; - if (propertyHolder.ImageFileHolder is null) + item = filteredItems[i]; + if (item.ImageFileHolder is null) continue; - if (propertyHolder.Property?.Id is null || propertyHolder.MinimumDateTime is null || propertyHolder.ResizedFileHolder is null) + if (item.Property?.Id is null || item.ResizedFileHolder is null) continue; - if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(propertyHolder.Property.Id.Value)) + if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(item.Property.Id.Value)) continue; - minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property); - personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value]; - (isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileHolder.FullName, minimumDateTime); + minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property); + personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[item.Property.Id.Value]; + (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime); for (int j = 0; j < personKeys.Length; j++) { segments = Shared.Models.Stateless.Methods.IPersonBirthday.GetSegments(personKeys[j]); @@ -138,14 +121,15 @@ public class PropertyHolder pixelPercentage = null; else pixelPercentage = value; - propertyHolder.Named.Add(new(isWrongYear, minimumDateTime, personBirthday, pixelPercentage)); + item.Named.Add(new(isWrongYear, minimumDateTime, personBirthday, pixelPercentage)); } } } - public static List<(PropertyHolder, (string, IFace?, (string, string, string, string))[])> GetCollection(PropertyLogic propertyLogic, PropertyHolder[] filteredPropertyHolderCollection, string dFacesContentDirectory) + public static List<(Item, (string, IFace?, (string, string, string, string))[])> GetCollection(PropertyLogic propertyLogic, Item[] filteredItems, string dFacesContentDirectory) { - List<(PropertyHolder, (string, IFace?, (string, string, string, string))[])> results = new(); + List<(Item, (string, IFace?, (string, string, string, string))[])> results = new(); + Item item; string[] keys; string directory; string personKey; @@ -160,37 +144,40 @@ public class PropertyHolder string shortcutFileName; string subDirectoryName; List indices = new(); + DateTime? minimumDateTime; List faceCollection; - PropertyHolder propertyHolder; PersonBirthday? personBirthday; List<(string, IFace?, (string, string, string, string))> collection; - for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) + for (int i = 0; i < filteredItems.Length; i++) { indices.Clear(); personKey = string.Empty; copyFileName = string.Empty; copyDirectory = string.Empty; - propertyHolder = filteredPropertyHolderCollection[i]; - if (propertyHolder.ImageFileHolder is null) + item = filteredItems[i]; + if (item.ImageFileHolder is null) continue; - relativePath = Path.GetDirectoryName($"C:{propertyHolder.RelativePath}"); + relativePath = Path.GetDirectoryName($"C:{item.RelativePath}"); if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3) continue; - if (propertyHolder.Property?.Id is null || propertyHolder.MinimumDateTime is null || propertyHolder.ResizedFileHolder is null) + if (item.Property?.Id is null || item.ResizedFileHolder is null) continue; collection = new(); - if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(propertyHolder.Property.Id.Value)) + if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(item.Property.Id.Value)) { faceCollection = new(); directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}"); } else { - faceCollection = propertyHolder.Faces; - keys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value]; - (isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileHolder.FullName, propertyHolder.MinimumDateTime.Value); + faceCollection = item.Faces; + keys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[item.Property.Id.Value]; + minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property); + if (minimumDateTime is null) + continue; + (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime.Value); isWrongYearFlag = GetWrongYearFlag(isWrongYear); - subDirectoryName = $"{isWrongYearFlag}{propertyHolder.MinimumDateTime.Value:yyyy}"; + subDirectoryName = $"{isWrongYearFlag}{minimumDateTime.Value:yyyy}"; if (!faceCollection.Any()) directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName); else if (keys.Length != 1) @@ -204,7 +191,7 @@ public class PropertyHolder personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(keys[zero]); if (personBirthday is null) continue; - timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(propertyHolder.MinimumDateTime.Value, isWrongYear, personBirthday); + timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime.Value, isWrongYear, personBirthday); if (timeSpan.HasValue) { if (timeSpan.Value.Ticks < 0) @@ -218,10 +205,10 @@ public class PropertyHolder copyDirectory = Path.Combine(dFacesContentDirectory, "Images", personKey, subDirectoryName); else copyDirectory = Path.Combine(dFacesContentDirectory, "ImagesBut", personKey, subDirectoryName); - copyFileName = Path.Combine(copyDirectory, $"{propertyHolder.Property.Id.Value}{propertyHolder.ResizedFileHolder.Extension}"); + copyFileName = Path.Combine(copyDirectory, $"{item.Property.Id.Value}{item.ResizedFileHolder.ExtensionLowered}"); } } - shortcutFileName = Path.Combine(directory, $"{propertyHolder.Property.Id.Value}.lnk"); + shortcutFileName = Path.Combine(directory, $"{item.Property.Id.Value}.lnk"); if (string.IsNullOrEmpty(personKey) || !indices.Any()) collection.Add(new(personKey, null, (directory, copyDirectory, copyFileName, shortcutFileName))); else @@ -229,56 +216,75 @@ public class PropertyHolder foreach (int index in indices) collection.Add(new(personKey, faceCollection[index], (directory, copyDirectory, copyFileName, shortcutFileName))); } - results.Add(new(propertyHolder, collection.ToArray())); + results.Add(new(item, collection.ToArray())); } return results; } - public static Dictionary> GetKeyValuePairs(string argZero, List propertyHolderCollections) + public static string GetKey(DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday) { - Dictionary> results = new(); - string key; - string personKey; - TimeSpan? timeSpan; - string[] directories; - string isWrongYearFlag; - const string facePopulatedKey = "Images"; - foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections) + string result; + string personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday); + TimeSpan? timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday); + if (timeSpan.HasValue && timeSpan.Value.Ticks < 0) + result = string.Concat(personKey, "!---"); + else if (timeSpan.HasValue) + result = string.Concat(personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}"); + else { - if (!propertyHolderCollection.Any()) + string isWrongYearFlag = GetWrongYearFlag(isWrongYear); + result = string.Concat(personKey, $"{isWrongYearFlag}{minimumDateTime:yyyy}"); + } + return result; + } + + public static string GetDirectory(string directory, string subDirectory, DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday, string personKey) + { + string result; + TimeSpan? timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday); + if (timeSpan.HasValue && timeSpan.Value.Ticks < 0) + result = Path.Combine(directory, subDirectory, personKey, "!---"); + else if (timeSpan.HasValue) + result = Path.Combine(directory, subDirectory, personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}"); + else + { + string isWrongYearFlag = GetWrongYearFlag(isWrongYear); + result = Path.Combine(directory, subDirectory, personKey, $"{isWrongYearFlag}{minimumDateTime:yyyy}"); + } + return result; + } + + public static Dictionary> GetKeyValuePairs(string argZero, List containers) + { + Dictionary> results = new(); + string key; + foreach (Container container in containers) + { + if (!container.Items.Any()) continue; - if (!propertyHolderCollection[0].SourceDirectory.StartsWith(argZero)) + if (!container.SourceDirectory.StartsWith(argZero)) continue; - foreach (PropertyHolder propertyHolder in propertyHolderCollection) + foreach (Item item in container.Items) { - if (propertyHolder.ImageFileHolder is null || propertyHolder.Property is null || !propertyHolder.Named.Any()) + if (item.ImageFileHolder is null || item.Property is null || !item.Named.Any()) continue; - foreach ((bool? isWrongYear, DateTime minimumDateTime, PersonBirthday personBirthday, double? pixelPercentage) in propertyHolder.Named) + foreach (Named named in item.Named) { - if (pixelPercentage is null && (propertyHolder.Named.Count != 1 || propertyHolder.Faces.Count != 1)) + if (named.PixelPercentage is null && (item.Named.Count != 1 || item.Faces.Count != 1)) continue; - foreach (IFace face in propertyHolder.Faces) + foreach (IFace face in item.Faces) { if (!face.Populated) continue; - if (pixelPercentage.HasValue && pixelPercentage.Value != face.Location.PixelPercentage) + if (named.PersonBirthday is null) continue; - personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday); - timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday); - if (timeSpan.HasValue && timeSpan.Value.Ticks < 0) - directories = new string[] { string.Empty, facePopulatedKey, personKey, "!---" }; - else if (timeSpan.HasValue) - directories = new string[] { string.Empty, facePopulatedKey, personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}" }; - else - { - isWrongYearFlag = GetWrongYearFlag(isWrongYear); - directories = new string[] { string.Empty, facePopulatedKey, personKey, $"{isWrongYearFlag}{minimumDateTime:yyyy}" }; - } - key = string.Join('\t', directories); + if (named.PixelPercentage.HasValue && named.PixelPercentage.Value != face.Location.PixelPercentage) + continue; + key = GetKey(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday); if (!results.ContainsKey(key)) results.Add(key, new()); - results[key].Add(new(directories, personBirthday, face)); - if (pixelPercentage is null) + results[key].Add(new(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday, face)); + if (named.PixelPercentage is null) break; } } diff --git a/Property/Models/Named.cs b/Property/Models/Named.cs new file mode 100644 index 0000000..d7d73be --- /dev/null +++ b/Property/Models/Named.cs @@ -0,0 +1,27 @@ +using System.Text.Json.Serialization; +using View_by_Distance.Shared.Models; + +namespace View_by_Distance.Property.Models; + +public class Named +{ + + protected readonly bool? _IsWrongYear; + protected readonly DateTime _MinimumDateTime; + protected readonly PersonBirthday? _PersonBirthday; + protected readonly double? _PixelPercentage; + public bool? IsWrongYear => _IsWrongYear; + public DateTime MinimumDateTime => _MinimumDateTime; + public PersonBirthday? PersonBirthday => _PersonBirthday; + public double? PixelPercentage => _PixelPercentage; + + [JsonConstructor] + public Named(bool? isWrongYear, DateTime minimumDateTime, PersonBirthday? personBirthday, double? pixelPercentage) + { + _IsWrongYear = isWrongYear; + _MinimumDateTime = minimumDateTime; + _PersonBirthday = personBirthday; + _PixelPercentage = pixelPercentage; + } + +} \ No newline at end of file diff --git a/Property/Models/PropertyLogic.cs b/Property/Models/PropertyLogic.cs index cc5fa88..c7b0bc9 100644 --- a/Property/Models/PropertyLogic.cs +++ b/Property/Models/PropertyLogic.cs @@ -21,24 +21,30 @@ public class PropertyLogic protected readonly Dictionary _SixCharacterNamedFaceInfo; protected readonly Dictionary _NamedFaceInfoDeterministicHashCodeIndices; + public bool Reverse { get; } public List AngleBracketCollection { get; } public Dictionary KeyValuePairs => _KeyValuePairs; public Dictionary IndicesFromNew => _IndicesFromNew; public List ExceptionsDirectories => _ExceptionsDirectories; public Dictionary NamedFaceInfoDeterministicHashCodeIndices => _NamedFaceInfoDeterministicHashCodeIndices; + private readonly Model? _Model; private readonly Serilog.ILogger? _Log; private readonly string[] _VerifyToSeason; private readonly int _MaxDegreeOfParallelism; private readonly ASCIIEncoding _ASCIIEncoding; private readonly Configuration _Configuration; + private readonly PredictorModel? _PredictorModel; private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions; - public PropertyLogic(int maxDegreeOfParallelism, Configuration configuration) + public PropertyLogic(int maxDegreeOfParallelism, Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel) { + _Model = model; + Reverse = reverse; _AllCollection = new(); _Configuration = configuration; _ExceptionsDirectories = new(); + _PredictorModel = predictorModel; _ASCIIEncoding = new ASCIIEncoding(); AngleBracketCollection = new List(); _Log = Serilog.Log.ForContext(); @@ -57,7 +63,7 @@ public class PropertyLogic Dictionary? sixCharacterNamedFaceInfo; string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory); if (string.IsNullOrEmpty(rootDirectoryParent)) - throw new ArgumentNullException(nameof(rootDirectoryParent)); + throw new NullReferenceException(nameof(rootDirectoryParent)); files = Directory.GetFiles(rootDirectoryParent, "*DeterministicHashCode*.json", SearchOption.TopDirectoryOnly); if (files.Length != 1) namedFaceInfoDeterministicHashCodeIndices = new(); @@ -66,7 +72,7 @@ public class PropertyLogic json = File.ReadAllText(files[0]); namedFaceInfoDeterministicHashCodeIndices = JsonSerializer.Deserialize>(json); if (namedFaceInfoDeterministicHashCodeIndices is null) - throw new ArgumentNullException(nameof(namedFaceInfoDeterministicHashCodeIndices)); + throw new NullReferenceException(nameof(namedFaceInfoDeterministicHashCodeIndices)); } if (namedFaceInfoDeterministicHashCodeIndices.Any()) sixCharacterNamedFaceInfo = new(); @@ -80,7 +86,7 @@ public class PropertyLogic json = File.ReadAllText(files[0]); sixCharacterNamedFaceInfo = JsonSerializer.Deserialize>(json); if (sixCharacterNamedFaceInfo is null) - throw new ArgumentNullException(nameof(sixCharacterNamedFaceInfo)); + throw new NullReferenceException(nameof(sixCharacterNamedFaceInfo)); } } files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly); @@ -91,7 +97,7 @@ public class PropertyLogic json = File.ReadAllText(files[0]); keyValuePairs = JsonSerializer.Deserialize>(json); if (keyValuePairs is null) - throw new ArgumentNullException(nameof(keyValuePairs)); + throw new NullReferenceException(nameof(keyValuePairs)); } foreach (string propertyContentCollectionFile in configuration.PropertyContentCollectionFiles) { @@ -103,7 +109,7 @@ public class PropertyLogic json = File.ReadAllText(fullPath); collection = JsonSerializer.Deserialize>>(json); if (collection is null) - throw new ArgumentNullException(nameof(collection)); + throw new NullReferenceException(nameof(collection)); foreach (KeyValuePair keyValuePair in collection) { if (indicesFromNew.ContainsKey(keyValuePair.Key)) @@ -127,7 +133,7 @@ public class PropertyLogic { long result; if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); result = DateTime.Now.Ticks; @@ -168,13 +174,13 @@ public class PropertyLogic #pragma warning disable CA1416 - private A_Property GetImageProperty(string angleBracket, FileHolder filteredSourceDirectoryFileHolder, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List indices) + private A_Property GetImageProperty(FileHolder filteredSourceDirectoryFileHolder, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List indices) { A_Property result; if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_Configuration.WriteBitmapDataBytes is null) - throw new ArgumentNullException(nameof(_Configuration.WriteBitmapDataBytes)); + throw new NullReferenceException(nameof(_Configuration.WriteBitmapDataBytes)); long ticks; byte[] bytes; string value; @@ -201,7 +207,7 @@ public class PropertyLogic } else if (!isIgnoreExtension && isValidImageFormatExtension) { - if (!_IndicesFromNew.Any() && !_KeyValuePairs.Any()) + if (populateId && (id is null || !indices.Any()) && !_IndicesFromNew.Any() && !_KeyValuePairs.Any()) throw new Exception("In order to keep six character indices at least one need to have an item!"); try { @@ -209,6 +215,7 @@ public class PropertyLogic if (populateId && (id is null || !indices.Any())) { using Bitmap bitmap = new(image); + string angleBracket = AngleBracketCollection[0]; Rectangle rectangle = new(0, 0, image.Width, image.Height); BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat); IntPtr intPtr = bitmapData.Scan0; @@ -341,24 +348,27 @@ public class PropertyLogic #pragma warning restore CA1416 - private A_Property GetPropertyOfPrivate(string angleBracket, PropertyHolder propertyHolder, bool firstPass, List> filteredSourceDirectoryFileTuples, List parseExceptions, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, string extensionLowered) + private A_Property GetPropertyOfPrivate(Item item, bool firstPass, List> filteredSourceDirectoryFileTuples, List parseExceptions, bool isIgnoreExtension, bool isValidMetadataExtensions) { A_Property? result; if (_Configuration.ForcePropertyLastWriteTimeToCreationTime is null) - throw new ArgumentNullException(nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime)); + throw new NullReferenceException(nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime)); if (_Configuration.PopulatePropertyId is null) - throw new ArgumentNullException(nameof(_Configuration.PopulatePropertyId)); + throw new NullReferenceException(nameof(_Configuration.PopulatePropertyId)); if (_Configuration.PropertiesChangedForProperty is null) - throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForProperty)); + throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForProperty)); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); string json; int? id = null; List indices = new(); bool hasWrongYearProperty = false; string[] changesFrom = Array.Empty(); + string angleBracket = AngleBracketCollection[0]; bool populateId = !firstPass && _Configuration.PopulatePropertyId.Value; - string without = Path.Combine(angleBracket.Replace("<>", "{}"), $"{propertyHolder.ImageFileNameWithoutExtension}.json"); - FileInfo fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{propertyHolder.ImageFileNameWithoutExtension}{extensionLowered}.json")); - if (isValidImageFormatExtension && File.Exists(without)) + string without = Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}.json"); + FileInfo fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json")); + if (item.ValidImageFormatExtension && File.Exists(without)) { File.Move(without, fileInfo.FullName); fileInfo.Refresh(); @@ -398,40 +408,40 @@ public class PropertyLogic json = File.ReadAllText(fileInfo.FullName); try { - if (propertyHolder.ImageFileHolder is null) - throw new ArgumentException($"{propertyHolder.ImageFileHolder} is null!"); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); bool check = true; A_Property? property = JsonSerializer.Deserialize(json); - if (!isIgnoreExtension && isValidImageFormatExtension && ((populateId && property?.Id is null) || property?.Width is null || property?.Height is null)) + if (!isIgnoreExtension && item.ValidImageFormatExtension && ((populateId && property?.Id is null) || property?.Width is null || property?.Height is null)) { check = false; id = property?.Id; if (property is not null && property.Indices.Any()) indices = property.Indices.ToList(); - property = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices); + property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices); } - if (!isIgnoreExtension && isValidImageFormatExtension && populateId && property is not null && !property.Indices.Any()) + if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && property is not null && !property.Indices.Any()) { check = false; id = property?.Id; if (property is not null && property.Indices.Any()) indices = property.Indices.ToList(); - property = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices); + property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices); } - if (!isIgnoreExtension && isValidImageFormatExtension && populateId && property is not null && property.LastWriteTime != propertyHolder.ImageFileHolder.LastWriteTime) + if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && property is not null && property.LastWriteTime != item.ImageFileHolder.LastWriteTime) { check = false; id = null; indices.Clear(); - property = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices); + property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices); } - if (!isIgnoreExtension && isValidImageFormatExtension && property?.Width is not null && property?.Height is not null && property.Width.Value == property.Height.Value && propertyHolder.ImageFileHolder.Exists) + if (!isIgnoreExtension && item.ValidImageFormatExtension && property?.Width is not null && property?.Height is not null && property.Width.Value == property.Height.Value && item.ImageFileHolder.Exists) { check = false; id = property?.Id; if (property is not null && property.Indices.Any()) indices = property.Indices.ToList(); - property = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices); + property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices); if (property?.Width is not null && property?.Height is not null && property.Width.Value != property.Height.Value) throw new Exception("Was square!"); } @@ -440,7 +450,7 @@ public class PropertyLogic // check = false; // id = null; // indices.Clear(); - // property = GetImagePropertyB(angleBracket, filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices); + // property = GetImagePropertyB(filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices); // } if (json.Contains("WrongYear")) { @@ -465,9 +475,9 @@ public class PropertyLogic } if (result is null) { - if (propertyHolder.ImageFileHolder is null) - throw new ArgumentException($"{propertyHolder.ImageFileHolder} is null!"); - result = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); + result = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices); json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions); if (populateId && IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true)) { @@ -494,11 +504,11 @@ public class PropertyLogic return result; } - private bool AnyFilesMoved(string sourceDirectory, PropertyHolder[] filteredPropertyHolderCollection) + private bool AnyFilesMoved(string sourceDirectory, Item[] filteredItems) { bool result = false; if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); int season; string[] matches; string deleteFile; @@ -510,20 +520,16 @@ public class PropertyLogic string destinationDirectory; string[] sourceDirectorySegments; DateTime directoryMaximumOfMinimumDateTime = DateTime.MinValue; - foreach (PropertyHolder propertyHolder in filteredPropertyHolderCollection) + foreach (Item filteredItem in filteredItems) { - if (propertyHolder.ValidImageFormatExtension is null || !propertyHolder.ValidImageFormatExtension.Value) + if (!filteredItem.ValidImageFormatExtension || filteredItem.Property is null || filteredItem.ImageFileHolder is null) continue; - if (propertyHolder.Property is null) - continue; - if (propertyHolder.ImageFileHolder is null) - continue; - minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property); + minimumDateTime = Stateless.A_Property.GetMinimumDateTime(filteredItem.Property); if (minimumDateTime > directoryMaximumOfMinimumDateTime) directoryMaximumOfMinimumDateTime = minimumDateTime; - if (minimumDateTime != propertyHolder.ImageFileHolder.CreationTime) + if (minimumDateTime != filteredItem.ImageFileHolder.CreationTime) { - (isWrongYear, matches) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileHolder.FullName, minimumDateTime); + (isWrongYear, matches) = filteredItem.Property.IsWrongYear(filteredItem.ImageFileHolder.FullName, minimumDateTime); if (isWrongYear is null || !isWrongYear.Value) dateTime = minimumDateTime; else @@ -534,20 +540,20 @@ public class PropertyLogic continue; } try - { File.SetCreationTime(propertyHolder.ImageFileHolder.FullName, dateTime); } + { File.SetCreationTime(filteredItem.ImageFileHolder.FullName, dateTime); } catch (Exception) { } } if (!_VerifyToSeason.Contains(sourceDirectory)) continue; - if (!propertyHolder.ImageFileHolder.FullName.Contains("zzz ") && !propertyHolder.ImageFileHolder.FullName.Contains("Camera ") && propertyHolder.Property.DateTimeOriginal.HasValue) + if (!filteredItem.ImageFileHolder.FullName.Contains("zzz ") && !filteredItem.ImageFileHolder.FullName.Contains("Camera ") && filteredItem.Property.DateTimeOriginal.HasValue) { - TimeSpan timeSpan = new(propertyHolder.Property.DateTimeOriginal.Value.Ticks - propertyHolder.Property.LastWriteTime.Ticks); + TimeSpan timeSpan = new(filteredItem.Property.DateTimeOriginal.Value.Ticks - filteredItem.Property.LastWriteTime.Ticks); if (timeSpan.TotalHours > 6) { - _Log.Warning($"*** propertyHolder.FileInfo.FullName <{propertyHolder.ImageFileHolder.FullName}>"); - _Log.Warning($"*** DateTimeOriginal <{propertyHolder.Property.DateTimeOriginal.Value}>"); - _Log.Warning($"*** LastWriteTime <{propertyHolder.Property.LastWriteTime}>"); + _Log.Warning($"*** propertyHolder.FileInfo.FullName <{filteredItem.ImageFileHolder.FullName}>"); + _Log.Warning($"*** DateTimeOriginal <{filteredItem.Property.DateTimeOriginal.Value}>"); + _Log.Warning($"*** LastWriteTime <{filteredItem.Property.LastWriteTime}>"); _Log.Warning($"*** TotalHours <{timeSpan.TotalHours}>"); } } @@ -561,41 +567,41 @@ public class PropertyLogic destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName}"); if (destinationDirectory == sourceDirectory) continue; - lock (propertyHolder) - propertyHolder.SetMoved(true); + lock (filteredItem) + filteredItem.SetMoved(true); if (!result) result = true; if (!Directory.Exists(destinationDirectory)) _ = Directory.CreateDirectory(destinationDirectory); - destinationFile = Path.Combine(destinationDirectory, propertyHolder.ImageFileHolder.Name); + destinationFile = Path.Combine(destinationDirectory, filteredItem.ImageFileHolder.Name); if (File.Exists(destinationFile)) { if (destinationFile.EndsWith(".jpg", ignoreCase: true, CultureInfo.CurrentCulture)) - destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(propertyHolder.ImageFileHolder.Name, ".jpeg")); + destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(filteredItem.ImageFileHolder.Name, ".jpeg")); else if (destinationFile.EndsWith(".jpeg", ignoreCase: true, CultureInfo.CurrentCulture)) - destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(propertyHolder.ImageFileHolder.Name, ".jpg")); + destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(filteredItem.ImageFileHolder.Name, ".jpg")); } if (File.Exists(destinationFile)) { - _Log.Information($"*** source <{propertyHolder.ImageFileHolder.FullName}>"); + _Log.Information($"*** source <{filteredItem.ImageFileHolder.FullName}>"); _Log.Information($"*** destination <{destinationFile}>"); - if (propertyHolder.ImageFileHolder.Exists) + if (filteredItem.ImageFileHolder.Exists) { - deleteFile = Path.ChangeExtension(propertyHolder.ImageFileHolder.FullName, ".delete"); + deleteFile = Path.ChangeExtension(filteredItem.ImageFileHolder.FullName, ".delete"); if (File.Exists(deleteFile)) File.Delete(deleteFile); - File.Move(propertyHolder.ImageFileHolder.FullName, deleteFile); + File.Move(filteredItem.ImageFileHolder.FullName, deleteFile); } } else { - File.Move(propertyHolder.ImageFileHolder.FullName, destinationFile); - if (propertyHolder.ImageFileHolder.Exists) + File.Move(filteredItem.ImageFileHolder.FullName, destinationFile); + if (filteredItem.ImageFileHolder.Exists) { - deleteFile = Path.ChangeExtension(propertyHolder.ImageFileHolder.FullName, ".delete"); + deleteFile = Path.ChangeExtension(filteredItem.ImageFileHolder.FullName, ".delete"); if (File.Exists(deleteFile)) File.Delete(deleteFile); - File.Move(propertyHolder.ImageFileHolder.FullName, deleteFile); + File.Move(filteredItem.ImageFileHolder.FullName, deleteFile); } } } @@ -608,46 +614,42 @@ public class PropertyLogic return result; } - private void ParallelForWork(bool firstPass, string angleBracket, string sourceDirectory, List> filteredSourceDirectoryFileTuples, List> sourceDirectoryChanges, PropertyHolder propertyHolder) + private void ParallelForWork(bool firstPass, string sourceDirectory, List> filteredSourceDirectoryFileTuples, List> sourceDirectoryChanges, Item item) { - if (propertyHolder.ImageFileHolder is null) - throw new ArgumentNullException(nameof(propertyHolder.ImageFileHolder)); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); A_Property property; List parseExceptions = new(); - string extensionLowered = propertyHolder.ImageFileHolder.Extension.ToLower(); - bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(extensionLowered); - bool isValidImageFormatExtension = _Configuration.ValidImageFormatExtensions.Contains(extensionLowered); - lock (propertyHolder) - propertyHolder.SetValidImageFormatExtension(isValidImageFormatExtension); - bool isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(extensionLowered); - string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{propertyHolder.ImageFileNameWithoutExtension}{extensionLowered}"); - if (isValidImageFormatExtension && propertyHolder.ImageFileHolder.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && propertyHolder.ImageFileHolder.FullName != filteredSourceDirectoryFileExtensionLowered) - File.Move(propertyHolder.ImageFileHolder.FullName, filteredSourceDirectoryFileExtensionLowered); - if (propertyHolder.Changed is null || propertyHolder.Changed.Value || propertyHolder.Property is null) + bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered); + bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered); + string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}"); + if (item.ValidImageFormatExtension && item.ImageFileHolder.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && item.ImageFileHolder.FullName != filteredSourceDirectoryFileExtensionLowered) + File.Move(item.ImageFileHolder.FullName, filteredSourceDirectoryFileExtensionLowered); + if (item.Changed is null || item.Changed.Value || item.Property is null) { - property = GetPropertyOfPrivate(angleBracket, propertyHolder, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, extensionLowered); + property = GetPropertyOfPrivate(item, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions); lock (sourceDirectoryChanges) sourceDirectoryChanges.Add(new Tuple(nameof(A_Property), DateTime.Now)); - lock (propertyHolder) - propertyHolder.Update(property); + lock (item) + item.Update(property); } } - private void ParallelWork(bool firstPass, List exceptions, List> sourceDirectoryChanges, int propertyHolderCollectionsCount, int g, string sourceDirectory, int r, PropertyHolder[] filteredPropertyHolderCollection, int totalSeconds, string angleBracket) + private void ParallelWork(bool firstPass, List exceptions, List> sourceDirectoryChanges, int containersCount, Container container, Item[] filteredItems, int totalSeconds) { List> filteredSourceDirectoryFileTuples = new(); ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; - string message = $"{r + 1:000}.{g} / {propertyHolderCollectionsCount:000}) {filteredPropertyHolderCollection.Length:000} file(s) - {totalSeconds} total second(s) - {sourceDirectory}"; - using ProgressBar progressBar = new(filteredPropertyHolderCollection.Length, message, options); - _ = Parallel.For(0, filteredPropertyHolderCollection.Length, parallelOptions, i => + string message = $"{container.R + 1: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 => { try { long ticks = DateTime.Now.Ticks; DateTime dateTime = DateTime.Now; List> collection; - ParallelForWork(firstPass, angleBracket, sourceDirectory, sourceDirectoryChanges, filteredSourceDirectoryFileTuples, filteredPropertyHolderCollection[i]); + ParallelForWork(firstPass, container.SourceDirectory, sourceDirectoryChanges, filteredSourceDirectoryFileTuples, filteredItems[i]); if (i == 0 || sourceDirectoryChanges.Any()) progressBar.Tick(); lock (filteredSourceDirectoryFileTuples) @@ -663,13 +665,12 @@ public class PropertyLogic }); } - private string SetAngleBracketCollectionAndGetZero(Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory) + private void SetAngleBracketCollection(string sourceDirectory) { - string result; AngleBracketCollection.Clear(); - AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(configuration, - model, - predictorModel, + AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(_Configuration, + _Model, + _PredictorModel, sourceDirectory, nameof(A_Property), string.Empty, @@ -679,54 +680,45 @@ public class PropertyLogic contentDescription: string.Empty, singletonDescription: "Properties for each image", collectionDescription: string.Empty)); - result = AngleBracketCollection[0]; - return result; } - public void ParallelWork(Configuration configuration, Model? model, PredictorModel? predictorModel, long ticks, List propertyHolderCollections, bool firstPass) + public void ParallelWork(long ticks, List containers, bool firstPass) { if (_Log is null) - throw new ArgumentNullException(nameof(_Log)); + throw new NullReferenceException(nameof(_Log)); if (_Configuration.PopulatePropertyId is null) - throw new ArgumentNullException(nameof(_Configuration.PopulatePropertyId)); - int g; - int r; + throw new NullReferenceException(nameof(_Configuration.PopulatePropertyId)); int totalSeconds; bool? anyFilesMoved; - string angleBracket; - string sourceDirectory; + Item[] filteredItems; List exceptions = new(); - PropertyHolder[] filteredPropertyHolderCollection; + int containersCount = containers.Count; List> sourceDirectoryChanges = new(); - int propertyHolderCollectionsCount = propertyHolderCollections.Count; - string propertyRoot = IResult.GetResultsGroupDirectory(configuration, nameof(A_Property)); - foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections) + string propertyRoot = IResult.GetResultsGroupDirectory(_Configuration, nameof(A_Property)); + foreach (Container container in containers) { - if (!propertyHolderCollection.Any()) + if (!container.Items.Any()) continue; sourceDirectoryChanges.Clear(); if (firstPass) - filteredPropertyHolderCollection = (from l in propertyHolderCollection where l.NoJson is null || !l.NoJson.Value && (l.Changed is null || l.Changed.Value) select l).ToArray(); + filteredItems = (from l in container.Items where l.NoJson is null || !l.NoJson.Value && (l.Changed is null || l.Changed.Value) select l).ToArray(); else - filteredPropertyHolderCollection = (from l in propertyHolderCollection where l.ImageFileHolder is not null && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.Extension) select l).ToArray(); - if (!filteredPropertyHolderCollection.Any()) + filteredItems = (from l in container.Items where l.ImageFileHolder is not null && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray(); + if (!filteredItems.Any()) continue; - g = filteredPropertyHolderCollection[0].G; - r = filteredPropertyHolderCollection[0].R; - sourceDirectory = filteredPropertyHolderCollection[0].SourceDirectory; totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); - angleBracket = SetAngleBracketCollectionAndGetZero(configuration, model, predictorModel, sourceDirectory); - ParallelWork(firstPass, exceptions, sourceDirectoryChanges, propertyHolderCollectionsCount, g, sourceDirectory, r, filteredPropertyHolderCollection, totalSeconds, angleBracket); + SetAngleBracketCollection(container.SourceDirectory); + ParallelWork(firstPass, exceptions, sourceDirectoryChanges, containersCount, container, filteredItems, totalSeconds); foreach (Exception exception in exceptions) - _Log.Error(string.Concat(sourceDirectory, Environment.NewLine, exception.Message, Environment.NewLine, exception.StackTrace), exception); - if (exceptions.Count == filteredPropertyHolderCollection.Length) - throw new Exception(string.Concat("All in [", sourceDirectory, "]failed!")); + _Log.Error(string.Concat(container.SourceDirectory, Environment.NewLine, exception.Message, Environment.NewLine, exception.StackTrace), exception); + if (exceptions.Count == filteredItems.Length) + throw new Exception(string.Concat("All in [", container.SourceDirectory, "]failed!")); if (exceptions.Count != 0) - _ExceptionsDirectories.Add(sourceDirectory); + _ExceptionsDirectories.Add(container.SourceDirectory); if (!firstPass || exceptions.Count != 0) anyFilesMoved = null; else - anyFilesMoved = AnyFilesMoved(sourceDirectory, filteredPropertyHolderCollection); + anyFilesMoved = AnyFilesMoved(container.SourceDirectory, filteredItems); if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any()) { for (int y = 0; y < int.MaxValue; y++) @@ -740,32 +732,30 @@ public class PropertyLogic } } - public A_Property GetProperty(string angleBracket, PropertyHolder propertyHolder, List> filteredSourceDirectoryFileTuples, List parseExceptions) + public A_Property GetProperty(Item item, List> filteredSourceDirectoryFileTuples, List parseExceptions) { A_Property result; - if (propertyHolder.ImageFileHolder is null) - throw new ArgumentException($"{propertyHolder.ImageFileHolder} is null!"); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); bool firstPass = false; - string extensionLowered = propertyHolder.ImageFileHolder.Extension.ToLower(); - bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(extensionLowered); - bool isValidImageFormatExtension = _Configuration.ValidImageFormatExtensions.Contains(extensionLowered); - bool isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(extensionLowered); - result = GetPropertyOfPrivate(angleBracket, propertyHolder, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, extensionLowered); + bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered); + bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered); + result = GetPropertyOfPrivate(item, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions); return result; } - public (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] GetPropertyIds(Configuration configuration, Model? model, PredictorModel? predictorModel, List groupCollection, bool saveToCollection) + public (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] GetPropertyIds(List groupCollection, bool saveToCollection) { List<(long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)> results = new(); int level; - string angleBracket; A_Property? property; string checkDirectory; List directories; string propertyDirectory; + string angleBracket = AngleBracketCollection[0]; foreach (DirectoryInfo group in groupCollection) { - angleBracket = SetAngleBracketCollectionAndGetZero(configuration, model, predictorModel, group.SourceDirectory); + SetAngleBracketCollection(group.SourceDirectory); if (string.IsNullOrEmpty(group.SourceDirectory)) throw new Exception(); if (!saveToCollection) @@ -789,23 +779,23 @@ public class PropertyLogic return results.OrderBy(l => l.Ticks).ToArray(); } - public void AddToPropertyLogicAllCollection(PropertyHolder[] filteredPropertyHolderCollection) + public void AddToPropertyLogicAllCollection(Item[] filteredItems) { if (_SixCharacterNamedFaceInfo.Any()) { string[] keys; - PropertyHolder propertyHolder; - for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) + Item item; + for (int i = 0; i < filteredItems.Length; i++) { - propertyHolder = filteredPropertyHolderCollection[i]; - if (propertyHolder.Property?.Id is null) + item = filteredItems[i]; + if (item.Property?.Id is null) continue; - foreach (int sixCharacterIndex in propertyHolder.Property.Indices) + foreach (int sixCharacterIndex in item.Property.Indices) { if (!_SixCharacterNamedFaceInfo.ContainsKey(sixCharacterIndex)) continue; keys = _SixCharacterNamedFaceInfo[sixCharacterIndex]; - _AllCollection.Add(new(propertyHolder.Property.Id.Value, keys)); + _AllCollection.Add(new(item.Property.Id.Value, keys)); } } } @@ -818,7 +808,7 @@ public class PropertyLogic string[] keys; string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.RootDirectory); if (string.IsNullOrEmpty(rootDirectoryParent)) - throw new ArgumentNullException(nameof(rootDirectoryParent)); + throw new NullReferenceException(nameof(rootDirectoryParent)); Dictionary namedFaceInfoDeterministicHashCodeIndices = new(); List<(int, string[])> allCollection = _AllCollection.OrderBy(l => l.Item1).ToList(); foreach ((int deterministicHashCode, string[] values) in allCollection) diff --git a/Property/Models/Stateless/A_Property.cs b/Property/Models/Stateless/A_Property.cs index 2485395..15bfe64 100644 --- a/Property/Models/Stateless/A_Property.cs +++ b/Property/Models/Stateless/A_Property.cs @@ -1,6 +1,3 @@ -using System.Text.Json; -using View_by_Distance.Shared.Models.Stateless; - namespace View_by_Distance.Property.Models.Stateless; public static class A_Property @@ -21,237 +18,14 @@ public static class A_Property return result; } - public static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetGroupCollection(string rootDirectory, string searchPattern, List topDirectories, int maxImagesInDirectoryForTopLevelFirstPass = 50, bool reverse = false) + public static List Get(Models.Configuration configuration, PropertyLogic propertyLogic) { - List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results = new(); - string? parentDirectory; - string[] subDirectories; - string[] sourceDirectoryFiles; - List fileCollections = new(); - if (!topDirectories.Any()) - topDirectories.AddRange(from l in Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly) select Path.GetFullPath(l)); - for (int g = 1; g < 5; g++) - { - if (g == 4) - { - for (int i = fileCollections.Count - 1; i > -1; i--) - { - parentDirectory = Path.GetDirectoryName(fileCollections[i][0]); - if (string.IsNullOrEmpty(parentDirectory)) - continue; - results.Add(new(g, parentDirectory, fileCollections[i], results.Count)); - fileCollections.RemoveAt(i); - } - } - else if (g == 2) - { - fileCollections = (from l in fileCollections orderby l.Length descending select l).ToList(); - for (int i = fileCollections.Count - 1; i > -1; i--) - { - if (fileCollections[i].Length > maxImagesInDirectoryForTopLevelFirstPass * g) - break; - parentDirectory = Path.GetDirectoryName(fileCollections[i][0]); - if (string.IsNullOrEmpty(parentDirectory)) - continue; - results.Add(new(g, parentDirectory, fileCollections[i], results.Count)); - fileCollections.RemoveAt(i); - } - } - else if (g == 3) - { - subDirectories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories); - if (reverse) - subDirectories = subDirectories.Reverse().ToArray(); - foreach (string subDirectory in subDirectories) - { - sourceDirectoryFiles = Directory.GetFiles(subDirectory, "*", SearchOption.TopDirectoryOnly); - if (!topDirectories.Contains(subDirectory)) - results.Add(new(g, subDirectory, sourceDirectoryFiles, results.Count)); - } - } - else if (g == 1) - { - sourceDirectoryFiles = Directory.GetFiles(rootDirectory, searchPattern, SearchOption.TopDirectoryOnly); - if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass) - fileCollections.Add(sourceDirectoryFiles); - else - results.Add(new(g, rootDirectory, sourceDirectoryFiles, results.Count)); - if (reverse) - topDirectories.Reverse(); - subDirectories = topDirectories.ToArray(); - foreach (string subDirectory in subDirectories) - { - sourceDirectoryFiles = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly); - if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass) - fileCollections.Add(sourceDirectoryFiles); - else - { - if (sourceDirectoryFiles.Any() || Directory.GetDirectories(subDirectory, "*", SearchOption.TopDirectoryOnly).Any()) - results.Add(new(g, subDirectory, sourceDirectoryFiles, results.Count)); - else if (searchPattern == "*") - { - sourceDirectoryFiles = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly); - foreach (string subFile in sourceDirectoryFiles) - File.Delete(subFile); - Directory.Delete(subDirectory); - } - } - } - fileCollections.Reverse(); - } - else - throw new Exception(); - } - return results; - } - - public static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetJsonGroupCollection(string rootDirectory) - { - List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results; - bool reverse = false; - string searchPattern = "*.json"; - List topDirectories = new(); - int maxImagesInDirectoryForTopLevelFirstPass = 50; - results = GetGroupCollection(rootDirectory, searchPattern, topDirectories, maxImagesInDirectoryForTopLevelFirstPass, reverse); - return results; - } - - public static List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> GetFileHolderGroupCollection(Models.Configuration configuration, bool reverse, string searchPattern, List topDirectories) - { - if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null) - throw new ArgumentNullException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass)); - List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> results = new(); - List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)>? collection = GetGroupCollection(configuration.RootDirectory, searchPattern, topDirectories, configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value, reverse); - foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in collection) - results.Add(new(g, sourceDirectory, (from l in sourceDirectoryFiles select new FileHolder(l)).ToArray(), r)); - return results; - } - - private static List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Models.A_Property? property)> collection, int r)> GetCollection(string rootDirectory, List<(int g, string sourceDirectory, string[] SourceDirectoryFiles, int r)> jsonCollection) - { - List<(int, string, List<(string, Models.A_Property?)>, int)> results = new(); - int length = rootDirectory.Length; - ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = Environment.ProcessorCount }; - _ = Parallel.For(0, jsonCollection.Count, parallelOptions, i => ParallelFor(jsonCollection, i, length, results)); - return results; - } - - private static List Populate(Models.Configuration configuration, string aPropertySingletonDirectory, List<(int, string, FileHolder[], int)> fileHolderGroupCollection, List<(int, string, List<(string, Models.A_Property?)>, int)> collectionFromJson) - { - List results = new(); - if (configuration.PropertiesChangedForProperty is null) - throw new Exception($"{configuration.PropertiesChangedForProperty} is null"); - int length; - string inferred; - string relativePath; - FileHolder keyFileHolder; - string keySourceDirectory; - List propertyHolderCollection; - Dictionary fileHolderKeyValuePairs = new(); - length = configuration.RootDirectory.Length; - foreach ((int g, string sourceDirectory, FileHolder[] sourceDirectoryFileHolderCollection, int r) in fileHolderGroupCollection) - { - foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection) - { - relativePath = $"{XPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length)}.json"; - fileHolderKeyValuePairs.Add(relativePath, new(sourceDirectory, sourceDirectoryFileHolder)); - } - } - length = aPropertySingletonDirectory.Length; - foreach ((int g, string _, List<(string, Models.A_Property?)> collection, int r) in collectionFromJson) - { - if (!collection.Any()) - continue; - propertyHolderCollection = new(); - foreach ((string sourceDirectoryFile, Models.A_Property? property) in collection) - { - relativePath = XPath.GetRelativePath(sourceDirectoryFile, length); - if (!fileHolderKeyValuePairs.ContainsKey(relativePath)) - { - inferred = string.Concat(configuration.RootDirectory, relativePath); - keyFileHolder = new(inferred[..^5]); - if (keyFileHolder.Extension is ".json") - continue; - keySourceDirectory = string.Concat(keyFileHolder.DirectoryName); - propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileHolder, property, true, null, null, null)); - } - else - { - keyFileHolder = fileHolderKeyValuePairs[relativePath].FileHolder; - keySourceDirectory = fileHolderKeyValuePairs[relativePath].SourceDirectory; - if (!fileHolderKeyValuePairs.Remove(relativePath)) - throw new Exception(); - if (keyFileHolder.Extension is ".json") - continue; - if (property?.Id is null || property?.Width is null || property?.Height is null) - propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileHolder, property, false, null, null, null)); - else if (configuration.PropertiesChangedForProperty.Value || property.LastWriteTime != keyFileHolder.LastWriteTime || property.FileSize != keyFileHolder.Length) - propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileHolder, property, false, true, null, null)); - else - propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileHolder, property, false, false, null, null)); - } - } - if (propertyHolderCollection.Any()) - results.Add(propertyHolderCollection.ToArray()); - } - length = configuration.RootDirectory.Length; - foreach ((int g, string sourceDirectory, FileHolder[] sourceDirectoryFileHolderCollection, int r) in fileHolderGroupCollection) - { - propertyHolderCollection = new(); - foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection) - { - relativePath = $"{XPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length)}.json"; - if (!fileHolderKeyValuePairs.ContainsKey(relativePath)) - continue; - if (!fileHolderKeyValuePairs.Remove(relativePath)) - throw new Exception(); - if (sourceDirectoryFileHolder.Extension is ".json") - continue; - propertyHolderCollection.Add(new(g, sourceDirectory, relativePath, sourceDirectoryFileHolder.FullName, r, sourceDirectoryFileHolder, null, null, null, null, null)); - } - if (propertyHolderCollection.Any()) - results.Add(propertyHolderCollection.ToArray()); - } - if (fileHolderKeyValuePairs.Any()) - throw new Exception(); - results = (from l in results orderby l[0].G, l[0].R select l).ToList(); - return results; - } - - private static void ParallelFor(List<(int, string, string[], int)> jsonCollection, int i, int length, List<(int, string, List<(string, Models.A_Property?)>, int)> results) - { - string key; - string json; - Models.A_Property? property; - (int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) = jsonCollection[i]; - List<(string, Models.A_Property?)> collection = new(); - foreach (string sourceDirectoryFile in sourceDirectoryFiles) - { - json = File.ReadAllText(sourceDirectoryFile); - key = XPath.GetRelativePath(sourceDirectoryFile, length); - property = JsonSerializer.Deserialize(json); - collection.Add(new(sourceDirectoryFile, property)); - } - lock (results) - results.Add(new(g, sourceDirectory, collection, r)); - } - - public static List Get(Models.Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic) - { - List results; - string searchPattern = "*"; + List results; long ticks = DateTime.Now.Ticks; - List topDirectories = new(); - List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> jsonCollection; - List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> fileHolderGroupCollection; - string aPropertySingletonDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}"); - List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Models.A_Property? property)> collection, int r)> collectionFromJson; - jsonCollection = GetJsonGroupCollection(aPropertySingletonDirectory); - fileHolderGroupCollection = GetFileHolderGroupCollection(configuration, reverse, searchPattern, topDirectories); - collectionFromJson = GetCollection(aPropertySingletonDirectory, jsonCollection); - results = Populate(configuration, aPropertySingletonDirectory, fileHolderGroupCollection, collectionFromJson); - propertyLogic.ParallelWork(configuration, model, predictorModel, ticks, results, firstPass: false); - if (propertyLogic.ExceptionsDirectories.Any()) + List exceptionsDirectories = new(); + results = Container.GetContainers(configuration, propertyLogic); + propertyLogic.ParallelWork(ticks, results, firstPass: false); + if (exceptionsDirectories.Any()) throw new Exception(); return results; } @@ -413,15 +187,19 @@ public static class A_Property return result; } - public static TimeSpan GetThreeStandardDeviationHigh(int minimum, PropertyHolder[] propertyHolderCollection) + public static TimeSpan GetThreeStandardDeviationHigh(int minimum, Models.Container container) { TimeSpan result; + DateTime? minimumDateTime; List ticksCollection = new(); - foreach (PropertyHolder propertyHolder in propertyHolderCollection) + foreach (Item item in container.Items) { - if (propertyHolder.Property is null || propertyHolder.MinimumDateTime is null) + if (item.Property is null) continue; - ticksCollection.Add(propertyHolder.MinimumDateTime.Value.Ticks); + minimumDateTime = GetMinimumDateTime(item.Property); + if (minimumDateTime is null) + continue; + ticksCollection.Add(minimumDateTime.Value.Ticks); } long threeStandardDeviationHigh; long min; @@ -443,35 +221,42 @@ public static class A_Property return result; } - public static (int, List, List) Get(PropertyHolder[] propertyHolderCollection, TimeSpan threeStandardDeviationHigh, int i) + public static (int, List, List) Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i) { - List results = new(); + List results = new(); int j = i; + Item item; long? ticks; + Item nextItem; TimeSpan timeSpan; - PropertyHolder propertyHolder; + DateTime? minimumDateTime; + DateTime? nextMinimumDateTime; List dateTimes = new(); - PropertyHolder nextPropertyHolder; - for (; j < propertyHolderCollection.Length; j++) + for (; j < container.Items.Count; j++) { ticks = null; - propertyHolder = propertyHolderCollection[j]; - if (propertyHolder.Property is null || propertyHolder.MinimumDateTime is null) + item = container.Items[j]; + if (item.Property is null) continue; - for (int k = j + 1; k < propertyHolderCollection.Length; k++) + minimumDateTime = GetMinimumDateTime(item.Property); + if (minimumDateTime is null) + continue; + for (int k = j + 1; k < container.Items.Count; k++) { - nextPropertyHolder = propertyHolderCollection[k]; - if (nextPropertyHolder.Property is not null && nextPropertyHolder.MinimumDateTime is not null) - { - ticks = nextPropertyHolder.MinimumDateTime.Value.Ticks; - break; - } + nextItem = container.Items[k]; + if (nextItem.Property is null) + continue; + nextMinimumDateTime = GetMinimumDateTime(nextItem.Property); + if (nextMinimumDateTime is null) + continue; + ticks = nextMinimumDateTime.Value.Ticks; + break; } - results.Add(propertyHolder); - dateTimes.Add(propertyHolder.MinimumDateTime.Value); + results.Add(item); + dateTimes.Add(minimumDateTime.Value); if (ticks.HasValue) { - timeSpan = new(ticks.Value - propertyHolder.MinimumDateTime.Value.Ticks); + timeSpan = new(ticks.Value - minimumDateTime.Value.Ticks); if (timeSpan > threeStandardDeviationHigh) break; } @@ -479,14 +264,14 @@ public static class A_Property return new(j, dateTimes, results); } - public static bool Any(List propertyHolderCollections) + public static bool Any(List propertyHolderCollections) { bool result = false; - foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections) + foreach (Models.Container container in propertyHolderCollections) { - if (!propertyHolderCollection.Any()) + if (!container.Items.Any()) continue; - if ((from l in propertyHolderCollection where l.Any() select true).Any()) + if ((from l in container.Items where l.Any() select true).Any()) { result = true; break; diff --git a/Property/Models/Stateless/Container.cs b/Property/Models/Stateless/Container.cs new file mode 100644 index 0000000..8cb82ea --- /dev/null +++ b/Property/Models/Stateless/Container.cs @@ -0,0 +1,267 @@ +using System.Text.Json; + +namespace View_by_Distance.Property.Models.Stateless; + +public class Container +{ + + public static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetGroupCollection(string rootDirectory, int maxImagesInDirectoryForTopLevelFirstPass, bool reverse, string searchPattern, List topDirectories) + { + List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results = new(); + string? parentDirectory; + string[] subDirectories; + string[] sourceDirectoryFiles; + List fileCollections = new(); + if (!topDirectories.Any()) + topDirectories.AddRange(from l in Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly) select Path.GetFullPath(l)); + for (int g = 1; g < 5; g++) + { + if (g == 4) + { + for (int i = fileCollections.Count - 1; i > -1; i--) + { + parentDirectory = Path.GetDirectoryName(fileCollections[i][0]); + if (string.IsNullOrEmpty(parentDirectory)) + continue; + results.Add(new(g, parentDirectory, fileCollections[i], results.Count)); + fileCollections.RemoveAt(i); + } + } + else if (g == 2) + { + fileCollections = (from l in fileCollections orderby l.Length descending select l).ToList(); + for (int i = fileCollections.Count - 1; i > -1; i--) + { + if (fileCollections[i].Length > maxImagesInDirectoryForTopLevelFirstPass * g) + break; + parentDirectory = Path.GetDirectoryName(fileCollections[i][0]); + if (string.IsNullOrEmpty(parentDirectory)) + continue; + results.Add(new(g, parentDirectory, fileCollections[i], results.Count)); + fileCollections.RemoveAt(i); + } + } + else if (g == 3) + { + subDirectories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories); + if (reverse) + subDirectories = subDirectories.Reverse().ToArray(); + foreach (string subDirectory in subDirectories) + { + sourceDirectoryFiles = Directory.GetFiles(subDirectory, "*", SearchOption.TopDirectoryOnly); + if (!topDirectories.Contains(subDirectory)) + results.Add(new(g, subDirectory, sourceDirectoryFiles, results.Count)); + } + } + else if (g == 1) + { + sourceDirectoryFiles = Directory.GetFiles(rootDirectory, searchPattern, SearchOption.TopDirectoryOnly); + if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass) + fileCollections.Add(sourceDirectoryFiles); + else + results.Add(new(g, rootDirectory, sourceDirectoryFiles, results.Count)); + if (reverse) + topDirectories.Reverse(); + subDirectories = topDirectories.ToArray(); + foreach (string subDirectory in subDirectories) + { + sourceDirectoryFiles = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly); + if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass) + fileCollections.Add(sourceDirectoryFiles); + else + { + if (sourceDirectoryFiles.Any() || Directory.GetDirectories(subDirectory, "*", SearchOption.TopDirectoryOnly).Any()) + results.Add(new(g, subDirectory, sourceDirectoryFiles, results.Count)); + else if (searchPattern == "*") + { + sourceDirectoryFiles = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly); + foreach (string subFile in sourceDirectoryFiles) + File.Delete(subFile); + Directory.Delete(subDirectory); + } + } + } + fileCollections.Reverse(); + } + else + throw new Exception(); + } + return results; + } + + public static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetGroupCollection(string rootDirectory, string searchPattern, List topDirectories) + { + List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results; + int maxImagesInDirectoryForTopLevelFirstPass = 50; + bool reverse = false; + results = GetGroupCollection(rootDirectory, maxImagesInDirectoryForTopLevelFirstPass, reverse, searchPattern, topDirectories); + return results; + } + + private static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetJsonGroupCollection(Models.Configuration configuration, PropertyLogic propertyLogic, string rootDirectory) + { + List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results; + if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null) + throw new NullReferenceException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass)); + string searchPattern = "*.json"; + List topDirectories = new(); + results = GetGroupCollection(rootDirectory, configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value, propertyLogic.Reverse, searchPattern, topDirectories); + return results; + } + + private static List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> GetFileHolderGroupCollection(Models.Configuration configuration, PropertyLogic propertyLogic, string searchPattern, List topDirectories) + { + List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> results = new(); + if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null) + throw new NullReferenceException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass)); + List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)>? collection = GetGroupCollection(configuration.RootDirectory, configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value, propertyLogic.Reverse, searchPattern, topDirectories); + foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in collection) + results.Add(new(g, sourceDirectory, (from l in sourceDirectoryFiles select new FileHolder(l)).ToArray(), r)); + return results; + } + + private static void ParallelFor(List<(int, string, string[], int)> jsonCollection, int i, int length, List<(int, string, List<(string, Models.A_Property?)>, int)> results) + { + string key; + string json; + Models.A_Property? property; + (int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) = jsonCollection[i]; + List<(string, Models.A_Property?)> collection = new(); + foreach (string sourceDirectoryFile in sourceDirectoryFiles) + { + json = File.ReadAllText(sourceDirectoryFile); + key = XPath.GetRelativePath(sourceDirectoryFile, length); + property = JsonSerializer.Deserialize(json); + collection.Add(new(sourceDirectoryFile, property)); + } + lock (results) + results.Add(new(g, sourceDirectory, collection, r)); + } + + private static List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Models.A_Property? property)> collection, int r)> GetCollection(string rootDirectory, List<(int g, string sourceDirectory, string[] SourceDirectoryFiles, int r)> jsonCollection) + { + List<(int, string, List<(string, Models.A_Property?)>, int)> results = new(); + int length = rootDirectory.Length; + ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = Environment.ProcessorCount }; + _ = Parallel.For(0, jsonCollection.Count, parallelOptions, i => ParallelFor(jsonCollection, i, length, results)); + return results; + } + + private static List GetContainers(Models.Configuration configuration, string aPropertySingletonDirectory, List<(int, string, FileHolder[], int)> fileHolderGroupCollection, List<(int, string, List<(string, Models.A_Property?)>, int)> collectionFromJson) + { + List results = new(); + if (configuration.PropertiesChangedForProperty is null) + throw new Exception($"{configuration.PropertiesChangedForProperty} is null"); + int length; + string key; + string inferred; + List items; + string relativePath; + FileHolder keyFileHolder; + Models.Container container; + bool isValidImageFormatExtension; + List keySourceDirectories; + Dictionary fileHolderKeyValuePairs = new(); + length = configuration.RootDirectory.Length; + foreach ((int g, string sourceDirectory, FileHolder[] sourceDirectoryFileHolderCollection, int r) in fileHolderGroupCollection) + { + foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection) + { + relativePath = XPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length); + key = string.Concat(relativePath, ".json"); + fileHolderKeyValuePairs.Add(key, new(sourceDirectory, sourceDirectoryFileHolder)); + } + } + length = aPropertySingletonDirectory.Length; + foreach ((int g, string _, List<(string, Models.A_Property?)> collection, int r) in collectionFromJson) + { + if (!collection.Any()) + continue; + items = new(); + keySourceDirectories = new(); + foreach ((string sourceDirectoryFile, Models.A_Property? property) in collection) + { + key = XPath.GetRelativePath(sourceDirectoryFile, length); + relativePath = key[..^5]; + if (!fileHolderKeyValuePairs.ContainsKey(key)) + { + inferred = string.Concat(configuration.RootDirectory, relativePath); + keyFileHolder = new(inferred); + if (keyFileHolder.ExtensionLowered is ".json") + continue; + keySourceDirectories.Add(string.Concat(keyFileHolder.DirectoryName)); + isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered); + items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, true, null)); + } + else + { + keyFileHolder = fileHolderKeyValuePairs[key].FileHolder; + keySourceDirectories.Add(fileHolderKeyValuePairs[key].SourceDirectory); + if (!fileHolderKeyValuePairs.Remove(key)) + throw new Exception(); + if (keyFileHolder.ExtensionLowered is ".json") + continue; + isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered); + if (property?.Id is null || property?.Width is null || property?.Height is null) + items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, null)); + else if (configuration.PropertiesChangedForProperty.Value || property.LastWriteTime != keyFileHolder.LastWriteTime || property.FileSize != keyFileHolder.Length) + items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, true)); + else + items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, false)); + } + } + if (items.Any()) + { + if (keySourceDirectories.Distinct().Count() != 1) + continue; + container = new(g, r, items, keySourceDirectories[0]); + results.Add(container); + } + } + length = configuration.RootDirectory.Length; + foreach ((int g, string sourceDirectory, FileHolder[] sourceDirectoryFileHolderCollection, int r) in fileHolderGroupCollection) + { + items = new(); + foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection) + { + relativePath = XPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length); + key = string.Concat(relativePath, ".json"); + if (!fileHolderKeyValuePairs.ContainsKey(key)) + continue; + if (!fileHolderKeyValuePairs.Remove(key)) + throw new Exception(); + if (sourceDirectoryFileHolder.ExtensionLowered is ".json") + continue; + isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(sourceDirectoryFileHolder.ExtensionLowered); + items.Add(new(relativePath, sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder, isValidImageFormatExtension, null, null, null)); + } + if (items.Any()) + { + container = new(g, r, items, sourceDirectory); + results.Add(container); + } + } + if (fileHolderKeyValuePairs.Any()) + throw new Exception(); + results = (from l in results orderby l.G, l.R select l).ToList(); + return results; + } + + public static List GetContainers(Models.Configuration configuration, PropertyLogic propertyLogic) + { + List results; + string searchPattern = "*"; + long ticks = DateTime.Now.Ticks; + List topDirectories = new(); + List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> jsonCollection; + List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> fileHolderGroupCollection; + string aPropertySingletonDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}"); + List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Models.A_Property? property)> collection, int r)> collectionFromJson; + jsonCollection = GetJsonGroupCollection(configuration, propertyLogic, aPropertySingletonDirectory); + fileHolderGroupCollection = GetFileHolderGroupCollection(configuration, propertyLogic, searchPattern, topDirectories); + collectionFromJson = GetCollection(aPropertySingletonDirectory, jsonCollection); + results = GetContainers(configuration, aPropertySingletonDirectory, fileHolderGroupCollection, collectionFromJson); + return results; + } + +} \ No newline at end of file diff --git a/Property/Models/Stateless/Path.cs b/Property/Models/Stateless/Path.cs index 5048328..08fffb3 100644 --- a/Property/Models/Stateless/Path.cs +++ b/Property/Models/Stateless/Path.cs @@ -92,7 +92,7 @@ internal class XPath string? pathRoot = Path.GetPathRoot(directory); string extension = Path.GetExtension(directory); if (string.IsNullOrEmpty(pathRoot)) - throw new ArgumentNullException(nameof(pathRoot)); + throw new NullReferenceException(nameof(pathRoot)); if (Directory.Exists(directory)) results.Add(Path.GetFileName(directory)); else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory)) diff --git a/Resize/Models/_C_Resize.cs b/Resize/Models/_C_Resize.cs index 0b40979..d6e711f 100644 --- a/Resize/Models/_C_Resize.cs +++ b/Resize/Models/_C_Resize.cs @@ -284,29 +284,29 @@ public class C_Resize return results; } - public byte[] GetResizedBytes(string outputResolution, List> subFileTuples, PropertyHolder propertyHolder, A_Property property, Dictionary imageResizes) + public byte[] GetResizedBytes(string outputResolution, List> subFileTuples, Item item, A_Property property, Dictionary imageResizes) { byte[] results; - if (propertyHolder.ImageFileHolder is null) - throw new Exception($"{propertyHolder.ImageFileHolder} is null!"); + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); if (!imageResizes.ContainsKey(outputResolution)) throw new Exception(); int[] resize = imageResizes[outputResolution]; int outputResolutionWidth = resize[_OutputResolutionWidthIndex]; int outputResolutionHeight = resize[_OutputResolutionHeightIndex]; int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex]; - results = SaveResizedSubfile(propertyHolder.ImageFileHolder.FullName, property, resize, fileHolder: null); + results = SaveResizedSubfile(item.ImageFileHolder.FullName, property, resize, fileHolder: null); subFileTuples.Add(new Tuple(nameof(C_Resize), DateTime.Now)); return results; } - public void SaveResizedSubfile(string outputResolution, List> subFileTuples, PropertyHolder propertyHolder, string original, A_Property property, Dictionary imageResizes) + public void SaveResizedSubfile(string outputResolution, List> subFileTuples, Item item, string original, A_Property property, Dictionary imageResizes) { - if (propertyHolder.ImageFileHolder is null) - throw new Exception($"{propertyHolder.ImageFileHolder} is null!"); - if (propertyHolder.ResizedFileHolder is null) - throw new Exception($"{propertyHolder.ResizedFileHolder} is null!"); - FileHolder fileHolder = propertyHolder.ResizedFileHolder; + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); + if (item.ResizedFileHolder is null) + throw new NullReferenceException(nameof(item.ResizedFileHolder)); + FileHolder fileHolder = item.ResizedFileHolder; if (!imageResizes.ContainsKey(outputResolution)) throw new Exception(); if (!fileHolder.Exists) @@ -318,7 +318,7 @@ public class C_Resize if (File.Exists(parentCheck)) { File.Move(parentCheck, fileInfo.FullName); - propertyHolder.SetResizedFileHolder(FileHolder.Refresh(fileHolder)); + item.SetResizedFileHolder(FileHolder.Refresh(fileHolder)); } } int[] resize = imageResizes[outputResolution]; @@ -330,7 +330,7 @@ public class C_Resize { if (!fileHolder.Exists) { - File.Copy(propertyHolder.ImageFileHolder.FullName, fileHolder.FullName); + File.Copy(item.ImageFileHolder.FullName, fileHolder.FullName); subFileTuples.Add(new Tuple(nameof(C_Resize), DateTime.Now)); } } @@ -347,7 +347,7 @@ public class C_Resize check = true; if (check) { - _ = SaveResizedSubfile(propertyHolder.ImageFileHolder.FullName, property, resize, fileHolder); + _ = SaveResizedSubfile(item.ImageFileHolder.FullName, property, resize, fileHolder); subFileTuples.Add(new Tuple(nameof(C_Resize), DateTime.Now)); } } @@ -422,13 +422,15 @@ public class C_Resize return results; } - public Dictionary GetResizeKeyValuePairs(List> subFileTuples, List parseExceptions, string original, List> metadataCollection, A_Property property, PropertyHolder propertyHolder) + public Dictionary GetResizeKeyValuePairs(List> subFileTuples, List parseExceptions, string original, List> metadataCollection, A_Property property, Item item) { Dictionary results; + if (item.ImageFileHolder is null) + throw new NullReferenceException(nameof(item.ImageFileHolder)); 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(propertyHolder.ImageFileNameWithoutExtension, ".json"))); + FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "{}"), string.Concat(item.ImageFileHolder.NameWithoutExtension, ".json"))); if (!fileInfo.Exists) { if (fileInfo.Directory?.Parent is null) diff --git a/Shared/Models/Stateless/Methods/Person.cs b/Shared/Models/Stateless/Methods/Person.cs index c8f9b3c..d661bb4 100644 --- a/Shared/Models/Stateless/Methods/Person.cs +++ b/Shared/Models/Stateless/Methods/Person.cs @@ -189,7 +189,7 @@ internal abstract class Person _ = Directory.CreateDirectory(directory); string? rootDirectoryParent = Path.GetDirectoryName(storage.RootDirectory); if (string.IsNullOrEmpty(rootDirectoryParent)) - throw new ArgumentNullException(nameof(rootDirectoryParent)); + throw new NullReferenceException(nameof(rootDirectoryParent)); if (!Directory.Exists(rootDirectoryParent)) localKnownPeopleFile = string.Empty; else diff --git a/Shared/Phares/Shared/RijndaelEncryption.cs b/Shared/Phares/Shared/RijndaelEncryption.cs index 1a9a074..bcfc898 100644 --- a/Shared/Phares/Shared/RijndaelEncryption.cs +++ b/Shared/Phares/Shared/RijndaelEncryption.cs @@ -25,7 +25,7 @@ public static class RijndaelEncryption { string result; if (string.IsNullOrEmpty(text)) - throw new ArgumentNullException(nameof(text)); + throw new NullReferenceException(nameof(text)); RijndaelManaged aesAlg = NewRijndaelManaged(salt); ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); MemoryStream msEncrypt = new(); @@ -58,7 +58,7 @@ public static class RijndaelEncryption public static string Decrypt(string cipherText, string salt) { if (string.IsNullOrEmpty(cipherText)) - throw new ArgumentNullException(nameof(cipherText)); + throw new NullReferenceException(nameof(cipherText)); if (!IsBase64String(cipherText)) throw new Exception("The cipherText input parameter is not base64 encoded"); string text; @@ -82,7 +82,7 @@ public static class RijndaelEncryption private static RijndaelManaged NewRijndaelManaged(string salt) { if (salt == null) - throw new ArgumentNullException(nameof(salt)); + throw new NullReferenceException(nameof(salt)); byte[] saltBytes = Encoding.ASCII.GetBytes(salt); Rfc2898DeriveBytes key = new(_Inputkey, saltBytes); RijndaelManaged aesAlg = new(); diff --git a/Tests/UnitTestResize.cs b/Tests/UnitTestResize.cs index 8ed4589..304021f 100644 --- a/Tests/UnitTestResize.cs +++ b/Tests/UnitTestResize.cs @@ -72,14 +72,14 @@ public class UnitTestResize Assert.IsFalse(_PropertyConfiguration is null); } - private Property.Models.PropertyLogic GetPropertyLogic() + private Property.Models.PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel) { Property.Models.PropertyLogic result; if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); - result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); + result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel); return result; } @@ -91,31 +91,31 @@ public class UnitTestResize string sourceFileName = "Fall 2005 (113).jpg"; string sourceDirectoryName = "=2005.3 Fall"; if (_Configuration.ForceMetadataLastWriteTimeToCreationTime is null) - throw new ArgumentNullException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime)); + throw new NullReferenceException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime)); if (_Configuration.ForceResizeLastWriteTimeToCreationTime is null) - throw new ArgumentNullException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime)); + throw new NullReferenceException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime)); if (_Configuration.OutputQuality is null) - throw new ArgumentNullException(nameof(_Configuration.OutputQuality)); + throw new NullReferenceException(nameof(_Configuration.OutputQuality)); if (_Configuration.OverrideForResizeImages is null) - throw new ArgumentNullException(nameof(_Configuration.OverrideForResizeImages)); + throw new NullReferenceException(nameof(_Configuration.OverrideForResizeImages)); if (_Configuration.PropertiesChangedForMetadata is null) - throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata)); + throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForMetadata)); if (_Configuration.PropertiesChangedForResize is null) - throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize)); - int g = 1; - int r = 1; + throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForResize)); Model? model = null; + bool reverse = false; + Property.Models.Item item; string original = "Original"; List parseExceptions = new(); + PredictorModel? predictorModel = null; + bool isValidImageFormatExtension = true; Property.Models.A_Property? property = null; - Property.Models.PropertyHolder propertyHolder; Dictionary imageResizeKeyValuePairs; List> subFileTuples = new(); - PredictorModel? predictorModel = null; List> metadataCollection; int length = _PropertyConfiguration.RootDirectory.Length; string outputResolution = _Configuration.OutputResolutions[0]; - Property.Models.PropertyLogic propertyLogic = GetPropertyLogic(); + Property.Models.PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel); string sourceDirectory = Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName); string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_PropertyConfiguration, nameof(Property.Models.A_Property), "{}"); B_Metadata metadata = new(_Configuration.ForceMetadataLastWriteTimeToCreationTime.Value, _Configuration.PropertiesChangedForMetadata.Value); @@ -161,15 +161,15 @@ public class UnitTestResize Property.Models.FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName)); string relativePath = Property.Models.Stateless.IPath.GetRelativePath(fileHolder.FullName, length); sourceDirectory = Path.Combine(aPropertySingletonDirectory, sourceDirectoryName); - propertyHolder = new(g, sourceDirectory, sourceDirectoryFile, relativePath, r, fileHolder, property, false, false, null, null); - Assert.IsNotNull(propertyHolder.ImageFileHolder); - property = propertyLogic.GetProperty(propertyLogic.AngleBracketCollection[0], propertyHolder, subFileTuples, parseExceptions); - (int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, propertyHolder); - imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, propertyHolder); - Property.Models.FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(propertyHolder.ImageFileHolder.FullName))); - propertyHolder.SetResizedFileHolder(resizedFileHolder); - resize.SaveResizedSubfile(outputResolution, subFileTuples, propertyHolder, original, property, imageResizeKeyValuePairs); - propertyHolder.SetResizedFileHolder(Property.Models.FileHolder.Refresh(resizedFileHolder)); + item = new(sourceDirectoryFile, relativePath, fileHolder, isValidImageFormatExtension, property, false, false); + Assert.IsNotNull(item.ImageFileHolder); + property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions); + (int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, item); + imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, item); + Property.Models.FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName))); + item.SetResizedFileHolder(resizedFileHolder); + resize.SaveResizedSubfile(outputResolution, subFileTuples, item, original, property, imageResizeKeyValuePairs); + item.SetResizedFileHolder(Property.Models.FileHolder.Refresh(resizedFileHolder)); } } \ No newline at end of file diff --git a/TestsWithFaceRecognitionDotNet/UnitTestFace.cs b/TestsWithFaceRecognitionDotNet/UnitTestFace.cs index 056f860..8891fa4 100644 --- a/TestsWithFaceRecognitionDotNet/UnitTestFace.cs +++ b/TestsWithFaceRecognitionDotNet/UnitTestFace.cs @@ -74,14 +74,14 @@ public class UnitTestFace Assert.IsFalse(_PropertyConfiguration is null); } - private Property.Models.PropertyLogic GetPropertyLogic() + private Property.Models.PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel) { Property.Models.PropertyLogic result; if (_AppSettings.MaxDegreeOfParallelism is null) - throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); + throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration?.PropertyConfiguration is null) - throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); - result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); + throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); + result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel); return result; } @@ -150,34 +150,34 @@ public class UnitTestFace // string sourceFileName = "Logan Michael Sept 08 (193).jpg"; // string sourceDirectoryName = "=2008.2 Summer Logan Michael"; if (_Configuration.ForceMetadataLastWriteTimeToCreationTime is null) - throw new ArgumentNullException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime)); + throw new NullReferenceException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime)); if (_Configuration.ForceResizeLastWriteTimeToCreationTime is null) - throw new ArgumentNullException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime)); + throw new NullReferenceException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime)); if (_Configuration.OutputQuality is null) - throw new ArgumentNullException(nameof(_Configuration.OutputQuality)); + throw new NullReferenceException(nameof(_Configuration.OutputQuality)); if (_Configuration.OverrideForResizeImages is null) - throw new ArgumentNullException(nameof(_Configuration.OverrideForResizeImages)); + throw new NullReferenceException(nameof(_Configuration.OverrideForResizeImages)); if (_Configuration.PropertiesChangedForMetadata is null) - throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata)); + throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForMetadata)); if (_Configuration.PropertiesChangedForResize is null) - throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize)); + throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForResize)); if (_Configuration.NumberOfJitters is null) - throw new ArgumentNullException(nameof(_Configuration.NumberOfJitters)); + throw new NullReferenceException(nameof(_Configuration.NumberOfJitters)); if (_Configuration.NumberOfTimesToUpsample is null) - throw new ArgumentNullException(nameof(_Configuration.NumberOfTimesToUpsample)); - int g = 1; - int r = 1; + throw new NullReferenceException(nameof(_Configuration.NumberOfTimesToUpsample)); + bool reverse = false; + Property.Models.Item item; string original = "Original"; List parseExceptions = new(); + bool isValidImageFormatExtension = true; Property.Models.A_Property? property = null; - Property.Models.PropertyHolder propertyHolder; Dictionary imageResizeKeyValuePairs; List> subFileTuples = new(); List> metadataCollection; int length = _PropertyConfiguration.RootDirectory.Length; string outputResolution = _Configuration.OutputResolutions[0]; - Property.Models.PropertyLogic propertyLogic = GetPropertyLogic(); (Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(_Configuration); + Property.Models.PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel); string sourceDirectory = Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName); _Logger.Information(_Configuration.ModelDirectory); string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_PropertyConfiguration, nameof(Property.Models.A_Property), "{}"); @@ -224,17 +224,17 @@ public class UnitTestFace Property.Models.FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName)); string relativePath = Property.Models.Stateless.IPath.GetRelativePath(fileHolder.FullName, length); sourceDirectory = Path.Combine(aPropertySingletonDirectory, sourceDirectoryName); - propertyHolder = new(g, sourceDirectory, sourceDirectoryFile, relativePath, r, fileHolder, property, false, false, null, null); - Assert.IsNotNull(propertyHolder.ImageFileHolder); - property = propertyLogic.GetProperty(propertyLogic.AngleBracketCollection[0], propertyHolder, subFileTuples, parseExceptions); - (int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, propertyHolder); - imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, propertyHolder); - Property.Models.FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(propertyHolder.ImageFileHolder.FullName))); - propertyHolder.SetResizedFileHolder(resizedFileHolder); - resize.SaveResizedSubfile(outputResolution, subFileTuples, propertyHolder, original, property, imageResizeKeyValuePairs); - propertyHolder.SetResizedFileHolder(Property.Models.FileHolder.Refresh(resizedFileHolder)); - Assert.IsNotNull(propertyHolder.ResizedFileHolder); - Image? image = FaceRecognition.LoadImageFile(propertyHolder.ResizedFileHolder.FullName); + item = new(sourceDirectoryFile, relativePath, fileHolder, isValidImageFormatExtension, property, false, false); + Assert.IsNotNull(item.ImageFileHolder); + property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions); + (int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, item); + imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, item); + Property.Models.FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName))); + item.SetResizedFileHolder(resizedFileHolder); + resize.SaveResizedSubfile(outputResolution, subFileTuples, item, original, property, imageResizeKeyValuePairs); + item.SetResizedFileHolder(Property.Models.FileHolder.Refresh(resizedFileHolder)); + Assert.IsNotNull(item.ResizedFileHolder); + Image? image = FaceRecognition.LoadImageFile(item.ResizedFileHolder.FullName); Assert.IsNotNull(image); FaceRecognition faceRecognition = FaceRecognition.Create(modelParameter); List locations = faceRecognition.FaceLocations(model, image, _Configuration.NumberOfTimesToUpsample.Value, sortByPixelPercentage: true);