NullReferenceException

This commit is contained in:
Mike Phares 2022-08-13 11:19:08 -07:00
parent 3aeab88384
commit 0392de1920
33 changed files with 1278 additions and 1030 deletions

View File

@ -35,7 +35,7 @@ public class Compare
string[] segments; string[] segments;
_AppSettings = appSettings; _AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null) if (appSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism));
_RenameFindReplace = new(); _RenameFindReplace = new();
_RenameBFindReplace = new(); _RenameBFindReplace = new();
_RenameCFindReplace = new(); _RenameCFindReplace = new();
@ -55,8 +55,9 @@ public class Compare
bool reverse = false; bool reverse = false;
Model? model = null; Model? model = null;
PredictorModel? predictorModel = null; PredictorModel? predictorModel = null;
PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel);
if (propertyConfiguration.PopulatePropertyId is null) if (propertyConfiguration.PopulatePropertyId is null)
throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId)); throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId));
foreach (string spelling in configuration.Spelling) foreach (string spelling in configuration.Spelling)
{ {
segments = spelling.Split('|'); segments = spelling.Split('|');
@ -104,10 +105,10 @@ public class Compare
throw new Exception("Change configuration!"); throw new Exception("Change configuration!");
_RenameCFindReplace.Add(new(renameFrom, renameTo)); _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) 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(Property.Models.Stateless.A_Property.GetGroupCollection)} has finished"); _Log.Information($"{nameof(Property.Models.Stateless.Container.GetGroupCollection)} has finished");
_Configuration = configuration; _Configuration = configuration;
List<string> missingVerifyToSeasonCollection = GetMissingVerifyToSeasonCollection(topDirectories, groupCollection); List<string> missingVerifyToSeasonCollection = GetMissingVerifyToSeasonCollection(topDirectories, groupCollection);
if (missingVerifyToSeasonCollection.Any()) if (missingVerifyToSeasonCollection.Any())
@ -116,36 +117,36 @@ public class Compare
{ {
topDirectories.Clear(); topDirectories.Clear();
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); _ = 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) 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"); _Log.Information($"{nameof(PossiblyRename)} has finished");
if (PossiblyRenameB(topDirectories, groupCollection)) if (PossiblyRenameB(topDirectories, groupCollection))
{ {
topDirectories.Clear(); topDirectories.Clear();
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); _ = 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) 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"); _Log.Information($"{nameof(PossiblyRenameB)} has finished");
if (PossiblyRenameC(topDirectories, groupCollection)) if (PossiblyRenameC(topDirectories, groupCollection))
{ {
topDirectories.Clear(); topDirectories.Clear();
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); _ = 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) 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"); _Log.Information($"{nameof(PossiblyRenameC)} has finished");
if (PossiblyCorrect(topDirectories, groupCollection)) if (PossiblyCorrect(topDirectories, groupCollection))
{ {
topDirectories.Clear(); topDirectories.Clear();
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); _ = 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) 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"); _Log.Information($"{nameof(PossiblyCorrect)} has finished");
string[] dbFiles = Directory.GetFiles(propertyConfiguration.RootDirectory, "*.db", SearchOption.AllDirectories); string[] dbFiles = Directory.GetFiles(propertyConfiguration.RootDirectory, "*.db", SearchOption.AllDirectories);
@ -156,14 +157,13 @@ public class Compare
{ {
topDirectories.Clear(); topDirectories.Clear();
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); _ = 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) 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()) if (_IsEnvironment.Development && propertyConfiguration.PopulatePropertyId.Value && !propertyLogic.KeyValuePairs.Any())
throw new Exception("Copy keyValuePairs-####.json file"); throw new Exception("Copy keyValuePairs-####.json file");
List<PropertyHolder[]> propertyHolderCollections = Property.Models.Stateless.A_Property.Get(propertyConfiguration, reverse, model, predictorModel, propertyLogic); List<Container> containers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic);
if (!isSilent) if (!isSilent)
{ {
_Log.Information("First pass completed"); _Log.Information("First pass completed");
@ -205,7 +205,7 @@ public class Compare
_Log.Information(". . ."); _Log.Information(". . .");
} }
string aPropertyContentCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A_Property), "[()]"); 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) if (!isSilent)
{ {
_Log.Information("Third pass completed"); _Log.Information("Third pass completed");
@ -217,7 +217,7 @@ public class Compare
} }
_Log.Information(". . ."); _Log.Information(". . .");
} }
FourthPassCreateWindowsShortcuts(propertyConfiguration, model, predictorModel, propertyLogic, propertyHolderCollections, saveToCollection: false, keepAll: false); FourthPassCreateWindowsShortcuts(propertyConfiguration, model, predictorModel, propertyLogic, containers, saveToCollection: false, keepAll: false);
if (!isSilent) if (!isSilent)
{ {
_Log.Information("Fourth pass completed"); _Log.Information("Fourth pass completed");
@ -372,28 +372,28 @@ public class Compare
private static void Verify(Models.Configuration configuration) private static void Verify(Models.Configuration configuration)
{ {
if (configuration.Spelling is null || !configuration.Spelling.Any()) 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) private long LogDelta(long ticks, string methodName)
{ {
long result; long result;
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks; result = DateTime.Now.Ticks;
return result; return result;
} }
private PropertyLogic GetPropertyLogic() private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel)
{ {
PropertyLogic result; PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
string fromPrepareForOld = "34720-637858334555170379.tsv"; string fromPrepareForOld = "34720-637858334555170379.tsv";
string fromPrepareForOldFile = Path.Combine(_Configuration.PropertyConfiguration.RootDirectory, fromPrepareForOld); string fromPrepareForOldFile = Path.Combine(_Configuration.PropertyConfiguration.RootDirectory, fromPrepareForOld);
if (File.Exists(fromPrepareForOldFile)) if (File.Exists(fromPrepareForOldFile))
@ -432,11 +432,11 @@ public class Compare
private void SaveDiffFilesOrSaveLogAndMoveFiles(Property.Models.Configuration configuration) private void SaveDiffFilesOrSaveLogAndMoveFiles(Property.Models.Configuration configuration)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) 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), "{}"); string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
_Log.Information(aPropertySingletonDirectory); _Log.Information(aPropertySingletonDirectory);
_Log.Information("to"); _Log.Information("to");
@ -510,14 +510,14 @@ public class Compare
private void ChangeExtensionFromDeleteToJson(string aPropertySingletonDirectory) private void ChangeExtensionFromDeleteToJson(string aPropertySingletonDirectory)
{ {
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
string searchPattern = "*.delete"; string searchPattern = "*.delete";
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
List<string> topDirectories = new(); List<string> topDirectories = new();
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection; 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) 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) foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in groupCollection)
{ {
if (!topDirectories.Any()) if (!topDirectories.Any())
@ -647,7 +647,7 @@ public class Compare
private bool PossiblyCorrect(List<string> topDirectories, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection) private bool PossiblyCorrect(List<string> topDirectories, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection)
{ {
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
bool result = false; bool result = false;
string corrected; string corrected;
string correctedMoveTo; string correctedMoveTo;
@ -695,7 +695,7 @@ public class Compare
private List<string> GetMissingVerifyToSeasonCollection(List<string> _, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection) private List<string> GetMissingVerifyToSeasonCollection(List<string> _, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection)
{ {
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
List<string> results = new(); List<string> results = new();
string check; string check;
foreach ((int _, string sourceDirectory, string[] _, int _) in groupCollection) 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) private void CreateWindowsShortcuts((long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] collection, bool keepAll)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
int z = 0; int z = 0;
string fileName; string fileName;
WindowsShortcut windowsShortcut; WindowsShortcut windowsShortcut;
@ -750,12 +750,12 @@ public class Compare
} }
} }
private void ThirdPassToMove(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List<PropertyHolder[]> propertyHolderCollections, string aPropertyContentCollectionDirectory) private void ThirdPassToMove(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List<Container> containers, string aPropertyContentCollectionDirectory)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
int stay = 0; int stay = 0;
string fileName; string fileName;
string id = " - Id"; string id = " - Id";
@ -769,7 +769,7 @@ public class Compare
List<string> distinctDirectories = new(); List<string> distinctDirectories = new();
List<KeyValuePair<int, int[]>> valueCollection = new(); List<KeyValuePair<int, int[]>> valueCollection = new();
List<Property.Models.DirectoryInfo> directoryInfoCollection = new(); List<Property.Models.DirectoryInfo> directoryInfoCollection = new();
propertyLogic.ParallelWork(configuration, model, predictorModel, ticks, propertyHolderCollections, firstPass: false); propertyLogic.ParallelWork(ticks, containers, firstPass: false);
if (propertyLogic.ExceptionsDirectories.Any()) if (propertyLogic.ExceptionsDirectories.Any())
throw new Exception(); throw new Exception();
foreach (Property.Models.DirectoryInfo group in directoryInfoCollection) 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<PropertyHolder[]> propertyHolderCollections, bool saveToCollection, bool keepAll) private void FourthPassCreateWindowsShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List<Container> containers, bool saveToCollection, bool keepAll)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
int stay = 0; int stay = 0;
A_Property? property; A_Property? property;
ConsoleKey? consoleKey = null; ConsoleKey? consoleKey = null;
@ -841,7 +841,7 @@ public class Compare
List<KeyValuePair<int, int[]>> valueCollection = new(); List<KeyValuePair<int, int[]>> valueCollection = new();
(long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] collection; (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] collection;
List<Property.Models.DirectoryInfo> directoryInfoCollection = new(); List<Property.Models.DirectoryInfo> directoryInfoCollection = new();
propertyLogic.ParallelWork(configuration, model, predictorModel, ticks, propertyHolderCollections, firstPass: false); propertyLogic.ParallelWork(ticks, containers, firstPass: false);
if (propertyLogic.ExceptionsDirectories.Any()) if (propertyLogic.ExceptionsDirectories.Any())
throw new Exception(); throw new Exception();
foreach (Property.Models.DirectoryInfo group in directoryInfoCollection) foreach (Property.Models.DirectoryInfo group in directoryInfoCollection)
@ -859,7 +859,7 @@ public class Compare
fileMoveCollection.Add(filteredSourceDirectoryFile); 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"); _Log.Information($"{stay} file(s) are staying and {fileMoveCollection.Count} file(s) will be moved");
for (int x = 0; x < int.MaxValue; x++) for (int x = 0; x < int.MaxValue; x++)
{ {

View File

@ -31,7 +31,7 @@ public class DateGroup
{ } { }
_AppSettings = appSettings; _AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null) if (appSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism));
_IsEnvironment = isEnvironment; _IsEnvironment = isEnvironment;
_Exceptions = new List<string>(); _Exceptions = new List<string>();
_Log = Serilog.Log.ForContext<DateGroup>(); _Log = Serilog.Log.ForContext<DateGroup>();
@ -46,15 +46,15 @@ public class DateGroup
PredictorModel? predictorModel = null; PredictorModel? predictorModel = null;
_Configuration = configuration; _Configuration = configuration;
if (configuration.ByHash is null) if (configuration.ByHash is null)
throw new ArgumentNullException(nameof(configuration.ByHash)); throw new NullReferenceException(nameof(configuration.ByHash));
if (configuration.ByCreateDateShortcut is null) if (configuration.ByCreateDateShortcut is null)
throw new ArgumentNullException(nameof(configuration.ByCreateDateShortcut)); throw new NullReferenceException(nameof(configuration.ByCreateDateShortcut));
if (propertyConfiguration.PopulatePropertyId is null) if (propertyConfiguration.PopulatePropertyId is null)
throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId)); throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId));
if (!_IsEnvironment.Development) if (!_IsEnvironment.Development)
throw new Exception("This program only allows development environments!"); throw new Exception("This program only allows development environments!");
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
PropertyLogic propertyLogic = GetPropertyLogic(); PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel);
string[] dbFiles = Directory.GetFiles(propertyConfiguration.RootDirectory, "*.db", SearchOption.AllDirectories); string[] dbFiles = Directory.GetFiles(propertyConfiguration.RootDirectory, "*.db", SearchOption.AllDirectories);
foreach (string dbFile in dbFiles) foreach (string dbFile in dbFiles)
File.Delete(dbFile); File.Delete(dbFile);
@ -64,22 +64,22 @@ public class DateGroup
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
if (true || appSettings.MaxDegreeOfParallelism.Value < 2) if (true || appSettings.MaxDegreeOfParallelism.Value < 2)
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.IPath.DeleteEmptyDirectories)); ticks = LogDelta(ticks, nameof(Property.Models.Stateless.IPath.DeleteEmptyDirectories));
List<PropertyHolder[]> propertyHolderCollections = Property.Models.Stateless.A_Property.Get(propertyConfiguration, reverse, model, predictorModel, propertyLogic); List<Container> containers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic);
if (configuration.ByCreateDateShortcut.HasValue && configuration.ByCreateDateShortcut.Value) if (configuration.ByCreateDateShortcut.HasValue && configuration.ByCreateDateShortcut.Value)
CreateDateShortcut(propertyConfiguration, propertyHolderCollections); CreateDateShortcut(propertyConfiguration, containers);
else else
{ {
List<string> topDirectories = new(); List<string> topDirectories = new();
List<Property.Models.DirectoryInfo> directoryInfoCollection = new(); List<Property.Models.DirectoryInfo> directoryInfoCollection = new();
propertyLogic.ParallelWork(propertyConfiguration, model, predictorModel, ticks, propertyHolderCollections, firstPass: true); propertyLogic.ParallelWork(ticks, containers, firstPass: true);
if (appSettings.MaxDegreeOfParallelism.Value < 2) if (appSettings.MaxDegreeOfParallelism.Value < 2)
ticks = LogDelta(ticks, nameof(PropertyLogic.ParallelWork)); ticks = LogDelta(ticks, nameof(PropertyLogic.ParallelWork));
if (propertyLogic.ExceptionsDirectories.Any()) if (propertyLogic.ExceptionsDirectories.Any())
throw new Exception(); throw new Exception();
if (propertyConfiguration.PopulatePropertyId.Value && (configuration.ByCreateDateShortcut.Value || configuration.ByHash.Value)) if (propertyConfiguration.PopulatePropertyId.Value && (configuration.ByCreateDateShortcut.Value || configuration.ByHash.Value))
{ {
if (Property.Models.Stateless.A_Property.Any(propertyHolderCollections)) if (Property.Models.Stateless.A_Property.Any(containers))
propertyLogic.ParallelWork(propertyConfiguration, model, predictorModel, ticks, propertyHolderCollections, firstPass: false); propertyLogic.ParallelWork(ticks, containers, firstPass: false);
if (appSettings.MaxDegreeOfParallelism.Value < 2) if (appSettings.MaxDegreeOfParallelism.Value < 2)
ticks = LogDelta(ticks, nameof(PropertyLogic.ParallelWork)); ticks = LogDelta(ticks, nameof(PropertyLogic.ParallelWork));
if (propertyLogic.ExceptionsDirectories.Any()) if (propertyLogic.ExceptionsDirectories.Any())
@ -94,21 +94,21 @@ public class DateGroup
private static void Verify(Models.Configuration configuration) private static void Verify(Models.Configuration configuration)
{ {
if (configuration.ByCreateDateShortcut is null) if (configuration.ByCreateDateShortcut is null)
throw new ArgumentNullException(nameof(configuration.ByCreateDateShortcut)); throw new NullReferenceException(nameof(configuration.ByCreateDateShortcut));
if (configuration.ByDay is null) if (configuration.ByDay is null)
throw new ArgumentNullException(nameof(configuration.ByDay)); throw new NullReferenceException(nameof(configuration.ByDay));
if (configuration.ByHash is null) if (configuration.ByHash is null)
throw new ArgumentNullException(nameof(configuration.ByHash)); throw new NullReferenceException(nameof(configuration.ByHash));
if (configuration.BySeason is null) if (configuration.BySeason is null)
throw new ArgumentNullException(nameof(configuration.BySeason)); throw new NullReferenceException(nameof(configuration.BySeason));
if (configuration.ByWeek is null) 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) if (!configuration.ByCreateDateShortcut.Value && !configuration.ByDay.Value && !configuration.ByWeek.Value && !configuration.BySeason.Value && !configuration.ByHash.Value)
throw new Exception("Change configuration!"); throw new Exception("Change configuration!");
if (configuration.KeepFullPath is null) if (configuration.KeepFullPath is null)
throw new ArgumentNullException(nameof(configuration.KeepFullPath)); throw new NullReferenceException(nameof(configuration.KeepFullPath));
if (configuration?.PropertyConfiguration?.PopulatePropertyId is null) 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) if (configuration.PropertyConfiguration.PopulatePropertyId.Value && !configuration.ByCreateDateShortcut.Value && !configuration.ByHash.Value)
throw new Exception("Change configuration!"); throw new Exception("Change configuration!");
if (!configuration.PropertyConfiguration.PopulatePropertyId.Value && configuration.ByHash.Value) if (!configuration.PropertyConfiguration.PopulatePropertyId.Value && configuration.ByHash.Value)
@ -153,7 +153,7 @@ public class DateGroup
{ {
long result; long result;
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks; result = DateTime.Now.Ticks;
@ -164,17 +164,17 @@ public class DateGroup
{ {
List<(string Source, string[] Destination)> results = new(); List<(string Source, string[] Destination)> results = new();
if (_Configuration.ByCreateDateShortcut is null) if (_Configuration.ByCreateDateShortcut is null)
throw new ArgumentNullException(nameof(_Configuration.ByCreateDateShortcut)); throw new NullReferenceException(nameof(_Configuration.ByCreateDateShortcut));
if (_Configuration.ByDay is null) if (_Configuration.ByDay is null)
throw new ArgumentNullException(nameof(_Configuration.ByDay)); throw new NullReferenceException(nameof(_Configuration.ByDay));
if (_Configuration.ByHash is null) if (_Configuration.ByHash is null)
throw new ArgumentNullException(nameof(_Configuration.ByHash)); throw new NullReferenceException(nameof(_Configuration.ByHash));
if (_Configuration.BySeason is null) if (_Configuration.BySeason is null)
throw new ArgumentNullException(nameof(_Configuration.BySeason)); throw new NullReferenceException(nameof(_Configuration.BySeason));
if (_Configuration.ByWeek is null) if (_Configuration.ByWeek is null)
throw new ArgumentNullException(nameof(_Configuration.ByWeek)); throw new NullReferenceException(nameof(_Configuration.ByWeek));
if (_Configuration.KeepFullPath is null) if (_Configuration.KeepFullPath is null)
throw new ArgumentNullException(nameof(_Configuration.KeepFullPath)); throw new NullReferenceException(nameof(_Configuration.KeepFullPath));
char flag; char flag;
string day; string day;
int season; int season;
@ -319,7 +319,7 @@ public class DateGroup
if (!_Configuration.ByHash.Value || property.Id is null) if (!_Configuration.ByHash.Value || property.Id is null)
fileName = filteredSourceDirectoryFileHolder.Name; fileName = filteredSourceDirectoryFileHolder.Name;
else else
fileName = $"{property.Id.Value}{filteredSourceDirectoryFileHolder.Extension.ToLower()}"; fileName = $"{property.Id.Value}{filteredSourceDirectoryFileHolder.ExtensionLowered}";
destinationCollection.Add(destinationDirectory); destinationCollection.Add(destinationDirectory);
destinationCollection.AddRange(directoryNames); destinationCollection.AddRange(directoryNames);
destinationCollection.Add(fileName); destinationCollection.Add(fileName);
@ -328,14 +328,14 @@ public class DateGroup
return results; return results;
} }
private PropertyLogic GetPropertyLogic() private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel)
{ {
PropertyLogic result; PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
return result; return result;
} }
@ -343,9 +343,9 @@ public class DateGroup
{ {
List<(string Source, string[] Destination)> results = new(); List<(string Source, string[] Destination)> results = new();
if (_Configuration.KeepFullPath is null) if (_Configuration.KeepFullPath is null)
throw new ArgumentNullException(nameof(_Configuration.KeepFullPath)); throw new NullReferenceException(nameof(_Configuration.KeepFullPath));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
string? topDirectory; string? topDirectory;
string? checkDirectory; string? checkDirectory;
string sourceDirectory; string sourceDirectory;
@ -380,9 +380,9 @@ public class DateGroup
private void MoveFiles(List<string> topDirectories, List<Property.Models.DirectoryInfo> groupCollection) private void MoveFiles(List<string> topDirectories, List<Property.Models.DirectoryInfo> groupCollection)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
string directoryName; string directoryName;
List<string> distinct = new(); List<string> distinct = new();
List<(string Source, string[] Destination)> fileMoveCollectionAll = GetFileMoveCollectionAll(topDirectories, groupCollection); List<(string Source, string[] Destination)> fileMoveCollectionAll = GetFileMoveCollectionAll(topDirectories, groupCollection);
@ -434,44 +434,48 @@ public class DateGroup
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory); _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory);
} }
private static void CreateDateShortcut(Property.Models.Configuration configuration, List<PropertyHolder[]> propertyHolderCollections) private static void CreateDateShortcut(Property.Models.Configuration configuration, List<Container> containers)
{ {
string path; string path;
string fileName; string fileName;
string directory; string directory;
int selectedTotal; int selectedTotal;
const int minimum = 3; const int minimum = 3;
List<Item> selectedItems;
List<DateTime> dateTimes; List<DateTime> dateTimes;
DateTime? minimumDateTime;
const int maximumHours = 24; const int maximumHours = 24;
string? relativePathDirectory; string? relativePathDirectory;
WindowsShortcut windowsShortcut; WindowsShortcut windowsShortcut;
TimeSpan threeStandardDeviationHigh; TimeSpan threeStandardDeviationHigh;
List<PropertyHolder> selectedPropertyHolderCollection;
string aPropertyContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "()"); 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; continue;
selectedTotal = 0; selectedTotal = 0;
threeStandardDeviationHigh = Property.Models.Stateless.A_Property.GetThreeStandardDeviationHigh(minimum, propertyHolderCollection); threeStandardDeviationHigh = Property.Models.Stateless.A_Property.GetThreeStandardDeviationHigh(minimum, container);
if (threeStandardDeviationHigh.TotalHours > maximumHours) if (threeStandardDeviationHigh.TotalHours > maximumHours)
threeStandardDeviationHigh = new(maximumHours, 0, 0); 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); (i, dateTimes, selectedItems) = Property.Models.Stateless.A_Property.Get(container, threeStandardDeviationHigh, i);
selectedTotal += selectedPropertyHolderCollection.Count; selectedTotal += selectedItems.Count;
foreach (PropertyHolder propertyHolder in selectedPropertyHolderCollection) foreach (Item item in selectedItems)
{ {
if (propertyHolder.Property is null || propertyHolder.MinimumDateTime is null) if (item.Property is null)
continue; continue;
relativePathDirectory = Path.GetDirectoryName(propertyHolder.RelativePath); relativePathDirectory = Path.GetDirectoryName(item.RelativePath);
if (string.IsNullOrEmpty(relativePathDirectory)) if (string.IsNullOrEmpty(relativePathDirectory))
continue; 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}"); 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)) if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(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)) if (File.Exists(fileName))
continue; continue;
windowsShortcut = new() { Path = path }; windowsShortcut = new() { Path = path };
@ -479,10 +483,10 @@ public class DateGroup
windowsShortcut.Dispose(); windowsShortcut.Dispose();
if (!File.Exists(fileName)) if (!File.Exists(fileName))
continue; 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; continue;
} }
} }

View File

@ -120,9 +120,9 @@ internal sealed class SimpleObjectDetector
uint upsamplingAmount) uint upsamplingAmount)
{ {
if (detector == null) if (detector == null)
throw new ArgumentNullException(nameof(detector)); throw new NullReferenceException(nameof(detector));
if (image == null) if (image == null)
throw new ArgumentNullException(nameof(image)); throw new NullReferenceException(nameof(image));
detector.ThrowIfDisposed(); detector.ThrowIfDisposed();
image.ThrowIfDisposed(); image.ThrowIfDisposed();

View File

@ -24,15 +24,15 @@ public sealed class FaceEncoding : DisposableObject, ISerializable
private FaceEncoding(SerializationInfo info, StreamingContext context) private FaceEncoding(SerializationInfo info, StreamingContext context)
{ {
if (info == null) if (info == null)
throw new ArgumentNullException(nameof(info)); throw new NullReferenceException(nameof(info));
double[]? array = info.GetValue(nameof(_Encoding), typeof(double[])) as double[]; double[]? array = info.GetValue(nameof(_Encoding), typeof(double[])) as double[];
int? row = (int?)info.GetValue(nameof(_Encoding.Rows), typeof(int)); int? row = (int?)info.GetValue(nameof(_Encoding.Rows), typeof(int));
int? column = (int?)info.GetValue(nameof(_Encoding.Columns), typeof(int)); int? column = (int?)info.GetValue(nameof(_Encoding.Columns), typeof(int));
if (row is null) if (row is null)
throw new ArgumentNullException(nameof(row)); throw new NullReferenceException(nameof(row));
if (column is null) if (column is null)
throw new ArgumentNullException(nameof(column)); throw new NullReferenceException(nameof(column));
_Encoding = new Matrix<double>(array, row.Value, column.Value); _Encoding = new Matrix<double>(array, row.Value, column.Value);
} }

View File

@ -80,12 +80,12 @@ public sealed class FaceRecognition : DisposableObject
/// Initializes a new instance of the <see cref="FaceRecognition"/> class with the instance that contains model binary datum. /// Initializes a new instance of the <see cref="FaceRecognition"/> class with the instance that contains model binary datum.
/// </summary> /// </summary>
/// <param name="parameter">The instance that contains model binary datum.</param> /// <param name="parameter">The instance that contains model binary datum.</param>
/// <exception cref="ArgumentNullException"><paramref name="parameter"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="parameter"/> is null.</exception>
/// <exception cref="NullReferenceException">The model data is null.</exception> /// <exception cref="NullReferenceException">The model data is null.</exception>
private FaceRecognition(ModelParameter parameter) private FaceRecognition(ModelParameter parameter)
{ {
if (parameter == null) if (parameter == null)
throw new ArgumentNullException(nameof(parameter)); throw new NullReferenceException(nameof(parameter));
if (parameter.PosePredictor5FaceLandmarksModel == null) if (parameter.PosePredictor5FaceLandmarksModel == null)
throw new NullReferenceException(nameof(parameter.PosePredictor5FaceLandmarksModel)); throw new NullReferenceException(nameof(parameter.PosePredictor5FaceLandmarksModel));
@ -149,11 +149,11 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="numberOfTimesToUpsample">The number of image looking for faces. Higher numbers find smaller faces.</param> /// <param name="numberOfTimesToUpsample">The number of image looking for faces. Higher numbers find smaller faces.</param>
/// <param name="batchSize">The number of images to include in each GPU processing batch.</param> /// <param name="batchSize">The number of images to include in each GPU processing batch.</param>
/// <returns>An enumerable collection of array of found face locations.</returns> /// <returns>An enumerable collection of array of found face locations.</returns>
/// <exception cref="ArgumentNullException"><paramref name="images"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="images"/> is null.</exception>
public IEnumerable<Location[]> BatchFaceLocations(IEnumerable<Image> images, int numberOfTimesToUpsample, int batchSize = 128) public IEnumerable<Location[]> BatchFaceLocations(IEnumerable<Image> images, int numberOfTimesToUpsample, int batchSize = 128)
{ {
if (images == null) if (images == null)
throw new ArgumentNullException(nameof(images)); throw new NullReferenceException(nameof(images));
List<Location[]>? results = new(); List<Location[]>? results = new();
@ -183,14 +183,14 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="faceEncodingToCheck">A single face encoding to compare against a known face encoding.</param> /// <param name="faceEncodingToCheck">A single face encoding to compare against a known face encoding.</param>
/// <param name="tolerance">The distance between faces to consider it a match. Lower is more strict. The default value is 0.6.</param> /// <param name="tolerance">The distance between faces to consider it a match. Lower is more strict. The default value is 0.6.</param>
/// <returns>A True/False value indicating which known a face encoding matches the face encoding to check.</returns> /// <returns>A True/False value indicating which known a face encoding matches the face encoding to check.</returns>
/// <exception cref="ArgumentNullException"><paramref name="knownFaceEncoding"/> or <paramref name="faceEncodingToCheck"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="knownFaceEncoding"/> or <paramref name="faceEncodingToCheck"/> is null.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="knownFaceEncoding"/> or <paramref name="faceEncodingToCheck"/>.</exception> /// <exception cref="ObjectDisposedException"><paramref name="knownFaceEncoding"/> or <paramref name="faceEncodingToCheck"/>.</exception>
public static bool CompareFace(FaceEncoding knownFaceEncoding, FaceEncoding faceEncodingToCheck, double tolerance = 0.6d) public static bool CompareFace(FaceEncoding knownFaceEncoding, FaceEncoding faceEncodingToCheck, double tolerance = 0.6d)
{ {
if (knownFaceEncoding == null) if (knownFaceEncoding == null)
throw new ArgumentNullException(nameof(knownFaceEncoding)); throw new NullReferenceException(nameof(knownFaceEncoding));
if (faceEncodingToCheck == null) if (faceEncodingToCheck == null)
throw new ArgumentNullException(nameof(faceEncodingToCheck)); throw new NullReferenceException(nameof(faceEncodingToCheck));
knownFaceEncoding.ThrowIfDisposed(); knownFaceEncoding.ThrowIfDisposed();
faceEncodingToCheck.ThrowIfDisposed(); faceEncodingToCheck.ThrowIfDisposed();
@ -205,14 +205,14 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="faceEncodingToCheck">A single face encoding to compare against the enumerable collection.</param> /// <param name="faceEncodingToCheck">A single face encoding to compare against the enumerable collection.</param>
/// <param name="tolerance">The distance between faces to consider it a match. Lower is more strict. The default value is 0.6.</param> /// <param name="tolerance">The distance between faces to consider it a match. Lower is more strict. The default value is 0.6.</param>
/// <returns>An enumerable collection of True/False values indicating which known face encodings match the face encoding to check.</returns> /// <returns>An enumerable collection of True/False values indicating which known face encodings match the face encoding to check.</returns>
/// <exception cref="ArgumentNullException"><paramref name="knownFaceEncodings"/> or <paramref name="faceEncodingToCheck"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="knownFaceEncodings"/> or <paramref name="faceEncodingToCheck"/> is null.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="faceEncodingToCheck"/> is disposed. Or <paramref name="knownFaceEncodings"/> contains disposed object.</exception> /// <exception cref="ObjectDisposedException"><paramref name="faceEncodingToCheck"/> is disposed. Or <paramref name="knownFaceEncodings"/> contains disposed object.</exception>
public static IEnumerable<bool> CompareFaces(IEnumerable<FaceEncoding> knownFaceEncodings, FaceEncoding faceEncodingToCheck, double tolerance = 0.6d) public static IEnumerable<bool> CompareFaces(IEnumerable<FaceEncoding> knownFaceEncodings, FaceEncoding faceEncodingToCheck, double tolerance = 0.6d)
{ {
if (knownFaceEncodings == null) if (knownFaceEncodings == null)
throw new ArgumentNullException(nameof(knownFaceEncodings)); throw new NullReferenceException(nameof(knownFaceEncodings));
if (faceEncodingToCheck == null) if (faceEncodingToCheck == null)
throw new ArgumentNullException(nameof(faceEncodingToCheck)); throw new NullReferenceException(nameof(faceEncodingToCheck));
faceEncodingToCheck.ThrowIfDisposed(); faceEncodingToCheck.ThrowIfDisposed();
@ -242,7 +242,7 @@ public sealed class FaceRecognition : DisposableObject
/// Create a new instance of the <see cref="FaceRecognition"/> class. /// Create a new instance of the <see cref="FaceRecognition"/> class.
/// </summary> /// </summary>
/// <param name="parameter">The instance that contains model binary datum.</param> /// <param name="parameter">The instance that contains model binary datum.</param>
/// <exception cref="ArgumentNullException"><paramref name="parameter"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="parameter"/> is null.</exception>
/// <exception cref="NullReferenceException">The model data is null.</exception> /// <exception cref="NullReferenceException">The model data is null.</exception>
public static FaceRecognition Create(ModelParameter parameter) => new(parameter); public static FaceRecognition Create(ModelParameter parameter) => new(parameter);
@ -252,14 +252,14 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="image">The image contains a face.</param> /// <param name="image">The image contains a face.</param>
/// <param name="locations">The enumerable collection of location rectangle for faces.</param> /// <param name="locations">The enumerable collection of location rectangle for faces.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="ArgumentNullException"><paramref name="image"/> or <paramref name="locations"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="image"/> or <paramref name="locations"/> is null.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="image"/> is disposed.</exception> /// <exception cref="ObjectDisposedException"><paramref name="image"/> is disposed.</exception>
public static IEnumerable<Image> CropFaces(Image image, IEnumerable<Location> locations) public static IEnumerable<Image> CropFaces(Image image, IEnumerable<Location> locations)
{ {
if (image == null) if (image == null)
throw new ArgumentNullException(nameof(image)); throw new NullReferenceException(nameof(image));
if (locations == null) if (locations == null)
throw new ArgumentNullException(nameof(locations)); throw new NullReferenceException(nameof(locations));
image.ThrowIfDisposed(); image.ThrowIfDisposed();
@ -302,14 +302,14 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="faceEncoding">The face encoding to compare.</param> /// <param name="faceEncoding">The face encoding to compare.</param>
/// <param name="faceToCompare">The face encoding to compare against.</param> /// <param name="faceToCompare">The face encoding to compare against.</param>
/// <returns>The euclidean distance for comparison face. If 0, faces are completely equal.</returns> /// <returns>The euclidean distance for comparison face. If 0, faces are completely equal.</returns>
/// <exception cref="ArgumentNullException"><paramref name="faceEncoding"/> or <paramref name="faceToCompare"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="faceEncoding"/> or <paramref name="faceToCompare"/> is null.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="faceEncoding"/> or <paramref name="faceToCompare"/> is disposed.</exception> /// <exception cref="ObjectDisposedException"><paramref name="faceEncoding"/> or <paramref name="faceToCompare"/> is disposed.</exception>
public static double FaceDistance(FaceEncoding faceEncoding, FaceEncoding faceToCompare) public static double FaceDistance(FaceEncoding faceEncoding, FaceEncoding faceToCompare)
{ {
if (faceEncoding == null) if (faceEncoding == null)
throw new ArgumentNullException(nameof(faceEncoding)); throw new NullReferenceException(nameof(faceEncoding));
if (faceToCompare == null) if (faceToCompare == null)
throw new ArgumentNullException(nameof(faceToCompare)); throw new NullReferenceException(nameof(faceToCompare));
faceEncoding.ThrowIfDisposed(); faceEncoding.ThrowIfDisposed();
faceToCompare.ThrowIfDisposed(); faceToCompare.ThrowIfDisposed();
@ -327,14 +327,14 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="faceEncodings">The enumerable collection of face encoding to compare.</param> /// <param name="faceEncodings">The enumerable collection of face encoding to compare.</param>
/// <param name="faceToCompare">The face encoding to compare against.</param> /// <param name="faceToCompare">The face encoding to compare against.</param>
/// <returns>The enumerable collection of euclidean distance for comparison face. If 0, faces are completely equal.</returns> /// <returns>The enumerable collection of euclidean distance for comparison face. If 0, faces are completely equal.</returns>
/// <exception cref="ArgumentNullException"><paramref name="faceEncodings"/> or <paramref name="faceToCompare"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="faceEncodings"/> or <paramref name="faceToCompare"/> is null.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="faceToCompare"/> is disposed. Or <paramref name="faceEncodings"/> contains disposed object.</exception> /// <exception cref="ObjectDisposedException"><paramref name="faceToCompare"/> is disposed. Or <paramref name="faceEncodings"/> contains disposed object.</exception>
public static List<double> FaceDistances(IEnumerable<FaceEncoding> faceEncodings, FaceEncoding faceToCompare) public static List<double> FaceDistances(IEnumerable<FaceEncoding> faceEncodings, FaceEncoding faceToCompare)
{ {
if (faceEncodings == null) if (faceEncodings == null)
throw new ArgumentNullException(nameof(faceEncodings)); throw new NullReferenceException(nameof(faceEncodings));
if (faceToCompare == null) if (faceToCompare == null)
throw new ArgumentNullException(nameof(faceToCompare)); throw new NullReferenceException(nameof(faceToCompare));
faceToCompare.ThrowIfDisposed(); faceToCompare.ThrowIfDisposed();
@ -362,14 +362,14 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="predictorModel">The dimension of vector which be returned from detector.</param> /// <param name="predictorModel">The dimension of vector which be returned from detector.</param>
/// <param name="model">The model of face detector to detect in image. If <paramref name="knownFaceLocation"/> is not null, this value is ignored.</param> /// <param name="model">The model of face detector to detect in image. If <paramref name="knownFaceLocation"/> is not null, this value is ignored.</param>
/// <returns>An enumerable collection of face feature data corresponds to all faces in specified image.</returns> /// <returns>An enumerable collection of face feature data corresponds to all faces in specified image.</returns>
/// <exception cref="ArgumentNullException"><paramref name="image"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="image"/> is null.</exception>
/// <exception cref="InvalidOperationException"><paramref name="knownFaceLocation"/> contains no elements.</exception> /// <exception cref="InvalidOperationException"><paramref name="knownFaceLocation"/> contains no elements.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="image"/> or this object or custom face landmark detector is disposed.</exception> /// <exception cref="ObjectDisposedException"><paramref name="image"/> or this object or custom face landmark detector is disposed.</exception>
/// <exception cref="NotSupportedException"><see cref="PredictorModel.Custom"/> is not supported.</exception> /// <exception cref="NotSupportedException"><see cref="PredictorModel.Custom"/> is not supported.</exception>
public List<FaceEncoding> FaceEncodings(Image image, int numberOfTimesToUpsample, IEnumerable<Location>? knownFaceLocation, int numberOfJitters, PredictorModel predictorModel, Model model) public List<FaceEncoding> FaceEncodings(Image image, int numberOfTimesToUpsample, IEnumerable<Location>? knownFaceLocation, int numberOfJitters, PredictorModel predictorModel, Model model)
{ {
if (image == null) if (image == null)
throw new ArgumentNullException(nameof(image)); throw new NullReferenceException(nameof(image));
if (predictorModel == PredictorModel.Custom) if (predictorModel == PredictorModel.Custom)
throw new NotSupportedException("FaceRecognition.PredictorModel.Custom is not supported."); throw new NotSupportedException("FaceRecognition.PredictorModel.Custom is not supported.");
@ -408,7 +408,7 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="predictorModel">The dimension of vector which be returned from detector.</param> /// <param name="predictorModel">The dimension of vector which be returned from detector.</param>
/// <param name="model">The model of face detector to detect in image. If <paramref name="faceLocations"/> is not null, this value is ignored.</param> /// <param name="model">The model of face detector to detect in image. If <paramref name="faceLocations"/> is not null, this value is ignored.</param>
/// <returns>An enumerable collection of dictionary of face parts locations (eyes, nose, etc).</returns> /// <returns>An enumerable collection of dictionary of face parts locations (eyes, nose, etc).</returns>
/// <exception cref="ArgumentNullException"><paramref name="faceImage"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="faceImage"/> is null.</exception>
/// <exception cref="InvalidOperationException"><paramref name="faceLocations"/> contains no elements.</exception> /// <exception cref="InvalidOperationException"><paramref name="faceLocations"/> contains no elements.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="faceImage"/> or this object or custom face landmark detector is disposed.</exception> /// <exception cref="ObjectDisposedException"><paramref name="faceImage"/> or this object or custom face landmark detector is disposed.</exception>
/// <exception cref="NotSupportedException">The custom face landmark detector is not ready.</exception> /// <exception cref="NotSupportedException">The custom face landmark detector is not ready.</exception>
@ -416,7 +416,7 @@ public sealed class FaceRecognition : DisposableObject
{ {
List<(FacePart, FacePoint[])[]> results = new(); List<(FacePart, FacePoint[])[]> results = new();
if (faceImage == null) if (faceImage == null)
throw new ArgumentNullException(nameof(faceImage)); throw new NullReferenceException(nameof(faceImage));
if (faceLocations != null && !faceLocations.Any()) if (faceLocations != null && !faceLocations.Any())
throw new InvalidOperationException($"{nameof(faceLocations)} contains no elements."); throw new InvalidOperationException($"{nameof(faceLocations)} contains no elements.");
faceImage.ThrowIfDisposed(); faceImage.ThrowIfDisposed();
@ -469,12 +469,12 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="numberOfTimesToUpsample">The number of times to up-sample the image when finding faces.</param> /// <param name="numberOfTimesToUpsample">The number of times to up-sample the image when finding faces.</param>
/// <param name="model">The model of face detector to detect in image.</param> /// <param name="model">The model of face detector to detect in image.</param>
/// <returns>An enumerable collection of face location correspond to all faces in specified image.</returns> /// <returns>An enumerable collection of face location correspond to all faces in specified image.</returns>
/// <exception cref="ArgumentNullException"><paramref name="image"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="image"/> is null.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="image"/> or this object is disposed.</exception> /// <exception cref="ObjectDisposedException"><paramref name="image"/> or this object is disposed.</exception>
public List<Location> FaceLocations(Model model, Image image, int numberOfTimesToUpsample, bool sortByPixelPercentage) public List<Location> FaceLocations(Model model, Image image, int numberOfTimesToUpsample, bool sortByPixelPercentage)
{ {
if (image == null) if (image == null)
throw new ArgumentNullException(nameof(image)); throw new NullReferenceException(nameof(image));
image.ThrowIfDisposed(); image.ThrowIfDisposed();
ThrowIfDisposed(); ThrowIfDisposed();
@ -497,12 +497,12 @@ public sealed class FaceRecognition : DisposableObject
/// </summary> /// </summary>
/// <param name="encoding">The <see cref="double"/> array contains face encoding data.</param> /// <param name="encoding">The <see cref="double"/> array contains face encoding data.</param>
/// <returns>The <see cref="FaceEncoding"/> this method creates.</returns> /// <returns>The <see cref="FaceEncoding"/> this method creates.</returns>
/// <exception cref="ArgumentNullException"><paramref name="encoding"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="encoding"/> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="encoding"/> must be 128.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="encoding"/> must be 128.</exception>
public static FaceEncoding LoadFaceEncoding(double[] encoding) public static FaceEncoding LoadFaceEncoding(double[] encoding)
{ {
if (encoding == null) if (encoding == null)
throw new ArgumentNullException(nameof(encoding)); throw new NullReferenceException(nameof(encoding));
if (encoding.Length != 128) if (encoding.Length != 128)
{ {
string message = $"{nameof(encoding)}.{nameof(encoding.Length)} must be 128."; string message = $"{nameof(encoding)}.{nameof(encoding.Length)} must be 128.";
@ -523,7 +523,7 @@ public sealed class FaceRecognition : DisposableObject
/// </summary> /// </summary>
/// <param name="bitmap">The <see cref="Bitmap"/> from which to create the new <see cref="Image"/>.</param> /// <param name="bitmap">The <see cref="Bitmap"/> from which to create the new <see cref="Image"/>.</param>
/// <returns>The <see cref="Image"/> this method creates.</returns> /// <returns>The <see cref="Image"/> this method creates.</returns>
/// <exception cref="ArgumentNullException"><paramref name="bitmap"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="bitmap"/> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException">The specified <see cref="PixelFormat"/> is not supported.</exception> /// <exception cref="ArgumentOutOfRangeException">The specified <see cref="PixelFormat"/> is not supported.</exception>
public static Image? LoadImage(Bitmap bitmap) public static Image? LoadImage(Bitmap bitmap)
{ {
@ -635,7 +635,7 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="stride">The stride width in bytes.</param> /// <param name="stride">The stride width in bytes.</param>
/// <param name="mode">A image color mode.</param> /// <param name="mode">A image color mode.</param>
/// <returns>The <see cref="Image"/> this method creates.</returns> /// <returns>The <see cref="Image"/> this method creates.</returns>
/// <exception cref="ArgumentNullException"><paramref name="array"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="array"/> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="row"/> is less than 0.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="row"/> is less than 0.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="column"/> is less than 0.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="column"/> is less than 0.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="stride"/> is less than 0.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="stride"/> is less than 0.</exception>
@ -644,7 +644,7 @@ public sealed class FaceRecognition : DisposableObject
public static Image? LoadImage(byte[] array, int row, int column, int stride, Mode mode) public static Image? LoadImage(byte[] array, int row, int column, int stride, Mode mode)
{ {
if (array == null) if (array == null)
throw new ArgumentNullException(nameof(array)); throw new NullReferenceException(nameof(array));
if (row < 0) if (row < 0)
throw new ArgumentOutOfRangeException($"{nameof(row)}", $"{nameof(row)} is less than 0."); throw new ArgumentOutOfRangeException($"{nameof(row)}", $"{nameof(row)} is less than 0.");
if (column < 0) if (column < 0)
@ -757,7 +757,7 @@ public sealed class FaceRecognition : DisposableObject
if (predictorModel == PredictorModel.Custom) if (predictorModel == PredictorModel.Custom)
{ {
if (CustomFaceLandmarkDetector is null) if (CustomFaceLandmarkDetector is null)
throw new ArgumentNullException(nameof(CustomFaceLandmarkDetector)); throw new NullReferenceException(nameof(CustomFaceLandmarkDetector));
foreach (Location? rect in locations) foreach (Location? rect in locations)
{ {
FullObjectDetection? ret = CustomFaceLandmarkDetector.Detect(faceImage, rect); FullObjectDetection? ret = CustomFaceLandmarkDetector.Detect(faceImage, rect);

View File

@ -66,12 +66,12 @@ public sealed class Image : DisposableObject
/// </summary> /// </summary>
/// <param name="filename">A string that contains the name of the file to which to save this <see cref="Image"/>.</param> /// <param name="filename">A string that contains the name of the file to which to save this <see cref="Image"/>.</param>
/// <param name="format">The <see cref="ImageFormat"/> for this <see cref="Image"/>.</param> /// <param name="format">The <see cref="ImageFormat"/> for this <see cref="Image"/>.</param>
/// <exception cref="ArgumentNullException"><paramref name="filename"/> is null.</exception> /// <exception cref="NullReferenceException"><paramref name="filename"/> is null.</exception>
/// <exception cref="ObjectDisposedException">This object is disposed.</exception> /// <exception cref="ObjectDisposedException">This object is disposed.</exception>
public void Save(string filename, ImageFormat format) public void Save(string filename, ImageFormat format)
{ {
if (filename == null) if (filename == null)
throw new ArgumentNullException(nameof(filename)); throw new NullReferenceException(nameof(filename));
ThrowIfDisposed(); ThrowIfDisposed();

View File

@ -41,7 +41,7 @@ public class DlibDotNet
Person[] people; Person[] people;
_AppSettings = appSettings; _AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null) if (appSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism));
_IsEnvironment = isEnvironment; _IsEnvironment = isEnvironment;
_Exceptions = new List<string>(); _Exceptions = new List<string>();
_Log = Serilog.Log.ForContext<DlibDotNet>(); _Log = Serilog.Log.ForContext<DlibDotNet>();
@ -61,21 +61,21 @@ public class DlibDotNet
_Distance = new E_Distance(configuration); _Distance = new E_Distance(configuration);
_FaceLandmarks = new D2_FaceLandmarks(configuration); _FaceLandmarks = new D2_FaceLandmarks(configuration);
if (configuration.ForceMetadataLastWriteTimeToCreationTime is null) if (configuration.ForceMetadataLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)); throw new NullReferenceException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
if (configuration.ForceResizeLastWriteTimeToCreationTime is null) if (configuration.ForceResizeLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime)); throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime));
if (configuration.IgnoreExtensions is null) if (configuration.IgnoreExtensions is null)
throw new ArgumentNullException(nameof(configuration.IgnoreExtensions)); throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.OutputQuality is null) if (configuration.OutputQuality is null)
throw new ArgumentNullException(nameof(configuration.OutputQuality)); throw new NullReferenceException(nameof(configuration.OutputQuality));
if (configuration.OverrideForResizeImages is null) if (configuration.OverrideForResizeImages is null)
throw new ArgumentNullException(nameof(configuration.OverrideForResizeImages)); throw new NullReferenceException(nameof(configuration.OverrideForResizeImages));
if (configuration.PropertiesChangedForMetadata is null) if (configuration.PropertiesChangedForMetadata is null)
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForMetadata)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForResize is null) if (configuration.PropertiesChangedForResize is null)
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForResize)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize));
if (configuration.Reverse is null) 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); _Metadata = new(configuration.ForceMetadataLastWriteTimeToCreationTime.Value, configuration.PropertiesChangedForMetadata.Value);
if (args.Count > 0) if (args.Count > 0)
argZero = Path.GetFullPath(args[0]); argZero = Path.GetFullPath(args[0]);
@ -88,7 +88,7 @@ public class DlibDotNet
(Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(configuration); (Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(configuration);
_Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel); _Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel);
if (configuration.SkipSearch is null) if (configuration.SkipSearch is null)
throw new ArgumentNullException(nameof(configuration.SkipSearch)); throw new NullReferenceException(nameof(configuration.SkipSearch));
if (!_ArgZeroIsConfigurationRootDirectory) if (!_ArgZeroIsConfigurationRootDirectory)
people = Array.Empty<Person>(); people = Array.Empty<Person>();
else else
@ -134,7 +134,7 @@ public class DlibDotNet
{ {
long result; long result;
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks; result = DateTime.Now.Ticks;
@ -188,7 +188,7 @@ public class DlibDotNet
private void Verify(Models.Configuration configuration) private void Verify(Models.Configuration configuration)
{ {
if (!configuration.OutputResolutions.Any() || string.IsNullOrEmpty(configuration.OutputResolutions[0]) || !configuration.ValidResolutions.Contains(configuration.OutputResolutions[0])) 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()) 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!"); 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()) 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()) 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!"); throw new Exception($"One or more {nameof(configuration.SaveFaceLandmarkForOutputResolutions)} are not in the ValidResolutions list!");
if (configuration.CheckJsonForDistanceResults is null) if (configuration.CheckJsonForDistanceResults is null)
throw new ArgumentNullException(nameof(configuration.CheckJsonForDistanceResults)); throw new NullReferenceException(nameof(configuration.CheckJsonForDistanceResults));
if (configuration.CrossDirectoryMaxItemsInDistanceCollection is null) if (configuration.CrossDirectoryMaxItemsInDistanceCollection is null)
throw new ArgumentNullException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection)); throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
if (configuration.DistanceFactor is null) if (configuration.DistanceFactor is null)
throw new ArgumentNullException(nameof(configuration.DistanceFactor)); throw new NullReferenceException(nameof(configuration.DistanceFactor));
if (configuration.ForceMetadataLastWriteTimeToCreationTime is null) if (configuration.ForceMetadataLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)); throw new NullReferenceException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
if (configuration.ForceResizeLastWriteTimeToCreationTime is null) if (configuration.ForceResizeLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime)); throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime));
if (configuration.IgnoreExtensions is null) if (configuration.IgnoreExtensions is null)
throw new ArgumentNullException(nameof(configuration.IgnoreExtensions)); throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.IgnoreRelativePaths is null) if (configuration.IgnoreRelativePaths is null)
throw new ArgumentNullException(nameof(configuration.IgnoreRelativePaths)); throw new NullReferenceException(nameof(configuration.IgnoreRelativePaths));
if (configuration.LoadOrCreateThenSaveIndex is null) if (configuration.LoadOrCreateThenSaveIndex is null)
throw new ArgumentNullException(nameof(configuration.LoadOrCreateThenSaveIndex)); throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveIndex));
if (configuration.LocationConfidenceFactor is null) if (configuration.LocationConfidenceFactor is null)
throw new ArgumentNullException(nameof(configuration.LocationConfidenceFactor)); throw new NullReferenceException(nameof(configuration.LocationConfidenceFactor));
if (configuration.MappedMaxIndex is null) 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) 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) if (configuration.MaxItemsInDistanceCollection is null)
throw new ArgumentNullException(nameof(configuration.MaxItemsInDistanceCollection)); throw new NullReferenceException(nameof(configuration.MaxItemsInDistanceCollection));
if (configuration.MixedYearRelativePaths is null) if (configuration.MixedYearRelativePaths is null)
throw new ArgumentNullException(nameof(configuration.MixedYearRelativePaths)); throw new NullReferenceException(nameof(configuration.MixedYearRelativePaths));
if (configuration.NumberOfJitters is null) if (configuration.NumberOfJitters is null)
throw new ArgumentNullException(nameof(configuration.NumberOfJitters)); throw new NullReferenceException(nameof(configuration.NumberOfJitters));
if (configuration.NumberOfTimesToUpsample is null) if (configuration.NumberOfTimesToUpsample is null)
throw new ArgumentNullException(nameof(configuration.NumberOfTimesToUpsample)); throw new NullReferenceException(nameof(configuration.NumberOfTimesToUpsample));
if (configuration.OutputQuality is null) if (configuration.OutputQuality is null)
throw new ArgumentNullException(nameof(configuration.OutputQuality)); throw new NullReferenceException(nameof(configuration.OutputQuality));
if (configuration.OutputResolutions is null) if (configuration.OutputResolutions is null)
throw new ArgumentNullException(nameof(configuration.OutputResolutions)); throw new NullReferenceException(nameof(configuration.OutputResolutions));
if (configuration.OverrideForFaceImages is null) if (configuration.OverrideForFaceImages is null)
throw new ArgumentNullException(nameof(configuration.OverrideForFaceImages)); throw new NullReferenceException(nameof(configuration.OverrideForFaceImages));
if (configuration.OverrideForFaceLandmarkImages is null) if (configuration.OverrideForFaceLandmarkImages is null)
throw new ArgumentNullException(nameof(configuration.OverrideForFaceLandmarkImages)); throw new NullReferenceException(nameof(configuration.OverrideForFaceLandmarkImages));
if (configuration.OverrideForResizeImages is null) if (configuration.OverrideForResizeImages is null)
throw new ArgumentNullException(nameof(configuration.OverrideForResizeImages)); throw new NullReferenceException(nameof(configuration.OverrideForResizeImages));
if (configuration.PaddingLoops is null) if (configuration.PaddingLoops is null)
throw new ArgumentNullException(nameof(configuration.PaddingLoops)); throw new NullReferenceException(nameof(configuration.PaddingLoops));
if (configuration.PropertiesChangedForDistance is null) if (configuration.PropertiesChangedForDistance is null)
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForDistance)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForDistance));
if (configuration.PropertiesChangedForFaces is null) if (configuration.PropertiesChangedForFaces is null)
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForFaces)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForFaces));
if (configuration.PropertiesChangedForIndex is null) if (configuration.PropertiesChangedForIndex is null)
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForIndex)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForIndex));
if (configuration.PropertiesChangedForMetadata is null) if (configuration.PropertiesChangedForMetadata is null)
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForMetadata)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForResize is null) if (configuration.PropertiesChangedForResize is null)
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForResize)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize));
if (configuration.Reverse is null) if (configuration.Reverse is null)
throw new ArgumentNullException(nameof(configuration.Reverse)); throw new NullReferenceException(nameof(configuration.Reverse));
if (configuration.SaveFaceLandmarkForOutputResolutions is null) if (configuration.SaveFaceLandmarkForOutputResolutions is null)
throw new ArgumentNullException(nameof(configuration.SaveFaceLandmarkForOutputResolutions)); throw new NullReferenceException(nameof(configuration.SaveFaceLandmarkForOutputResolutions));
if (configuration.SaveFullYearOfRandomFiles is null) if (configuration.SaveFullYearOfRandomFiles is null)
throw new ArgumentNullException(nameof(configuration.SaveFullYearOfRandomFiles)); throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles));
if (configuration.SaveResizedSubfiles is null) if (configuration.SaveResizedSubfiles is null)
throw new ArgumentNullException(nameof(configuration.SaveResizedSubfiles)); throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles));
if (configuration.SkipSearch is null) if (configuration.SkipSearch is null)
throw new ArgumentNullException(nameof(configuration.SkipSearch)); throw new NullReferenceException(nameof(configuration.SkipSearch));
if (configuration.TestDistanceResults is null) if (configuration.TestDistanceResults is null)
throw new ArgumentNullException(nameof(configuration.TestDistanceResults)); throw new NullReferenceException(nameof(configuration.TestDistanceResults));
if (configuration.ValidResolutions is null) 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)) 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)) if (string.IsNullOrEmpty(configuration.ModelName))
throw new ArgumentNullException(nameof(configuration.ModelName)); throw new NullReferenceException(nameof(configuration.ModelName));
if (string.IsNullOrEmpty(configuration.OutputExtension)) if (string.IsNullOrEmpty(configuration.OutputExtension))
throw new ArgumentNullException(nameof(configuration.OutputExtension)); throw new NullReferenceException(nameof(configuration.OutputExtension));
if (string.IsNullOrEmpty(configuration.PredictorModelName)) 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) if (configuration.DistanceFactor.Value + configuration.LocationConfidenceFactor.Value != 10)
throw new ArgumentNullException(nameof(configuration.DistanceFactor)); throw new NullReferenceException(nameof(configuration.DistanceFactor));
} }
private void VerifyExtra(List<string> args, Property.Models.Configuration propertyConfiguration, Models.Configuration configuration) private void VerifyExtra(List<string> 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!"); throw new Exception("Input directory should be the source and not a resized directory!");
} }
private void FullParallelForWork(PropertyLogic propertyLogic, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<D_Face>> imageFaceCollections, string sourceDirectory, int index, PropertyHolder propertyHolder) private void FullParallelForWork(PropertyLogic propertyLogic, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<D_Face>> imageFaceCollections, string sourceDirectory, int index, Item item)
{ {
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new ArgumentNullException(nameof(propertyHolder.ImageFileHolder)); throw new NullReferenceException(nameof(item.ImageFileHolder));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration.SaveResizedSubfiles is null) if (_Configuration.SaveResizedSubfiles is null)
throw new ArgumentNullException(nameof(_Configuration.SaveResizedSubfiles)); throw new NullReferenceException(nameof(_Configuration.SaveResizedSubfiles));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
if (_Configuration.PropertyConfiguration.WriteBitmapDataBytes is null) if (_Configuration.PropertyConfiguration.WriteBitmapDataBytes is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration.WriteBitmapDataBytes)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration.WriteBitmapDataBytes));
A_Property property; A_Property property;
List<D_Face> faceCollection; List<D_Face> faceCollection;
string original = "Original"; string original = "Original";
@ -326,40 +326,44 @@ public class DlibDotNet
Dictionary<string, int[]> imageResizeKeyValuePairs; Dictionary<string, int[]> imageResizeKeyValuePairs;
List<Tuple<string, DateTime>> subFileTuples = new(); List<Tuple<string, DateTime>> subFileTuples = new();
List<KeyValuePair<string, string>> metadataCollection; List<KeyValuePair<string, string>> metadataCollection;
if (propertyHolder.Property is null) if (item.Property is null)
{
property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
item.Update(property);
if (subFileTuples.Any())
{ {
lock (sourceDirectoryChanges) lock (sourceDirectoryChanges)
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now)); sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), (from l in subFileTuples select l.Item2).Max()));
property = propertyLogic.GetProperty(propertyLogic.AngleBracketCollection[0], propertyHolder, subFileTuples, parseExceptions); }
propertyHolder.Update(property);
} }
else else
{ {
property = propertyHolder.Property; property = item.Property;
if (propertyHolder.Changed.HasValue && propertyHolder.Changed.Value) if (item.Changed.HasValue && item.Changed.Value)
{ {
lock (sourceDirectoryChanges) // lock (sourceDirectoryChanges)
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now)); // sourceDirectoryChanges.Add(new Tuple<string, DateTime>(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) if (_AppSettings.MaxDegreeOfParallelism.Value < 2)
ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection)); ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection));
FileHolder resizedFileHolder = new(Path.Combine(_Resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(propertyHolder.ImageFileHolder.FullName))); FileHolder resizedFileHolder = new(Path.Combine(_Resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName)));
propertyHolder.SetResizedFileHolder(resizedFileHolder); item.SetResizedFileHolder(resizedFileHolder);
imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, propertyHolder); imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, item);
if (_AppSettings.MaxDegreeOfParallelism.Value < 2) if (_AppSettings.MaxDegreeOfParallelism.Value < 2)
ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs)); ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs));
if (_Configuration.SaveResizedSubfiles.Value) 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) if (_AppSettings.MaxDegreeOfParallelism.Value < 2)
ticks = LogDelta(ticks, nameof(C_Resize.SaveResizedSubfile)); ticks = LogDelta(ticks, nameof(C_Resize.SaveResizedSubfile));
propertyHolder.SetResizedFileHolder(FileHolder.Refresh(resizedFileHolder)); item.SetResizedFileHolder(FileHolder.Refresh(resizedFileHolder));
} }
else if (outputResolution == _Configuration.OutputResolutions[0] && false) 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) if (_AppSettings.MaxDegreeOfParallelism.Value < 2)
ticks = LogDelta(ticks, nameof(C_Resize.GetResizedBytes)); ticks = LogDelta(ticks, nameof(C_Resize.GetResizedBytes));
string path = Path.Combine(resizedFileHolder.DirectoryName, resizedFileHolder.NameWithoutExtension); string path = Path.Combine(resizedFileHolder.DirectoryName, resizedFileHolder.NameWithoutExtension);
@ -373,15 +377,15 @@ public class DlibDotNet
int outputResolutionWidth = outputResolutionCollection[0]; int outputResolutionWidth = outputResolutionCollection[0];
int outputResolutionHeight = outputResolutionCollection[1]; int outputResolutionHeight = outputResolutionCollection[1];
int outputResolutionOrientation = outputResolutionCollection[2]; 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) if (_AppSettings.MaxDegreeOfParallelism.Value < 2)
ticks = LogDelta(ticks, nameof(D_Face.GetFaces)); 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) if (_AppSettings.MaxDegreeOfParallelism.Value < 2)
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces)); ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
{ {
_FaceLandmarks.SaveFaceLandmarkImages(subFileTuples, parseExceptions, propertyHolder, faceCollection); _FaceLandmarks.SaveFaceLandmarkImages(subFileTuples, parseExceptions, item, faceCollection);
if (_AppSettings.MaxDegreeOfParallelism.Value < 2) if (_AppSettings.MaxDegreeOfParallelism.Value < 2)
ticks = LogDelta(ticks, nameof(D2_FaceLandmarks.SaveFaceLandmarkImages)); ticks = LogDelta(ticks, nameof(D2_FaceLandmarks.SaveFaceLandmarkImages));
} }
@ -392,23 +396,23 @@ public class DlibDotNet
imageFaceCollections[index] = faceCollection; imageFaceCollections[index] = faceCollection;
metadataCollections[index] = metadataCollection; metadataCollections[index] = metadataCollection;
resizeKeyValuePairs[index] = imageResizeKeyValuePairs; resizeKeyValuePairs[index] = imageResizeKeyValuePairs;
propertyFileHolderCollection[index] = propertyHolder.ImageFileHolder; propertyFileHolderCollection[index] = item.ImageFileHolder;
sourceDirectoryChanges.AddRange(from l in subFileTuples where l.Item2 > dateTime select l); sourceDirectoryChanges.AddRange(from l in subFileTuples where l.Item2 > dateTime select l);
} }
} }
private int FullParallelWork(long ticks, PropertyLogic propertyLogic, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<D_Face>> faceCollections, int propertyHolderCollectionsCount, int g, string sourceDirectory, int r, PropertyHolder[] filteredPropertyHolderCollection) private int FullParallelWork(long ticks, PropertyLogic propertyLogic, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<D_Face>> faceCollections, int containersCount, Container container, Item[] filteredItems)
{ {
int result = 0; int result = 0;
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(AppSettings.MaxDegreeOfParallelism));
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism.Value }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism.Value };
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; 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()); faceCollections.Add(new());
metadataCollection.Add(new()); metadataCollection.Add(new());
@ -418,23 +422,23 @@ public class DlibDotNet
} }
} }
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); 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}"; 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(filteredPropertyHolderCollection.Length, message, options)) using (ProgressBar progressBar = new(filteredItems.Length, message, options))
{ {
_ = Parallel.For(0, filteredPropertyHolderCollection.Length, parallelOptions, i => _ = Parallel.For(0, filteredItems.Length, parallelOptions, i =>
{ {
try 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()) if (i == 0 || sourceDirectoryChanges.Any())
progressBar.Tick(); progressBar.Tick();
} }
catch (Exception ex) catch (Exception ex)
{ {
result += 1; result += 1;
_Log.Error(string.Concat(sourceDirectory, Environment.NewLine, ex.Message, Environment.NewLine, ex.StackTrace), ex); _Log.Error(string.Concat(container.SourceDirectory, Environment.NewLine, ex.Message, Environment.NewLine, ex.StackTrace), ex);
if (result == filteredPropertyHolderCollection.Length) if (result == filteredItems.Length)
throw new Exception(string.Concat("All in [", sourceDirectory, "] failed!")); 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<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<List<D_Face>> faceCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, string sourceDirectory, string outputResolution, PropertyHolder[] filteredPropertyHolderCollection) private void WriteGroup(Property.Models.Configuration configuration, PropertyLogic propertyLogic, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<List<D_Face>> faceCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, string sourceDirectory, string outputResolution, Item[] filteredItems)
{ {
if (_Configuration.PropertiesChangedForMetadata is null) if (_Configuration.PropertiesChangedForMetadata is null)
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata)); throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForProperty is null) if (configuration.PropertiesChangedForProperty is null)
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForProperty)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForProperty));
if (_Configuration.PropertiesChangedForResize is null) if (_Configuration.PropertiesChangedForResize is null)
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize)); throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForResize));
if (_Configuration.PropertiesChangedForFaces is null) if (_Configuration.PropertiesChangedForFaces is null)
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForFaces)); throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForFaces));
Item item;
string key; string key;
string json; string json;
string checkFile; string checkFile;
PropertyHolder propertyHolder;
int sourceDirectoryLength = sourceDirectory.Length; int sourceDirectoryLength = sourceDirectory.Length;
_FilePropertiesKeyValuePairs.Add(sourceDirectory, new List<Tuple<string, A_Property>>()); _FilePropertiesKeyValuePairs.Add(sourceDirectory, new List<Tuple<string, A_Property>>());
JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false }; JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false };
@ -502,14 +506,14 @@ public class DlibDotNet
List<KeyValuePair<string, List<KeyValuePair<string, string>>>> metadataCollectionKeyValuePairs = new(); List<KeyValuePair<string, List<KeyValuePair<string, string>>>> metadataCollectionKeyValuePairs = new();
(int level, List<string> directories) = Property.Models.Stateless.IPath.Get(configuration.RootDirectory, sourceDirectory); (int level, List<string> directories) = Property.Models.Stateless.IPath.Get(configuration.RootDirectory, sourceDirectory);
string fileName = string.Concat(string.Join(configuration.FileNameDirectorySeparator, directories), ".json"); 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]; item = filteredItems[i];
if (propertyHolder.Property is null) if (item.Property is null)
continue; continue;
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
continue; 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<string, string>(sourceDirectory, key)); _FileKeyValuePairs.Add(new KeyValuePair<string, string>(sourceDirectory, key));
_FilePropertiesKeyValuePairs[sourceDirectory].Add(new Tuple<string, A_Property>(key, propertyCollection[i])); _FilePropertiesKeyValuePairs[sourceDirectory].Add(new Tuple<string, A_Property>(key, propertyCollection[i]));
faceCollectionsKeyValuePairs.Add(new KeyValuePair<string, List<D_Face>>(key, faceCollections[i])); faceCollectionsKeyValuePairs.Add(new KeyValuePair<string, List<D_Face>>(key, faceCollections[i]));
@ -560,41 +564,35 @@ public class DlibDotNet
} }
} }
private void FullDoWork(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, List<PropertyHolder[]> propertyHolderCollections) private void FullDoWork(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, List<Container> containers)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
int g;
int r;
int exceptionCount; int exceptionCount;
string sourceDirectory; Item[] filteredItems;
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
string eDistanceCollectionDirectory;
List<List<D_Face>> faceCollections = new(); List<List<D_Face>> faceCollections = new();
List<A_Property> propertyCollection = new(); List<A_Property> propertyCollection = new();
PropertyHolder[] filteredPropertyHolderCollection;
List<FileHolder?> propertyFileHolderCollection = new(); List<FileHolder?> propertyFileHolderCollection = new();
List<Dictionary<string, int[]>> resizeKeyValuePairs = new(); List<Dictionary<string, int[]>> resizeKeyValuePairs = new();
List<Tuple<string, DateTime>> sourceDirectoryChanges = new(); List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
List<List<KeyValuePair<string, string>>> metadataCollection = new(); List<List<KeyValuePair<string, string>>> metadataCollection = new();
List<(string[], PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection;
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}"); string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
string propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(A_Property)); string propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(A_Property));
foreach (string outputResolution in _Configuration.OutputResolutions) foreach (string outputResolution in _Configuration.OutputResolutions)
{ {
_FileKeyValuePairs.Clear(); _FileKeyValuePairs.Clear();
_FilePropertiesKeyValuePairs.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 (Container container in containers)
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
{ {
if (!propertyHolderCollection.Any()) if (!container.Items.Any())
continue; continue;
if (!_ArgZeroIsConfigurationRootDirectory && !propertyHolderCollection[0].SourceDirectory.StartsWith(argZero)) if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue; 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(); filteredItems = (from l in container.Items where l.ImageFileHolder is not null && l.ValidImageFormatExtension && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray();
if (!filteredPropertyHolderCollection.Any()) if (!filteredItems.Any())
continue; continue;
faceCollections.Clear(); faceCollections.Clear();
metadataCollection.Clear(); metadataCollection.Clear();
@ -605,15 +603,12 @@ public class DlibDotNet
_Faces.AngleBracketCollection.Clear(); _Faces.AngleBracketCollection.Clear();
_Resize.AngleBracketCollection.Clear(); _Resize.AngleBracketCollection.Clear();
_Metadata.AngleBracketCollection.Clear(); _Metadata.AngleBracketCollection.Clear();
g = filteredPropertyHolderCollection[0].G;
r = filteredPropertyHolderCollection[0].R;
propertyLogic.AngleBracketCollection.Clear(); propertyLogic.AngleBracketCollection.Clear();
_FaceLandmarks.AngleBracketCollection.Clear(); _FaceLandmarks.AngleBracketCollection.Clear();
sourceDirectory = filteredPropertyHolderCollection[0].SourceDirectory;
propertyLogic.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, propertyLogic.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
model, model,
predictorModel, predictorModel,
sourceDirectory, container.SourceDirectory,
nameof(A_Property), nameof(A_Property),
outputResolution, outputResolution,
includeResizeGroup: false, includeResizeGroup: false,
@ -625,7 +620,7 @@ public class DlibDotNet
_Metadata.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, _Metadata.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
model, model,
predictorModel, predictorModel,
sourceDirectory, container.SourceDirectory,
nameof(B_Metadata), nameof(B_Metadata),
outputResolution, outputResolution,
includeResizeGroup: false, includeResizeGroup: false,
@ -637,7 +632,7 @@ public class DlibDotNet
_Resize.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, _Resize.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
model, model,
predictorModel, predictorModel,
sourceDirectory, container.SourceDirectory,
nameof(C_Resize), nameof(C_Resize),
outputResolution, outputResolution,
includeResizeGroup: true, includeResizeGroup: true,
@ -650,7 +645,7 @@ public class DlibDotNet
_Faces.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, _Faces.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
model, model,
predictorModel, predictorModel,
sourceDirectory, container.SourceDirectory,
nameof(D_Face), nameof(D_Face),
outputResolution, outputResolution,
includeResizeGroup: true, includeResizeGroup: true,
@ -663,7 +658,7 @@ public class DlibDotNet
_FaceLandmarks.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, _FaceLandmarks.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
model, model,
predictorModel, predictorModel,
sourceDirectory, container.SourceDirectory,
nameof(D2_FaceLandmarks), nameof(D2_FaceLandmarks),
outputResolution, outputResolution,
includeResizeGroup: true, includeResizeGroup: true,
@ -672,28 +667,28 @@ public class DlibDotNet
contentDescription: "n x 2 png file(s) for each face found", contentDescription: "n x 2 png file(s) for each face found",
singletonDescription: string.Empty, singletonDescription: string.Empty,
collectionDescription: string.Empty)); collectionDescription: string.Empty));
exceptionCount = FullParallelWork(ticks, propertyLogic, outputResolution, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, propertyHolderCollections.Count, g, sourceDirectory, r, filteredPropertyHolderCollection); exceptionCount = FullParallelWork(ticks, propertyLogic, outputResolution, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, containers.Count, container, filteredItems);
if (metadataCollection.Count != filteredPropertyHolderCollection.Length || propertyCollection.Count != filteredPropertyHolderCollection.Length || resizeKeyValuePairs.Count != filteredPropertyHolderCollection.Length || faceCollections.Count != filteredPropertyHolderCollection.Length) if (metadataCollection.Count != filteredItems.Length || propertyCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || faceCollections.Count != filteredItems.Length)
throw new Exception("Counts don't match!"); throw new Exception("Counts don't match!");
if (exceptionCount != 0) if (exceptionCount != 0)
_Exceptions.Add(sourceDirectory); _Exceptions.Add(container.SourceDirectory);
if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0) 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]) if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0 && outputResolution == _Configuration.OutputResolutions[0])
propertyLogic.AddToPropertyLogicAllCollection(filteredPropertyHolderCollection); propertyLogic.AddToPropertyLogicAllCollection(filteredItems);
if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0 && propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.Any()) if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0 && propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.Any())
{ {
if (outputResolution == _Configuration.OutputResolutions[0] || _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) if (outputResolution == _Configuration.OutputResolutions[0] || _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
{ {
for (int i = 0; i < faceCollections.Count; i++) for (int i = 0; i < faceCollections.Count; i++)
filteredPropertyHolderCollection[i].Faces.AddRange(from l in faceCollections[i] select l); filteredItems[i].Faces.AddRange(from l in faceCollections[i] select l);
PropertyHolder.AddToNamed(propertyLogic, filteredPropertyHolderCollection); Item.AddToNamed(propertyLogic, filteredItems);
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) 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)) 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()) if (_Resize.AngleBracketCollection.Any())
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(_Resize.AngleBracketCollection[0].Replace("<>", "()")); _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(_Resize.AngleBracketCollection[0].Replace("<>", "()"));
if (_Faces.AngleBracketCollection.Any()) if (_Faces.AngleBracketCollection.Any())
@ -716,9 +711,22 @@ public class DlibDotNet
propertyLogic.SaveAllCollection(); propertyLogic.SaveAllCollection();
if (propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.Any()) if (propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.Any())
{ {
collection = E_Distance.GetGroupedFaceEncodings(argZero, propertyHolderCollections); const int maxPer = 5;
E_Distance.SaveGroupedFaceEncodings(collection, peopleCollection, eDistanceCollectionDirectory); const bool skipIsWrongYear = true;
E_Distance.GetClosest(argZero, propertyHolderCollections, collection, peopleCollection, eDistanceCollectionDirectory); 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()) if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
break; break;
@ -739,23 +747,27 @@ public class DlibDotNet
} }
} }
private PropertyLogic GetPropertyLogic() private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel)
{ {
PropertyLogic result; PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
return result; return result;
} }
private void Search(Property.Models.Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel, string argZero, Person[] people) private void Search(Property.Models.Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel, string argZero, Person[] people)
{ {
PropertyLogic propertyLogic = GetPropertyLogic(); List<Container> containers;
Dictionary<string, List<Person>> peopleCollection = A2_People.Convert(people); Dictionary<string, List<Person>> peopleCollection = A2_People.Convert(people);
List<PropertyHolder[]> propertyHolderCollections = Property.Models.Stateless.A_Property.Get(configuration, reverse, model, predictorModel, propertyLogic); PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel);
FullDoWork(configuration, model, predictorModel, argZero, peopleCollection, propertyLogic, propertyHolderCollections); 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); internal void RenameQueue(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel) => _Rename.RenameQueue(configuration, model, predictorModel);

View File

@ -65,7 +65,7 @@ internal class A2_People
{ {
Person[] results; Person[] results;
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory; string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People)); string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People));
string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory)); string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory));

View File

@ -107,10 +107,12 @@ internal class D2_FaceLandmarks
#pragma warning restore CA1416 #pragma warning restore CA1416
internal void SaveFaceLandmarkImages(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, PropertyHolder propertyHolder, List<D_Face> faceCollections) internal void SaveFaceLandmarkImages(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<D_Face> faceCollections)
{ {
if (propertyHolder.ResizedFileHolder is null) if (item.ImageFileHolder is null)
throw new Exception($"{propertyHolder.ResizedFileHolder} is null!"); throw new NullReferenceException(nameof(item.ImageFileHolder));
if (item.ResizedFileHolder is null)
throw new NullReferenceException(nameof(item.ResizedFileHolder));
FileInfo fileInfo; FileInfo fileInfo;
bool check = false; bool check = false;
string parentCheck; string parentCheck;
@ -120,7 +122,7 @@ internal class D2_FaceLandmarks
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
List<string[]> imageFiles = new(); List<string[]> imageFiles = new();
bool updateDateWhenMatches = false; 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) }; string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (!Directory.Exists(facesDirectory)) if (!Directory.Exists(facesDirectory))
@ -132,7 +134,7 @@ internal class D2_FaceLandmarks
imageFiles.Add(Array.Empty<string>()); imageFiles.Add(Array.Empty<string>());
continue; 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.Exists)
{ {
if (fileInfo.Directory?.Parent is null) if (fileInfo.Directory?.Parent is null)
@ -164,7 +166,7 @@ internal class D2_FaceLandmarks
} }
} }
if (check) if (check)
SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, propertyHolder.ResizedFileHolder); SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, item.ResizedFileHolder);
} }
} }

View File

@ -251,15 +251,17 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
} }
} }
private List<D_Face> GetFaces(FileHolder resizedFileHolder, PropertyHolder propertyHolder, A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string facesDirectory) private List<D_Face> GetFaces(FileHolder resizedFileHolder, Item item, A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string facesDirectory)
{ {
List<D_Face> results = new(); List<D_Face> results = new();
if (_Configuration.PaddingLoops is null) if (_Configuration.PaddingLoops is null)
throw new Exception(); throw new Exception();
if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder));
if (_Configuration.NumberOfJitters is null) if (_Configuration.NumberOfJitters is null)
throw new ArgumentNullException(nameof(_Configuration.NumberOfJitters)); throw new NullReferenceException(nameof(_Configuration.NumberOfJitters));
if (_Configuration.NumberOfTimesToUpsample is null) if (_Configuration.NumberOfTimesToUpsample is null)
throw new ArgumentNullException(nameof(_Configuration.NumberOfTimesToUpsample)); throw new NullReferenceException(nameof(_Configuration.NumberOfTimesToUpsample));
List<Location> locations; List<Location> locations;
FaceRecognitionDotNet.Image? unknownImage = null; FaceRecognitionDotNet.Image? unknownImage = null;
if (resizedFileHolder.Exists) if (resizedFileHolder.Exists)
@ -269,13 +271,13 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
catch (Exception) { } catch (Exception) { }
} }
if (unknownImage is null) 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 else
{ {
FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter); FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter);
locations = faceRecognition.FaceLocations(_Model, unknownImage, _Configuration.NumberOfTimesToUpsample.Value, sortByPixelPercentage: true); locations = faceRecognition.FaceLocations(_Model, unknownImage, _Configuration.NumberOfTimesToUpsample.Value, sortByPixelPercentage: true);
if (!locations.Any()) 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 else
{ {
double? α; double? α;
@ -312,7 +314,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
locations[i].Top - (padding * p), locations[i].Top - (padding * p),
source.Width, source.Width,
source.Height); 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; width = location.Right - location.Left;
height = location.Bottom - location.Top; height = location.Bottom - location.Top;
rectangle = new Rectangle(location.Left, location.Top, width, height); 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)) using (knownImage = FaceRecognition.LoadImage(preRotated))
{ {
if (knownImage is null || knownImage.IsDisposed) 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); facesLandmarks = faceRecognition.GetFaceLandmarkCollection(knownImage, _Configuration.NumberOfTimesToUpsample.Value, faceLocations: null, _PredictorModel, _Model);
} }
if (facesLandmarks.Count == 0 && p < _Configuration.PaddingLoops.Value) 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)) using (rotatedImage = FaceRecognition.LoadImage(rotated))
{ {
if (rotatedImage is null || rotatedImage.IsDisposed) 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); faceEncodings = faceRecognition.FaceEncodings(rotatedImage, _Configuration.NumberOfTimesToUpsample.Value, knownFaceLocation: null, _Configuration.NumberOfJitters.Value, _PredictorModel, _Model);
} }
if (faceEncodings.Count == 0 && p < _Configuration.PaddingLoops.Value) 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); faceEncoding = new(rawEncoding, faceEncodings[0].Size);
face.Update(α, faceEncoding, populated: true); 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); preRotated.Save(faceFile, System.Drawing.Imaging.ImageFormat.Png);
results.Add(face); results.Add(face);
} }
@ -388,7 +390,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
locations[i].Top, locations[i].Top,
source.Width, source.Width,
source.Height); 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); results.Add(face);
} }
} }
@ -410,18 +412,20 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
_Populated = populated; _Populated = populated;
} }
internal List<D_Face> GetFaces(Property.Models.Configuration configuration, string outputResolution, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, PropertyHolder propertyHolder, A_Property property, FileHolder resizedFileHolder, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) internal List<D_Face> GetFaces(Property.Models.Configuration configuration, string outputResolution, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, A_Property property, FileHolder resizedFileHolder, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
{ {
List<D_Face>? results; List<D_Face>? results;
if (_Configuration.PropertiesChangedForFaces is null) if (_Configuration.PropertiesChangedForFaces is null)
throw new Exception(); throw new Exception();
if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder));
string json; string json;
D_Face face; D_Face face;
bool checkForOutputResolutionChange = false; bool checkForOutputResolutionChange = false;
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) }; string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), propertyHolder.ImageFileNameWithoutExtension); string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{propertyHolder.ImageFileNameWithoutExtension}.json")); FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json"));
if (!fileInfo.Exists) if (!fileInfo.Exists)
{ {
if (fileInfo.Directory?.Parent is null) if (fileInfo.Directory?.Parent is null)
@ -445,7 +449,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
{ {
results = JsonSerializer.Deserialize<List<D_Face>>(json); results = JsonSerializer.Deserialize<List<D_Face>>(json);
if (results is null) if (results is null)
throw new ArgumentNullException(nameof(results)); throw new NullReferenceException(nameof(results));
for (int i = 0; i < results.Count; i++) for (int i = 0; i < results.Count; i++)
{ {
face = results[i]; face = results[i];
@ -473,7 +477,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
} }
else if (results is null) 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); json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime; bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max(); DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
@ -483,18 +487,20 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
return results; return results;
} }
internal void SaveFaces(Property.Models.Configuration configuration, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, PropertyHolder propertyHolder, List<D_Face> faceCollection) internal void SaveFaces(Property.Models.Configuration configuration, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<D_Face> faceCollection)
{ {
if (_Configuration.OverrideForFaceImages is null) if (_Configuration.OverrideForFaceImages is null)
throw new Exception(); throw new Exception();
if (propertyHolder.ResizedFileHolder is null) if (item.ImageFileHolder is null)
throw new Exception($"{propertyHolder.ResizedFileHolder} is null!"); throw new NullReferenceException(nameof(item.ImageFileHolder));
if (item.ResizedFileHolder is null)
throw new NullReferenceException(nameof(item.ResizedFileHolder));
FileInfo fileInfo; FileInfo fileInfo;
bool check = false; bool check = false;
string parentCheck; string parentCheck;
List<string> imageFiles = new(); List<string> imageFiles = new();
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) }; 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<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
bool facesDirectoryExisted = Directory.Exists(facesDirectory); bool facesDirectoryExisted = Directory.Exists(facesDirectory);
if (!facesDirectoryExisted) if (!facesDirectoryExisted)
@ -506,7 +512,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
imageFiles.Add(string.Empty); imageFiles.Add(string.Empty);
continue; 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.Exists)
{ {
if (fileInfo.Directory?.Parent is null) if (fileInfo.Directory?.Parent is null)
@ -524,19 +530,20 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
check = true; check = true;
} }
if (check) 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<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, string outputResolution, PropertyHolder[] filteredPropertyHolderCollection) internal static void SaveShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string[] juliePhares, long ticks, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, string outputResolution, Item[] filteredItems)
{ {
Person person; Person person;
string fileName; string fileName;
string fullName; string fullName;
DateTime? minimumDateTime;
WindowsShortcut windowsShortcut; WindowsShortcut windowsShortcut;
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]"; 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})"); 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); List<(Item, (string, Shared.Models.Properties.IFace?, (string, string, string, string))[])> collections = Item.GetCollection(propertyLogic, filteredItems, dFacesContentDirectory);
foreach ((PropertyHolder propertyHolder, (string personKey, Shared.Models.Properties.IFace? _, (string, string, string, string))[] collection) in collections) foreach ((Item item, (string personKey, Shared.Models.Properties.IFace? _, (string, string, string, string))[] collection) in collections)
{ {
if (collection.Length != 1) if (collection.Length != 1)
continue; continue;
@ -544,7 +551,10 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
{ {
if (string.IsNullOrEmpty(personKey)) if (string.IsNullOrEmpty(personKey))
continue; 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; continue;
if (!Directory.Exists(directory)) if (!Directory.Exists(directory))
{ {
@ -560,19 +570,19 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
{ {
if (!Directory.Exists(copyDirectory)) if (!Directory.Exists(copyDirectory))
_ = Directory.CreateDirectory(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)) 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)) if (File.Exists(fileName))
continue; continue;
windowsShortcut = new() { Path = propertyHolder.ImageFileHolder.FullName }; windowsShortcut = new() { Path = item.ImageFileHolder.FullName };
windowsShortcut.Save(fileName); windowsShortcut.Save(fileName);
windowsShortcut.Dispose(); windowsShortcut.Dispose();
if (!File.Exists(fileName)) if (!File.Exists(fileName))
continue; continue;
File.SetLastWriteTime(fileName, propertyHolder.MinimumDateTime.Value); File.SetLastWriteTime(fileName, minimumDateTime.Value);
} }
} }
} }

View File

@ -38,7 +38,7 @@ internal class E2_Navigate
private void DisplayTags(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string[] directories, Dictionary<ConsoleKey, int> directoryKeyValuePairs, string[] files, Dictionary<ConsoleKey, int> fileKeyValuePairs) private void DisplayTags(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string[] directories, Dictionary<ConsoleKey, int> directoryKeyValuePairs, string[] files, Dictionary<ConsoleKey, int> fileKeyValuePairs)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
bool all = false; bool all = false;
FileSystem fileSystem; FileSystem fileSystem;
string requestPath = "/RootResultsDirectory"; 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) private void DisplayFaces(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string selectedFileFullName)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
string requestPath = "/RootResultsDirectory"; string requestPath = "/RootResultsDirectory";
string? rootResultsDirectory = Path.GetDirectoryName(Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(B_Metadata))); string? rootResultsDirectory = Path.GetDirectoryName(Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(B_Metadata)));
if (string.IsNullOrEmpty(rootResultsDirectory)) if (string.IsNullOrEmpty(rootResultsDirectory))
@ -95,9 +95,9 @@ internal class E2_Navigate
{ {
string result; string result;
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null) 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, ">?")); _Log.Warn(string.Concat("What is the new name for [", Path.GetFileName(subSourceDirectory), "]<", subSourceDirectory, ">?"));
string? newDirectoryName = _Console.ReadLine(); string? newDirectoryName = _Console.ReadLine();
_Log.Warn("Are you sure y[es] || n[o]?"); _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) internal void Navigate(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
string[] subFiles; string[] subFiles;
ConsoleKey consoleKey; ConsoleKey consoleKey;
string[] subDirectories; string[] subDirectories;

View File

@ -115,7 +115,7 @@ internal class E3_Rename
{ {
List<string[]> results = new(); List<string[]> results = new();
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
bool add; bool add;
string to; string to;
bool exists; 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) internal void DirectoryRename(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string relativePath, string newDirectoryName)
{ {
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
string json; string json;
FileInfo current; FileInfo current;
FileInfo fileInfo; FileInfo fileInfo;

View File

@ -33,11 +33,11 @@ internal class E_Distance
return result; return result;
} }
private static void LoadFaceEncodingCollections(PropertyHolder[] filteredPropertyHolderCollection, List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<FaceEncoding> faceEncodingCollection, List<List<FaceEncoding>> faceEncodingCollections) private static void LoadFaceEncodingCollections(Item[] filteredItems, List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<FaceEncoding> faceEncodingCollection, List<List<FaceEncoding>> faceEncodingCollections)
{ {
List<D_Face> faceCollection; List<D_Face> faceCollection;
FaceEncoding faceEncoding; FaceEncoding faceEncoding;
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) for (int i = 0; i < filteredItems.Length; i++)
{ {
faceCollection = faceCollections[i]; faceCollection = faceCollections[i];
if (!faceCollection.Any()) if (!faceCollection.Any())
@ -171,28 +171,28 @@ internal class E_Distance
} }
} }
private void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, PropertyHolder[] filteredPropertyHolderCollection, List<List<D_Face>> faceCollections, List<string[]> directories, bool updateDateWhenMatches, DateTime? updateToWhenMatches) private void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, Item[] filteredItems, List<List<D_Face>> faceCollections, List<string[]> directories, bool updateDateWhenMatches, DateTime? updateToWhenMatches)
{ {
FileHolder? fileHolder; FileHolder? fileHolder;
List<int[]> locationIndicesCollection = new(); List<int[]> locationIndicesCollection = new();
List<Tuple<string, DateTime>> subFileTuples = new(); List<Tuple<string, DateTime>> subFileTuples = new();
List<FaceEncoding> faceEncodingCollection = new(); List<FaceEncoding> faceEncodingCollection = new();
List<List<FaceEncoding>> faceEncodingCollections = new(); List<List<FaceEncoding>> faceEncodingCollections = new();
LoadFaceEncodingCollections(filteredPropertyHolderCollection, faceCollections, locationIndicesCollection, faceEncodingCollection, faceEncodingCollections); LoadFaceEncodingCollections(filteredItems, faceCollections, locationIndicesCollection, faceEncodingCollection, faceEncodingCollections);
if (faceEncodingCollections.Count != faceCollections.Count) if (faceEncodingCollections.Count != faceCollections.Count)
throw new Exception(); throw new Exception();
if (locationIndicesCollection.Count != faceEncodingCollection.Count) if (locationIndicesCollection.Count != faceEncodingCollection.Count)
throw new Exception(); 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) if (fileHolder is null)
continue; 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<Tuple<string, DateTime>> sourceDirectoryChanges, PropertyHolder[] filteredPropertyHolderCollection, List<List<D_Face>> faceCollections) internal void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item[] filteredItems, List<List<D_Face>> faceCollections)
{ {
if (_Configuration.CheckJsonForDistanceResults is null) if (_Configuration.CheckJsonForDistanceResults is null)
throw new Exception(); throw new Exception();
@ -222,9 +222,9 @@ internal class E_Distance
contentDescription: ".tvs File", contentDescription: ".tvs File",
singletonDescription: string.Empty, singletonDescription: string.Empty,
collectionDescription: "n json file(s) for each face found (one to many)"); collectionDescription: "n json file(s) for each face found (one to many)");
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) if (fileHolder is null)
continue; continue;
directoryInfo = new System.IO.DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), fileHolder.NameWithoutExtension)); directoryInfo = new System.IO.DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), fileHolder.NameWithoutExtension));
@ -269,7 +269,7 @@ internal class E_Distance
} }
} }
if (check) 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("<>", "()")); _ = 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) internal void LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
string? relativePath; string? relativePath;
Shared.Models.Face face; Shared.Models.Face face;
ParallelOptions parallelOptions = new(); ParallelOptions parallelOptions = new();
@ -414,9 +414,9 @@ internal class E_Distance
return result; return result;
} }
internal static List<(string[], Shared.Models.PersonBirthday, FaceEncoding[])> GetGroupedFaceEncodings(string argZero, List<PropertyHolder[]> propertyHolderCollections) internal static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> GetThreeSigmaFaceEncodings(string argZero, List<Container> containers)
{ {
List<(string[], Shared.Models.PersonBirthday, FaceEncoding[])> results = new(); List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> results = new();
double lcl; double lcl;
double ucl; double ucl;
double sum; double sum;
@ -428,13 +428,13 @@ internal class E_Distance
FaceEncoding faceEncoding; FaceEncoding faceEncoding;
List<double> faceDistances; List<double> faceDistances;
List<FaceEncoding> faceEncodings; List<FaceEncoding> faceEncodings;
Dictionary<string, List<(string[], Shared.Models.PersonBirthday, Shared.Models.Properties.IFace)>> keyValuePairs = PropertyHolder.GetKeyValuePairs(argZero, propertyHolderCollections); Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, Shared.Models.Properties.IFace)>> keyValuePairs = Item.GetKeyValuePairs(argZero, containers);
foreach (KeyValuePair<string, List<(string[] Directories, Shared.Models.PersonBirthday PersonBirthday, Shared.Models.Properties.IFace _)>> keyValuePair in keyValuePairs) foreach (KeyValuePair<string, List<(DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, Shared.Models.Properties.IFace _)>> keyValuePair in keyValuePairs)
{ {
lowestIndex = 0; lowestIndex = 0;
faceEncodings = new(); faceEncodings = new();
lowestSum = double.MaxValue; 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) if (!face.Populated)
continue; continue;
@ -462,17 +462,17 @@ internal class E_Distance
standardDeviation = GetStandardDeviation(faceDistances, average); standardDeviation = GetStandardDeviation(faceDistances, average);
lcl = average - (standardDeviation * 3); lcl = average - (standardDeviation * 3);
ucl = 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) if (faceDistances[i] < lcl || faceDistances[i] > ucl)
faceEncodings.RemoveAt(i); 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; return results;
} }
internal static void SaveGroupedFaceEncodings(List<(string[], Shared.Models.PersonBirthday, FaceEncoding[])> collection, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceCollectionDirectory) internal static void SaveThreeSigmaFaceEncodings(List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceCollectionDirectory)
{ {
string json; string json;
string checkFile; string checkFile;
@ -480,14 +480,14 @@ internal class E_Distance
string directory; string directory;
List<double[]> rawEncodings; List<double[]> rawEncodings;
Shared.Models.Person person; Shared.Models.Person person;
const string facePopulatedKey = "ThreeSigma";
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]"; 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(); rawEncodings = new();
checkFile = string.Empty; checkFile = string.Empty;
directory = Path.Combine(directories);
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday); personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
directory = Item.GetDirectory(eDistanceCollectionDirectory, facePopulatedKey, minimumDateTime, isWrongYear, personBirthday, personKey);
person = peopleCollection[personKey][0]; person = peopleCollection[personKey][0];
checkFile = string.Concat(directory, " - ", Regex.Replace(Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name), pattern, string.Empty), ".json"); checkFile = string.Concat(directory, " - ", Regex.Replace(Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name), pattern, string.Empty), ".json");
if (string.IsNullOrEmpty(checkFile)) if (string.IsNullOrEmpty(checkFile))
@ -501,81 +501,150 @@ internal class E_Distance
} }
} }
public static void GetKeyValuePairs(string argZero, List<PropertyHolder[]> propertyHolderCollections, List<(string[], Shared.Models.PersonBirthday, FaceEncoding[])> collection) public static void AddClosest(string argZero, List<Container> containers, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, bool skipIsWrongYear, int maxPer)
{ {
string key;
double average; double average;
string personKey;
bool? isWrongYear;
TimeSpan? timeSpan;
double lowestAverage; double lowestAverage;
string[] directories; bool? itemIsWrongYear;
string isWrongYearFlag; bool? lowestIsWrongYear;
FaceEncoding faceEncoding; FaceEncoding faceEncoding;
List<double> faceDistances; List<double> faceDistances;
const string facePopulatedKey = "MatchImages"; DateTime? itemMinimumDateTime;
DateTime? lowestMinimumDateTime;
Shared.Models.Properties.IFace face;
Dictionary<string, int> results = new();
Shared.Models.PersonBirthday? lowestPersonBirthday; Shared.Models.PersonBirthday? lowestPersonBirthday;
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections) foreach (Container container in containers)
{ {
lowestIsWrongYear = null;
lowestPersonBirthday = null; lowestPersonBirthday = null;
lowestMinimumDateTime = null;
lowestAverage = double.MaxValue; lowestAverage = double.MaxValue;
if (!propertyHolderCollection.Any()) if (!container.Items.Any())
continue; continue;
if (!propertyHolderCollection[0].SourceDirectory.StartsWith(argZero)) if (!container.SourceDirectory.StartsWith(argZero))
continue; 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; continue;
if (propertyHolder.MinimumDateTime is null) itemMinimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(item.Property);
if (itemMinimumDateTime is null)
continue; continue;
(isWrongYear, _) = propertyHolder.IsWrongYear(); (itemIsWrongYear, _) = item.IsWrongYear();
foreach (Shared.Models.Properties.IFace face in propertyHolder.Faces) 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) if (!face.Populated)
continue; continue;
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); 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); faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncoding);
average = faceDistances.Average(); average = faceDistances.Average();
if (average < lowestAverage) if (average > lowestAverage)
continue; continue;
lowestAverage = average;
lowestIsWrongYear = isWrongYear;
lowestPersonBirthday = personBirthday; lowestPersonBirthday = personBirthday;
lowestMinimumDateTime = minimumDateTime;
} }
if (lowestPersonBirthday is null) if (lowestPersonBirthday is null || lowestMinimumDateTime is null)
continue; continue;
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(lowestPersonBirthday); key = Item.GetKey(lowestMinimumDateTime.Value, lowestIsWrongYear, lowestPersonBirthday);
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(propertyHolder.MinimumDateTime.Value, isWrongYear, lowestPersonBirthday); if (!results.ContainsKey(key))
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0) results.Add(key, 0);
directories = new string[] { string.Empty, facePopulatedKey, personKey, "!---" }; else if (results[key] > maxPer)
else if (timeSpan.HasValue) continue;
directories = new string[] { string.Empty, facePopulatedKey, personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}" }; results[key] += 1;
item.Closest[0] = new(face.LocationIndex, lowestMinimumDateTime.Value, lowestIsWrongYear, lowestPersonBirthday, lowestAverage);
}
}
}
}
public static void SavePropertyHolders(string argZero, List<Container> containers, string zPropertyHolderSingletonDirectory)
{
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<Container> 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 else
{ copyFile = item.ResizedFileHolder.FullName;
isWrongYearFlag = PropertyHolder.GetWrongYearFlag(isWrongYear); if (File.Exists(checkFile))
directories = new string[] { string.Empty, facePopulatedKey, personKey, $"{isWrongYearFlag}{propertyHolder.MinimumDateTime.Value:yyyy}" }; continue;
} File.Copy(copyFile, checkFile);
}
} }
} }
} }
internal static void GetClosest(string argZero, List<PropertyHolder[]> propertyHolderCollections, List<(string[], Shared.Models.PersonBirthday, FaceEncoding[])> collection, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceCollectionDirectory)
{
GetKeyValuePairs(argZero, propertyHolderCollections, collection);
if (peopleCollection is null)
{ }
if (string.IsNullOrEmpty(eDistanceCollectionDirectory))
{ }
// foreach (KeyValuePair<string, List<(string[] Directories, Shared.Models.PersonBirthday PersonBirthday, Shared.Models.Properties.IFace _)>> keyValuePair in keyValuePairs)
// {
// foreach ((string[] directories, Shared.Models.PersonBirthday personBirthday, Shared.Models.Properties.IFace face) in keyValuePair.Value)
// {
// if (face.Populated)
// continue;
// }
// }
} }
} }

View File

@ -29,7 +29,7 @@ internal class F_Random
{ {
bool result = false; bool result = false;
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
string? checkDirectory = Path.GetFullPath(directory); string? checkDirectory = Path.GetFullPath(directory);
for (int i = 0; i < int.MaxValue; i++) for (int i = 0; i < int.MaxValue; i++)
{ {

View File

@ -39,7 +39,7 @@ public class B_Metadata
{ {
Dictionary<string, List<KeyValuePair<string, string>>> results = new(); Dictionary<string, List<KeyValuePair<string, string>>> results = new();
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
try try
{ {
object? @object; object? @object;
@ -78,16 +78,16 @@ public class B_Metadata
return results; return results;
} }
public (int, List<KeyValuePair<string, string>>) GetMetadataCollection(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Property.Models.PropertyHolder propertyHolder) public (int, List<KeyValuePair<string, string>>) GetMetadataCollection(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Property.Models.Item item)
{ {
List<KeyValuePair<string, string>> results = new(); List<KeyValuePair<string, string>> results = new();
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new Exception($"{propertyHolder.ImageFileHolder} is null!"); throw new NullReferenceException(nameof(item.ImageFileHolder));
Dictionary<string, List<KeyValuePair<string, string>>>? dictionary; Dictionary<string, List<KeyValuePair<string, string>>>? dictionary;
string json = string.Empty; string json = string.Empty;
string[] changesFrom = Array.Empty<string>(); string[] changesFrom = Array.Empty<string>();
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> 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.Exists)
{ {
if (fileInfo.Directory?.Parent is null) if (fileInfo.Directory?.Parent is null)
@ -135,7 +135,7 @@ public class B_Metadata
} }
if (dictionary is null || !dictionary.Any()) if (dictionary is null || !dictionary.Any())
{ {
dictionary = GetMetadataCollection(propertyHolder.ImageFileHolder.FullName); dictionary = GetMetadataCollection(item.ImageFileHolder.FullName);
json = JsonSerializer.Serialize(dictionary, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(dictionary, _WriteIndentedJsonSerializerOptions);
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime; bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max(); DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();

View File

@ -28,7 +28,7 @@ public class NotCopyCopy
{ } { }
_AppSettings = appSettings; _AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null) if (appSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism));
_IsEnvironment = isEnvironment; _IsEnvironment = isEnvironment;
_Exceptions = new List<string>(); _Exceptions = new List<string>();
_Log = Serilog.Log.ForContext<NotCopyCopy>(); _Log = Serilog.Log.ForContext<NotCopyCopy>();
@ -43,15 +43,15 @@ public class NotCopyCopy
PredictorModel? predictorModel = null; PredictorModel? predictorModel = null;
_Configuration = configuration; _Configuration = configuration;
if (propertyConfiguration.PopulatePropertyId is null) if (propertyConfiguration.PopulatePropertyId is null)
throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId)); throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId));
if (!_IsEnvironment.Development) if (!_IsEnvironment.Development)
throw new Exception("This program only allows development environments!"); throw new Exception("This program only allows development environments!");
PropertyLogic propertyLogic = GetPropertyLogic(); PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel);
propertyConfiguration.ChangeRootDirectory(configuration.CompareSource); propertyConfiguration.ChangeRootDirectory(configuration.CompareSource);
List<PropertyHolder[]> comparePropertyHolderCollections = Property.Models.Stateless.A_Property.Get(propertyConfiguration, reverse, model, predictorModel, propertyLogic); List<Container> compareContainers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic);
propertyConfiguration.ChangeRootDirectory(configuration.SelectedSource); propertyConfiguration.ChangeRootDirectory(configuration.SelectedSource);
List<PropertyHolder[]> selectedPropertyHolderCollections = Property.Models.Stateless.A_Property.Get(propertyConfiguration, reverse, model, predictorModel, propertyLogic); List<Container> selectedContainers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic);
if (comparePropertyHolderCollections.Count == selectedPropertyHolderCollections.Count) if (compareContainers.Count == selectedContainers.Count)
throw new Exception(); throw new Exception();
string directoryName; string directoryName;
List<string> distinct = new(); List<string> distinct = new();
@ -100,36 +100,36 @@ public class NotCopyCopy
private static void Verify(Models.Configuration configuration) private static void Verify(Models.Configuration configuration)
{ {
if (Path.GetPathRoot(configuration.SelectedSource) == configuration.SelectedSource) 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)) 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)) 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)) 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) 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) private long LogDelta(long ticks, string methodName)
{ {
long result; long result;
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks; result = DateTime.Now.Ticks;
return result; return result;
} }
private PropertyLogic GetPropertyLogic() private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel)
{ {
PropertyLogic result; PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
return result; return result;
} }
@ -137,7 +137,7 @@ public class NotCopyCopy
{ {
List<(string Source, string[] Destination)> results = new(); List<(string Source, string[] Destination)> results = new();
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
string key; string key;
string fileName; string fileName;
A_Property? property; A_Property? property;

View File

@ -30,7 +30,7 @@ public class PrepareForOld
string spellingB; string spellingB;
_AppSettings = appSettings; _AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null) if (appSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism));
_SpellingFindReplace = new(); _SpellingFindReplace = new();
_IsEnvironment = isEnvironment; _IsEnvironment = isEnvironment;
_Exceptions = new List<string>(); _Exceptions = new List<string>();
@ -42,7 +42,7 @@ public class PrepareForOld
Models.Configuration configuration = Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory, propertyConfiguration); Models.Configuration configuration = Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory, propertyConfiguration);
Verify(configuration); Verify(configuration);
if (propertyConfiguration.IgnoreExtensions is null) 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++) for (int i = 0; i < configuration.Spelling.Length; i++)
{ {
spellingA = configuration.Spelling[i]; spellingA = configuration.Spelling[i];
@ -109,7 +109,7 @@ public class PrepareForOld
private static void Verify(Models.Configuration configuration) private static void Verify(Models.Configuration configuration)
{ {
if (configuration.Spelling is null || !configuration.Spelling.Any()) if (configuration.Spelling is null || !configuration.Spelling.Any())
throw new ArgumentNullException(nameof(configuration.Spelling)); throw new NullReferenceException(nameof(configuration.Spelling));
} }
private static List<Models.SaveTabSeparatedValues.ImageExifInfo> GetExifCollection(string infoDirectory, string infoDirectoryExtra, bool checkDistinct) private static List<Models.SaveTabSeparatedValues.ImageExifInfo> 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(); List<(int Index, long Ticks, string RelativeDirectory, string FileNameWithoutExtension, string Extension, string RegexResult)> results = new();
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
long ticks; long ticks;
string json; string json;
string extension; string extension;
@ -224,14 +224,14 @@ public class PrepareForOld
private void SaveTabSeparatedValues(Property.Models.Configuration configuration, string aPropertySingletonDirectory) private void SaveTabSeparatedValues(Property.Models.Configuration configuration, string aPropertySingletonDirectory)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new ArgumentNullException(nameof(rootDirectoryParent)); throw new NullReferenceException(nameof(rootDirectoryParent));
int z = 0; int z = 0;
int mappedIndex; int mappedIndex;
int? propertyId; int? propertyId;
@ -414,7 +414,7 @@ public class PrepareForOld
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
Dictionary<int, string[]>? source = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json); Dictionary<int, string[]>? source = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
if (source is null) if (source is null)
throw new ArgumentNullException(nameof(source)); throw new NullReferenceException(nameof(source));
{ {
int propertyId; int propertyId;
foreach (KeyValuePair<int, string[]> keyValuePair in source) foreach (KeyValuePair<int, string[]> keyValuePair in source)
@ -469,12 +469,12 @@ public class PrepareForOld
private void ReSaveJsonFiles() private void ReSaveJsonFiles()
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new ArgumentNullException(nameof(rootDirectoryParent)); throw new NullReferenceException(nameof(rootDirectoryParent));
int z = 0; int z = 0;
int propertyId; int propertyId;
List<int> missingIndices = new(); List<int> missingIndices = new();
@ -523,14 +523,14 @@ public class PrepareForOld
private void CopyMissingImagesLogs() private void CopyMissingImagesLogs()
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory);
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new ArgumentNullException(nameof(rootDirectoryParent)); throw new NullReferenceException(nameof(rootDirectoryParent));
int z = 0; int z = 0;
int propertyId; int propertyId;
Dictionary<int, int> findReplace = new(); Dictionary<int, int> findReplace = new();
@ -591,14 +591,14 @@ public class PrepareForOld
private void VerifyAgainstIndexInfoJsonFiles(Property.Models.Configuration configuration, string aPropertySingletonDirectory) private void VerifyAgainstIndexInfoJsonFiles(Property.Models.Configuration configuration, string aPropertySingletonDirectory)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new ArgumentNullException(nameof(rootDirectoryParent)); throw new NullReferenceException(nameof(rootDirectoryParent));
int z = 0; int z = 0;
int? propertyId; int? propertyId;
long? propertyTicks; long? propertyTicks;

View File

@ -33,7 +33,7 @@ public class PropertyCompareLogic
{ {
List<PropertyCompare> results = new(); List<PropertyCompare> results = new();
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
int index; int index;
string value; string value;
long[] distinctNumberValues; long[] distinctNumberValues;
@ -81,7 +81,7 @@ public class PropertyCompareLogic
{ {
List<string[]> fromThenToCollection = new(); List<string[]> fromThenToCollection = new();
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
int z = 0; int z = 0;
string to; string to;
string from; string from;
@ -177,7 +177,7 @@ public class PropertyCompareLogic
string json = File.ReadAllText(jsonFile); string json = File.ReadAllText(jsonFile);
A_Property? property = JsonSerializer.Deserialize<A_Property>(json); A_Property? property = JsonSerializer.Deserialize<A_Property>(json);
if (property?.Id is null) if (property?.Id is null)
throw new ArgumentNullException(nameof(property)); throw new NullReferenceException(nameof(property));
DateTime minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(property); DateTime minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(property);
corrected = string.Concat(relativeDirectory, jsonFileNameWithoutExtension); corrected = string.Concat(relativeDirectory, jsonFileNameWithoutExtension);
if (_SpellingFindReplace is not null && (from l in _SpellingFindReplace where corrected.Contains(l.Find) select true).Any()) 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<PropertyCompare> results = new(); List<PropertyCompare> results = new();
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
string[] files; string[] files;
int totalSeconds; int totalSeconds;
string directory; string directory;
@ -274,7 +274,7 @@ public class PropertyCompareLogic
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection; List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection;
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism };
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; 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) foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in groupCollection)
{ {
if (!topDirectories.Any()) if (!topDirectories.Any())
@ -319,7 +319,7 @@ public class PropertyCompareLogic
private void MoveFiles(string[] directories, List<string[]> fromThenToCollection) private void MoveFiles(string[] directories, List<string[]> fromThenToCollection)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
int z; int z;
string to; string to;
string from; string from;
@ -406,7 +406,7 @@ public class PropertyCompareLogic
public void SaveDiffFiles(string aPropertyCollectionDirectory, int loadLessThan, PropertyCompare[] propertyCompares, PropertyCompare[]? diffPropertyCompares) public void SaveDiffFiles(string aPropertyCollectionDirectory, int loadLessThan, PropertyCompare[] propertyCompares, PropertyCompare[]? diffPropertyCompares)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
string text; string text;
string[] lines; string[] lines;
string fileName; string fileName;
@ -459,7 +459,7 @@ public class PropertyCompareLogic
public void SaveLogAndMoveFiles(string aPropertyCollectionDirectory, int loadLessThan, PropertyCompare[] propertyCompares, PropertyCompare[]? diffPropertyCompares, int i) public void SaveLogAndMoveFiles(string aPropertyCollectionDirectory, int loadLessThan, PropertyCompare[] propertyCompares, PropertyCompare[]? diffPropertyCompares, int i)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
List<string> lines; List<string> lines;
string checkDirectory; string checkDirectory;
string[] toDirectories; string[] toDirectories;
@ -498,7 +498,7 @@ public class PropertyCompareLogic
public void WithSubdirectory(string propertyDirectory, bool subDirectoriesAny, string fileName, bool renameCompare, bool deleteArg) public void WithSubdirectory(string propertyDirectory, bool subDirectoriesAny, string fileName, bool renameCompare, bool deleteArg)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
List<string[]> fileCollection = new(); List<string[]> fileCollection = new();
if (renameCompare && deleteArg) if (renameCompare && deleteArg)
throw new Exception(); throw new Exception();

View File

@ -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;
}
}

View File

@ -65,37 +65,37 @@ public class Configuration
public static void Verify(Configuration? propertyConfiguration) public static void Verify(Configuration? propertyConfiguration)
{ {
if (propertyConfiguration is null) if (propertyConfiguration is null)
throw new ArgumentNullException(nameof(propertyConfiguration)); throw new NullReferenceException(nameof(propertyConfiguration));
if (propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime is null) 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()) 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) if (propertyConfiguration.PopulatePropertyId is null)
throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId)); throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId));
if (propertyConfiguration.PropertiesChangedForProperty is null) if (propertyConfiguration.PropertiesChangedForProperty is null)
throw new ArgumentNullException(nameof(propertyConfiguration.PropertiesChangedForProperty)); throw new NullReferenceException(nameof(propertyConfiguration.PropertiesChangedForProperty));
if (propertyConfiguration.PropertyContentCollectionFiles is null) 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()) 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()) 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()) 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) if (propertyConfiguration.WriteBitmapDataBytes is null)
throw new ArgumentNullException(nameof(propertyConfiguration.WriteBitmapDataBytes)); throw new NullReferenceException(nameof(propertyConfiguration.WriteBitmapDataBytes));
if (Path.GetPathRoot(propertyConfiguration.RootDirectory) == propertyConfiguration.RootDirectory) if (Path.GetPathRoot(propertyConfiguration.RootDirectory) == propertyConfiguration.RootDirectory)
throw new ArgumentNullException(nameof(propertyConfiguration.RootDirectory)); throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory));
if (propertyConfiguration is null) if (propertyConfiguration is null)
throw new ArgumentNullException(nameof(propertyConfiguration)); throw new NullReferenceException(nameof(propertyConfiguration));
if (string.IsNullOrEmpty(propertyConfiguration.DateGroup)) if (string.IsNullOrEmpty(propertyConfiguration.DateGroup))
throw new ArgumentNullException(nameof(propertyConfiguration.DateGroup)); throw new NullReferenceException(nameof(propertyConfiguration.DateGroup));
if (string.IsNullOrEmpty(propertyConfiguration.FileNameDirectorySeparator)) if (string.IsNullOrEmpty(propertyConfiguration.FileNameDirectorySeparator))
throw new ArgumentNullException(nameof(propertyConfiguration.FileNameDirectorySeparator)); throw new NullReferenceException(nameof(propertyConfiguration.FileNameDirectorySeparator));
if (string.IsNullOrEmpty(propertyConfiguration.Pattern)) 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)) 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; public void ChangeRootDirectory(string rootDirectory) => _RootDirectory = rootDirectory;

View File

@ -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<Item> _Items;
protected readonly string _SourceDirectory;
public int G => _G;
public List<Item> Items => _Items;
public int R => _R;
public string SourceDirectory => _SourceDirectory;
[JsonConstructor]
public Container(int g, int r, List<Item> 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;
}
}

View File

@ -5,7 +5,7 @@ public class FileHolder
protected readonly DateTime _CreationTime; protected readonly DateTime _CreationTime;
protected readonly string? _DirectoryName; protected readonly string? _DirectoryName;
protected readonly bool _Exists; protected readonly bool _Exists;
protected readonly string _Extension; protected readonly string _ExtensionLowered;
protected readonly string _FullName; protected readonly string _FullName;
protected readonly DateTime _LastWriteTime; protected readonly DateTime _LastWriteTime;
protected readonly long? _Length; protected readonly long? _Length;
@ -14,19 +14,19 @@ public class FileHolder
public DateTime CreationTime => _CreationTime; public DateTime CreationTime => _CreationTime;
public string? DirectoryName => _DirectoryName; public string? DirectoryName => _DirectoryName;
public bool Exists => _Exists; public bool Exists => _Exists;
public string Extension => _Extension; public string ExtensionLowered => _ExtensionLowered;
public string FullName => _FullName; public string FullName => _FullName;
public DateTime LastWriteTime => _LastWriteTime; public DateTime LastWriteTime => _LastWriteTime;
public long? Length => _Length; public long? Length => _Length;
public string Name => _Name; public string Name => _Name;
public string NameWithoutExtension => _NameWithoutExtension; 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; _CreationTime = creationTime;
_DirectoryName = directoryName; _DirectoryName = directoryName;
_Exists = exists; _Exists = exists;
_Extension = extension; _ExtensionLowered = extensionLowered;
_FullName = fullName; _FullName = fullName;
_LastWriteTime = lastWriteTime; _LastWriteTime = lastWriteTime;
_Length = length; _Length = length;
@ -41,7 +41,7 @@ public class FileHolder
_CreationTime = fileInfo.CreationTime; _CreationTime = fileInfo.CreationTime;
_DirectoryName = fileInfo.DirectoryName; _DirectoryName = fileInfo.DirectoryName;
_Exists = fileInfo.Exists; _Exists = fileInfo.Exists;
_Extension = fileInfo.Extension; _ExtensionLowered = fileInfo.Extension.ToLower();
_FullName = fileInfo.FullName; _FullName = fileInfo.FullName;
_LastWriteTime = fileInfo.LastWriteTime; _LastWriteTime = fileInfo.LastWriteTime;
if (fileInfo.Exists) if (fileInfo.Exists)
@ -56,7 +56,7 @@ public class FileHolder
_CreationTime = fileInfo.CreationTime; _CreationTime = fileInfo.CreationTime;
_DirectoryName = fileInfo.DirectoryName; _DirectoryName = fileInfo.DirectoryName;
_Exists = fileInfo.Exists; _Exists = fileInfo.Exists;
_Extension = fileInfo.Extension; _ExtensionLowered = fileInfo.Extension.ToLower();
_FullName = fileInfo.FullName; _FullName = fileInfo.FullName;
_LastWriteTime = fileInfo.LastWriteTime; _LastWriteTime = fileInfo.LastWriteTime;
if (fileInfo.Exists) if (fileInfo.Exists)

View File

@ -4,86 +4,72 @@ using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Property.Models; namespace View_by_Distance.Property.Models;
public class PropertyHolder public class Item
{ {
protected readonly bool? _Abandoned; protected readonly bool? _Abandoned;
protected readonly bool? _Changed; protected readonly bool? _Changed;
protected List<Closest> _Closest;
protected List<IFace> _Faces; protected List<IFace> _Faces;
protected readonly FileHolder? _ImageFileHolder; protected readonly FileHolder? _ImageFileHolder;
protected readonly string _ImageFileNameWithoutExtension;
protected readonly int _G;
protected DateTime? _MinimumDateTime;
protected bool? _Moved; protected bool? _Moved;
protected List<(bool?, DateTime, PersonBirthday, double?)> _Named; protected List<Named> _Named;
protected readonly bool? _NoJson; protected readonly bool? _NoJson;
protected A_Property? _Property; protected A_Property? _Property;
protected readonly int _R;
protected readonly string _RelativePath; protected readonly string _RelativePath;
protected FileHolder? _ResizedFileHolder; protected FileHolder? _ResizedFileHolder;
protected readonly string _SourceDirectory;
protected readonly string _SourceDirectoryFile; protected readonly string _SourceDirectoryFile;
protected bool? _ValidImageFormatExtension; protected bool _ValidImageFormatExtension;
public bool? Abandoned => _Abandoned; public bool? Abandoned => _Abandoned;
public bool? Changed => _Changed; public bool? Changed => _Changed;
public List<Closest> Closest => _Closest;
public List<IFace> Faces => _Faces; public List<IFace> Faces => _Faces;
public FileHolder? ImageFileHolder => _ImageFileHolder; public FileHolder? ImageFileHolder => _ImageFileHolder;
public string ImageFileNameWithoutExtension => _ImageFileNameWithoutExtension;
public int G => _G;
public DateTime? MinimumDateTime => _MinimumDateTime;
public bool? Moved => _Moved; public bool? Moved => _Moved;
public bool? NoJson => _NoJson; public bool? NoJson => _NoJson;
public List<(bool? isWrongYear, DateTime minimumDateTime, PersonBirthday personBirthday, double? pixelPercentage)> Named => _Named; public List<Named> Named => _Named;
public A_Property? Property => _Property; public A_Property? Property => _Property;
public int R => _R;
public string RelativePath => _RelativePath; public string RelativePath => _RelativePath;
public FileHolder? ResizedFileHolder => _ResizedFileHolder; public FileHolder? ResizedFileHolder => _ResizedFileHolder;
public string SourceDirectory => _SourceDirectory;
public string SourceDirectoryFile => _SourceDirectoryFile; public string SourceDirectoryFile => _SourceDirectoryFile;
public bool? ValidImageFormatExtension => _ValidImageFormatExtension; 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;
}
[JsonConstructor] [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> closest, List<IFace> faces, FileHolder? imageFileHolder, bool? moved, List<Named> named, bool? noJson, A_Property? property, string relativePath, FileHolder? resizedFileHolder, string sourceDirectoryFile, bool validImageFormatExtension)
{ {
_G = g; _Abandoned = abandoned;
_R = r;
_Faces = new();
_Moved = moved;
_Named = new();
_Changed = changed; _Changed = changed;
_Closest = closest;
_Faces = faces;
_ImageFileHolder = imageFileHolder;
_Moved = moved;
_Named = named;
_NoJson = noJson;
_Property = property; _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; _Abandoned = abandoned;
_NoJson = abandoned is null; _NoJson = abandoned is null;
_RelativePath = relativePath; _RelativePath = relativePath;
_ImageFileHolder = imageFileInfo; _ImageFileHolder = imageFileInfo;
_SourceDirectory = sourceDirectory;
_SourceDirectoryFile = sourceDirectoryFile; _SourceDirectoryFile = sourceDirectoryFile;
_ValidImageFormatExtension = validImageFormatExtension; _ValidImageFormatExtension = isValidImageFormatExtension;
_MinimumDateTime = Stateless.A_Property.GetMinimumDateTime(property); if (relativePath.EndsWith(".json"))
if (imageFileInfo is null) throw new ArgumentException("Can not be a *.json file!");
_ImageFileNameWithoutExtension = string.Empty; if (imageFileInfo is not null && imageFileInfo.ExtensionLowered is ".json")
else
_ImageFileNameWithoutExtension = Path.GetFileNameWithoutExtension(imageFileInfo.FullName);
if (imageFileInfo is not null && imageFileInfo.Extension is ".json")
throw new ArgumentException("Can not be a *.json file!"); 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; internal void SetMoved(bool moved) => _Moved = moved;
public static string GetWrongYearFlag(bool? isWrongYear) => isWrongYear is null ? "#" : isWrongYear.Value ? "~" : "="; 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 bool Any() => (_Abandoned.HasValue && _Abandoned.Value) || (_Changed.HasValue && _Changed.Value) || (_Moved.HasValue && _Moved.Value) || (_NoJson.HasValue && _NoJson.Value);
public void Update(A_Property property) public void Update(A_Property property) => _Property = property;
{
_Property = property;
_MinimumDateTime = Stateless.A_Property.GetMinimumDateTime(property);
}
public (bool?, string[]) IsWrongYear() public (bool?, string[]) IsWrongYear()
{ {
(bool?, string[]) result; (bool?, string[]) result;
if (_Property is null || _ImageFileHolder is null) if (_Property is null || _ImageFileHolder is null)
throw new ArgumentNullException(); throw new NullReferenceException();
result = _Property.IsWrongYear(_ImageFileHolder.FullName, _MinimumDateTime); DateTime? minimumDateTime = Stateless.A_Property.GetMinimumDateTime(_Property);
result = _Property.IsWrongYear(_ImageFileHolder.FullName, minimumDateTime);
return result; return result;
} }
public static void AddToNamed(PropertyLogic propertyLogic, PropertyHolder[] filteredPropertyHolderCollection) public static void AddToNamed(PropertyLogic propertyLogic, Item[] filteredItems)
{ {
Item item;
bool? isWrongYear; bool? isWrongYear;
string[] segments; string[] segments;
string[] personKeys; string[] personKeys;
double? pixelPercentage; double? pixelPercentage;
DateTime minimumDateTime; DateTime minimumDateTime;
PropertyHolder propertyHolder;
PersonBirthday? personBirthday; PersonBirthday? personBirthday;
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) for (int i = 0; i < filteredItems.Length; i++)
{ {
propertyHolder = filteredPropertyHolderCollection[i]; item = filteredItems[i];
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
continue; 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; continue;
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(propertyHolder.Property.Id.Value)) if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(item.Property.Id.Value))
continue; continue;
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property); minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property);
personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value]; personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[item.Property.Id.Value];
(isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileHolder.FullName, minimumDateTime); (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
for (int j = 0; j < personKeys.Length; j++) for (int j = 0; j < personKeys.Length; j++)
{ {
segments = Shared.Models.Stateless.Methods.IPersonBirthday.GetSegments(personKeys[j]); segments = Shared.Models.Stateless.Methods.IPersonBirthday.GetSegments(personKeys[j]);
@ -138,14 +121,15 @@ public class PropertyHolder
pixelPercentage = null; pixelPercentage = null;
else else
pixelPercentage = value; 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[] keys;
string directory; string directory;
string personKey; string personKey;
@ -160,37 +144,40 @@ public class PropertyHolder
string shortcutFileName; string shortcutFileName;
string subDirectoryName; string subDirectoryName;
List<int> indices = new(); List<int> indices = new();
DateTime? minimumDateTime;
List<IFace> faceCollection; List<IFace> faceCollection;
PropertyHolder propertyHolder;
PersonBirthday? personBirthday; PersonBirthday? personBirthday;
List<(string, IFace?, (string, string, string, string))> collection; 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(); indices.Clear();
personKey = string.Empty; personKey = string.Empty;
copyFileName = string.Empty; copyFileName = string.Empty;
copyDirectory = string.Empty; copyDirectory = string.Empty;
propertyHolder = filteredPropertyHolderCollection[i]; item = filteredItems[i];
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
continue; continue;
relativePath = Path.GetDirectoryName($"C:{propertyHolder.RelativePath}"); relativePath = Path.GetDirectoryName($"C:{item.RelativePath}");
if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3) if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3)
continue; 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; continue;
collection = new(); collection = new();
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(propertyHolder.Property.Id.Value)) if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(item.Property.Id.Value))
{ {
faceCollection = new(); faceCollection = new();
directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}"); directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}");
} }
else else
{ {
faceCollection = propertyHolder.Faces; faceCollection = item.Faces;
keys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value]; keys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[item.Property.Id.Value];
(isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileHolder.FullName, propertyHolder.MinimumDateTime.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); isWrongYearFlag = GetWrongYearFlag(isWrongYear);
subDirectoryName = $"{isWrongYearFlag}{propertyHolder.MinimumDateTime.Value:yyyy}"; subDirectoryName = $"{isWrongYearFlag}{minimumDateTime.Value:yyyy}";
if (!faceCollection.Any()) if (!faceCollection.Any())
directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName); directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName);
else if (keys.Length != 1) else if (keys.Length != 1)
@ -204,7 +191,7 @@ public class PropertyHolder
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(keys[zero]); personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(keys[zero]);
if (personBirthday is null) if (personBirthday is null)
continue; 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.HasValue)
{ {
if (timeSpan.Value.Ticks < 0) if (timeSpan.Value.Ticks < 0)
@ -218,10 +205,10 @@ public class PropertyHolder
copyDirectory = Path.Combine(dFacesContentDirectory, "Images", personKey, subDirectoryName); copyDirectory = Path.Combine(dFacesContentDirectory, "Images", personKey, subDirectoryName);
else else
copyDirectory = Path.Combine(dFacesContentDirectory, "ImagesBut", personKey, subDirectoryName); 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()) if (string.IsNullOrEmpty(personKey) || !indices.Any())
collection.Add(new(personKey, null, (directory, copyDirectory, copyFileName, shortcutFileName))); collection.Add(new(personKey, null, (directory, copyDirectory, copyFileName, shortcutFileName)));
else else
@ -229,56 +216,75 @@ public class PropertyHolder
foreach (int index in indices) foreach (int index in indices)
collection.Add(new(personKey, faceCollection[index], (directory, copyDirectory, copyFileName, shortcutFileName))); collection.Add(new(personKey, faceCollection[index], (directory, copyDirectory, copyFileName, shortcutFileName)));
} }
results.Add(new(propertyHolder, collection.ToArray())); results.Add(new(item, collection.ToArray()));
} }
return results; return results;
} }
public static Dictionary<string, List<(string[], PersonBirthday, IFace)>> GetKeyValuePairs(string argZero, List<PropertyHolder[]> propertyHolderCollections) public static string GetKey(DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday)
{ {
Dictionary<string, List<(string[], PersonBirthday, IFace)>> results = new(); 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
{
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<string, List<(DateTime, bool?, PersonBirthday, IFace)>> GetKeyValuePairs(string argZero, List<Container> containers)
{
Dictionary<string, List<(DateTime, bool?, PersonBirthday, IFace)>> results = new();
string key; string key;
string personKey; foreach (Container container in containers)
TimeSpan? timeSpan;
string[] directories;
string isWrongYearFlag;
const string facePopulatedKey = "Images";
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
{ {
if (!propertyHolderCollection.Any()) if (!container.Items.Any())
continue; continue;
if (!propertyHolderCollection[0].SourceDirectory.StartsWith(argZero)) if (!container.SourceDirectory.StartsWith(argZero))
continue; 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; 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; continue;
foreach (IFace face in propertyHolder.Faces) foreach (IFace face in item.Faces)
{ {
if (!face.Populated) if (!face.Populated)
continue; continue;
if (pixelPercentage.HasValue && pixelPercentage.Value != face.Location.PixelPercentage) if (named.PersonBirthday is null)
continue; continue;
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday); if (named.PixelPercentage.HasValue && named.PixelPercentage.Value != face.Location.PixelPercentage)
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday); continue;
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0) key = GetKey(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday);
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 (!results.ContainsKey(key)) if (!results.ContainsKey(key))
results.Add(key, new()); results.Add(key, new());
results[key].Add(new(directories, personBirthday, face)); results[key].Add(new(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday, face));
if (pixelPercentage is null) if (named.PixelPercentage is null)
break; break;
} }
} }

27
Property/Models/Named.cs Normal file
View File

@ -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;
}
}

View File

@ -21,24 +21,30 @@ public class PropertyLogic
protected readonly Dictionary<int, string[]> _SixCharacterNamedFaceInfo; protected readonly Dictionary<int, string[]> _SixCharacterNamedFaceInfo;
protected readonly Dictionary<int, string[]> _NamedFaceInfoDeterministicHashCodeIndices; protected readonly Dictionary<int, string[]> _NamedFaceInfoDeterministicHashCodeIndices;
public bool Reverse { get; }
public List<string> AngleBracketCollection { get; } public List<string> AngleBracketCollection { get; }
public Dictionary<int, int[]> KeyValuePairs => _KeyValuePairs; public Dictionary<int, int[]> KeyValuePairs => _KeyValuePairs;
public Dictionary<int, int[]> IndicesFromNew => _IndicesFromNew; public Dictionary<int, int[]> IndicesFromNew => _IndicesFromNew;
public List<string> ExceptionsDirectories => _ExceptionsDirectories; public List<string> ExceptionsDirectories => _ExceptionsDirectories;
public Dictionary<int, string[]> NamedFaceInfoDeterministicHashCodeIndices => _NamedFaceInfoDeterministicHashCodeIndices; public Dictionary<int, string[]> NamedFaceInfoDeterministicHashCodeIndices => _NamedFaceInfoDeterministicHashCodeIndices;
private readonly Model? _Model;
private readonly Serilog.ILogger? _Log; private readonly Serilog.ILogger? _Log;
private readonly string[] _VerifyToSeason; private readonly string[] _VerifyToSeason;
private readonly int _MaxDegreeOfParallelism; private readonly int _MaxDegreeOfParallelism;
private readonly ASCIIEncoding _ASCIIEncoding; private readonly ASCIIEncoding _ASCIIEncoding;
private readonly Configuration _Configuration; private readonly Configuration _Configuration;
private readonly PredictorModel? _PredictorModel;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions; 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(); _AllCollection = new();
_Configuration = configuration; _Configuration = configuration;
_ExceptionsDirectories = new(); _ExceptionsDirectories = new();
_PredictorModel = predictorModel;
_ASCIIEncoding = new ASCIIEncoding(); _ASCIIEncoding = new ASCIIEncoding();
AngleBracketCollection = new List<string>(); AngleBracketCollection = new List<string>();
_Log = Serilog.Log.ForContext<A_Property>(); _Log = Serilog.Log.ForContext<A_Property>();
@ -57,7 +63,7 @@ public class PropertyLogic
Dictionary<int, string[]>? sixCharacterNamedFaceInfo; Dictionary<int, string[]>? sixCharacterNamedFaceInfo;
string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new ArgumentNullException(nameof(rootDirectoryParent)); throw new NullReferenceException(nameof(rootDirectoryParent));
files = Directory.GetFiles(rootDirectoryParent, "*DeterministicHashCode*.json", SearchOption.TopDirectoryOnly); files = Directory.GetFiles(rootDirectoryParent, "*DeterministicHashCode*.json", SearchOption.TopDirectoryOnly);
if (files.Length != 1) if (files.Length != 1)
namedFaceInfoDeterministicHashCodeIndices = new(); namedFaceInfoDeterministicHashCodeIndices = new();
@ -66,7 +72,7 @@ public class PropertyLogic
json = File.ReadAllText(files[0]); json = File.ReadAllText(files[0]);
namedFaceInfoDeterministicHashCodeIndices = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json); namedFaceInfoDeterministicHashCodeIndices = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
if (namedFaceInfoDeterministicHashCodeIndices is null) if (namedFaceInfoDeterministicHashCodeIndices is null)
throw new ArgumentNullException(nameof(namedFaceInfoDeterministicHashCodeIndices)); throw new NullReferenceException(nameof(namedFaceInfoDeterministicHashCodeIndices));
} }
if (namedFaceInfoDeterministicHashCodeIndices.Any()) if (namedFaceInfoDeterministicHashCodeIndices.Any())
sixCharacterNamedFaceInfo = new(); sixCharacterNamedFaceInfo = new();
@ -80,7 +86,7 @@ public class PropertyLogic
json = File.ReadAllText(files[0]); json = File.ReadAllText(files[0]);
sixCharacterNamedFaceInfo = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json); sixCharacterNamedFaceInfo = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
if (sixCharacterNamedFaceInfo is null) if (sixCharacterNamedFaceInfo is null)
throw new ArgumentNullException(nameof(sixCharacterNamedFaceInfo)); throw new NullReferenceException(nameof(sixCharacterNamedFaceInfo));
} }
} }
files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly); files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly);
@ -91,7 +97,7 @@ public class PropertyLogic
json = File.ReadAllText(files[0]); json = File.ReadAllText(files[0]);
keyValuePairs = JsonSerializer.Deserialize<Dictionary<int, int[]>>(json); keyValuePairs = JsonSerializer.Deserialize<Dictionary<int, int[]>>(json);
if (keyValuePairs is null) if (keyValuePairs is null)
throw new ArgumentNullException(nameof(keyValuePairs)); throw new NullReferenceException(nameof(keyValuePairs));
} }
foreach (string propertyContentCollectionFile in configuration.PropertyContentCollectionFiles) foreach (string propertyContentCollectionFile in configuration.PropertyContentCollectionFiles)
{ {
@ -103,7 +109,7 @@ public class PropertyLogic
json = File.ReadAllText(fullPath); json = File.ReadAllText(fullPath);
collection = JsonSerializer.Deserialize<List<KeyValuePair<int, int[]>>>(json); collection = JsonSerializer.Deserialize<List<KeyValuePair<int, int[]>>>(json);
if (collection is null) if (collection is null)
throw new ArgumentNullException(nameof(collection)); throw new NullReferenceException(nameof(collection));
foreach (KeyValuePair<int, int[]> keyValuePair in collection) foreach (KeyValuePair<int, int[]> keyValuePair in collection)
{ {
if (indicesFromNew.ContainsKey(keyValuePair.Key)) if (indicesFromNew.ContainsKey(keyValuePair.Key))
@ -127,7 +133,7 @@ public class PropertyLogic
{ {
long result; long result;
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks; result = DateTime.Now.Ticks;
@ -168,13 +174,13 @@ public class PropertyLogic
#pragma warning disable CA1416 #pragma warning disable CA1416
private A_Property GetImageProperty(string angleBracket, FileHolder filteredSourceDirectoryFileHolder, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List<int> indices) private A_Property GetImageProperty(FileHolder filteredSourceDirectoryFileHolder, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List<int> indices)
{ {
A_Property result; A_Property result;
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_Configuration.WriteBitmapDataBytes is null) if (_Configuration.WriteBitmapDataBytes is null)
throw new ArgumentNullException(nameof(_Configuration.WriteBitmapDataBytes)); throw new NullReferenceException(nameof(_Configuration.WriteBitmapDataBytes));
long ticks; long ticks;
byte[] bytes; byte[] bytes;
string value; string value;
@ -201,7 +207,7 @@ public class PropertyLogic
} }
else if (!isIgnoreExtension && isValidImageFormatExtension) 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!"); throw new Exception("In order to keep six character indices at least one need to have an item!");
try try
{ {
@ -209,6 +215,7 @@ public class PropertyLogic
if (populateId && (id is null || !indices.Any())) if (populateId && (id is null || !indices.Any()))
{ {
using Bitmap bitmap = new(image); using Bitmap bitmap = new(image);
string angleBracket = AngleBracketCollection[0];
Rectangle rectangle = new(0, 0, image.Width, image.Height); Rectangle rectangle = new(0, 0, image.Width, image.Height);
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat); BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
IntPtr intPtr = bitmapData.Scan0; IntPtr intPtr = bitmapData.Scan0;
@ -341,24 +348,27 @@ public class PropertyLogic
#pragma warning restore CA1416 #pragma warning restore CA1416
private A_Property GetPropertyOfPrivate(string angleBracket, PropertyHolder propertyHolder, bool firstPass, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, string extensionLowered) private A_Property GetPropertyOfPrivate(Item item, bool firstPass, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension, bool isValidMetadataExtensions)
{ {
A_Property? result; A_Property? result;
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime is null) if (_Configuration.ForcePropertyLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime)); throw new NullReferenceException(nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime));
if (_Configuration.PopulatePropertyId is null) if (_Configuration.PopulatePropertyId is null)
throw new ArgumentNullException(nameof(_Configuration.PopulatePropertyId)); throw new NullReferenceException(nameof(_Configuration.PopulatePropertyId));
if (_Configuration.PropertiesChangedForProperty is null) 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; string json;
int? id = null; int? id = null;
List<int> indices = new(); List<int> indices = new();
bool hasWrongYearProperty = false; bool hasWrongYearProperty = false;
string[] changesFrom = Array.Empty<string>(); string[] changesFrom = Array.Empty<string>();
string angleBracket = AngleBracketCollection[0];
bool populateId = !firstPass && _Configuration.PopulatePropertyId.Value; bool populateId = !firstPass && _Configuration.PopulatePropertyId.Value;
string without = Path.Combine(angleBracket.Replace("<>", "{}"), $"{propertyHolder.ImageFileNameWithoutExtension}.json"); string without = Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}.json");
FileInfo fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{propertyHolder.ImageFileNameWithoutExtension}{extensionLowered}.json")); FileInfo fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
if (isValidImageFormatExtension && File.Exists(without)) if (item.ValidImageFormatExtension && File.Exists(without))
{ {
File.Move(without, fileInfo.FullName); File.Move(without, fileInfo.FullName);
fileInfo.Refresh(); fileInfo.Refresh();
@ -398,40 +408,40 @@ public class PropertyLogic
json = File.ReadAllText(fileInfo.FullName); json = File.ReadAllText(fileInfo.FullName);
try try
{ {
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new ArgumentException($"{propertyHolder.ImageFileHolder} is null!"); throw new NullReferenceException(nameof(item.ImageFileHolder));
bool check = true; bool check = true;
A_Property? property = JsonSerializer.Deserialize<A_Property>(json); A_Property? property = JsonSerializer.Deserialize<A_Property>(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; check = false;
id = property?.Id; id = property?.Id;
if (property is not null && property.Indices.Any()) if (property is not null && property.Indices.Any())
indices = property.Indices.ToList(); 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; check = false;
id = property?.Id; id = property?.Id;
if (property is not null && property.Indices.Any()) if (property is not null && property.Indices.Any())
indices = property.Indices.ToList(); 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; check = false;
id = null; id = null;
indices.Clear(); 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; check = false;
id = property?.Id; id = property?.Id;
if (property is not null && property.Indices.Any()) if (property is not null && property.Indices.Any())
indices = property.Indices.ToList(); 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) if (property?.Width is not null && property?.Height is not null && property.Width.Value != property.Height.Value)
throw new Exception("Was square!"); throw new Exception("Was square!");
} }
@ -440,7 +450,7 @@ public class PropertyLogic
// check = false; // check = false;
// id = null; // id = null;
// indices.Clear(); // 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")) if (json.Contains("WrongYear"))
{ {
@ -465,9 +475,9 @@ public class PropertyLogic
} }
if (result is null) if (result is null)
{ {
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new ArgumentException($"{propertyHolder.ImageFileHolder} is null!"); throw new NullReferenceException(nameof(item.ImageFileHolder));
result = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices); result = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
if (populateId && IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true)) if (populateId && IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
{ {
@ -494,11 +504,11 @@ public class PropertyLogic
return result; return result;
} }
private bool AnyFilesMoved(string sourceDirectory, PropertyHolder[] filteredPropertyHolderCollection) private bool AnyFilesMoved(string sourceDirectory, Item[] filteredItems)
{ {
bool result = false; bool result = false;
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
int season; int season;
string[] matches; string[] matches;
string deleteFile; string deleteFile;
@ -510,20 +520,16 @@ public class PropertyLogic
string destinationDirectory; string destinationDirectory;
string[] sourceDirectorySegments; string[] sourceDirectorySegments;
DateTime directoryMaximumOfMinimumDateTime = DateTime.MinValue; 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; continue;
if (propertyHolder.Property is null) minimumDateTime = Stateless.A_Property.GetMinimumDateTime(filteredItem.Property);
continue;
if (propertyHolder.ImageFileHolder is null)
continue;
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property);
if (minimumDateTime > directoryMaximumOfMinimumDateTime) if (minimumDateTime > directoryMaximumOfMinimumDateTime)
directoryMaximumOfMinimumDateTime = minimumDateTime; 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) if (isWrongYear is null || !isWrongYear.Value)
dateTime = minimumDateTime; dateTime = minimumDateTime;
else else
@ -534,20 +540,20 @@ public class PropertyLogic
continue; continue;
} }
try try
{ File.SetCreationTime(propertyHolder.ImageFileHolder.FullName, dateTime); } { File.SetCreationTime(filteredItem.ImageFileHolder.FullName, dateTime); }
catch (Exception) catch (Exception)
{ } { }
} }
if (!_VerifyToSeason.Contains(sourceDirectory)) if (!_VerifyToSeason.Contains(sourceDirectory))
continue; 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) if (timeSpan.TotalHours > 6)
{ {
_Log.Warning($"*** propertyHolder.FileInfo.FullName <{propertyHolder.ImageFileHolder.FullName}>"); _Log.Warning($"*** propertyHolder.FileInfo.FullName <{filteredItem.ImageFileHolder.FullName}>");
_Log.Warning($"*** DateTimeOriginal <{propertyHolder.Property.DateTimeOriginal.Value}>"); _Log.Warning($"*** DateTimeOriginal <{filteredItem.Property.DateTimeOriginal.Value}>");
_Log.Warning($"*** LastWriteTime <{propertyHolder.Property.LastWriteTime}>"); _Log.Warning($"*** LastWriteTime <{filteredItem.Property.LastWriteTime}>");
_Log.Warning($"*** TotalHours <{timeSpan.TotalHours}>"); _Log.Warning($"*** TotalHours <{timeSpan.TotalHours}>");
} }
} }
@ -561,41 +567,41 @@ public class PropertyLogic
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName}"); destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName}");
if (destinationDirectory == sourceDirectory) if (destinationDirectory == sourceDirectory)
continue; continue;
lock (propertyHolder) lock (filteredItem)
propertyHolder.SetMoved(true); filteredItem.SetMoved(true);
if (!result) if (!result)
result = true; result = true;
if (!Directory.Exists(destinationDirectory)) if (!Directory.Exists(destinationDirectory))
_ = Directory.CreateDirectory(destinationDirectory); _ = Directory.CreateDirectory(destinationDirectory);
destinationFile = Path.Combine(destinationDirectory, propertyHolder.ImageFileHolder.Name); destinationFile = Path.Combine(destinationDirectory, filteredItem.ImageFileHolder.Name);
if (File.Exists(destinationFile)) if (File.Exists(destinationFile))
{ {
if (destinationFile.EndsWith(".jpg", ignoreCase: true, CultureInfo.CurrentCulture)) 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)) 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)) if (File.Exists(destinationFile))
{ {
_Log.Information($"*** source <{propertyHolder.ImageFileHolder.FullName}>"); _Log.Information($"*** source <{filteredItem.ImageFileHolder.FullName}>");
_Log.Information($"*** destination <{destinationFile}>"); _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)) if (File.Exists(deleteFile))
File.Delete(deleteFile); File.Delete(deleteFile);
File.Move(propertyHolder.ImageFileHolder.FullName, deleteFile); File.Move(filteredItem.ImageFileHolder.FullName, deleteFile);
} }
} }
else else
{ {
File.Move(propertyHolder.ImageFileHolder.FullName, destinationFile); File.Move(filteredItem.ImageFileHolder.FullName, 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)) if (File.Exists(deleteFile))
File.Delete(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; return result;
} }
private void ParallelForWork(bool firstPass, string angleBracket, string sourceDirectory, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<Tuple<string, DateTime>> sourceDirectoryChanges, PropertyHolder propertyHolder) private void ParallelForWork(bool firstPass, string sourceDirectory, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item item)
{ {
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new ArgumentNullException(nameof(propertyHolder.ImageFileHolder)); throw new NullReferenceException(nameof(item.ImageFileHolder));
A_Property property; A_Property property;
List<string> parseExceptions = new(); List<string> parseExceptions = new();
string extensionLowered = propertyHolder.ImageFileHolder.Extension.ToLower(); bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(extensionLowered); bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
bool isValidImageFormatExtension = _Configuration.ValidImageFormatExtensions.Contains(extensionLowered); string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}");
lock (propertyHolder) if (item.ValidImageFormatExtension && item.ImageFileHolder.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && item.ImageFileHolder.FullName != filteredSourceDirectoryFileExtensionLowered)
propertyHolder.SetValidImageFormatExtension(isValidImageFormatExtension); File.Move(item.ImageFileHolder.FullName, filteredSourceDirectoryFileExtensionLowered);
bool isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(extensionLowered); if (item.Changed is null || item.Changed.Value || item.Property is null)
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)
{ {
property = GetPropertyOfPrivate(angleBracket, propertyHolder, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, extensionLowered); property = GetPropertyOfPrivate(item, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions);
lock (sourceDirectoryChanges) lock (sourceDirectoryChanges)
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now)); sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
lock (propertyHolder) lock (item)
propertyHolder.Update(property); item.Update(property);
} }
} }
private void ParallelWork(bool firstPass, List<Exception> exceptions, List<Tuple<string, DateTime>> sourceDirectoryChanges, int propertyHolderCollectionsCount, int g, string sourceDirectory, int r, PropertyHolder[] filteredPropertyHolderCollection, int totalSeconds, string angleBracket) private void ParallelWork(bool firstPass, List<Exception> exceptions, List<Tuple<string, DateTime>> sourceDirectoryChanges, int containersCount, Container container, Item[] filteredItems, int totalSeconds)
{ {
List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples = new(); List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples = new();
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism };
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; 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}"; 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(filteredPropertyHolderCollection.Length, message, options); using ProgressBar progressBar = new(filteredItems.Length, message, options);
_ = Parallel.For(0, filteredPropertyHolderCollection.Length, parallelOptions, i => _ = Parallel.For(0, filteredItems.Length, parallelOptions, i =>
{ {
try try
{ {
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
DateTime dateTime = DateTime.Now; DateTime dateTime = DateTime.Now;
List<Tuple<string, DateTime>> collection; List<Tuple<string, DateTime>> collection;
ParallelForWork(firstPass, angleBracket, sourceDirectory, sourceDirectoryChanges, filteredSourceDirectoryFileTuples, filteredPropertyHolderCollection[i]); ParallelForWork(firstPass, container.SourceDirectory, sourceDirectoryChanges, filteredSourceDirectoryFileTuples, filteredItems[i]);
if (i == 0 || sourceDirectoryChanges.Any()) if (i == 0 || sourceDirectoryChanges.Any())
progressBar.Tick(); progressBar.Tick();
lock (filteredSourceDirectoryFileTuples) 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.Clear();
AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(configuration, AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(_Configuration,
model, _Model,
predictorModel, _PredictorModel,
sourceDirectory, sourceDirectory,
nameof(A_Property), nameof(A_Property),
string.Empty, string.Empty,
@ -679,54 +680,45 @@ public class PropertyLogic
contentDescription: string.Empty, contentDescription: string.Empty,
singletonDescription: "Properties for each image", singletonDescription: "Properties for each image",
collectionDescription: string.Empty)); collectionDescription: string.Empty));
result = AngleBracketCollection[0];
return result;
} }
public void ParallelWork(Configuration configuration, Model? model, PredictorModel? predictorModel, long ticks, List<PropertyHolder[]> propertyHolderCollections, bool firstPass) public void ParallelWork(long ticks, List<Container> containers, bool firstPass)
{ {
if (_Log is null) if (_Log is null)
throw new ArgumentNullException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (_Configuration.PopulatePropertyId is null) if (_Configuration.PopulatePropertyId is null)
throw new ArgumentNullException(nameof(_Configuration.PopulatePropertyId)); throw new NullReferenceException(nameof(_Configuration.PopulatePropertyId));
int g;
int r;
int totalSeconds; int totalSeconds;
bool? anyFilesMoved; bool? anyFilesMoved;
string angleBracket; Item[] filteredItems;
string sourceDirectory;
List<Exception> exceptions = new(); List<Exception> exceptions = new();
PropertyHolder[] filteredPropertyHolderCollection; int containersCount = containers.Count;
List<Tuple<string, DateTime>> sourceDirectoryChanges = new(); List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
int propertyHolderCollectionsCount = propertyHolderCollections.Count; string propertyRoot = IResult.GetResultsGroupDirectory(_Configuration, nameof(A_Property));
string propertyRoot = IResult.GetResultsGroupDirectory(configuration, nameof(A_Property)); foreach (Container container in containers)
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
{ {
if (!propertyHolderCollection.Any()) if (!container.Items.Any())
continue; continue;
sourceDirectoryChanges.Clear(); sourceDirectoryChanges.Clear();
if (firstPass) 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 else
filteredPropertyHolderCollection = (from l in propertyHolderCollection where l.ImageFileHolder is not null && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.Extension) select l).ToArray(); filteredItems = (from l in container.Items where l.ImageFileHolder is not null && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray();
if (!filteredPropertyHolderCollection.Any()) if (!filteredItems.Any())
continue; continue;
g = filteredPropertyHolderCollection[0].G;
r = filteredPropertyHolderCollection[0].R;
sourceDirectory = filteredPropertyHolderCollection[0].SourceDirectory;
totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
angleBracket = SetAngleBracketCollectionAndGetZero(configuration, model, predictorModel, sourceDirectory); SetAngleBracketCollection(container.SourceDirectory);
ParallelWork(firstPass, exceptions, sourceDirectoryChanges, propertyHolderCollectionsCount, g, sourceDirectory, r, filteredPropertyHolderCollection, totalSeconds, angleBracket); ParallelWork(firstPass, exceptions, sourceDirectoryChanges, containersCount, container, filteredItems, totalSeconds);
foreach (Exception exception in exceptions) foreach (Exception exception in exceptions)
_Log.Error(string.Concat(sourceDirectory, Environment.NewLine, exception.Message, Environment.NewLine, exception.StackTrace), exception); _Log.Error(string.Concat(container.SourceDirectory, Environment.NewLine, exception.Message, Environment.NewLine, exception.StackTrace), exception);
if (exceptions.Count == filteredPropertyHolderCollection.Length) if (exceptions.Count == filteredItems.Length)
throw new Exception(string.Concat("All in [", sourceDirectory, "]failed!")); throw new Exception(string.Concat("All in [", container.SourceDirectory, "]failed!"));
if (exceptions.Count != 0) if (exceptions.Count != 0)
_ExceptionsDirectories.Add(sourceDirectory); _ExceptionsDirectories.Add(container.SourceDirectory);
if (!firstPass || exceptions.Count != 0) if (!firstPass || exceptions.Count != 0)
anyFilesMoved = null; anyFilesMoved = null;
else else
anyFilesMoved = AnyFilesMoved(sourceDirectory, filteredPropertyHolderCollection); anyFilesMoved = AnyFilesMoved(container.SourceDirectory, filteredItems);
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any()) if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
{ {
for (int y = 0; y < int.MaxValue; y++) for (int y = 0; y < int.MaxValue; y++)
@ -740,32 +732,30 @@ public class PropertyLogic
} }
} }
public A_Property GetProperty(string angleBracket, PropertyHolder propertyHolder, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions) public A_Property GetProperty(Item item, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions)
{ {
A_Property result; A_Property result;
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new ArgumentException($"{propertyHolder.ImageFileHolder} is null!"); throw new NullReferenceException(nameof(item.ImageFileHolder));
bool firstPass = false; bool firstPass = false;
string extensionLowered = propertyHolder.ImageFileHolder.Extension.ToLower(); bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(extensionLowered); bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
bool isValidImageFormatExtension = _Configuration.ValidImageFormatExtensions.Contains(extensionLowered); result = GetPropertyOfPrivate(item, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions);
bool isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(extensionLowered);
result = GetPropertyOfPrivate(angleBracket, propertyHolder, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, extensionLowered);
return result; return result;
} }
public (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] GetPropertyIds(Configuration configuration, Model? model, PredictorModel? predictorModel, List<DirectoryInfo> groupCollection, bool saveToCollection) public (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] GetPropertyIds(List<DirectoryInfo> groupCollection, bool saveToCollection)
{ {
List<(long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)> results = new(); List<(long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)> results = new();
int level; int level;
string angleBracket;
A_Property? property; A_Property? property;
string checkDirectory; string checkDirectory;
List<string> directories; List<string> directories;
string propertyDirectory; string propertyDirectory;
string angleBracket = AngleBracketCollection[0];
foreach (DirectoryInfo group in groupCollection) foreach (DirectoryInfo group in groupCollection)
{ {
angleBracket = SetAngleBracketCollectionAndGetZero(configuration, model, predictorModel, group.SourceDirectory); SetAngleBracketCollection(group.SourceDirectory);
if (string.IsNullOrEmpty(group.SourceDirectory)) if (string.IsNullOrEmpty(group.SourceDirectory))
throw new Exception(); throw new Exception();
if (!saveToCollection) if (!saveToCollection)
@ -789,23 +779,23 @@ public class PropertyLogic
return results.OrderBy(l => l.Ticks).ToArray(); return results.OrderBy(l => l.Ticks).ToArray();
} }
public void AddToPropertyLogicAllCollection(PropertyHolder[] filteredPropertyHolderCollection) public void AddToPropertyLogicAllCollection(Item[] filteredItems)
{ {
if (_SixCharacterNamedFaceInfo.Any()) if (_SixCharacterNamedFaceInfo.Any())
{ {
string[] keys; string[] keys;
PropertyHolder propertyHolder; Item item;
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) for (int i = 0; i < filteredItems.Length; i++)
{ {
propertyHolder = filteredPropertyHolderCollection[i]; item = filteredItems[i];
if (propertyHolder.Property?.Id is null) if (item.Property?.Id is null)
continue; continue;
foreach (int sixCharacterIndex in propertyHolder.Property.Indices) foreach (int sixCharacterIndex in item.Property.Indices)
{ {
if (!_SixCharacterNamedFaceInfo.ContainsKey(sixCharacterIndex)) if (!_SixCharacterNamedFaceInfo.ContainsKey(sixCharacterIndex))
continue; continue;
keys = _SixCharacterNamedFaceInfo[sixCharacterIndex]; 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[] keys;
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new ArgumentNullException(nameof(rootDirectoryParent)); throw new NullReferenceException(nameof(rootDirectoryParent));
Dictionary<int, string[]> namedFaceInfoDeterministicHashCodeIndices = new(); Dictionary<int, string[]> namedFaceInfoDeterministicHashCodeIndices = new();
List<(int, string[])> allCollection = _AllCollection.OrderBy(l => l.Item1).ToList(); List<(int, string[])> allCollection = _AllCollection.OrderBy(l => l.Item1).ToList();
foreach ((int deterministicHashCode, string[] values) in allCollection) foreach ((int deterministicHashCode, string[] values) in allCollection)

View File

@ -1,6 +1,3 @@
using System.Text.Json;
using View_by_Distance.Shared.Models.Stateless;
namespace View_by_Distance.Property.Models.Stateless; namespace View_by_Distance.Property.Models.Stateless;
public static class A_Property public static class A_Property
@ -21,237 +18,14 @@ public static class A_Property
return result; return result;
} }
public static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetGroupCollection(string rootDirectory, string searchPattern, List<string> topDirectories, int maxImagesInDirectoryForTopLevelFirstPass = 50, bool reverse = false) public static List<Models.Container> Get(Models.Configuration configuration, PropertyLogic propertyLogic)
{ {
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results = new(); List<Models.Container> results;
string? parentDirectory;
string[] subDirectories;
string[] sourceDirectoryFiles;
List<string[]> 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<string> 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<string> 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<PropertyHolder[]> Populate(Models.Configuration configuration, string aPropertySingletonDirectory, List<(int, string, FileHolder[], int)> fileHolderGroupCollection, List<(int, string, List<(string, Models.A_Property?)>, int)> collectionFromJson)
{
List<PropertyHolder[]> 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<PropertyHolder> propertyHolderCollection;
Dictionary<string, (string SourceDirectory, FileHolder FileHolder)> 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<Models.A_Property>(json);
collection.Add(new(sourceDirectoryFile, property));
}
lock (results)
results.Add(new(g, sourceDirectory, collection, r));
}
public static List<PropertyHolder[]> Get(Models.Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic)
{
List<PropertyHolder[]> results;
string searchPattern = "*";
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
List<string> topDirectories = new(); List<string> exceptionsDirectories = new();
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> jsonCollection; results = Container.GetContainers(configuration, propertyLogic);
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> fileHolderGroupCollection; propertyLogic.ParallelWork(ticks, results, firstPass: false);
string aPropertySingletonDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}"); if (exceptionsDirectories.Any())
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())
throw new Exception(); throw new Exception();
return results; return results;
} }
@ -413,15 +187,19 @@ public static class A_Property
return result; return result;
} }
public static TimeSpan GetThreeStandardDeviationHigh(int minimum, PropertyHolder[] propertyHolderCollection) public static TimeSpan GetThreeStandardDeviationHigh(int minimum, Models.Container container)
{ {
TimeSpan result; TimeSpan result;
DateTime? minimumDateTime;
List<long> ticksCollection = new(); List<long> 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; continue;
ticksCollection.Add(propertyHolder.MinimumDateTime.Value.Ticks); minimumDateTime = GetMinimumDateTime(item.Property);
if (minimumDateTime is null)
continue;
ticksCollection.Add(minimumDateTime.Value.Ticks);
} }
long threeStandardDeviationHigh; long threeStandardDeviationHigh;
long min; long min;
@ -443,35 +221,42 @@ public static class A_Property
return result; return result;
} }
public static (int, List<DateTime>, List<PropertyHolder>) Get(PropertyHolder[] propertyHolderCollection, TimeSpan threeStandardDeviationHigh, int i) public static (int, List<DateTime>, List<Item>) Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i)
{ {
List<PropertyHolder> results = new(); List<Item> results = new();
int j = i; int j = i;
Item item;
long? ticks; long? ticks;
Item nextItem;
TimeSpan timeSpan; TimeSpan timeSpan;
PropertyHolder propertyHolder; DateTime? minimumDateTime;
DateTime? nextMinimumDateTime;
List<DateTime> dateTimes = new(); List<DateTime> dateTimes = new();
PropertyHolder nextPropertyHolder; for (; j < container.Items.Count; j++)
for (; j < propertyHolderCollection.Length; j++)
{ {
ticks = null; ticks = null;
propertyHolder = propertyHolderCollection[j]; item = container.Items[j];
if (propertyHolder.Property is null || propertyHolder.MinimumDateTime is null) if (item.Property is null)
continue; 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]; nextItem = container.Items[k];
if (nextPropertyHolder.Property is not null && nextPropertyHolder.MinimumDateTime is not null) if (nextItem.Property is null)
{ continue;
ticks = nextPropertyHolder.MinimumDateTime.Value.Ticks; nextMinimumDateTime = GetMinimumDateTime(nextItem.Property);
if (nextMinimumDateTime is null)
continue;
ticks = nextMinimumDateTime.Value.Ticks;
break; break;
} }
} results.Add(item);
results.Add(propertyHolder); dateTimes.Add(minimumDateTime.Value);
dateTimes.Add(propertyHolder.MinimumDateTime.Value);
if (ticks.HasValue) if (ticks.HasValue)
{ {
timeSpan = new(ticks.Value - propertyHolder.MinimumDateTime.Value.Ticks); timeSpan = new(ticks.Value - minimumDateTime.Value.Ticks);
if (timeSpan > threeStandardDeviationHigh) if (timeSpan > threeStandardDeviationHigh)
break; break;
} }
@ -479,14 +264,14 @@ public static class A_Property
return new(j, dateTimes, results); return new(j, dateTimes, results);
} }
public static bool Any(List<PropertyHolder[]> propertyHolderCollections) public static bool Any(List<Models.Container> propertyHolderCollections)
{ {
bool result = false; bool result = false;
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections) foreach (Models.Container container in propertyHolderCollections)
{ {
if (!propertyHolderCollection.Any()) if (!container.Items.Any())
continue; 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; result = true;
break; break;

View File

@ -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<string> topDirectories)
{
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results = new();
string? parentDirectory;
string[] subDirectories;
string[] sourceDirectoryFiles;
List<string[]> 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<string> 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<string> 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<string> 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<Models.A_Property>(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<Models.Container> GetContainers(Models.Configuration configuration, string aPropertySingletonDirectory, List<(int, string, FileHolder[], int)> fileHolderGroupCollection, List<(int, string, List<(string, Models.A_Property?)>, int)> collectionFromJson)
{
List<Models.Container> results = new();
if (configuration.PropertiesChangedForProperty is null)
throw new Exception($"{configuration.PropertiesChangedForProperty} is null");
int length;
string key;
string inferred;
List<Item> items;
string relativePath;
FileHolder keyFileHolder;
Models.Container container;
bool isValidImageFormatExtension;
List<string> keySourceDirectories;
Dictionary<string, (string SourceDirectory, FileHolder FileHolder)> 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<Models.Container> GetContainers(Models.Configuration configuration, PropertyLogic propertyLogic)
{
List<Models.Container> results;
string searchPattern = "*";
long ticks = DateTime.Now.Ticks;
List<string> 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;
}
}

View File

@ -92,7 +92,7 @@ internal class XPath
string? pathRoot = Path.GetPathRoot(directory); string? pathRoot = Path.GetPathRoot(directory);
string extension = Path.GetExtension(directory); string extension = Path.GetExtension(directory);
if (string.IsNullOrEmpty(pathRoot)) if (string.IsNullOrEmpty(pathRoot))
throw new ArgumentNullException(nameof(pathRoot)); throw new NullReferenceException(nameof(pathRoot));
if (Directory.Exists(directory)) if (Directory.Exists(directory))
results.Add(Path.GetFileName(directory)); results.Add(Path.GetFileName(directory));
else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory)) else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory))

View File

@ -284,29 +284,29 @@ public class C_Resize
return results; return results;
} }
public byte[] GetResizedBytes(string outputResolution, List<Tuple<string, DateTime>> subFileTuples, PropertyHolder propertyHolder, A_Property property, Dictionary<string, int[]> imageResizes) public byte[] GetResizedBytes(string outputResolution, List<Tuple<string, DateTime>> subFileTuples, Item item, A_Property property, Dictionary<string, int[]> imageResizes)
{ {
byte[] results; byte[] results;
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new Exception($"{propertyHolder.ImageFileHolder} is null!"); throw new NullReferenceException(nameof(item.ImageFileHolder));
if (!imageResizes.ContainsKey(outputResolution)) if (!imageResizes.ContainsKey(outputResolution))
throw new Exception(); throw new Exception();
int[] resize = imageResizes[outputResolution]; int[] resize = imageResizes[outputResolution];
int outputResolutionWidth = resize[_OutputResolutionWidthIndex]; int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
int outputResolutionHeight = resize[_OutputResolutionHeightIndex]; int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex]; 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<string, DateTime>(nameof(C_Resize), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
return results; return results;
} }
public void SaveResizedSubfile(string outputResolution, List<Tuple<string, DateTime>> subFileTuples, PropertyHolder propertyHolder, string original, A_Property property, Dictionary<string, int[]> imageResizes) public void SaveResizedSubfile(string outputResolution, List<Tuple<string, DateTime>> subFileTuples, Item item, string original, A_Property property, Dictionary<string, int[]> imageResizes)
{ {
if (propertyHolder.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new Exception($"{propertyHolder.ImageFileHolder} is null!"); throw new NullReferenceException(nameof(item.ImageFileHolder));
if (propertyHolder.ResizedFileHolder is null) if (item.ResizedFileHolder is null)
throw new Exception($"{propertyHolder.ResizedFileHolder} is null!"); throw new NullReferenceException(nameof(item.ResizedFileHolder));
FileHolder fileHolder = propertyHolder.ResizedFileHolder; FileHolder fileHolder = item.ResizedFileHolder;
if (!imageResizes.ContainsKey(outputResolution)) if (!imageResizes.ContainsKey(outputResolution))
throw new Exception(); throw new Exception();
if (!fileHolder.Exists) if (!fileHolder.Exists)
@ -318,7 +318,7 @@ public class C_Resize
if (File.Exists(parentCheck)) if (File.Exists(parentCheck))
{ {
File.Move(parentCheck, fileInfo.FullName); File.Move(parentCheck, fileInfo.FullName);
propertyHolder.SetResizedFileHolder(FileHolder.Refresh(fileHolder)); item.SetResizedFileHolder(FileHolder.Refresh(fileHolder));
} }
} }
int[] resize = imageResizes[outputResolution]; int[] resize = imageResizes[outputResolution];
@ -330,7 +330,7 @@ public class C_Resize
{ {
if (!fileHolder.Exists) if (!fileHolder.Exists)
{ {
File.Copy(propertyHolder.ImageFileHolder.FullName, fileHolder.FullName); File.Copy(item.ImageFileHolder.FullName, fileHolder.FullName);
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
} }
} }
@ -347,7 +347,7 @@ public class C_Resize
check = true; check = true;
if (check) if (check)
{ {
_ = SaveResizedSubfile(propertyHolder.ImageFileHolder.FullName, property, resize, fileHolder); _ = SaveResizedSubfile(item.ImageFileHolder.FullName, property, resize, fileHolder);
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
} }
} }
@ -422,13 +422,15 @@ public class C_Resize
return results; return results;
} }
public Dictionary<string, int[]> GetResizeKeyValuePairs(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string original, List<KeyValuePair<string, string>> metadataCollection, A_Property property, PropertyHolder propertyHolder) public Dictionary<string, int[]> GetResizeKeyValuePairs(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string original, List<KeyValuePair<string, string>> metadataCollection, A_Property property, Item item)
{ {
Dictionary<string, int[]> results; Dictionary<string, int[]> results;
if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder));
string json; string json;
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata) }; string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> 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.Exists)
{ {
if (fileInfo.Directory?.Parent is null) if (fileInfo.Directory?.Parent is null)

View File

@ -189,7 +189,7 @@ internal abstract class Person
_ = Directory.CreateDirectory(directory); _ = Directory.CreateDirectory(directory);
string? rootDirectoryParent = Path.GetDirectoryName(storage.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(storage.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new ArgumentNullException(nameof(rootDirectoryParent)); throw new NullReferenceException(nameof(rootDirectoryParent));
if (!Directory.Exists(rootDirectoryParent)) if (!Directory.Exists(rootDirectoryParent))
localKnownPeopleFile = string.Empty; localKnownPeopleFile = string.Empty;
else else

View File

@ -25,7 +25,7 @@ public static class RijndaelEncryption
{ {
string result; string result;
if (string.IsNullOrEmpty(text)) if (string.IsNullOrEmpty(text))
throw new ArgumentNullException(nameof(text)); throw new NullReferenceException(nameof(text));
RijndaelManaged aesAlg = NewRijndaelManaged(salt); RijndaelManaged aesAlg = NewRijndaelManaged(salt);
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
MemoryStream msEncrypt = new(); MemoryStream msEncrypt = new();
@ -58,7 +58,7 @@ public static class RijndaelEncryption
public static string Decrypt(string cipherText, string salt) public static string Decrypt(string cipherText, string salt)
{ {
if (string.IsNullOrEmpty(cipherText)) if (string.IsNullOrEmpty(cipherText))
throw new ArgumentNullException(nameof(cipherText)); throw new NullReferenceException(nameof(cipherText));
if (!IsBase64String(cipherText)) if (!IsBase64String(cipherText))
throw new Exception("The cipherText input parameter is not base64 encoded"); throw new Exception("The cipherText input parameter is not base64 encoded");
string text; string text;
@ -82,7 +82,7 @@ public static class RijndaelEncryption
private static RijndaelManaged NewRijndaelManaged(string salt) private static RijndaelManaged NewRijndaelManaged(string salt)
{ {
if (salt == null) if (salt == null)
throw new ArgumentNullException(nameof(salt)); throw new NullReferenceException(nameof(salt));
byte[] saltBytes = Encoding.ASCII.GetBytes(salt); byte[] saltBytes = Encoding.ASCII.GetBytes(salt);
Rfc2898DeriveBytes key = new(_Inputkey, saltBytes); Rfc2898DeriveBytes key = new(_Inputkey, saltBytes);
RijndaelManaged aesAlg = new(); RijndaelManaged aesAlg = new();

View File

@ -72,14 +72,14 @@ public class UnitTestResize
Assert.IsFalse(_PropertyConfiguration is null); 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; Property.Models.PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
return result; return result;
} }
@ -91,31 +91,31 @@ public class UnitTestResize
string sourceFileName = "Fall 2005 (113).jpg"; string sourceFileName = "Fall 2005 (113).jpg";
string sourceDirectoryName = "=2005.3 Fall"; string sourceDirectoryName = "=2005.3 Fall";
if (_Configuration.ForceMetadataLastWriteTimeToCreationTime is null) if (_Configuration.ForceMetadataLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime)); throw new NullReferenceException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime));
if (_Configuration.ForceResizeLastWriteTimeToCreationTime is null) if (_Configuration.ForceResizeLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime)); throw new NullReferenceException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime));
if (_Configuration.OutputQuality is null) if (_Configuration.OutputQuality is null)
throw new ArgumentNullException(nameof(_Configuration.OutputQuality)); throw new NullReferenceException(nameof(_Configuration.OutputQuality));
if (_Configuration.OverrideForResizeImages is null) if (_Configuration.OverrideForResizeImages is null)
throw new ArgumentNullException(nameof(_Configuration.OverrideForResizeImages)); throw new NullReferenceException(nameof(_Configuration.OverrideForResizeImages));
if (_Configuration.PropertiesChangedForMetadata is null) if (_Configuration.PropertiesChangedForMetadata is null)
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata)); throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForMetadata));
if (_Configuration.PropertiesChangedForResize is null) if (_Configuration.PropertiesChangedForResize is null)
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize)); throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForResize));
int g = 1;
int r = 1;
Model? model = null; Model? model = null;
bool reverse = false;
Property.Models.Item item;
string original = "Original"; string original = "Original";
List<string> parseExceptions = new(); List<string> parseExceptions = new();
PredictorModel? predictorModel = null;
bool isValidImageFormatExtension = true;
Property.Models.A_Property? property = null; Property.Models.A_Property? property = null;
Property.Models.PropertyHolder propertyHolder;
Dictionary<string, int[]> imageResizeKeyValuePairs; Dictionary<string, int[]> imageResizeKeyValuePairs;
List<Tuple<string, DateTime>> subFileTuples = new(); List<Tuple<string, DateTime>> subFileTuples = new();
PredictorModel? predictorModel = null;
List<KeyValuePair<string, string>> metadataCollection; List<KeyValuePair<string, string>> metadataCollection;
int length = _PropertyConfiguration.RootDirectory.Length; int length = _PropertyConfiguration.RootDirectory.Length;
string outputResolution = _Configuration.OutputResolutions[0]; 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 sourceDirectory = Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName);
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_PropertyConfiguration, nameof(Property.Models.A_Property), "{}"); string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_PropertyConfiguration, nameof(Property.Models.A_Property), "{}");
B_Metadata metadata = new(_Configuration.ForceMetadataLastWriteTimeToCreationTime.Value, _Configuration.PropertiesChangedForMetadata.Value); 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)); Property.Models.FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName));
string relativePath = Property.Models.Stateless.IPath.GetRelativePath(fileHolder.FullName, length); string relativePath = Property.Models.Stateless.IPath.GetRelativePath(fileHolder.FullName, length);
sourceDirectory = Path.Combine(aPropertySingletonDirectory, sourceDirectoryName); sourceDirectory = Path.Combine(aPropertySingletonDirectory, sourceDirectoryName);
propertyHolder = new(g, sourceDirectory, sourceDirectoryFile, relativePath, r, fileHolder, property, false, false, null, null); item = new(sourceDirectoryFile, relativePath, fileHolder, isValidImageFormatExtension, property, false, false);
Assert.IsNotNull(propertyHolder.ImageFileHolder); Assert.IsNotNull(item.ImageFileHolder);
property = propertyLogic.GetProperty(propertyLogic.AngleBracketCollection[0], propertyHolder, subFileTuples, parseExceptions); property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
(int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, propertyHolder); (int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, item);
imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, propertyHolder); imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, item);
Property.Models.FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(propertyHolder.ImageFileHolder.FullName))); Property.Models.FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName)));
propertyHolder.SetResizedFileHolder(resizedFileHolder); item.SetResizedFileHolder(resizedFileHolder);
resize.SaveResizedSubfile(outputResolution, subFileTuples, propertyHolder, original, property, imageResizeKeyValuePairs); resize.SaveResizedSubfile(outputResolution, subFileTuples, item, original, property, imageResizeKeyValuePairs);
propertyHolder.SetResizedFileHolder(Property.Models.FileHolder.Refresh(resizedFileHolder)); item.SetResizedFileHolder(Property.Models.FileHolder.Refresh(resizedFileHolder));
} }
} }

View File

@ -74,14 +74,14 @@ public class UnitTestFace
Assert.IsFalse(_PropertyConfiguration is null); 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; Property.Models.PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); throw new NullReferenceException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
return result; return result;
} }
@ -150,34 +150,34 @@ public class UnitTestFace
// string sourceFileName = "Logan Michael Sept 08 (193).jpg"; // string sourceFileName = "Logan Michael Sept 08 (193).jpg";
// string sourceDirectoryName = "=2008.2 Summer Logan Michael"; // string sourceDirectoryName = "=2008.2 Summer Logan Michael";
if (_Configuration.ForceMetadataLastWriteTimeToCreationTime is null) if (_Configuration.ForceMetadataLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime)); throw new NullReferenceException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime));
if (_Configuration.ForceResizeLastWriteTimeToCreationTime is null) if (_Configuration.ForceResizeLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime)); throw new NullReferenceException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime));
if (_Configuration.OutputQuality is null) if (_Configuration.OutputQuality is null)
throw new ArgumentNullException(nameof(_Configuration.OutputQuality)); throw new NullReferenceException(nameof(_Configuration.OutputQuality));
if (_Configuration.OverrideForResizeImages is null) if (_Configuration.OverrideForResizeImages is null)
throw new ArgumentNullException(nameof(_Configuration.OverrideForResizeImages)); throw new NullReferenceException(nameof(_Configuration.OverrideForResizeImages));
if (_Configuration.PropertiesChangedForMetadata is null) if (_Configuration.PropertiesChangedForMetadata is null)
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata)); throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForMetadata));
if (_Configuration.PropertiesChangedForResize is null) if (_Configuration.PropertiesChangedForResize is null)
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize)); throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForResize));
if (_Configuration.NumberOfJitters is null) if (_Configuration.NumberOfJitters is null)
throw new ArgumentNullException(nameof(_Configuration.NumberOfJitters)); throw new NullReferenceException(nameof(_Configuration.NumberOfJitters));
if (_Configuration.NumberOfTimesToUpsample is null) if (_Configuration.NumberOfTimesToUpsample is null)
throw new ArgumentNullException(nameof(_Configuration.NumberOfTimesToUpsample)); throw new NullReferenceException(nameof(_Configuration.NumberOfTimesToUpsample));
int g = 1; bool reverse = false;
int r = 1; Property.Models.Item item;
string original = "Original"; string original = "Original";
List<string> parseExceptions = new(); List<string> parseExceptions = new();
bool isValidImageFormatExtension = true;
Property.Models.A_Property? property = null; Property.Models.A_Property? property = null;
Property.Models.PropertyHolder propertyHolder;
Dictionary<string, int[]> imageResizeKeyValuePairs; Dictionary<string, int[]> imageResizeKeyValuePairs;
List<Tuple<string, DateTime>> subFileTuples = new(); List<Tuple<string, DateTime>> subFileTuples = new();
List<KeyValuePair<string, string>> metadataCollection; List<KeyValuePair<string, string>> metadataCollection;
int length = _PropertyConfiguration.RootDirectory.Length; int length = _PropertyConfiguration.RootDirectory.Length;
string outputResolution = _Configuration.OutputResolutions[0]; string outputResolution = _Configuration.OutputResolutions[0];
Property.Models.PropertyLogic propertyLogic = GetPropertyLogic();
(Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(_Configuration); (Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(_Configuration);
Property.Models.PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel);
string sourceDirectory = Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName); string sourceDirectory = Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName);
_Logger.Information(_Configuration.ModelDirectory); _Logger.Information(_Configuration.ModelDirectory);
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_PropertyConfiguration, nameof(Property.Models.A_Property), "{}"); 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)); Property.Models.FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName));
string relativePath = Property.Models.Stateless.IPath.GetRelativePath(fileHolder.FullName, length); string relativePath = Property.Models.Stateless.IPath.GetRelativePath(fileHolder.FullName, length);
sourceDirectory = Path.Combine(aPropertySingletonDirectory, sourceDirectoryName); sourceDirectory = Path.Combine(aPropertySingletonDirectory, sourceDirectoryName);
propertyHolder = new(g, sourceDirectory, sourceDirectoryFile, relativePath, r, fileHolder, property, false, false, null, null); item = new(sourceDirectoryFile, relativePath, fileHolder, isValidImageFormatExtension, property, false, false);
Assert.IsNotNull(propertyHolder.ImageFileHolder); Assert.IsNotNull(item.ImageFileHolder);
property = propertyLogic.GetProperty(propertyLogic.AngleBracketCollection[0], propertyHolder, subFileTuples, parseExceptions); property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
(int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, propertyHolder); (int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, item);
imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, propertyHolder); imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, item);
Property.Models.FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(propertyHolder.ImageFileHolder.FullName))); Property.Models.FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName)));
propertyHolder.SetResizedFileHolder(resizedFileHolder); item.SetResizedFileHolder(resizedFileHolder);
resize.SaveResizedSubfile(outputResolution, subFileTuples, propertyHolder, original, property, imageResizeKeyValuePairs); resize.SaveResizedSubfile(outputResolution, subFileTuples, item, original, property, imageResizeKeyValuePairs);
propertyHolder.SetResizedFileHolder(Property.Models.FileHolder.Refresh(resizedFileHolder)); item.SetResizedFileHolder(Property.Models.FileHolder.Refresh(resizedFileHolder));
Assert.IsNotNull(propertyHolder.ResizedFileHolder); Assert.IsNotNull(item.ResizedFileHolder);
Image? image = FaceRecognition.LoadImageFile(propertyHolder.ResizedFileHolder.FullName); Image? image = FaceRecognition.LoadImageFile(item.ResizedFileHolder.FullName);
Assert.IsNotNull(image); Assert.IsNotNull(image);
FaceRecognition faceRecognition = FaceRecognition.Create(modelParameter); FaceRecognition faceRecognition = FaceRecognition.Create(modelParameter);
List<Location> locations = faceRecognition.FaceLocations(model, image, _Configuration.NumberOfTimesToUpsample.Value, sortByPixelPercentage: true); List<Location> locations = faceRecognition.FaceLocations(model, image, _Configuration.NumberOfTimesToUpsample.Value, sortByPixelPercentage: true);