Re-write
This commit is contained in:
parent
f72fcee1db
commit
bc2174b17a
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -5,18 +5,23 @@
|
|||||||
"ASPNETCORE",
|
"ASPNETCORE",
|
||||||
"Barrick",
|
"Barrick",
|
||||||
"bcdfghjklmnpqrstvwxyz",
|
"bcdfghjklmnpqrstvwxyz",
|
||||||
|
"Bday",
|
||||||
"Beichler",
|
"Beichler",
|
||||||
"Bohdi",
|
"Bohdi",
|
||||||
|
"Cobertura",
|
||||||
"cref",
|
"cref",
|
||||||
"CUDA",
|
"CUDA",
|
||||||
"Dlib",
|
"Dlib",
|
||||||
|
"DSCN",
|
||||||
"Exif",
|
"Exif",
|
||||||
"Getα",
|
"Getα",
|
||||||
"Greyscale",
|
"Greyscale",
|
||||||
|
"jfif",
|
||||||
"mmod",
|
"mmod",
|
||||||
"nosj",
|
"nosj",
|
||||||
"paramref",
|
"paramref",
|
||||||
"Phares",
|
"Phares",
|
||||||
|
"Rects",
|
||||||
"resnet",
|
"resnet",
|
||||||
"Serilog",
|
"Serilog",
|
||||||
"Subfile",
|
"Subfile",
|
||||||
@ -29,4 +34,5 @@
|
|||||||
"files.exclude": {
|
"files.exclude": {
|
||||||
"**/.git": false
|
"**/.git": false
|
||||||
},
|
},
|
||||||
|
"coverage-gutters.coverageBaseDir": "./.vscode/ReportGenerator/Cobertura/*"
|
||||||
}
|
}
|
@ -22,7 +22,7 @@ public class Compare
|
|||||||
private readonly List<(string Find, string Replace)> _RenameBFindReplace;
|
private readonly List<(string Find, string Replace)> _RenameBFindReplace;
|
||||||
private readonly List<(string Find, string Replace)> _RenameCFindReplace;
|
private readonly List<(string Find, string Replace)> _RenameCFindReplace;
|
||||||
private readonly List<(string Find, string Replace)> _SpellingFindReplace;
|
private readonly List<(string Find, string Replace)> _SpellingFindReplace;
|
||||||
private readonly Dictionary<string, List<Tuple<string, A_Property>>> _FilePropertiesKeyValuePairs;
|
private readonly Dictionary<string, List<Tuple<string, Shared.Models.Property>>> _FilePropertiesKeyValuePairs;
|
||||||
|
|
||||||
public Compare(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
public Compare(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
||||||
{
|
{
|
||||||
@ -41,21 +41,21 @@ public class Compare
|
|||||||
_IsEnvironment = isEnvironment;
|
_IsEnvironment = isEnvironment;
|
||||||
_Log = Serilog.Log.ForContext<Compare>();
|
_Log = Serilog.Log.ForContext<Compare>();
|
||||||
_FileKeyValuePairs = new List<KeyValuePair<string, string>>();
|
_FileKeyValuePairs = new List<KeyValuePair<string, string>>();
|
||||||
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, A_Property>>>();
|
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, Shared.Models.Property>>>();
|
||||||
string searchPattern = "*";
|
string searchPattern = "*";
|
||||||
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;
|
||||||
Property.Models.Configuration propertyConfiguration = Property.Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory);
|
Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
|
||||||
Property.Models.Configuration.Verify(propertyConfiguration);
|
Property.Models.Configuration.Verify(propertyConfiguration);
|
||||||
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);
|
||||||
bool reverse = false;
|
|
||||||
Model? model = null;
|
Model? model = null;
|
||||||
|
bool reverse = false;
|
||||||
|
string outputExtension = ".jpg";
|
||||||
PredictorModel? predictorModel = null;
|
PredictorModel? predictorModel = null;
|
||||||
PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel);
|
Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, propertyConfiguration);
|
||||||
if (propertyConfiguration.PopulatePropertyId is null)
|
A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, predictorModel, mapLogic);
|
||||||
throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId));
|
|
||||||
foreach (string spelling in configuration.Spelling)
|
foreach (string spelling in configuration.Spelling)
|
||||||
{
|
{
|
||||||
segments = spelling.Split('|');
|
segments = spelling.Split('|');
|
||||||
@ -114,7 +114,7 @@ public class Compare
|
|||||||
if (PossiblyRename(topDirectories, groupCollection))
|
if (PossiblyRename(topDirectories, groupCollection))
|
||||||
{
|
{
|
||||||
topDirectories.Clear();
|
topDirectories.Clear();
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
||||||
groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories);
|
groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories);
|
||||||
if (appSettings.MaxDegreeOfParallelism < 2)
|
if (appSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection));
|
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection));
|
||||||
@ -123,7 +123,7 @@ public class Compare
|
|||||||
if (PossiblyRenameB(topDirectories, groupCollection))
|
if (PossiblyRenameB(topDirectories, groupCollection))
|
||||||
{
|
{
|
||||||
topDirectories.Clear();
|
topDirectories.Clear();
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
||||||
groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories);
|
groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories);
|
||||||
if (appSettings.MaxDegreeOfParallelism < 2)
|
if (appSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection));
|
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection));
|
||||||
@ -132,7 +132,7 @@ public class Compare
|
|||||||
if (PossiblyRenameC(topDirectories, groupCollection))
|
if (PossiblyRenameC(topDirectories, groupCollection))
|
||||||
{
|
{
|
||||||
topDirectories.Clear();
|
topDirectories.Clear();
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
||||||
groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories);
|
groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories);
|
||||||
if (appSettings.MaxDegreeOfParallelism < 2)
|
if (appSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection));
|
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection));
|
||||||
@ -141,7 +141,7 @@ public class Compare
|
|||||||
if (PossiblyCorrect(topDirectories, groupCollection))
|
if (PossiblyCorrect(topDirectories, groupCollection))
|
||||||
{
|
{
|
||||||
topDirectories.Clear();
|
topDirectories.Clear();
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
||||||
groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories);
|
groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories);
|
||||||
if (appSettings.MaxDegreeOfParallelism < 2)
|
if (appSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection));
|
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection));
|
||||||
@ -154,14 +154,14 @@ public class Compare
|
|||||||
if (dbFiles.Any())
|
if (dbFiles.Any())
|
||||||
{
|
{
|
||||||
topDirectories.Clear();
|
topDirectories.Clear();
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
||||||
groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories);
|
groupCollection = Property.Models.Stateless.Container.GetGroupCollection(propertyConfiguration.RootDirectory, searchPattern, topDirectories);
|
||||||
if (appSettings.MaxDegreeOfParallelism < 2)
|
if (appSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection));
|
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.Container.GetGroupCollection));
|
||||||
}
|
}
|
||||||
if (_IsEnvironment.Development && propertyConfiguration.PopulatePropertyId.Value && !propertyLogic.KeyValuePairs.Any())
|
if (_IsEnvironment.Development && propertyConfiguration.PopulatePropertyId && !mapLogic.KeyValuePairs.Any())
|
||||||
throw new Exception("Copy keyValuePairs-####.json file");
|
throw new Exception("Copy keyValuePairs-####.json file");
|
||||||
List<Container> containers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic);
|
List<Shared.Models.Container> containers = A_Property.Get(propertyConfiguration, propertyLogic);
|
||||||
if (!isSilent)
|
if (!isSilent)
|
||||||
{
|
{
|
||||||
_Log.Information("First pass completed");
|
_Log.Information("First pass completed");
|
||||||
@ -203,7 +203,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, containers, aPropertyContentCollectionDirectory);
|
ThirdPassToMove(propertyConfiguration, model, predictorModel, mapLogic, propertyLogic, containers, aPropertyContentCollectionDirectory);
|
||||||
if (!isSilent)
|
if (!isSilent)
|
||||||
{
|
{
|
||||||
_Log.Information("Third pass completed");
|
_Log.Information("Third pass completed");
|
||||||
@ -215,7 +215,7 @@ public class Compare
|
|||||||
}
|
}
|
||||||
_Log.Information(". . .");
|
_Log.Information(". . .");
|
||||||
}
|
}
|
||||||
FourthPassCreateWindowsShortcuts(propertyConfiguration, model, predictorModel, propertyLogic, containers, saveToCollection: false, keepAll: false);
|
FourthPassCreateWindowsShortcuts(propertyConfiguration, model, predictorModel, mapLogic, propertyLogic, containers, saveToCollection: false, keepAll: false);
|
||||||
if (!isSilent)
|
if (!isSilent)
|
||||||
{
|
{
|
||||||
_Log.Information("Fourth pass completed");
|
_Log.Information("Fourth pass completed");
|
||||||
@ -262,7 +262,7 @@ public class Compare
|
|||||||
directorySegments = pathSegments[^1].Split(' ');
|
directorySegments = pathSegments[^1].Split(' ');
|
||||||
if (!DateTime.TryParseExact(string.Join(' ', directorySegments.Take(3)), "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
if (!DateTime.TryParseExact(string.Join(' ', directorySegments.Take(3)), "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
throw new Exception("l");
|
throw new Exception("l");
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else if (pathSegments.Length == 1)
|
else if (pathSegments.Length == 1)
|
||||||
@ -270,7 +270,7 @@ public class Compare
|
|||||||
directorySegments = pathSegments[^1].Split(' ');
|
directorySegments = pathSegments[^1].Split(' ');
|
||||||
if (DateTime.TryParseExact(directorySegments[^1], "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
if (DateTime.TryParseExact(directorySegments[^1], "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -284,7 +284,7 @@ public class Compare
|
|||||||
directorySegments = pathSegments[0].Split(' ');
|
directorySegments = pathSegments[0].Split(' ');
|
||||||
if (DateTime.TryParseExact(directorySegments[^1], "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
if (DateTime.TryParseExact(directorySegments[^1], "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -295,7 +295,7 @@ public class Compare
|
|||||||
directorySegments = pathSegments[0].Split(' ');
|
directorySegments = pathSegments[0].Split(' ');
|
||||||
if (DateTime.TryParseExact(directorySegments[^1], "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
if (DateTime.TryParseExact(directorySegments[^1], "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -305,22 +305,22 @@ public class Compare
|
|||||||
{
|
{
|
||||||
if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(2)), "MMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(2)), "MMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(2)), "MMM yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
else if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(2)), "MMM yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else if (DateTime.TryParseExact(string.Concat(directorySegments[0][..3], ' ', directorySegments[1]), "MMM yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
else if (DateTime.TryParseExact(string.Concat(directorySegments[0][..3], ' ', directorySegments[1]), "MMM yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(2)), "MMMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
else if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(2)), "MMMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -330,12 +330,12 @@ public class Compare
|
|||||||
{
|
{
|
||||||
if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(3)), "MMMM dd yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(3)), "MMMM dd yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(3)), "MMMM d yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
else if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(3)), "MMMM d yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -349,12 +349,12 @@ public class Compare
|
|||||||
directorySegments = pathSegments[^1].Split(' ');
|
directorySegments = pathSegments[^1].Split(' ');
|
||||||
if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(3)), "MMMM dd yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(3)), "MMMM dd yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(3)), "MMMM d yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
else if (DateTime.TryParseExact(string.Join(' ', directorySegments.Take(3)), "MMMM d yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
{
|
{
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(dateTime.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
result = string.Concat($"={dateTime:yyyy}.{season} {seasonName} ", string.Join(' ', pathSegments[0].Split(' ').Take(2)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -373,7 +373,7 @@ public class Compare
|
|||||||
throw new NullReferenceException(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)
|
||||||
@ -384,12 +384,12 @@ public class Compare
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel)
|
private A_Property GetPropertyLogic(bool reverse, Model? model, string outputExtension, PredictorModel? predictorModel, Map.Models.MapLogic mapLogic)
|
||||||
{
|
{
|
||||||
PropertyLogic result;
|
A_Property result;
|
||||||
if (_Configuration?.PropertyConfiguration is null)
|
if (_Configuration?.PropertyConfiguration is null)
|
||||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||||
result = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
|
result = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, outputExtension, 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))
|
||||||
@ -400,12 +400,12 @@ public class Compare
|
|||||||
long ticks = DateTime.Now.Ticks;
|
long ticks = DateTime.Now.Ticks;
|
||||||
lines = File.ReadAllLines(fromPrepareForOldFile);
|
lines = File.ReadAllLines(fromPrepareForOldFile);
|
||||||
string resultsDirectory = $"{_Configuration.PropertyConfiguration.RootDirectory} - Results";
|
string resultsDirectory = $"{_Configuration.PropertyConfiguration.RootDirectory} - Results";
|
||||||
int[]? zeros = (from l in result.IndicesFromNew where l.Value.Any() select l.Value[0]).ToArray();
|
int[]? zeros = (from l in mapLogic.IndicesFromNew where l.Value.Any() select l.Value[0]).ToArray();
|
||||||
lines = (from l in result.IndicesFromNew select string.Concat(l.Key, '\t', string.Join('\t', l.Value))).ToArray();
|
lines = (from l in mapLogic.IndicesFromNew select string.Concat(l.Key, '\t', string.Join('\t', l.Value))).ToArray();
|
||||||
if (!Directory.Exists(resultsDirectory))
|
if (!Directory.Exists(resultsDirectory))
|
||||||
_ = Directory.CreateDirectory(resultsDirectory);
|
_ = Directory.CreateDirectory(resultsDirectory);
|
||||||
File.WriteAllLines(Path.Combine(resultsDirectory, $"{ticks}.tsv"), lines);
|
File.WriteAllLines(Path.Combine(resultsDirectory, $"{ticks}.tsv"), lines);
|
||||||
string json = JsonSerializer.Serialize(result.IndicesFromNew, new JsonSerializerOptions { WriteIndented = true });
|
string json = JsonSerializer.Serialize(mapLogic.IndicesFromNew, new JsonSerializerOptions { WriteIndented = true });
|
||||||
File.WriteAllText(Path.Combine(resultsDirectory, $"{ticks}.json"), json);
|
File.WriteAllText(Path.Combine(resultsDirectory, $"{ticks}.json"), json);
|
||||||
foreach (string line in lines)
|
foreach (string line in lines)
|
||||||
{
|
{
|
||||||
@ -453,7 +453,7 @@ public class Compare
|
|||||||
{
|
{
|
||||||
if (!_Configuration.DiffPropertyDirectory.EndsWith("{}"))
|
if (!_Configuration.DiffPropertyDirectory.EndsWith("{}"))
|
||||||
throw new Exception("Invalid directory should end with {}!");
|
throw new Exception("Invalid directory should end with {}!");
|
||||||
diffRootDirectory = Property.Models.Stateless.A_Property.GetDiffRootDirectory(_Configuration.DiffPropertyDirectory);
|
diffRootDirectory = Shared.Models.Stateless.Methods.IProperty.GetDiffRootDirectory(_Configuration.DiffPropertyDirectory);
|
||||||
}
|
}
|
||||||
PropertyCompare.Models.PropertyCompareLogic propertyCompareLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _SpellingFindReplace, diffRootDirectory);
|
PropertyCompare.Models.PropertyCompareLogic propertyCompareLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _SpellingFindReplace, diffRootDirectory);
|
||||||
if (string.IsNullOrEmpty(_Configuration.DiffPropertyDirectory) || !Directory.Exists(_Configuration.DiffPropertyDirectory))
|
if (string.IsNullOrEmpty(_Configuration.DiffPropertyDirectory) || !Directory.Exists(_Configuration.DiffPropertyDirectory))
|
||||||
@ -742,7 +742,7 @@ public class Compare
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThirdPassToMove(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List<Container> containers, string aPropertyContentCollectionDirectory)
|
private void ThirdPassToMove(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, Map.Models.MapLogic mapLogic, A_Property propertyLogic, List<Shared.Models.Container> containers, string aPropertyContentCollectionDirectory)
|
||||||
{
|
{
|
||||||
if (_Log is null)
|
if (_Log is null)
|
||||||
throw new NullReferenceException(nameof(_Log));
|
throw new NullReferenceException(nameof(_Log));
|
||||||
@ -751,7 +751,7 @@ public class Compare
|
|||||||
int stay = 0;
|
int stay = 0;
|
||||||
string fileName;
|
string fileName;
|
||||||
string id = " - Id";
|
string id = " - Id";
|
||||||
A_Property? property;
|
Shared.Models.Property? property;
|
||||||
string? directoryName;
|
string? directoryName;
|
||||||
ConsoleKey? consoleKey = null;
|
ConsoleKey? consoleKey = null;
|
||||||
long ticks = DateTime.Now.Ticks;
|
long ticks = DateTime.Now.Ticks;
|
||||||
@ -773,7 +773,7 @@ public class Compare
|
|||||||
continue;
|
continue;
|
||||||
filteredSourceDirectoryFile = group.FilteredSourceDirectoryFiles[i];
|
filteredSourceDirectoryFile = group.FilteredSourceDirectoryFiles[i];
|
||||||
valueCollection.Add(new(property.Id.Value, property.Indices));
|
valueCollection.Add(new(property.Id.Value, property.Indices));
|
||||||
if (!propertyLogic.IndicesFromNew.ContainsKey(property.Id.Value))
|
if (!mapLogic.IndicesFromNew.ContainsKey(property.Id.Value))
|
||||||
stay += 1;
|
stay += 1;
|
||||||
else if (!fileMoveCollection.Contains(filteredSourceDirectoryFile))
|
else if (!fileMoveCollection.Contains(filteredSourceDirectoryFile))
|
||||||
fileMoveCollection.Add(filteredSourceDirectoryFile);
|
fileMoveCollection.Add(filteredSourceDirectoryFile);
|
||||||
@ -816,16 +816,16 @@ public class Compare
|
|||||||
File.Move(fileMove, fileName);
|
File.Move(fileMove, fileName);
|
||||||
}
|
}
|
||||||
for (int i = 1; i < 4; i++)
|
for (int i = 1; i < 4; i++)
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FourthPassCreateWindowsShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List<Container> containers, bool saveToCollection, bool keepAll)
|
private void FourthPassCreateWindowsShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, Map.Models.MapLogic mapLogic, A_Property propertyLogic, List<Shared.Models.Container> containers, bool saveToCollection, bool keepAll)
|
||||||
{
|
{
|
||||||
if (_Log is null)
|
if (_Log is null)
|
||||||
throw new NullReferenceException(nameof(_Log));
|
throw new NullReferenceException(nameof(_Log));
|
||||||
int stay = 0;
|
int stay = 0;
|
||||||
A_Property? property;
|
Shared.Models.Property? property;
|
||||||
ConsoleKey? consoleKey = null;
|
ConsoleKey? consoleKey = null;
|
||||||
long ticks = DateTime.Now.Ticks;
|
long ticks = DateTime.Now.Ticks;
|
||||||
string filteredSourceDirectoryFile;
|
string filteredSourceDirectoryFile;
|
||||||
@ -845,7 +845,7 @@ public class Compare
|
|||||||
continue;
|
continue;
|
||||||
filteredSourceDirectoryFile = group.FilteredSourceDirectoryFiles[i];
|
filteredSourceDirectoryFile = group.FilteredSourceDirectoryFiles[i];
|
||||||
valueCollection.Add(new(property.Id.Value, property.Indices));
|
valueCollection.Add(new(property.Id.Value, property.Indices));
|
||||||
if (!propertyLogic.IndicesFromNew.ContainsKey(property.Id.Value))
|
if (!mapLogic.IndicesFromNew.ContainsKey(property.Id.Value))
|
||||||
stay += 1;
|
stay += 1;
|
||||||
else
|
else
|
||||||
fileMoveCollection.Add(filteredSourceDirectoryFile);
|
fileMoveCollection.Add(filteredSourceDirectoryFile);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Phares.View.by.Distance.Compare</PackageId>
|
<PackageId>Phares.View.by.Distance.Compare</PackageId>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<Version>5.0.402.104</Version>
|
<Version>6.0.100.1</Version>
|
||||||
<Authors>Mike Phares</Authors>
|
<Authors>Mike Phares</Authors>
|
||||||
<Company>Phares</Company>
|
<Company>Phares</Company>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
@ -52,9 +52,10 @@
|
|||||||
<PackageReference Include="System.Text.Json" Version="6.0.0" />
|
<PackageReference Include="System.Text.Json" Version="6.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
<ProjectReference Include="..\Map\Map.csproj" />
|
||||||
<ProjectReference Include="..\Property\Property.csproj" />
|
|
||||||
<ProjectReference Include="..\Property-Compare\Property-Compare.csproj" />
|
<ProjectReference Include="..\Property-Compare\Property-Compare.csproj" />
|
||||||
|
<ProjectReference Include="..\Property\Property.csproj" />
|
||||||
|
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="appsettings.Development.json">
|
<None Include="appsettings.Development.json">
|
||||||
|
@ -79,28 +79,28 @@
|
|||||||
"/zzz Phares Slides/Slides 2015-06-10/Magazine 01"
|
"/zzz Phares Slides/Slides 2015-06-10/Magazine 01"
|
||||||
],
|
],
|
||||||
"Configuration": {
|
"Configuration": {
|
||||||
"DateGroup": "2022-08-14",
|
"DateGroup": "2022-08-22",
|
||||||
"DiffPropertyDirectory": "",
|
"DiffPropertyDirectory": "",
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||||
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
||||||
"PopulatePropertyId": true,
|
"PopulatePropertyId": true,
|
||||||
"PropertiesChangedForProperty": false,
|
"PropertiesChangedForProperty": false,
|
||||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-08-14 - b756859b616424dc98b7742a64c15a8951632473 - III",
|
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-08-22 - b756859b616424dc98b7742a64c15a8951632473 - III",
|
||||||
"WriteBitmapDataBytes": false,
|
"WriteBitmapDataBytes": false,
|
||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF"
|
".GIF"
|
||||||
],
|
],
|
||||||
"PropertyContentCollectionFiles": [
|
"PropertyContentCollectionFiles": [
|
||||||
"/Images 2022-08-14 - b756859b616424dc98b7742a64c15a8951632473 - III - Results/A) Property/2022-08-14/[()]/637869381676042455.json",
|
"/Images 2022-08-22 - b756859b616424dc98b7742a64c15a8951632473 - III - Results/A) Property/2022-08-22/[()]/637869381676042455.json",
|
||||||
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-08-14/[()]/637869733124119330.json",
|
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-08-22/[()]/637869733124119330.json",
|
||||||
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-08-14/[()]/637869734240700328.json",
|
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-08-22/[()]/637869734240700328.json",
|
||||||
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-08-14/[()]/637869734970730630.json",
|
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-08-22/[()]/637869734970730630.json",
|
||||||
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-08-14/[()]/637869743752078399.json",
|
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-08-22/[()]/637869743752078399.json",
|
||||||
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-08-14/[()]/637869744751177715.json",
|
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-08-22/[()]/637869744751177715.json",
|
||||||
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-08-14/[()]/637869745134124462.json"
|
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-08-22/[()]/637869745134124462.json"
|
||||||
],
|
],
|
||||||
"ValidImageFormatExtensions": [
|
"ValidImageFormatExtensions": [
|
||||||
".bmp",
|
".bmp",
|
||||||
|
@ -50,11 +50,11 @@
|
|||||||
"WorkingDirectoryName": "PharesApps",
|
"WorkingDirectoryName": "PharesApps",
|
||||||
"Windows": {
|
"Windows": {
|
||||||
"Configuration": {
|
"Configuration": {
|
||||||
"DateGroup": "2022-08-14",
|
"DateGroup": "2022-08-22",
|
||||||
"DiffPropertyDirectory": "",
|
"DiffPropertyDirectory": "",
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||||
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
||||||
"PopulatePropertyId": true,
|
"PopulatePropertyId": true,
|
||||||
"PropertiesChangedForProperty": false,
|
"PropertiesChangedForProperty": false,
|
||||||
@ -94,13 +94,13 @@
|
|||||||
".GIF"
|
".GIF"
|
||||||
],
|
],
|
||||||
"PropertyContentCollectionFiles": [
|
"PropertyContentCollectionFiles": [
|
||||||
"/Images 2022-08-14 - b756859b616424dc98b7742a64c15a8951632473 - III - Results/A) Property/2022-08-14/[()]/637869381676042455.json",
|
"/Images 2022-08-22 - b756859b616424dc98b7742a64c15a8951632473 - III - Results/A) Property/2022-08-22/[()]/637869381676042455.json",
|
||||||
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-08-14/[()]/637869733124119330.json",
|
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-08-22/[()]/637869733124119330.json",
|
||||||
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-08-14/[()]/637869734240700328.json",
|
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-08-22/[()]/637869734240700328.json",
|
||||||
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-08-14/[()]/637869734970730630.json",
|
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-08-22/[()]/637869734970730630.json",
|
||||||
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-08-14/[()]/637869743752078399.json",
|
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-08-22/[()]/637869743752078399.json",
|
||||||
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-08-14/[()]/637869744751177715.json",
|
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-08-22/[()]/637869744751177715.json",
|
||||||
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-08-14/[()]/637869745134124462.json"
|
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-08-22/[()]/637869745134124462.json"
|
||||||
],
|
],
|
||||||
"ValidImageFormatExtensions": [
|
"ValidImageFormatExtensions": [
|
||||||
".bmp",
|
".bmp",
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Phares.View.by.Distance.Date.Group</PackageId>
|
<PackageId>Phares.View.by.Distance.Date.Group</PackageId>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<Version>5.0.402.104</Version>
|
<Version>6.0.100.1</Version>
|
||||||
<Authors>Mike Phares</Authors>
|
<Authors>Mike Phares</Authors>
|
||||||
<Company>Phares</Company>
|
<Company>Phares</Company>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
@ -19,7 +19,7 @@ public class DateGroup
|
|||||||
private readonly IsEnvironment _IsEnvironment;
|
private readonly IsEnvironment _IsEnvironment;
|
||||||
private readonly Models.Configuration _Configuration;
|
private readonly Models.Configuration _Configuration;
|
||||||
private readonly List<KeyValuePair<string, string>> _FileKeyValuePairs;
|
private readonly List<KeyValuePair<string, string>> _FileKeyValuePairs;
|
||||||
private readonly Dictionary<string, List<Tuple<string, A_Property>>> _FilePropertiesKeyValuePairs;
|
private readonly Dictionary<string, List<Tuple<string, Shared.Models.Property>>> _FilePropertiesKeyValuePairs;
|
||||||
|
|
||||||
public DateGroup(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
public DateGroup(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
||||||
{
|
{
|
||||||
@ -34,35 +34,34 @@ public class DateGroup
|
|||||||
_Exceptions = new List<string>();
|
_Exceptions = new List<string>();
|
||||||
_Log = Serilog.Log.ForContext<DateGroup>();
|
_Log = Serilog.Log.ForContext<DateGroup>();
|
||||||
_FileKeyValuePairs = new List<KeyValuePair<string, string>>();
|
_FileKeyValuePairs = new List<KeyValuePair<string, string>>();
|
||||||
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, A_Property>>>();
|
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, Shared.Models.Property>>>();
|
||||||
Property.Models.Configuration propertyConfiguration = Property.Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory);
|
Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
|
||||||
Property.Models.Configuration.Verify(propertyConfiguration);
|
Property.Models.Configuration.Verify(propertyConfiguration);
|
||||||
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);
|
||||||
bool reverse = false;
|
bool reverse = false;
|
||||||
Model? model = null;
|
Model? model = null;
|
||||||
PredictorModel? predictorModel = null;
|
|
||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
|
string outputExtension = ".jpg";
|
||||||
|
PredictorModel? predictorModel = null;
|
||||||
if (configuration.ByHash is null)
|
if (configuration.ByHash is null)
|
||||||
throw new NullReferenceException(nameof(configuration.ByHash));
|
throw new NullReferenceException(nameof(configuration.ByHash));
|
||||||
if (configuration.ByCreateDateShortcut is null)
|
if (configuration.ByCreateDateShortcut is null)
|
||||||
throw new NullReferenceException(nameof(configuration.ByCreateDateShortcut));
|
throw new NullReferenceException(nameof(configuration.ByCreateDateShortcut));
|
||||||
if (propertyConfiguration.PopulatePropertyId is null)
|
|
||||||
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(reverse, model, predictorModel);
|
A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, 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);
|
||||||
if (true || appSettings.MaxDegreeOfParallelism < 2)
|
if (true || appSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(File.Delete));
|
ticks = LogDelta(ticks, nameof(File.Delete));
|
||||||
for (int i = 1; i < 10; i++)
|
for (int i = 1; i < 10; i++)
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
|
||||||
if (true || appSettings.MaxDegreeOfParallelism < 2)
|
if (true || appSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.IPath.DeleteEmptyDirectories));
|
ticks = LogDelta(ticks, nameof(Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories));
|
||||||
List<Container> containers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic);
|
List<Shared.Models.Container> containers = A_Property.Get(propertyConfiguration, propertyLogic);
|
||||||
if (configuration.ByCreateDateShortcut.HasValue && configuration.ByCreateDateShortcut.Value)
|
if (configuration.ByCreateDateShortcut.HasValue && configuration.ByCreateDateShortcut.Value)
|
||||||
CreateDateShortcut(propertyConfiguration, containers);
|
CreateDateShortcut(propertyConfiguration, containers);
|
||||||
else
|
else
|
||||||
@ -71,15 +70,15 @@ public class DateGroup
|
|||||||
List<Property.Models.DirectoryInfo> directoryInfoCollection = new();
|
List<Property.Models.DirectoryInfo> directoryInfoCollection = new();
|
||||||
propertyLogic.ParallelWork(ticks, containers, firstPass: true);
|
propertyLogic.ParallelWork(ticks, containers, firstPass: true);
|
||||||
if (appSettings.MaxDegreeOfParallelism < 2)
|
if (appSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(PropertyLogic.ParallelWork));
|
ticks = LogDelta(ticks, nameof(A_Property.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 && (configuration.ByCreateDateShortcut.Value || configuration.ByHash.Value))
|
||||||
{
|
{
|
||||||
if (Property.Models.Stateless.A_Property.Any(containers))
|
if (Shared.Models.Stateless.Methods.IProperty.Any(containers))
|
||||||
propertyLogic.ParallelWork(ticks, containers, firstPass: false);
|
propertyLogic.ParallelWork(ticks, containers, firstPass: false);
|
||||||
if (appSettings.MaxDegreeOfParallelism < 2)
|
if (appSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(PropertyLogic.ParallelWork));
|
ticks = LogDelta(ticks, nameof(A_Property.ParallelWork));
|
||||||
if (propertyLogic.ExceptionsDirectories.Any())
|
if (propertyLogic.ExceptionsDirectories.Any())
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
@ -107,9 +106,9 @@ public class DateGroup
|
|||||||
throw new NullReferenceException(nameof(configuration.KeepFullPath));
|
throw new NullReferenceException(nameof(configuration.KeepFullPath));
|
||||||
if (configuration?.PropertyConfiguration?.PopulatePropertyId is null)
|
if (configuration?.PropertyConfiguration?.PopulatePropertyId is null)
|
||||||
throw new NullReferenceException(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 && !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 && configuration.ByHash.Value)
|
||||||
throw new Exception("Change configuration!");
|
throw new Exception("Change configuration!");
|
||||||
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!");
|
||||||
@ -147,7 +146,7 @@ public class DateGroup
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -185,19 +184,19 @@ public class DateGroup
|
|||||||
string weekOfYear;
|
string weekOfYear;
|
||||||
string? directory;
|
string? directory;
|
||||||
string seasonValue;
|
string seasonValue;
|
||||||
A_Property? property;
|
|
||||||
string directoryName;
|
string directoryName;
|
||||||
bool? propertyWrongYear;
|
bool? propertyWrongYear;
|
||||||
string topDirectoryName;
|
string topDirectoryName;
|
||||||
string[]? matches = null;
|
string[]? matches = null;
|
||||||
string[] directorySegments;
|
string[] directorySegments;
|
||||||
|
Shared.Models.Property? property;
|
||||||
DateTime? minimumDateTime = null;
|
DateTime? minimumDateTime = null;
|
||||||
List<string> destinationCollection;
|
List<string> destinationCollection;
|
||||||
List<string> directoryNames = new();
|
List<string> directoryNames = new();
|
||||||
FileHolder filteredSourceDirectoryFileHolder;
|
|
||||||
List<string> topDirectorySegments = new();
|
List<string> topDirectorySegments = new();
|
||||||
StringBuilder destinationDirectoryName = new();
|
StringBuilder destinationDirectoryName = new();
|
||||||
Calendar calendar = new CultureInfo("en-US").Calendar;
|
Calendar calendar = new CultureInfo("en-US").Calendar;
|
||||||
|
Shared.Models.FileHolder filteredSourceDirectoryFileHolder;
|
||||||
for (int z = 1; z < 3; z++)
|
for (int z = 1; z < 3; z++)
|
||||||
{
|
{
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
@ -222,7 +221,7 @@ public class DateGroup
|
|||||||
directoryName = Path.GetFileName(check);
|
directoryName = Path.GetFileName(check);
|
||||||
directorySegments = directoryName.Split(' ');
|
directorySegments = directoryName.Split(' ');
|
||||||
topDirectorySegments.AddRange(directorySegments);
|
topDirectorySegments.AddRange(directorySegments);
|
||||||
(_, matches) = Property.Models.Stateless.A_Property.IsWrongYear(directorySegments, string.Empty);
|
(_, matches) = Shared.Models.Stateless.Methods.IProperty.IsWrongYear(directorySegments, string.Empty);
|
||||||
if (matches.Any())
|
if (matches.Any())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -240,7 +239,7 @@ public class DateGroup
|
|||||||
if (property is null)
|
if (property is null)
|
||||||
continue;
|
continue;
|
||||||
filteredSourceDirectoryFileHolder = group.SourceDirectoryFileHolderCollection[i];
|
filteredSourceDirectoryFileHolder = group.SourceDirectoryFileHolderCollection[i];
|
||||||
minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(property);
|
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(property);
|
||||||
directory = filteredSourceDirectoryFileHolder.DirectoryName;
|
directory = filteredSourceDirectoryFileHolder.DirectoryName;
|
||||||
if (string.IsNullOrEmpty(directory))
|
if (string.IsNullOrEmpty(directory))
|
||||||
continue;
|
continue;
|
||||||
@ -261,7 +260,7 @@ public class DateGroup
|
|||||||
flag = '=';
|
flag = '=';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(season, seasonName) = Property.Models.Stateless.A_Property.GetSeason(minimumDateTime.Value.DayOfYear);
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(minimumDateTime.Value.DayOfYear);
|
||||||
if ((from l in topDirectorySegments where l == "Christmas" select true).Any())
|
if ((from l in topDirectorySegments where l == "Christmas" select true).Any())
|
||||||
seasonValue = string.Empty;
|
seasonValue = string.Empty;
|
||||||
else
|
else
|
||||||
@ -326,12 +325,12 @@ public class DateGroup
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel)
|
private A_Property GetPropertyLogic(bool reverse, Model? model, string outputExtension, PredictorModel? predictorModel)
|
||||||
{
|
{
|
||||||
PropertyLogic result;
|
A_Property result;
|
||||||
if (_Configuration?.PropertyConfiguration is null)
|
if (_Configuration?.PropertyConfiguration is null)
|
||||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||||
result = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
|
result = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, outputExtension, reverse, model, predictorModel);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,17 +426,17 @@ public class DateGroup
|
|||||||
}
|
}
|
||||||
_Log.Information($"Done moving back {moved} file(s)");
|
_Log.Information($"Done moving back {moved} file(s)");
|
||||||
for (int i = 1; i < 10; i++)
|
for (int i = 1; i < 10; i++)
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateDateShortcut(Property.Models.Configuration configuration, List<Container> containers)
|
private static void CreateDateShortcut(Property.Models.Configuration configuration, List<Shared.Models.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<Shared.Models.Item> selectedItems;
|
||||||
List<DateTime> dateTimes;
|
List<DateTime> dateTimes;
|
||||||
DateTime? minimumDateTime;
|
DateTime? minimumDateTime;
|
||||||
const int maximumHours = 24;
|
const int maximumHours = 24;
|
||||||
@ -445,26 +444,26 @@ public class DateGroup
|
|||||||
WindowsShortcut windowsShortcut;
|
WindowsShortcut windowsShortcut;
|
||||||
TimeSpan threeStandardDeviationHigh;
|
TimeSpan threeStandardDeviationHigh;
|
||||||
string aPropertyContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "()");
|
string aPropertyContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "()");
|
||||||
foreach (Container container in containers)
|
foreach (Shared.Models.Container container in containers)
|
||||||
{
|
{
|
||||||
if (!container.Items.Any())
|
if (!container.Items.Any())
|
||||||
continue;
|
continue;
|
||||||
selectedTotal = 0;
|
selectedTotal = 0;
|
||||||
threeStandardDeviationHigh = Property.Models.Stateless.A_Property.GetThreeStandardDeviationHigh(minimum, container);
|
threeStandardDeviationHigh = Shared.Models.Stateless.Methods.IProperty.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 < container.Items.Count; i++)
|
for (int i = 0; i < container.Items.Count; i++)
|
||||||
{
|
{
|
||||||
(i, dateTimes, selectedItems) = Property.Models.Stateless.A_Property.Get(container, threeStandardDeviationHigh, i);
|
(i, dateTimes, selectedItems) = Shared.Models.Stateless.Methods.IProperty.Get(container, threeStandardDeviationHigh, i);
|
||||||
selectedTotal += selectedItems.Count;
|
selectedTotal += selectedItems.Count;
|
||||||
foreach (Item item in selectedItems)
|
foreach (Shared.Models.Item item in selectedItems)
|
||||||
{
|
{
|
||||||
if (item.Property is null)
|
if (item.Property is null)
|
||||||
continue;
|
continue;
|
||||||
relativePathDirectory = Path.GetDirectoryName(item.RelativePath);
|
relativePathDirectory = Path.GetDirectoryName(item.RelativePath);
|
||||||
if (string.IsNullOrEmpty(relativePathDirectory))
|
if (string.IsNullOrEmpty(relativePathDirectory))
|
||||||
continue;
|
continue;
|
||||||
minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(item.Property);
|
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||||
if (minimumDateTime is null)
|
if (minimumDateTime is null)
|
||||||
continue;
|
continue;
|
||||||
path = Path.GetFullPath($"{configuration.RootDirectory}{item.RelativePath[..^5]}");
|
path = Path.GetFullPath($"{configuration.RootDirectory}{item.RelativePath[..^5]}");
|
||||||
|
@ -39,41 +39,41 @@ public class Program
|
|||||||
if (args is null)
|
if (args is null)
|
||||||
throw new Exception("args is null!");
|
throw new Exception("args is null!");
|
||||||
#nullable disable
|
#nullable disable
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("-".Split(' '), "2021").Item1.HasValue)
|
if (IProperty.IsWrongYear("-".Split(' '), "2021").Item1.HasValue)
|
||||||
throw new Exception("-");
|
throw new Exception("-");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Christmass".Split(' '), "2021").Item1.HasValue)
|
if (IProperty.IsWrongYear("Christmass".Split(' '), "2021").Item1.HasValue)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Christmass 2021".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Christmass 2021".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Christmass ~2021".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Christmass ~2021".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Christmass ~2021.4".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Christmass ~2021.4".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Christmass 2021".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Christmass 2021".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Christmass ~2021".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Christmass ~2021".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Christmass ~2021.4".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Christmass ~2021.4".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("England 2017".Split(' '), "2017").Item1.Value)
|
if (IProperty.IsWrongYear("England 2017".Split(' '), "2017").Item1.Value)
|
||||||
throw new Exception("England");
|
throw new Exception("England");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael".Split(' '), "2021").Item1.HasValue)
|
if (IProperty.IsWrongYear("Logan Michael".Split(' '), "2021").Item1.HasValue)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael 2021".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Logan Michael 2021".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael ~2021".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Logan Michael ~2021".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael 2021".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Logan Michael 2021".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael ~2021".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Logan Michael ~2021".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2021").Item2[0] != "~2021.4")
|
if (IProperty.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2021").Item2[0] != "~2021.4")
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Chelsea's 2nd Birthday =2014".Split(' '), "2014").Item1.Value)
|
if (IProperty.IsWrongYear("Chelsea's 2nd Birthday =2014".Split(' '), "2014").Item1.Value)
|
||||||
throw new Exception("Chelsea");
|
throw new Exception("Chelsea");
|
||||||
#nullable restore
|
#nullable restore
|
||||||
Shared.Models.Console console = new();
|
Shared.Models.Console console = new();
|
||||||
|
@ -55,15 +55,15 @@
|
|||||||
"ByHash": false,
|
"ByHash": false,
|
||||||
"BySeason": false,
|
"BySeason": false,
|
||||||
"ByWeek": false,
|
"ByWeek": false,
|
||||||
"DateGroup": "2022-08-14",
|
"DateGroup": "2022-08-22",
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||||
"KeepFullPath": false,
|
"KeepFullPath": false,
|
||||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||||
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
||||||
"PopulatePropertyId": true,
|
"PopulatePropertyId": true,
|
||||||
"PropertiesChangedForProperty": false,
|
"PropertiesChangedForProperty": false,
|
||||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-08-14 - b756859b616424dc98b7742a64c15a8951632473 - III",
|
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-08-22 - b756859b616424dc98b7742a64c15a8951632473 - III",
|
||||||
"WriteBitmapDataBytes": false,
|
"WriteBitmapDataBytes": false,
|
||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Phares.View.by.Distance.FaceRecognitionDotNet</PackageId>
|
<PackageId>Phares.View.by.Distance.FaceRecognitionDotNet</PackageId>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<Version>5.0.402.104</Version>
|
<Version>6.0.100.1</Version>
|
||||||
<Authors>Mike Phares</Authors>
|
<Authors>Mike Phares</Authors>
|
||||||
<Company>Phares</Company>
|
<Company>Phares</Company>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
@ -26,14 +26,14 @@ public class DlibDotNet
|
|||||||
private readonly B_Metadata _Metadata;
|
private readonly B_Metadata _Metadata;
|
||||||
private readonly E_Distance _Distance;
|
private readonly E_Distance _Distance;
|
||||||
private readonly Serilog.ILogger? _Log;
|
private readonly Serilog.ILogger? _Log;
|
||||||
|
private readonly D2_FaceParts _FaceParts;
|
||||||
private readonly AppSettings _AppSettings;
|
private readonly AppSettings _AppSettings;
|
||||||
private readonly List<string> _Exceptions;
|
private readonly List<string> _Exceptions;
|
||||||
private readonly IsEnvironment _IsEnvironment;
|
private readonly IsEnvironment _IsEnvironment;
|
||||||
private readonly D2_FaceLandmarks _FaceLandmarks;
|
|
||||||
private readonly Models.Configuration _Configuration;
|
private readonly Models.Configuration _Configuration;
|
||||||
private readonly bool _ArgZeroIsConfigurationRootDirectory;
|
private readonly bool _ArgZeroIsConfigurationRootDirectory;
|
||||||
private readonly List<KeyValuePair<string, string>> _FileKeyValuePairs;
|
private readonly List<KeyValuePair<string, string>> _FileKeyValuePairs;
|
||||||
private readonly Dictionary<string, List<Tuple<string, A_Property>>> _FilePropertiesKeyValuePairs;
|
private readonly Dictionary<string, List<Tuple<string, Shared.Models.Property>>> _FilePropertiesKeyValuePairs;
|
||||||
|
|
||||||
public DlibDotNet(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
public DlibDotNet(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
||||||
{
|
{
|
||||||
@ -44,8 +44,8 @@ public class DlibDotNet
|
|||||||
_Exceptions = new List<string>();
|
_Exceptions = new List<string>();
|
||||||
_Log = Serilog.Log.ForContext<DlibDotNet>();
|
_Log = Serilog.Log.ForContext<DlibDotNet>();
|
||||||
_FileKeyValuePairs = new List<KeyValuePair<string, string>>();
|
_FileKeyValuePairs = new List<KeyValuePair<string, string>>();
|
||||||
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, A_Property>>>();
|
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, Shared.Models.Property>>>();
|
||||||
Property.Models.Configuration propertyConfiguration = Property.Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory);
|
Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
|
||||||
_Log.Information(propertyConfiguration.RootDirectory);
|
_Log.Information(propertyConfiguration.RootDirectory);
|
||||||
Property.Models.Configuration.Verify(propertyConfiguration);
|
Property.Models.Configuration.Verify(propertyConfiguration);
|
||||||
Models.Configuration configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration);
|
Models.Configuration configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration);
|
||||||
@ -57,7 +57,6 @@ public class DlibDotNet
|
|||||||
_People = new A2_People(configuration);
|
_People = new A2_People(configuration);
|
||||||
_Rename = new E3_Rename(configuration);
|
_Rename = new E3_Rename(configuration);
|
||||||
_Distance = new E_Distance(configuration);
|
_Distance = new E_Distance(configuration);
|
||||||
_FaceLandmarks = new D2_FaceLandmarks(configuration);
|
|
||||||
if (configuration.IgnoreExtensions is null)
|
if (configuration.IgnoreExtensions is null)
|
||||||
throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||||
_Metadata = new(configuration.ForceMetadataLastWriteTimeToCreationTime, configuration.PropertiesChangedForMetadata);
|
_Metadata = new(configuration.ForceMetadataLastWriteTimeToCreationTime, configuration.PropertiesChangedForMetadata);
|
||||||
@ -66,11 +65,8 @@ public class DlibDotNet
|
|||||||
else
|
else
|
||||||
argZero = Path.GetFullPath(propertyConfiguration.RootDirectory);
|
argZero = Path.GetFullPath(propertyConfiguration.RootDirectory);
|
||||||
_ArgZeroIsConfigurationRootDirectory = propertyConfiguration.RootDirectory == argZero;
|
_ArgZeroIsConfigurationRootDirectory = propertyConfiguration.RootDirectory == argZero;
|
||||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters) = C_Resize.GetTuple(configuration.OutputExtension, configuration.OutputQuality);
|
|
||||||
_Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters);
|
|
||||||
_Log.Information(configuration.ModelDirectory);
|
_Log.Information(configuration.ModelDirectory);
|
||||||
(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);
|
|
||||||
if (!_ArgZeroIsConfigurationRootDirectory)
|
if (!_ArgZeroIsConfigurationRootDirectory)
|
||||||
people = Array.Empty<Person>();
|
people = Array.Empty<Person>();
|
||||||
else
|
else
|
||||||
@ -81,6 +77,18 @@ public class DlibDotNet
|
|||||||
e2Navigate.Navigate(propertyConfiguration, model, predictorModel, configuration.OutputResolutions[0]);
|
e2Navigate.Navigate(propertyConfiguration, model, predictorModel, configuration.OutputResolutions[0]);
|
||||||
_Log.Information(propertyConfiguration.RootDirectory);
|
_Log.Information(propertyConfiguration.RootDirectory);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
|
||||||
|
_FaceParts = new D2_FaceParts(configuration, imageCodecInfo, encoderParameters, filenameExtension);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality();
|
||||||
|
_Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel, imageCodecInfo, encoderParameters, filenameExtension);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple(configuration.OutputExtension, configuration.OutputQuality);
|
||||||
|
_Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension);
|
||||||
|
}
|
||||||
if (!configuration.SkipSearch)
|
if (!configuration.SkipSearch)
|
||||||
Search(propertyConfiguration, configuration.Reverse, model, predictorModel, argZero, people, isSilent);
|
Search(propertyConfiguration, configuration.Reverse, model, predictorModel, argZero, people, isSilent);
|
||||||
if (_Exceptions.Count == 0 && _ArgZeroIsConfigurationRootDirectory)
|
if (_Exceptions.Count == 0 && _ArgZeroIsConfigurationRootDirectory)
|
||||||
@ -90,13 +98,13 @@ public class DlibDotNet
|
|||||||
foreach (string[] directoryCollection in directoryCollections)
|
foreach (string[] directoryCollection in directoryCollections)
|
||||||
{
|
{
|
||||||
_Log.Information(string.Concat("Cleaning <", directoryCollection[0], ">"));
|
_Log.Information(string.Concat("Cleaning <", directoryCollection[0], ">"));
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryCollection[0]);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directoryCollection[0]);
|
||||||
}
|
}
|
||||||
string d2FaceLandmarksRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(D2_FaceLandmarks));
|
string d2FacePartsRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(D2_FaceParts));
|
||||||
_Log.Information(string.Concat("Cleaning <", d2FaceLandmarksRootDirectory, ">"));
|
_Log.Information(string.Concat("Cleaning <", d2FacePartsRootDirectory, ">"));
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(d2FaceLandmarksRootDirectory);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(d2FacePartsRootDirectory);
|
||||||
if (appSettings.MaxDegreeOfParallelism < 2)
|
if (appSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.IPath.DeleteEmptyDirectories));
|
ticks = LogDelta(ticks, nameof(Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories));
|
||||||
}
|
}
|
||||||
string message = $"There were {_Exceptions.Count} exception(s) thrown! {Environment.NewLine}{string.Join(Environment.NewLine, _Exceptions)}";
|
string message = $"There were {_Exceptions.Count} exception(s) thrown! {Environment.NewLine}{string.Join(Environment.NewLine, _Exceptions)}";
|
||||||
_Log.Information(message);
|
_Log.Information(message);
|
||||||
@ -112,7 +120,7 @@ public class DlibDotNet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -245,16 +253,12 @@ 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, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, 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)
|
private void FullParallelForWork(A_Property propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Face>> imageFaceCollections, string sourceDirectory, int index, Item item)
|
||||||
{
|
{
|
||||||
if (item.ImageFileHolder is null)
|
if (item.ImageFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
if (_Configuration?.PropertyConfiguration is null)
|
Shared.Models.Property property;
|
||||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
List<Face> faceCollection;
|
||||||
if (_Configuration.PropertyConfiguration.WriteBitmapDataBytes is null)
|
|
||||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration.WriteBitmapDataBytes));
|
|
||||||
A_Property property;
|
|
||||||
List<D_Face> faceCollection;
|
|
||||||
string original = "Original";
|
string original = "Original";
|
||||||
long ticks = DateTime.Now.Ticks;
|
long ticks = DateTime.Now.Ticks;
|
||||||
DateTime dateTime = DateTime.Now;
|
DateTime dateTime = DateTime.Now;
|
||||||
@ -282,7 +286,7 @@ public class DlibDotNet
|
|||||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
if (_AppSettings.MaxDegreeOfParallelism < 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(item.ImageFileHolder.FullName)));
|
FileHolder resizedFileHolder = new(Path.Combine(_Resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName)));
|
||||||
item.SetResizedFileHolder(resizedFileHolder);
|
item.SetResizedFileHolder(_Resize.FilenameExtension, resizedFileHolder);
|
||||||
imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
|
imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
|
||||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs));
|
ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs));
|
||||||
@ -291,7 +295,7 @@ public class DlibDotNet
|
|||||||
_Resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs);
|
_Resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs);
|
||||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(C_Resize.SaveResizedSubfile));
|
ticks = LogDelta(ticks, nameof(C_Resize.SaveResizedSubfile));
|
||||||
item.SetResizedFileHolder(FileHolder.Refresh(resizedFileHolder));
|
item.SetResizedFileHolder(_Resize.FilenameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(resizedFileHolder));
|
||||||
}
|
}
|
||||||
else if (outputResolution == _Configuration.OutputResolutions[0] && false)
|
else if (outputResolution == _Configuration.OutputResolutions[0] && false)
|
||||||
{
|
{
|
||||||
@ -315,11 +319,14 @@ public class DlibDotNet
|
|||||||
_Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faceCollection);
|
_Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faceCollection);
|
||||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
|
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
|
||||||
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
int?[] normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(faceCollection);
|
||||||
|
int normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||||
|
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length || _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||||
{
|
{
|
||||||
_FaceLandmarks.SaveFaceLandmarkImages(d2ResultsFullGroupDirectory, sourceDirectory, subFileTuples, parseExceptions, item, faceCollection);
|
bool saveRotated = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution);
|
||||||
|
_FaceParts.SaveFaceLandmarkImages(d2ResultsFullGroupDirectory, sourceDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated);
|
||||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(D2_FaceLandmarks.SaveFaceLandmarkImages));
|
ticks = LogDelta(ticks, nameof(D2_FaceParts.SaveFaceLandmarkImages));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lock (sourceDirectoryChanges)
|
lock (sourceDirectoryChanges)
|
||||||
@ -333,7 +340,7 @@ public class DlibDotNet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int FullParallelWork(long ticks, PropertyLogic propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, 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)
|
private int FullParallelWork(long ticks, A_Property propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Face>> faceCollections, int containersCount, Container container, Item[] filteredItems)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
if (_Log is null)
|
if (_Log is null)
|
||||||
@ -345,9 +352,9 @@ public class DlibDotNet
|
|||||||
for (int i = 0; i < filteredItems.Length; i++)
|
for (int i = 0; i < filteredItems.Length; i++)
|
||||||
{
|
{
|
||||||
faceCollections.Add(new());
|
faceCollections.Add(new());
|
||||||
|
propertyCollection.Add(null);
|
||||||
metadataCollection.Add(new());
|
metadataCollection.Add(new());
|
||||||
resizeKeyValuePairs.Add(new());
|
resizeKeyValuePairs.Add(new());
|
||||||
propertyCollection.Add(new());
|
|
||||||
propertyFileHolderCollection.Add(null);
|
propertyFileHolderCollection.Add(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -401,7 +408,7 @@ public class DlibDotNet
|
|||||||
if (metadataIdLines.Any())
|
if (metadataIdLines.Any())
|
||||||
{
|
{
|
||||||
text = string.Join(Environment.NewLine, from l in metadataIdLines orderby l.Id select l.Line);
|
text = string.Join(Environment.NewLine, from l in metadataIdLines orderby l.Id select l.Line);
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, text, updateDateWhenMatches: true, compareBeforeWrite: true);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, text, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -410,25 +417,23 @@ 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, Item[] filteredItems)
|
private void WriteGroup(Property.Models.Configuration configuration, A_Property propertyLogic, Shared.Models.Property[] propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<List<Face>> faceCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, string sourceDirectory, string outputResolution, Item[] filteredItems)
|
||||||
{
|
{
|
||||||
if (configuration.PropertiesChangedForProperty is null)
|
|
||||||
throw new NullReferenceException(nameof(configuration.PropertiesChangedForProperty));
|
|
||||||
Item item;
|
Item item;
|
||||||
string key;
|
string key;
|
||||||
string json;
|
string json;
|
||||||
string checkFile;
|
string checkFile;
|
||||||
int sourceDirectoryLength = sourceDirectory.Length;
|
int sourceDirectoryLength = sourceDirectory.Length;
|
||||||
_FilePropertiesKeyValuePairs.Add(sourceDirectory, new List<Tuple<string, A_Property>>());
|
_FilePropertiesKeyValuePairs.Add(sourceDirectory, new List<Tuple<string, Shared.Models.Property>>());
|
||||||
JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false };
|
JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false };
|
||||||
if (!(from l in propertyCollection where l?.Width is null select true).Any())
|
if (!(from l in propertyCollection where l?.Width is null select true).Any())
|
||||||
{
|
{
|
||||||
string checkDirectory;
|
string checkDirectory;
|
||||||
List<KeyValuePair<string, List<D_Face>>> faceCollectionsKeyValuePairs = new();
|
List<KeyValuePair<string, List<Face>>> faceCollectionsKeyValuePairs = new();
|
||||||
List<KeyValuePair<string, A_Property>> propertyCollectionKeyValuePairs = new();
|
List<KeyValuePair<string, Shared.Models.Property>> propertyCollectionKeyValuePairs = new();
|
||||||
List<KeyValuePair<string, Dictionary<string, int[]>>> resizeKeyValuePairsCollections = new();
|
List<KeyValuePair<string, Dictionary<string, int[]>>> resizeKeyValuePairsCollections = new();
|
||||||
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) = Shared.Models.Stateless.Methods.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 < filteredItems.Length; i++)
|
for (int i = 0; i < filteredItems.Length; i++)
|
||||||
{
|
{
|
||||||
@ -437,53 +442,53 @@ public class DlibDotNet
|
|||||||
continue;
|
continue;
|
||||||
if (item.ImageFileHolder is null)
|
if (item.ImageFileHolder is null)
|
||||||
continue;
|
continue;
|
||||||
key = Property.Models.Stateless.IPath.GetRelativePath(item.ImageFileHolder.FullName, sourceDirectoryLength);
|
key = Shared.Models.Stateless.Methods.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, Shared.Models.Property>(key, propertyCollection[i]));
|
||||||
faceCollectionsKeyValuePairs.Add(new KeyValuePair<string, List<D_Face>>(key, faceCollections[i]));
|
faceCollectionsKeyValuePairs.Add(new KeyValuePair<string, List<Face>>(key, faceCollections[i]));
|
||||||
propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, A_Property>(key, propertyCollection[i]));
|
propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, Shared.Models.Property>(key, propertyCollection[i]));
|
||||||
resizeKeyValuePairsCollections.Add(new KeyValuePair<string, Dictionary<string, int[]>>(key, resizeKeyValuePairs[i]));
|
resizeKeyValuePairsCollections.Add(new KeyValuePair<string, Dictionary<string, int[]>>(key, resizeKeyValuePairs[i]));
|
||||||
metadataCollectionKeyValuePairs.Add(new KeyValuePair<string, List<KeyValuePair<string, string>>>(key, metadataCollection[i]));
|
metadataCollectionKeyValuePairs.Add(new KeyValuePair<string, List<KeyValuePair<string, string>>>(key, metadataCollection[i]));
|
||||||
}
|
}
|
||||||
if (propertyLogic.AngleBracketCollection.Any())
|
if (propertyLogic.AngleBracketCollection.Any())
|
||||||
{
|
{
|
||||||
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(propertyLogic.AngleBracketCollection[0], level, "[{}]");
|
checkDirectory = Shared.Models.Stateless.Methods.IPath.GetDirectory(propertyLogic.AngleBracketCollection[0], level, "[{}]");
|
||||||
checkFile = Path.Combine(checkDirectory, fileName);
|
checkFile = Path.Combine(checkDirectory, fileName);
|
||||||
if (File.Exists(checkFile))
|
if (File.Exists(checkFile))
|
||||||
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
||||||
checkFile = Path.Combine(checkDirectory, fileName);
|
checkFile = Path.Combine(checkDirectory, fileName);
|
||||||
json = JsonSerializer.Serialize(propertyCollectionKeyValuePairs, writeIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(propertyCollectionKeyValuePairs, writeIndentedJsonSerializerOptions);
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||||
}
|
}
|
||||||
if (_Metadata.AngleBracketCollection.Any())
|
if (_Metadata.AngleBracketCollection.Any())
|
||||||
{
|
{
|
||||||
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(_Metadata.AngleBracketCollection[0], level, "[{}]");
|
checkDirectory = Shared.Models.Stateless.Methods.IPath.GetDirectory(_Metadata.AngleBracketCollection[0], level, "[{}]");
|
||||||
checkFile = Path.Combine(checkDirectory, fileName);
|
checkFile = Path.Combine(checkDirectory, fileName);
|
||||||
if (File.Exists(checkFile))
|
if (File.Exists(checkFile))
|
||||||
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
||||||
checkFile = Path.Combine(checkDirectory, fileName);
|
checkFile = Path.Combine(checkDirectory, fileName);
|
||||||
json = JsonSerializer.Serialize(metadataCollectionKeyValuePairs, writeIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(metadataCollectionKeyValuePairs, writeIndentedJsonSerializerOptions);
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||||
}
|
}
|
||||||
if (_Resize.AngleBracketCollection.Any())
|
if (_Resize.AngleBracketCollection.Any())
|
||||||
{
|
{
|
||||||
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(_Resize.AngleBracketCollection[0], level, "[{}]");
|
checkDirectory = Shared.Models.Stateless.Methods.IPath.GetDirectory(_Resize.AngleBracketCollection[0], level, "[{}]");
|
||||||
checkFile = Path.Combine(checkDirectory, fileName);
|
checkFile = Path.Combine(checkDirectory, fileName);
|
||||||
if (File.Exists(checkFile))
|
if (File.Exists(checkFile))
|
||||||
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
||||||
checkFile = Path.Combine(checkDirectory, fileName);
|
checkFile = Path.Combine(checkDirectory, fileName);
|
||||||
json = JsonSerializer.Serialize(resizeKeyValuePairsCollections, writeIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(resizeKeyValuePairsCollections, writeIndentedJsonSerializerOptions);
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||||
}
|
}
|
||||||
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution) && _Faces.AngleBracketCollection.Any())
|
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution) && _Faces.AngleBracketCollection.Any())
|
||||||
{
|
{
|
||||||
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(_Faces.AngleBracketCollection[0], level, "[{}]");
|
checkDirectory = Shared.Models.Stateless.Methods.IPath.GetDirectory(_Faces.AngleBracketCollection[0], level, "[{}]");
|
||||||
checkFile = Path.Combine(checkDirectory, fileName);
|
checkFile = Path.Combine(checkDirectory, fileName);
|
||||||
if (File.Exists(checkFile))
|
if (File.Exists(checkFile))
|
||||||
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
||||||
checkFile = Path.Combine(checkDirectory, fileName);
|
checkFile = Path.Combine(checkDirectory, fileName);
|
||||||
json = JsonSerializer.Serialize(faceCollectionsKeyValuePairs, writeIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(faceCollectionsKeyValuePairs, writeIndentedJsonSerializerOptions);
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -499,7 +504,7 @@ public class DlibDotNet
|
|||||||
string dResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
string dResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||||
configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
||||||
string d2ResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
string d2ResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||||
configuration, model, predictorModel, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
configuration, model, predictorModel, nameof(D2_FaceParts), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
||||||
string eResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
string eResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||||
configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
||||||
string zResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
string zResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||||
@ -507,7 +512,7 @@ public class DlibDotNet
|
|||||||
return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory, zResultsFullGroupDirectory);
|
return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory, zResultsFullGroupDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetAngleBracketCollections(Property.Models.Configuration configuration, PropertyLogic propertyLogic, string outputResolution, Container container, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory)
|
private void SetAngleBracketCollections(Property.Models.Configuration configuration, A_Property propertyLogic, string outputResolution, Container container, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory)
|
||||||
{
|
{
|
||||||
_Faces.AngleBracketCollection.Clear();
|
_Faces.AngleBracketCollection.Clear();
|
||||||
_Resize.AngleBracketCollection.Clear();
|
_Resize.AngleBracketCollection.Clear();
|
||||||
@ -544,7 +549,7 @@ public class DlibDotNet
|
|||||||
converted: true));
|
converted: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FullDoWork(bool isSilent, string argZero, Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, long ticks, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, List<Container> containers)
|
private void FullDoWork(string argZero, Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, long ticks, Map.Models.MapLogic mapLogic, A_Property propertyLogic, List<Container> containers)
|
||||||
{
|
{
|
||||||
if (_Log is null)
|
if (_Log is null)
|
||||||
throw new NullReferenceException(nameof(_Log));
|
throw new NullReferenceException(nameof(_Log));
|
||||||
@ -559,11 +564,12 @@ public class DlibDotNet
|
|||||||
string eResultsFullGroupDirectory;
|
string eResultsFullGroupDirectory;
|
||||||
string zResultsFullGroupDirectory;
|
string zResultsFullGroupDirectory;
|
||||||
string d2ResultsFullGroupDirectory;
|
string d2ResultsFullGroupDirectory;
|
||||||
List<List<D_Face>> faceCollections = new();
|
List<List<Face>> faceCollections = new();
|
||||||
List<A_Property> propertyCollection = new();
|
Shared.Models.Property[] propertyCollection;
|
||||||
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<Shared.Models.Property?> nullablePropertyCollection = new();
|
||||||
List<List<KeyValuePair<string, string>>> metadataCollection = new();
|
List<List<KeyValuePair<string, string>>> metadataCollection = new();
|
||||||
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));
|
||||||
@ -583,28 +589,29 @@ public class DlibDotNet
|
|||||||
continue;
|
continue;
|
||||||
faceCollections.Clear();
|
faceCollections.Clear();
|
||||||
metadataCollection.Clear();
|
metadataCollection.Clear();
|
||||||
propertyCollection.Clear();
|
|
||||||
resizeKeyValuePairs.Clear();
|
resizeKeyValuePairs.Clear();
|
||||||
sourceDirectoryChanges.Clear();
|
sourceDirectoryChanges.Clear();
|
||||||
|
nullablePropertyCollection.Clear();
|
||||||
propertyFileHolderCollection.Clear();
|
propertyFileHolderCollection.Clear();
|
||||||
SetAngleBracketCollections(configuration, propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory);
|
SetAngleBracketCollections(configuration, propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory);
|
||||||
exceptionCount = FullParallelWork(ticks, propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, containers.Count, container, filteredItems);
|
exceptionCount = FullParallelWork(ticks, propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, nullablePropertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, containers.Count, container, filteredItems);
|
||||||
#pragma warning disable
|
#pragma warning disable
|
||||||
ids = (from l in filteredItems where l.Property?.Id is not null select l.Property.Id.Value).ToArray();
|
ids = (from l in filteredItems where l.Property?.Id is not null select l.Property.Id.Value).ToArray();
|
||||||
#pragma warning restore
|
#pragma warning restore
|
||||||
distinctCount = ids.Distinct().Count();
|
distinctCount = ids.Distinct().Count();
|
||||||
if (ids.Length != distinctCount)
|
if (ids.Length != distinctCount)
|
||||||
_Log.Information($"{ids.Length} != {distinctCount} <{container.SourceDirectory}>");
|
_Log.Information($"{ids.Length} != {distinctCount} <{container.SourceDirectory}>");
|
||||||
if (metadataCollection.Count != filteredItems.Length || propertyCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || faceCollections.Count != filteredItems.Length)
|
if (metadataCollection.Count != filteredItems.Length || nullablePropertyCollection.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(container.SourceDirectory);
|
_Exceptions.Add(container.SourceDirectory);
|
||||||
for (int i = 0; i < faceCollections.Count; i++)
|
for (int i = 0; i < faceCollections.Count; i++)
|
||||||
filteredItems[i].Faces.AddRange(from l in faceCollections[i] select l);
|
filteredItems[i].Faces.AddRange(from l in faceCollections[i] select l);
|
||||||
|
propertyCollection = (from l in nullablePropertyCollection where l is not null select l).ToArray();
|
||||||
if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0)
|
if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0)
|
||||||
WriteGroup(configuration, propertyLogic, propertyCollection, metadataCollection, faceCollections, resizeKeyValuePairs, container.SourceDirectory, outputResolution, filteredItems);
|
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(filteredItems);
|
mapLogic.AddToMapLogicAllCollection(filteredItems);
|
||||||
if (exceptionCount == 0 && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution))
|
if (exceptionCount == 0 && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution))
|
||||||
_Distance.LoadOrCreateThenSaveDistanceResults(configuration, eResultsFullGroupDirectory, container.SourceDirectory, outputResolution, sourceDirectoryChanges, filteredItems);
|
_Distance.LoadOrCreateThenSaveDistanceResults(configuration, eResultsFullGroupDirectory, container.SourceDirectory, outputResolution, sourceDirectoryChanges, filteredItems);
|
||||||
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
|
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
|
||||||
@ -633,15 +640,6 @@ public class DlibDotNet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel)
|
|
||||||
{
|
|
||||||
PropertyLogic result;
|
|
||||||
if (_Configuration?.PropertyConfiguration is null)
|
|
||||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
|
||||||
result = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Search(Property.Models.Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel, string argZero, Person[] people, bool isSilent)
|
private void Search(Property.Models.Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel, string argZero, Person[] people, bool isSilent)
|
||||||
{
|
{
|
||||||
if (_Log is null)
|
if (_Log is null)
|
||||||
@ -656,26 +654,27 @@ public class DlibDotNet
|
|||||||
string zResultsFullGroupDirectory;
|
string zResultsFullGroupDirectory;
|
||||||
string d2ResultsFullGroupDirectory;
|
string d2ResultsFullGroupDirectory;
|
||||||
Dictionary<string, List<Person>> peopleCollection = A2_People.Convert(people);
|
Dictionary<string, List<Person>> peopleCollection = A2_People.Convert(people);
|
||||||
PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel);
|
Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration);
|
||||||
|
A_Property propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FilenameExtension, reverse, model, predictorModel, mapLogic.IndicesFromNew, mapLogic.KeyValuePairs);
|
||||||
if (string.IsNullOrEmpty(configuration.RootDirectory))
|
if (string.IsNullOrEmpty(configuration.RootDirectory))
|
||||||
containers = Property.Models.Stateless.A_Property.Get(configuration, propertyLogic);
|
containers = A_Property.Get(configuration, propertyLogic);
|
||||||
else
|
else
|
||||||
containers = Property.Models.Stateless.Container.GetContainers(configuration, propertyLogic);
|
containers = Property.Models.Stateless.Container.GetContainers(configuration, propertyLogic);
|
||||||
FullDoWork(isSilent, argZero, configuration, model, predictorModel, ticks, peopleCollection, propertyLogic, containers);
|
FullDoWork(argZero, configuration, model, predictorModel, ticks, mapLogic, propertyLogic, containers);
|
||||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||||
{
|
{
|
||||||
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory, zResultsFullGroupDirectory) = GetResultsFullGroupDirectories(configuration, model, predictorModel, outputResolution);
|
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory, zResultsFullGroupDirectory) = GetResultsFullGroupDirectories(configuration, model, predictorModel, outputResolution);
|
||||||
if (_ArgZeroIsConfigurationRootDirectory && _Exceptions.Count == 0 && outputResolution == _Configuration.OutputResolutions[0] && (propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.Any() || propertyLogic.NamedDeterministicHashCodeKeyValuePairs.Any()))
|
if (_ArgZeroIsConfigurationRootDirectory && _Exceptions.Count == 0 && outputResolution == _Configuration.OutputResolutions[0] && (mapLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.Any() || mapLogic.NamedDeterministicHashCodeKeyValuePairs.Any()))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(propertyLogic.DeterministicHashCodeRootDirectory) && !propertyLogic.IncorrectDeterministicHashCodeKeyValuePairs.Any())
|
if (!string.IsNullOrEmpty(mapLogic.DeterministicHashCodeRootDirectory) && !mapLogic.IncorrectDeterministicHashCodeKeyValuePairs.Any())
|
||||||
propertyLogic.UpdateKeyValuePairs(containers);
|
mapLogic.UpdateKeyValuePairs(containers);
|
||||||
foreach (Container container in containers)
|
foreach (Container container in containers)
|
||||||
{
|
{
|
||||||
Item.AddToNamed(propertyLogic, container.Items);
|
Map.Models.MapLogic.AddToNamed(mapLogic, container.Items);
|
||||||
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
|
||||||
D_Face.SaveShortcuts(_Configuration.JuliePhares, dResultsFullGroupDirectory, ticks, peopleCollection, propertyLogic, container.Items);
|
D_Face.SaveShortcuts(_Configuration.JuliePhares, dResultsFullGroupDirectory, ticks, peopleCollection, mapLogic, container.Items);
|
||||||
}
|
}
|
||||||
propertyLogic.SaveAllCollection();
|
mapLogic.SaveAllCollection();
|
||||||
if (_Configuration.SaveResizedSubfiles)
|
if (_Configuration.SaveResizedSubfiles)
|
||||||
{
|
{
|
||||||
string dFacesContentDirectory;
|
string dFacesContentDirectory;
|
||||||
@ -687,13 +686,13 @@ public class DlibDotNet
|
|||||||
zPropertyHolderSingletonDirectory = Path.Combine(zResultsFullGroupDirectory, "{}");
|
zPropertyHolderSingletonDirectory = Path.Combine(zResultsFullGroupDirectory, "{}");
|
||||||
eDistanceCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, $"[{ticks}]");
|
eDistanceCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, $"[{ticks}]");
|
||||||
List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection;
|
List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection;
|
||||||
collection = E_Distance.ParallelWork(_AppSettings.MaxDegreeOfParallelism, argZero, propertyLogic, containers);
|
collection = E_Distance.ParallelWork(_AppSettings.MaxDegreeOfParallelism, argZero, mapLogic, containers);
|
||||||
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.ParallelWork));
|
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.ParallelWork));
|
||||||
E_Distance.SavePropertyHolders(argZero, containers, zPropertyHolderSingletonDirectory);
|
E_Distance.SavePropertyHolders(argZero, containers, zPropertyHolderSingletonDirectory);
|
||||||
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.SavePropertyHolders));
|
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.SavePropertyHolders));
|
||||||
E_Distance.SaveThreeSigmaFaceEncodings(collection, peopleCollection, eDistanceCollectionDirectory);
|
E_Distance.SaveThreeSigmaFaceEncodings(collection, peopleCollection, eDistanceCollectionDirectory);
|
||||||
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.SaveThreeSigmaFaceEncodings));
|
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.SaveThreeSigmaFaceEncodings));
|
||||||
E_Distance.SaveClosest(argZero, containers, peopleCollection, eDistanceContentDirectory, dFacesContentDirectory);
|
E_Distance.SaveClosest(argZero, containers, peopleCollection, dFacesContentDirectory, d2ResultsFullGroupDirectory, eDistanceContentDirectory);
|
||||||
_ = LogDeltaInMinutes(ticks, nameof(E_Distance.SaveClosest));
|
_ = LogDeltaInMinutes(ticks, nameof(E_Distance.SaveClosest));
|
||||||
}
|
}
|
||||||
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
|
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
|
||||||
@ -709,17 +708,17 @@ public class DlibDotNet
|
|||||||
if (_Configuration.LoadOrCreateThenSaveIndex && _FilePropertiesKeyValuePairs.Any())
|
if (_Configuration.LoadOrCreateThenSaveIndex && _FilePropertiesKeyValuePairs.Any())
|
||||||
_Index.SetIndex(configuration, model, predictorModel, _Configuration.OutputResolutions[0], _FilePropertiesKeyValuePairs);
|
_Index.SetIndex(configuration, model, predictorModel, _Configuration.OutputResolutions[0], _FilePropertiesKeyValuePairs);
|
||||||
}
|
}
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}"));
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}"));
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, "{}"));
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, "{}"));
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}"));
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}"));
|
||||||
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, "[]"));
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, "[]"));
|
||||||
if (_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution))
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]"));
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]"));
|
||||||
if (_Configuration.LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions.Contains(outputResolution))
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]"));
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]"));
|
||||||
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(d2ResultsFullGroupDirectory, "[]"));
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(d2ResultsFullGroupDirectory, "[]"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Phares.View.by.Distance.Instance</PackageId>
|
<PackageId>Phares.View.by.Distance.Instance</PackageId>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<Version>5.0.402.104</Version>
|
<Version>6.0.100.1</Version>
|
||||||
<Authors>Mike Phares</Authors>
|
<Authors>Mike Phares</Authors>
|
||||||
<Company>Phares</Company>
|
<Company>Phares</Company>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
@ -53,12 +53,13 @@
|
|||||||
<PackageReference Include="WindowsShortcutFactory" Version="1.0.1" />
|
<PackageReference Include="WindowsShortcutFactory" Version="1.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
|
||||||
<ProjectReference Include="..\Property\Property.csproj" />
|
|
||||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
|
||||||
<ProjectReference Include="..\Resize\Resize.csproj" />
|
|
||||||
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />
|
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />
|
||||||
|
<ProjectReference Include="..\Map\Map.csproj" />
|
||||||
|
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||||
<ProjectReference Include="..\Property-Compare\Property-Compare.csproj" />
|
<ProjectReference Include="..\Property-Compare\Property-Compare.csproj" />
|
||||||
|
<ProjectReference Include="..\Property\Property.csproj" />
|
||||||
|
<ProjectReference Include="..\Resize\Resize.csproj" />
|
||||||
|
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="appsettings.json">
|
<None Include="appsettings.json">
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using View_by_Distance.Property.Models;
|
|
||||||
using View_by_Distance.Shared.Models;
|
using View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
namespace View_by_Distance.Instance.Models;
|
namespace View_by_Distance.Instance.Models;
|
||||||
@ -37,7 +36,7 @@ internal class A2_People
|
|||||||
string directoryFullName;
|
string directoryFullName;
|
||||||
Dictionary<string, List<G2_Identify>> keyValuePairs = new();
|
Dictionary<string, List<G2_Identify>> keyValuePairs = new();
|
||||||
string hPeopleCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People), "[]");
|
string hPeopleCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People), "[]");
|
||||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "{}");
|
||||||
foreach (G2_Identify identified in identifiedCollection)
|
foreach (G2_Identify identified in identifiedCollection)
|
||||||
{
|
{
|
||||||
fileInfo = new FileInfo(string.Concat(aPropertySingletonDirectory, identified.RelativePath));
|
fileInfo = new FileInfo(string.Concat(aPropertySingletonDirectory, identified.RelativePath));
|
||||||
@ -56,7 +55,7 @@ internal class A2_People
|
|||||||
_ = Directory.CreateDirectory(directoryFullName);
|
_ = Directory.CreateDirectory(directoryFullName);
|
||||||
jsonFile = Path.Combine(directoryFullName, $"{segments[1]}.json");
|
jsonFile = Path.Combine(directoryFullName, $"{segments[1]}.json");
|
||||||
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
|
||||||
if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,8 +63,6 @@ internal class A2_People
|
|||||||
internal Person[] GetPeople(Property.Models.Configuration configuration)
|
internal Person[] GetPeople(Property.Models.Configuration configuration)
|
||||||
{
|
{
|
||||||
Person[] results;
|
Person[] results;
|
||||||
if (_Configuration?.PropertyConfiguration is null)
|
|
||||||
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));
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using View_by_Distance.Metadata.Models;
|
using View_by_Distance.Metadata.Models;
|
||||||
using View_by_Distance.Property.Models;
|
|
||||||
using View_by_Distance.Resize.Models;
|
using View_by_Distance.Resize.Models;
|
||||||
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Properties;
|
using View_by_Distance.Shared.Models.Properties;
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
|
|
||||||
@ -11,16 +12,22 @@ namespace View_by_Distance.Instance.Models;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
// *.png
|
// *.png
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class D2_FaceLandmarks
|
internal class D2_FaceParts
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly Serilog.ILogger? _Log;
|
private readonly Serilog.ILogger? _Log;
|
||||||
|
private readonly string _FilenameExtension;
|
||||||
private readonly Configuration _Configuration;
|
private readonly Configuration _Configuration;
|
||||||
|
private readonly ImageCodecInfo _ImageCodecInfo;
|
||||||
|
private readonly EncoderParameters _EncoderParameters;
|
||||||
|
|
||||||
internal D2_FaceLandmarks(Configuration configuration)
|
internal D2_FaceParts(Configuration configuration, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension)
|
||||||
{
|
{
|
||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
_Log = Serilog.Log.ForContext<D2_FaceLandmarks>();
|
_ImageCodecInfo = imageCodecInfo;
|
||||||
|
_EncoderParameters = encoderParameters;
|
||||||
|
_FilenameExtension = filenameExtension;
|
||||||
|
_Log = Serilog.Log.ForContext<D2_FaceParts>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
@ -41,60 +48,64 @@ internal class D2_FaceLandmarks
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SaveFaceLandmarkImages(List<D_Face> faceCollections, List<string[]> imageFiles, int pointSize, FileHolder resizedFileHolder)
|
private void SaveFaceParts(int pointSize, IFileHolder resizedFileHolder, bool saveRotated, List<(Face, string, string)> collection)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
double? α;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
D_Face face;
|
|
||||||
string imageFileFullName;
|
|
||||||
Bitmap rotated;
|
Bitmap rotated;
|
||||||
string rotatedImageFileFullName;
|
foreach ((Face face, string fileName, string rotatedFileName) in collection)
|
||||||
Shared.Models.FacePoint[] facePoints;
|
|
||||||
for (int i = 0; i < faceCollections.Count; i++)
|
|
||||||
{
|
{
|
||||||
if (!faceCollections[i].Populated)
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
continue;
|
continue;
|
||||||
face = faceCollections[i];
|
|
||||||
imageFileFullName = imageFiles[i][0];
|
|
||||||
rotatedImageFileFullName = imageFiles[i][1];
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (Image image = Image.FromFile(resizedFileHolder.FullName))
|
using (Image image = Image.FromFile(resizedFileHolder.FullName))
|
||||||
{
|
{
|
||||||
using Graphics graphic = Graphics.FromImage(image);
|
using Graphics graphic = Graphics.FromImage(image);
|
||||||
if (face.FaceLandmarks is null || !face.FaceLandmarks.Any())
|
if (face.FaceParts is null || !face.FaceParts.Any())
|
||||||
{
|
{
|
||||||
|
if (face.Location is null)
|
||||||
|
continue;
|
||||||
width = face.Location.Right - face.Location.Left;
|
width = face.Location.Right - face.Location.Left;
|
||||||
height = face.Location.Bottom - face.Location.Top;
|
height = face.Location.Bottom - face.Location.Top;
|
||||||
graphic.DrawEllipse(Pens.Red, face.Location.Left, face.Location.Top, width, height);
|
graphic.DrawEllipse(Pens.Red, face.Location.Left, face.Location.Top, width, height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, Shared.Models.FacePoint[]> keyValuePair in face.FaceLandmarks)
|
foreach ((FacePart facePart, FacePoint[] facePoints) in face.FaceParts)
|
||||||
{
|
{
|
||||||
facePoints = keyValuePair.Value.ToArray();
|
foreach (FacePoint facePoint in facePoints)
|
||||||
foreach (Shared.Models.FacePoint facePoint in facePoints)
|
{
|
||||||
|
if (face.Location is null)
|
||||||
|
continue;
|
||||||
graphic.DrawEllipse(Pens.GreenYellow, face.Location.Left + facePoint.X - pointSize, face.Location.Top + facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
|
graphic.DrawEllipse(Pens.GreenYellow, face.Location.Left + facePoint.X - pointSize, face.Location.Top + facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
|
||||||
if (keyValuePair.Key == FacePart.Chin.ToString())
|
}
|
||||||
|
if (facePart == FacePart.Chin)
|
||||||
continue;
|
continue;
|
||||||
if (facePoints.Length < 3)
|
if (facePoints.Length < 3)
|
||||||
continue;
|
continue;
|
||||||
x = (int)(from l in facePoints select l.X).Average();
|
x = (int)(from l in facePoints select l.X).Average();
|
||||||
y = (int)(from l in facePoints select l.Y).Average();
|
y = (int)(from l in facePoints select l.Y).Average();
|
||||||
|
if (face.Location is null)
|
||||||
|
continue;
|
||||||
graphic.DrawEllipse(Pens.Purple, face.Location.Left + x - pointSize, face.Location.Top + y - pointSize, pointSize * 2, pointSize * 2);
|
graphic.DrawEllipse(Pens.Purple, face.Location.Left + x - pointSize, face.Location.Top + y - pointSize, pointSize * 2, pointSize * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
image.Save(imageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
|
image.Save(fileName, _ImageCodecInfo, _EncoderParameters);
|
||||||
}
|
}
|
||||||
if (face.α.HasValue)
|
if (saveRotated && face.FaceParts is not null)
|
||||||
{
|
{
|
||||||
|
α = Shared.Models.Stateless.Methods.IFace.Getα(face.FaceParts);
|
||||||
|
if (α is null)
|
||||||
|
continue;
|
||||||
using Image image = Image.FromFile(resizedFileHolder.FullName);
|
using Image image = Image.FromFile(resizedFileHolder.FullName);
|
||||||
rotated = RotateBitmap(image, (float)face.α.Value);
|
rotated = RotateBitmap(image, (float)α.Value);
|
||||||
if (rotated is not null)
|
if (rotated is not null)
|
||||||
{
|
{
|
||||||
rotated.Save(rotatedImageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
|
rotated.Save(rotatedFileName, _ImageCodecInfo, _EncoderParameters);
|
||||||
rotated.Dispose();
|
rotated.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,10 +116,8 @@ internal class D2_FaceLandmarks
|
|||||||
|
|
||||||
#pragma warning restore CA1416
|
#pragma warning restore CA1416
|
||||||
|
|
||||||
internal void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, string sourceDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<D_Face> faceCollection)
|
internal void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, string sourceDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Face> faceCollection, bool saveRotated)
|
||||||
{
|
{
|
||||||
if (_Configuration.PropertyConfiguration is null)
|
|
||||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
|
||||||
if (item.ImageFileHolder is null)
|
if (item.ImageFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
if (item.ResizedFileHolder is null)
|
if (item.ResizedFileHolder is null)
|
||||||
@ -121,31 +130,31 @@ internal class D2_FaceLandmarks
|
|||||||
DateTime? dateTime = null;
|
DateTime? dateTime = null;
|
||||||
double deterministicHashCodeKey;
|
double deterministicHashCodeKey;
|
||||||
long ticks = DateTime.Now.Ticks;
|
long ticks = DateTime.Now.Ticks;
|
||||||
List<string[]> imageFiles = new();
|
|
||||||
bool updateDateWhenMatches = false;
|
bool updateDateWhenMatches = false;
|
||||||
List<string> angleBracketCollection = new();
|
List<string> angleBracketCollection = new();
|
||||||
|
List<(Face, string, string)> collection = new();
|
||||||
angleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(
|
angleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(
|
||||||
_Configuration.PropertyConfiguration,
|
_Configuration.PropertyConfiguration,
|
||||||
sourceDirectory,
|
sourceDirectory,
|
||||||
d2ResultsFullGroupDirectory,
|
d2ResultsFullGroupDirectory,
|
||||||
contentDescription: "n x 2 png file(s) for each face found",
|
contentDescription: "n x 2 gif file(s) for each face found",
|
||||||
singletonDescription: string.Empty,
|
singletonDescription: string.Empty,
|
||||||
collectionDescription: string.Empty,
|
collectionDescription: string.Empty,
|
||||||
converted: false));
|
converted: false));
|
||||||
string facesDirectory = Path.Combine(angleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
|
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(Property.Models.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))
|
||||||
_ = Directory.CreateDirectory(facesDirectory);
|
_ = Directory.CreateDirectory(facesDirectory);
|
||||||
foreach (IFace face in faceCollection)
|
foreach (Face face in faceCollection)
|
||||||
{
|
{
|
||||||
if (!face.Populated || face.Location?.NormalizedPixelPercentage is null)
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
{
|
{
|
||||||
imageFiles.Add(Array.Empty<string>());
|
collection.Add(new(face, string.Empty, string.Empty));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face);
|
deterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetDeterministicHashCodeKey(item, face);
|
||||||
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
|
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FilenameExtension}"));
|
||||||
if (!fileInfo.Exists)
|
if (!fileInfo.Exists)
|
||||||
{
|
{
|
||||||
if (fileInfo.Directory?.Parent is null)
|
if (fileInfo.Directory?.Parent is null)
|
||||||
@ -156,15 +165,15 @@ internal class D2_FaceLandmarks
|
|||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
|
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
|
||||||
continue;
|
continue;
|
||||||
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{item.ImageFileHolder.ExtensionLowered}"));
|
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{item.ImageFileHolder.ExtensionLowered}{_FilenameExtension}"));
|
||||||
imageFiles.Add(new string[] { fileInfo.FullName, rotatedFileInfo.FullName });
|
collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName));
|
||||||
if (check)
|
if (check)
|
||||||
continue;
|
continue;
|
||||||
else if (_Configuration.OverrideForFaceLandmarkImages)
|
else if (_Configuration.OverrideForFaceLandmarkImages)
|
||||||
check = true;
|
check = true;
|
||||||
else if (!fileInfo.Exists)
|
else if (!fileInfo.Exists)
|
||||||
check = true;
|
check = true;
|
||||||
else if (!rotatedFileInfo.Exists)
|
else if (saveRotated && !rotatedFileInfo.Exists)
|
||||||
check = true;
|
check = true;
|
||||||
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||||
check = true;
|
check = true;
|
||||||
@ -175,7 +184,7 @@ internal class D2_FaceLandmarks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (check)
|
if (check)
|
||||||
SaveFaceLandmarkImages(faceCollection, imageFiles, pointSize, item.ResizedFileHolder);
|
SaveFaceParts(pointSize, item.ResizedFileHolder, saveRotated, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,14 +1,13 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using View_by_Distance.FaceRecognitionDotNet;
|
using View_by_Distance.FaceRecognitionDotNet;
|
||||||
using View_by_Distance.Metadata.Models;
|
using View_by_Distance.Metadata.Models;
|
||||||
using View_by_Distance.Property.Models;
|
using View_by_Distance.Property.Models;
|
||||||
using View_by_Distance.Resize.Models;
|
using View_by_Distance.Resize.Models;
|
||||||
using View_by_Distance.Shared.Models;
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Properties;
|
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
using WindowsShortcutFactory;
|
using WindowsShortcutFactory;
|
||||||
|
|
||||||
@ -17,7 +16,7 @@ namespace View_by_Distance.Instance.Models;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
// List<D_Faces>
|
// List<D_Faces>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class D_Face : IFace, Shared.Models.Methods.IFace
|
public class D_Face
|
||||||
{
|
{
|
||||||
|
|
||||||
internal List<string> AngleBracketCollection { get; }
|
internal List<string> AngleBracketCollection { get; }
|
||||||
@ -25,112 +24,29 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
private readonly Model _Model;
|
private readonly Model _Model;
|
||||||
private readonly string _ArgZero;
|
private readonly string _ArgZero;
|
||||||
private readonly Serilog.ILogger? _Log;
|
private readonly Serilog.ILogger? _Log;
|
||||||
|
private readonly string _FilenameExtension;
|
||||||
private readonly Configuration _Configuration;
|
private readonly Configuration _Configuration;
|
||||||
private readonly ModelParameter _ModelParameter;
|
private readonly ModelParameter _ModelParameter;
|
||||||
private readonly PredictorModel _PredictorModel;
|
private readonly PredictorModel _PredictorModel;
|
||||||
|
private readonly ImageCodecInfo _ImageCodecInfo;
|
||||||
|
private readonly EncoderParameters _EncoderParameters;
|
||||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||||
|
|
||||||
protected double? _Α;
|
internal D_Face(Configuration configuration, string argZero, Model model, ModelParameter modelParameter, PredictorModel predictorModel, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension)
|
||||||
protected DateTime _DateTime;
|
|
||||||
protected Shared.Models.FaceEncoding _FaceEncoding;
|
|
||||||
protected Dictionary<string, FacePoint[]> _FaceLandmarks;
|
|
||||||
protected Location _Location;
|
|
||||||
protected int? _LocationIndex;
|
|
||||||
protected OutputResolution _OutputResolution;
|
|
||||||
protected bool _Populated;
|
|
||||||
protected string _RelativePath;
|
|
||||||
public double? α => _Α;
|
|
||||||
public DateTime DateTime => _DateTime;
|
|
||||||
public Shared.Models.FaceEncoding FaceEncoding => _FaceEncoding;
|
|
||||||
public Dictionary<string, FacePoint[]> FaceLandmarks => _FaceLandmarks;
|
|
||||||
public OutputResolution OutputResolution => _OutputResolution;
|
|
||||||
public Location Location => _Location;
|
|
||||||
public int? LocationIndex => _LocationIndex;
|
|
||||||
public bool Populated => _Populated;
|
|
||||||
public string RelativePath => _RelativePath;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
[JsonConstructor]
|
|
||||||
public D_Face(double? α, DateTime dateTime, Shared.Models.FaceEncoding faceEncoding, Dictionary<string, FacePoint[]> faceLandmarks, Location location, int? locationIndex, OutputResolution outputResolution, bool populated, string relativePath)
|
|
||||||
{
|
|
||||||
_Α = α;
|
|
||||||
_DateTime = dateTime;
|
|
||||||
_FaceEncoding = faceEncoding;
|
|
||||||
_FaceLandmarks = faceLandmarks;
|
|
||||||
_Location = location;
|
|
||||||
_LocationIndex = locationIndex;
|
|
||||||
_OutputResolution = outputResolution;
|
|
||||||
_Populated = populated;
|
|
||||||
_RelativePath = relativePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal D_Face(Configuration configuration, string argZero, Model model, ModelParameter modelParameter, PredictorModel predictorModel)
|
|
||||||
{
|
{
|
||||||
_Model = model;
|
_Model = model;
|
||||||
_ArgZero = argZero;
|
_ArgZero = argZero;
|
||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
_ModelParameter = modelParameter;
|
_ModelParameter = modelParameter;
|
||||||
_PredictorModel = predictorModel;
|
_PredictorModel = predictorModel;
|
||||||
|
_ImageCodecInfo = imageCodecInfo;
|
||||||
|
_EncoderParameters = encoderParameters;
|
||||||
|
_FilenameExtension = filenameExtension;
|
||||||
AngleBracketCollection = new List<string>();
|
AngleBracketCollection = new List<string>();
|
||||||
_Log = Serilog.Log.ForContext<D_Face>();
|
_Log = Serilog.Log.ForContext<D_Face>();
|
||||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
private D_Face(Location location)
|
|
||||||
{
|
|
||||||
_Α = α;
|
|
||||||
_DateTime = DateTime.MinValue;
|
|
||||||
_FaceEncoding = null;
|
|
||||||
_FaceLandmarks = null;
|
|
||||||
_OutputResolution = null;
|
|
||||||
_Location = location;
|
|
||||||
_LocationIndex = null;
|
|
||||||
_Populated = false;
|
|
||||||
_RelativePath = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private D_Face()
|
|
||||||
{
|
|
||||||
_Α = α;
|
|
||||||
_DateTime = DateTime.MinValue;
|
|
||||||
_FaceEncoding = null;
|
|
||||||
_FaceLandmarks = null;
|
|
||||||
_OutputResolution = null;
|
|
||||||
_Location = null;
|
|
||||||
_LocationIndex = null;
|
|
||||||
_Populated = false;
|
|
||||||
_RelativePath = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private D_Face(A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string relativePath, int? i, Location location)
|
|
||||||
{
|
|
||||||
DateTime?[] dateTimes;
|
|
||||||
dateTimes = new DateTime?[] { property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
|
|
||||||
_DateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
|
|
||||||
_FaceLandmarks = new Dictionary<string, FacePoint[]>();
|
|
||||||
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
|
|
||||||
_Location = location;
|
|
||||||
_LocationIndex = i;
|
|
||||||
_Populated = false;
|
|
||||||
_RelativePath = relativePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
private D_Face(int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, IFace face)
|
|
||||||
{
|
|
||||||
_Α = face.α;
|
|
||||||
_DateTime = face.DateTime;
|
|
||||||
_FaceEncoding = face.FaceEncoding;
|
|
||||||
_FaceLandmarks = face.FaceLandmarks;
|
|
||||||
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
|
|
||||||
_Location = face.Location;
|
|
||||||
_LocationIndex = face.LocationIndex;
|
|
||||||
_Populated = face.Populated;
|
|
||||||
_RelativePath = face.RelativePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum)
|
private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum)
|
||||||
{
|
{
|
||||||
xMinimum = points[0].X;
|
xMinimum = points[0].X;
|
||||||
@ -219,26 +135,22 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SaveFaces(List<D_Face> faceCollection, FileHolder resizedFileHolder, List<string> imageFiles)
|
private void SaveFaces(FileHolder resizedFileHolder, List<(Face, string)> collection)
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
Graphics graphics;
|
Graphics graphics;
|
||||||
Location location;
|
Location? location;
|
||||||
Bitmap preRotated;
|
Bitmap preRotated;
|
||||||
Rectangle rectangle;
|
Rectangle rectangle;
|
||||||
using Bitmap source = new(resizedFileHolder.FullName);
|
using Bitmap source = new(resizedFileHolder.FullName);
|
||||||
for (int i = 0; i < faceCollection.Count; i++)
|
foreach ((Face face, string fileName) in collection)
|
||||||
{
|
{
|
||||||
if (!faceCollection[i].Populated || faceCollection[i]?.Location is null)
|
if (face.FaceEncoding is null || face?.Location is null)
|
||||||
|
continue;
|
||||||
|
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, source.Height, source.Width, collection.Count);
|
||||||
|
if (location is null)
|
||||||
continue;
|
continue;
|
||||||
location = new Location(faceCollection[i].Location.Confidence,
|
|
||||||
faceCollection[i].Location.Bottom,
|
|
||||||
faceCollection[i].Location.Left,
|
|
||||||
faceCollection[i].Location.Right,
|
|
||||||
faceCollection[i].Location.Top,
|
|
||||||
source.Width,
|
|
||||||
source.Height);
|
|
||||||
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);
|
||||||
@ -246,149 +158,54 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
{
|
{
|
||||||
using (graphics = Graphics.FromImage(preRotated))
|
using (graphics = Graphics.FromImage(preRotated))
|
||||||
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||||
preRotated.Save(imageFiles[i], System.Drawing.Imaging.ImageFormat.Png);
|
preRotated.Save(fileName, _ImageCodecInfo, _EncoderParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<D_Face> GetFaces(FileHolder resizedFileHolder, Item item, A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string facesDirectory)
|
private List<Face> GetFaces(FileHolder resizedFileHolder, Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||||
{
|
{
|
||||||
List<D_Face> results = new();
|
List<Face> results = new();
|
||||||
if (item.ImageFileHolder is null)
|
if (item.ImageFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
List<Location> locations;
|
FaceRecognitionDotNet.Image? unknownImage;
|
||||||
FaceRecognitionDotNet.Image? unknownImage = null;
|
if (!resizedFileHolder.Exists)
|
||||||
if (resizedFileHolder.Exists)
|
unknownImage = null;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{ unknownImage = FaceRecognition.LoadImageFile(resizedFileHolder.FullName); }
|
{ unknownImage = FaceRecognition.LoadImageFile(resizedFileHolder.FullName); }
|
||||||
catch (Exception) { }
|
catch (Exception)
|
||||||
|
{ unknownImage = null; }
|
||||||
}
|
}
|
||||||
if (unknownImage is null)
|
if (unknownImage is null)
|
||||||
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter);
|
List<(Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection;
|
||||||
locations = faceRecognition.FaceLocations(_Model, unknownImage, _Configuration.NumberOfTimesToUpsample, sortByNormalizedPixelPercentage: true);
|
FaceRecognition faceRecognition = new(_Configuration.NumberOfTimesToUpsample, _Configuration.NumberOfJitters, _PredictorModel, _Model, _ModelParameter);
|
||||||
if (!locations.Any())
|
collection = faceRecognition.GetCollection(unknownImage, includeFaceEncoding: true, includeFaceParts: true, sortByNormalizedPixelPercentage: true);
|
||||||
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
if (!collection.Any())
|
||||||
|
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double? α;
|
int i = 0;
|
||||||
int width;
|
Face face;
|
||||||
int height;
|
|
||||||
int padding;
|
|
||||||
int? leftEyeX;
|
|
||||||
int? leftEyeY;
|
|
||||||
int? rightEyeX;
|
|
||||||
int? rightEyeY;
|
|
||||||
Bitmap rotated;
|
|
||||||
string faceFile;
|
|
||||||
Location location;
|
|
||||||
Bitmap preRotated;
|
|
||||||
Graphics graphics;
|
|
||||||
D_Face? face = null;
|
|
||||||
Rectangle rectangle;
|
|
||||||
double[] rawEncoding;
|
double[] rawEncoding;
|
||||||
double deterministicHashCodeKey;
|
Shared.Models.FaceEncoding convertedFaceEncoding;
|
||||||
Shared.Models.FaceEncoding faceEncoding;
|
foreach ((Location location, FaceRecognitionDotNet.FaceEncoding? faceEncoding, Dictionary<FacePart, FacePoint[]>? faceParts) in collection)
|
||||||
FaceRecognitionDotNet.Image? knownImage;
|
|
||||||
FaceRecognitionDotNet.Image? rotatedImage;
|
|
||||||
List<(FacePart, FacePoint[])[]> facesLandmarks;
|
|
||||||
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings;
|
|
||||||
using Bitmap source = unknownImage.ToBitmap();
|
|
||||||
padding = (int)((source.Width + source.Height) / 2 * .01);
|
|
||||||
for (int i = 0; i < locations.Count; i++)
|
|
||||||
{
|
{
|
||||||
for (int p = 0; p <= _Configuration.PaddingLoops; p++)
|
face = new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i, location);
|
||||||
|
if (faceEncoding is not null)
|
||||||
{
|
{
|
||||||
location = new(locations[i].Confidence,
|
rawEncoding = faceEncoding.GetRawEncoding();
|
||||||
locations[i].Bottom + (padding * p),
|
convertedFaceEncoding = new(rawEncoding, faceEncoding.Size);
|
||||||
locations[i].Left - (padding * p),
|
face.SetFaceEncoding(convertedFaceEncoding);
|
||||||
locations[i].Right + (padding * p),
|
|
||||||
locations[i].Top - (padding * p),
|
|
||||||
source.Width,
|
|
||||||
source.Height);
|
|
||||||
face = new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i, location);
|
|
||||||
width = location.Right - location.Left;
|
|
||||||
height = location.Bottom - location.Top;
|
|
||||||
rectangle = new Rectangle(location.Left, location.Top, width, height);
|
|
||||||
using (preRotated = new Bitmap(width, height))
|
|
||||||
{
|
|
||||||
leftEyeX = null;
|
|
||||||
leftEyeY = null;
|
|
||||||
rightEyeX = null;
|
|
||||||
rightEyeY = null;
|
|
||||||
using (graphics = Graphics.FromImage(preRotated))
|
|
||||||
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
|
||||||
// source.Save(Path.Combine(_Configuration.RootDirectory, "source.jpg"));
|
|
||||||
// preRotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - preRotated.jpg"));
|
|
||||||
using (knownImage = FaceRecognition.LoadImage(preRotated))
|
|
||||||
{
|
|
||||||
if (knownImage is null || knownImage.IsDisposed)
|
|
||||||
throw new NullReferenceException(nameof(knownImage));
|
|
||||||
facesLandmarks = faceRecognition.GetFaceLandmarkCollection(knownImage, _Configuration.NumberOfTimesToUpsample, faceLocations: null, _PredictorModel, _Model);
|
|
||||||
}
|
|
||||||
if (facesLandmarks.Count == 0 && p < _Configuration.PaddingLoops)
|
|
||||||
continue;
|
|
||||||
else if (facesLandmarks.Count != 1)
|
|
||||||
continue;
|
|
||||||
foreach ((FacePart facePart, FacePoint[] facePoints) in facesLandmarks[0])
|
|
||||||
{
|
|
||||||
face.FaceLandmarks.Add(facePart.ToString(), facePoints);
|
|
||||||
if (facePart is not FacePart.LeftEye and not FacePart.RightEye)
|
|
||||||
continue;
|
|
||||||
if (facePart is FacePart.LeftEye)
|
|
||||||
{
|
|
||||||
leftEyeX = (int)(from l in facePoints select l.X).Average();
|
|
||||||
leftEyeY = (int)(from l in facePoints select l.Y).Average();
|
|
||||||
}
|
|
||||||
if (facePart is FacePart.RightEye)
|
|
||||||
{
|
|
||||||
rightEyeX = (int)(from l in facePoints select l.X).Average();
|
|
||||||
rightEyeY = (int)(from l in facePoints select l.Y).Average();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rightEyeX is null || leftEyeX is null || rightEyeY is null || leftEyeY is null)
|
|
||||||
continue;
|
|
||||||
α = Shared.Models.Stateless.Methods.IFace.Getα(rightEyeX.Value, leftEyeX.Value, rightEyeY.Value, leftEyeY.Value);
|
|
||||||
using (rotated = RotateBitmap(preRotated, (float)α.Value))
|
|
||||||
{
|
|
||||||
// rotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - rotated.jpg"));
|
|
||||||
using (rotatedImage = FaceRecognition.LoadImage(rotated))
|
|
||||||
{
|
|
||||||
if (rotatedImage is null || rotatedImage.IsDisposed)
|
|
||||||
throw new NullReferenceException(nameof(rotatedImage));
|
|
||||||
faceEncodings = faceRecognition.FaceEncodings(rotatedImage, _Configuration.NumberOfTimesToUpsample, knownFaceLocation: null, _Configuration.NumberOfJitters, _PredictorModel, _Model);
|
|
||||||
}
|
|
||||||
if (faceEncodings.Count == 0 && p < _Configuration.PaddingLoops)
|
|
||||||
continue;
|
|
||||||
else if (faceEncodings.Count != 1)
|
|
||||||
continue;
|
|
||||||
rawEncoding = faceEncodings[0].GetRawEncoding();
|
|
||||||
faceEncoding = new(rawEncoding, faceEncodings[0].Size);
|
|
||||||
face.Update(α, faceEncoding, populated: true);
|
|
||||||
}
|
|
||||||
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face);
|
|
||||||
faceFile = Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png");
|
|
||||||
preRotated.Save(faceFile, System.Drawing.Imaging.ImageFormat.Png);
|
|
||||||
results.Add(face);
|
|
||||||
}
|
|
||||||
if (face.Populated)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (face is null || !face.Populated)
|
|
||||||
{
|
|
||||||
location = new(locations[i].Confidence,
|
|
||||||
locations[i].Bottom,
|
|
||||||
locations[i].Left,
|
|
||||||
locations[i].Right,
|
|
||||||
locations[i].Top,
|
|
||||||
source.Width,
|
|
||||||
source.Height);
|
|
||||||
face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i, location);
|
|
||||||
results.Add(face);
|
|
||||||
}
|
}
|
||||||
|
if (faceParts is not null)
|
||||||
|
face.SetFaceParts(faceParts);
|
||||||
|
results.Add(face);
|
||||||
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unknownImage.Dispose();
|
unknownImage.Dispose();
|
||||||
@ -401,16 +218,9 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
|
|
||||||
#pragma warning restore CA1416
|
#pragma warning restore CA1416
|
||||||
|
|
||||||
private void Update(double? α, Shared.Models.FaceEncoding faceEncoding, bool populated)
|
internal List<Face> GetFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, Shared.Models.Property property, FileHolder resizedFileHolder, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||||
{
|
{
|
||||||
_Α = α;
|
List<Face>? results;
|
||||||
_FaceEncoding = faceEncoding;
|
|
||||||
_Populated = populated;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal List<D_Face> GetFaces(string dResultsFullGroupDirectory, 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;
|
|
||||||
if (item.Property?.Id is null)
|
if (item.Property?.Id is null)
|
||||||
throw new NullReferenceException(nameof(item.Property.Id));
|
throw new NullReferenceException(nameof(item.Property.Id));
|
||||||
if (item.ImageFileHolder is null)
|
if (item.ImageFileHolder is null)
|
||||||
@ -418,9 +228,10 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
|
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
|
||||||
throw new NullReferenceException(nameof(dResultsFullGroupDirectory));
|
throw new NullReferenceException(nameof(dResultsFullGroupDirectory));
|
||||||
string json;
|
string json;
|
||||||
|
int?[] normalizedPixelPercentageCollection;
|
||||||
|
int normalizedPixelPercentageDistinctCount;
|
||||||
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("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
|
|
||||||
string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json");
|
string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json");
|
||||||
string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
|
string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
|
||||||
FileInfo fileInfo = new(dCollectionFile);
|
FileInfo fileInfo = new(dCollectionFile);
|
||||||
@ -443,8 +254,6 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Directory.Exists(facesDirectory))
|
|
||||||
_ = Directory.CreateDirectory(facesDirectory);
|
|
||||||
if (_Configuration.ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
if (_Configuration.ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
||||||
{
|
{
|
||||||
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
||||||
@ -466,9 +275,18 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
json = Shared.Models.Stateless.Methods.IFace.GetJson(fileInfo.FullName);
|
json = Shared.Models.Stateless.Methods.IFace.GetJson(fileInfo.FullName);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
results = JsonSerializer.Deserialize<List<D_Face>>(json);
|
results = JsonSerializer.Deserialize<List<Face>>(json);
|
||||||
if (results is null)
|
if (results is null)
|
||||||
throw new NullReferenceException(nameof(results));
|
throw new NullReferenceException(nameof(results));
|
||||||
|
if (!_Configuration.ForceFaceLastWriteTimeToCreationTime)
|
||||||
|
{
|
||||||
|
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
|
||||||
|
if (normalizedPixelPercentageCollection.Contains(3))
|
||||||
|
throw new Exception($"Not allowed! <{fileInfo.FullName}>");
|
||||||
|
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||||
|
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
|
||||||
|
throw new Exception($"Not distinct! <{fileInfo.FullName}>");
|
||||||
|
}
|
||||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), fileInfo.LastWriteTime));
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), fileInfo.LastWriteTime));
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
@ -479,19 +297,24 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
}
|
}
|
||||||
if (results is null)
|
if (results is null)
|
||||||
{
|
{
|
||||||
results = GetFaces(resizedFileHolder, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, facesDirectory);
|
results = GetFaces(resizedFileHolder, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation);
|
||||||
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();
|
||||||
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
||||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now));
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now));
|
||||||
}
|
}
|
||||||
if (_Configuration.ForceFaceLastWriteTimeToCreationTime)
|
if (_Configuration.ForceFaceLastWriteTimeToCreationTime)
|
||||||
{
|
{
|
||||||
|
results = (from l in results select new Face(results.Count, l)).ToList();
|
||||||
|
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
|
||||||
|
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||||
|
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
|
||||||
|
throw new Exception($"Not distinct! <{fileInfo.FullName}>");
|
||||||
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();
|
||||||
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
||||||
{
|
{
|
||||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
||||||
fileInfo.Refresh();
|
fileInfo.Refresh();
|
||||||
@ -501,7 +324,7 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SaveFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<D_Face> faceCollection)
|
internal void SaveFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Face> faceCollection)
|
||||||
{
|
{
|
||||||
if (item.ImageFileHolder is null)
|
if (item.ImageFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
@ -511,22 +334,22 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
bool check = false;
|
bool check = false;
|
||||||
string parentCheck;
|
string parentCheck;
|
||||||
double deterministicHashCodeKey;
|
double deterministicHashCodeKey;
|
||||||
List<string> imageFiles = new();
|
List<(Face, string)> collection = 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("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
|
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)
|
||||||
_ = Directory.CreateDirectory(facesDirectory);
|
_ = Directory.CreateDirectory(facesDirectory);
|
||||||
foreach (IFace face in faceCollection)
|
foreach (Face face in faceCollection)
|
||||||
{
|
{
|
||||||
if (!face.Populated || face.Location?.NormalizedPixelPercentage is null)
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
{
|
{
|
||||||
imageFiles.Add(string.Empty);
|
collection.Add(new(face, string.Empty));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face);
|
deterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetDeterministicHashCodeKey(item, face);
|
||||||
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
|
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FilenameExtension}"));
|
||||||
if (!fileInfo.Exists)
|
if (!fileInfo.Exists)
|
||||||
{
|
{
|
||||||
if (fileInfo.Directory?.Parent is null)
|
if (fileInfo.Directory?.Parent is null)
|
||||||
@ -535,7 +358,7 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
if (File.Exists(parentCheck))
|
if (File.Exists(parentCheck))
|
||||||
File.Delete(parentCheck);
|
File.Delete(parentCheck);
|
||||||
}
|
}
|
||||||
imageFiles.Add(fileInfo.FullName);
|
collection.Add(new(face, fileInfo.FullName));
|
||||||
if (_Configuration.OverrideForFaceImages)
|
if (_Configuration.OverrideForFaceImages)
|
||||||
check = true;
|
check = true;
|
||||||
else if (!fileInfo.Exists)
|
else if (!fileInfo.Exists)
|
||||||
@ -544,10 +367,10 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
check = true;
|
check = true;
|
||||||
}
|
}
|
||||||
if (check)
|
if (check)
|
||||||
SaveFaces(faceCollection, item.ResizedFileHolder, imageFiles);
|
SaveFaces(item.ResizedFileHolder, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SaveShortcuts(string[] juliePhares, string dResultsFullGroupDirectory, long ticks, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, List<Item> items)
|
internal static void SaveShortcuts(string[] juliePhares, string dResultsFullGroupDirectory, long ticks, Dictionary<string, List<Person>> peopleCollection, Map.Models.MapLogic mapLogic, List<Item> items)
|
||||||
{
|
{
|
||||||
Person person;
|
Person person;
|
||||||
string fileName;
|
string fileName;
|
||||||
@ -556,18 +379,18 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
WindowsShortcut windowsShortcut;
|
WindowsShortcut windowsShortcut;
|
||||||
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
||||||
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, $"({ticks})");
|
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, $"({ticks})");
|
||||||
List<(Item, (string, IFace?, (string, string, string, string))[])> collections = Item.GetCollection(propertyLogic, items, dFacesContentDirectory);
|
List<(Item, (string, Face?, (string, string, string, string))[])> collections = Map.Models.MapLogic.GetCollection(mapLogic, items, dFacesContentDirectory);
|
||||||
foreach ((Item item, (string personKey, IFace? _, (string, string, string, string))[] collection) in collections)
|
foreach ((Item item, (string personKey, Face? _, (string, string, string, string))[] collection) in collections)
|
||||||
{
|
{
|
||||||
if (collection.Length != 1)
|
if (collection.Length != 1)
|
||||||
continue;
|
continue;
|
||||||
foreach ((string personKey, IFace? _, (string directory, string copyDirectory, string copyFileName, string shortcutFileName)) in collection)
|
foreach ((string personKey, Face? _, (string directory, string copyDirectory, string copyFileName, string shortcutFileName)) in collection)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(personKey))
|
if (string.IsNullOrEmpty(personKey))
|
||||||
continue;
|
continue;
|
||||||
if (item.Property?.Id is null || item.ImageFileHolder is null || item.ResizedFileHolder is null)
|
if (item.Property?.Id is null || item.ImageFileHolder is null || item.ResizedFileHolder is null)
|
||||||
continue;
|
continue;
|
||||||
minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(item.Property);
|
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||||
if (minimumDateTime is null)
|
if (minimumDateTime is null)
|
||||||
continue;
|
continue;
|
||||||
if (!Directory.Exists(directory))
|
if (!Directory.Exists(directory))
|
||||||
@ -601,24 +424,16 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double Shared.Models.Stateless.Methods.IFace.TestStatic_Getα(int x1, int x2, int y1, int y2) => throw new NotImplementedException();
|
private static bool HasLeftAndRight(Dictionary<string, FacePoint[]> faceParts)
|
||||||
|
|
||||||
string Shared.Models.Stateless.Methods.IFace.TestStatic_GetJson(string jsonFileFullName) => throw new NotImplementedException();
|
|
||||||
|
|
||||||
Face Shared.Models.Stateless.Methods.IFace.TestStatic_GetFace(string jsonFileFullName) => throw new NotImplementedException();
|
|
||||||
|
|
||||||
Face[] Shared.Models.Stateless.Methods.IFace.TestStatic_GetFaces(string jsonFileFullName) => throw new NotImplementedException();
|
|
||||||
|
|
||||||
private static bool HasLeftAndRight(Dictionary<string, FacePoint[]> faceLandmarks)
|
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (!faceLandmarks.ContainsKey(FacePart.LeftEye.ToString()))
|
if (!faceParts.ContainsKey(FacePart.LeftEye.ToString()))
|
||||||
result = false;
|
result = false;
|
||||||
else if (!faceLandmarks.ContainsKey(FacePart.RightEye.ToString()))
|
else if (!faceParts.ContainsKey(FacePart.RightEye.ToString()))
|
||||||
result = false;
|
result = false;
|
||||||
else if (!faceLandmarks.ContainsKey(FacePart.LeftEyebrow.ToString()))
|
else if (!faceParts.ContainsKey(FacePart.LeftEyebrow.ToString()))
|
||||||
result = false;
|
result = false;
|
||||||
else if (!faceLandmarks.ContainsKey(FacePart.RightEyebrow.ToString()))
|
else if (!faceParts.ContainsKey(FacePart.RightEyebrow.ToString()))
|
||||||
result = false;
|
result = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -96,8 +96,6 @@ internal class E2_Navigate
|
|||||||
string result;
|
string result;
|
||||||
if (_Log is null)
|
if (_Log is null)
|
||||||
throw new NullReferenceException(nameof(_Log));
|
throw new NullReferenceException(nameof(_Log));
|
||||||
if (_Configuration?.PropertyConfiguration is null)
|
|
||||||
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]?");
|
||||||
@ -111,7 +109,7 @@ internal class E2_Navigate
|
|||||||
{
|
{
|
||||||
_Log.Warn(string.Empty);
|
_Log.Warn(string.Empty);
|
||||||
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||||
string relativePath = Property.Models.Stateless.IPath.GetRelativePath(subSourceDirectory, eDistanceCollectionDirectory.Length);
|
string relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(subSourceDirectory, eDistanceCollectionDirectory.Length);
|
||||||
if (relativePath.Length == 1)
|
if (relativePath.Length == 1)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (Directory.Exists(Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName)))
|
if (Directory.Exists(Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName)))
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using View_by_Distance.Metadata.Models;
|
using View_by_Distance.Metadata.Models;
|
||||||
using View_by_Distance.Property.Models;
|
|
||||||
using View_by_Distance.Resize.Models;
|
using View_by_Distance.Resize.Models;
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
|
|
||||||
@ -40,10 +39,10 @@ internal class E3_Rename
|
|||||||
string cResizeSingletonDirectory;
|
string cResizeSingletonDirectory;
|
||||||
string eDistanceContentDirectory;
|
string eDistanceContentDirectory;
|
||||||
string aPropertySingletonDirectory;
|
string aPropertySingletonDirectory;
|
||||||
|
string d2FacePartsContentDirectory;
|
||||||
string bMetadataSingletonDirectory;
|
string bMetadataSingletonDirectory;
|
||||||
string eDistanceCollectionDirectory;
|
string eDistanceCollectionDirectory;
|
||||||
string g2IdentifyCollectionDirectory;
|
string g2IdentifyCollectionDirectory;
|
||||||
string d2FaceLandmarksContentDirectory;
|
|
||||||
add = Directory.Exists(string.Concat(Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(C_Resize), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()"), relativePath));
|
add = Directory.Exists(string.Concat(Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(C_Resize), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()"), relativePath));
|
||||||
bMetadataSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(B_Metadata), "{}");
|
bMetadataSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(B_Metadata), "{}");
|
||||||
if (Directory.Exists(bMetadataSingletonDirectory))
|
if (Directory.Exists(bMetadataSingletonDirectory))
|
||||||
@ -51,7 +50,7 @@ internal class E3_Rename
|
|||||||
to = Path.Combine(string.Concat(bMetadataSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
to = Path.Combine(string.Concat(bMetadataSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||||
results.Add(to);
|
results.Add(to);
|
||||||
}
|
}
|
||||||
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "{}");
|
||||||
if (Directory.Exists(aPropertySingletonDirectory))
|
if (Directory.Exists(aPropertySingletonDirectory))
|
||||||
{
|
{
|
||||||
to = Path.Combine(string.Concat(aPropertySingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
to = Path.Combine(string.Concat(aPropertySingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||||
@ -83,10 +82,10 @@ internal class E3_Rename
|
|||||||
to = Path.Combine(string.Concat(dFacesCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
to = Path.Combine(string.Concat(dFacesCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||||
results.Add(to);
|
results.Add(to);
|
||||||
}
|
}
|
||||||
d2FaceLandmarksContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
d2FacePartsContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D2_FaceParts), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||||
if (add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution) && Directory.Exists(d2FaceLandmarksContentDirectory))
|
if (add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution) && Directory.Exists(d2FacePartsContentDirectory))
|
||||||
{
|
{
|
||||||
to = Path.Combine(string.Concat(d2FaceLandmarksContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
to = Path.Combine(string.Concat(d2FacePartsContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||||
results.Add(to);
|
results.Add(to);
|
||||||
}
|
}
|
||||||
eDistanceContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), 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), "()");
|
||||||
@ -114,8 +113,6 @@ internal class E3_Rename
|
|||||||
internal List<string[]> GetDirectoryRenameCollections(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string relativePath, string newDirectoryName, bool jsonFiles4InfoAny)
|
internal List<string[]> GetDirectoryRenameCollections(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string relativePath, string newDirectoryName, bool jsonFiles4InfoAny)
|
||||||
{
|
{
|
||||||
List<string[]> results = new();
|
List<string[]> results = new();
|
||||||
if (_Configuration?.PropertyConfiguration is null)
|
|
||||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
|
||||||
bool add;
|
bool add;
|
||||||
string to;
|
string to;
|
||||||
bool exists;
|
bool exists;
|
||||||
@ -127,9 +124,9 @@ internal class E3_Rename
|
|||||||
string eDistanceContentDirectory;
|
string eDistanceContentDirectory;
|
||||||
string bMetadataSingletonDirectory;
|
string bMetadataSingletonDirectory;
|
||||||
string aPropertySingletonDirectory;
|
string aPropertySingletonDirectory;
|
||||||
|
string d2FacePartsContentDirectory;
|
||||||
string eDistanceCollectionDirectory;
|
string eDistanceCollectionDirectory;
|
||||||
string g2IdentifyCollectionDirectory;
|
string g2IdentifyCollectionDirectory;
|
||||||
string d2FaceLandmarksContentDirectory;
|
|
||||||
if (!string.IsNullOrEmpty(relativePath))
|
if (!string.IsNullOrEmpty(relativePath))
|
||||||
{
|
{
|
||||||
from = string.Concat(_Configuration.PropertyConfiguration.RootDirectory, relativePath);
|
from = string.Concat(_Configuration.PropertyConfiguration.RootDirectory, relativePath);
|
||||||
@ -147,7 +144,7 @@ internal class E3_Rename
|
|||||||
to = Path.Combine(string.Concat(bMetadataSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
to = Path.Combine(string.Concat(bMetadataSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||||
results.Add(new string[] { from, to });
|
results.Add(new string[] { from, to });
|
||||||
}
|
}
|
||||||
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "{}");
|
||||||
from = string.Concat(aPropertySingletonDirectory, relativePath);
|
from = string.Concat(aPropertySingletonDirectory, relativePath);
|
||||||
exists = Directory.Exists(aPropertySingletonDirectory);
|
exists = Directory.Exists(aPropertySingletonDirectory);
|
||||||
if (exists)
|
if (exists)
|
||||||
@ -187,14 +184,14 @@ internal class E3_Rename
|
|||||||
to = Path.Combine(string.Concat(dFacesCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
to = Path.Combine(string.Concat(dFacesCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||||
results.Add(new string[] { from, to });
|
results.Add(new string[] { from, to });
|
||||||
}
|
}
|
||||||
d2FaceLandmarksContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
d2FacePartsContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D2_FaceParts), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||||
from = string.Concat(d2FaceLandmarksContentDirectory, relativePath);
|
from = string.Concat(d2FacePartsContentDirectory, relativePath);
|
||||||
exists = Directory.Exists(d2FaceLandmarksContentDirectory);
|
exists = Directory.Exists(d2FacePartsContentDirectory);
|
||||||
if (!exists && add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
if (!exists && add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||||
results.Add(new string[] { from });
|
results.Add(new string[] { from });
|
||||||
else if (exists)
|
else if (exists)
|
||||||
{
|
{
|
||||||
to = Path.Combine(string.Concat(d2FaceLandmarksContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
to = Path.Combine(string.Concat(d2FacePartsContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||||
results.Add(new string[] { from, to });
|
results.Add(new string[] { from, to });
|
||||||
}
|
}
|
||||||
eDistanceContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), 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), "()");
|
||||||
@ -229,15 +226,13 @@ 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)
|
|
||||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
|
||||||
string json;
|
string json;
|
||||||
FileInfo current;
|
FileInfo current;
|
||||||
FileInfo fileInfo;
|
FileInfo fileInfo;
|
||||||
string error = "Error";
|
string error = "Error";
|
||||||
string target = "Target";
|
string target = "Target";
|
||||||
string pending = "Pending";
|
string pending = "Pending";
|
||||||
System.IO.DirectoryInfo directoryInfo;
|
DirectoryInfo directoryInfo;
|
||||||
IEnumerator<FileInfo> fileInfoCollection;
|
IEnumerator<FileInfo> fileInfoCollection;
|
||||||
string oldValue = string.Concat("\"", relativePath);
|
string oldValue = string.Concat("\"", relativePath);
|
||||||
string oldDirectoryName = Path.GetFileName(relativePath);
|
string oldDirectoryName = Path.GetFileName(relativePath);
|
||||||
@ -249,7 +244,7 @@ internal class E3_Rename
|
|||||||
string newValue = string.Concat("\"", Path.Combine(relativePathParent, newDirectoryName));
|
string newValue = string.Concat("\"", Path.Combine(relativePathParent, newDirectoryName));
|
||||||
string e3RenameContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(E3_Rename), "()");
|
string e3RenameContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(E3_Rename), "()");
|
||||||
string jsonRootDirectory = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, " - Copied"), string.Concat(directoryName, " - 4) Info"), _Configuration.PropertyConfiguration.DateGroup, "[]");
|
string jsonRootDirectory = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, " - Copied"), string.Concat(directoryName, " - 4) Info"), _Configuration.PropertyConfiguration.DateGroup, "[]");
|
||||||
directoryInfo = new System.IO.DirectoryInfo(jsonRootDirectory);
|
directoryInfo = new DirectoryInfo(jsonRootDirectory);
|
||||||
if (!directoryInfo.Exists)
|
if (!directoryInfo.Exists)
|
||||||
directoryInfo.Create();
|
directoryInfo.Create();
|
||||||
IEnumerator<FileInfo> fileInfoCollection4 = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
|
IEnumerator<FileInfo> fileInfoCollection4 = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
|
||||||
@ -278,7 +273,7 @@ internal class E3_Rename
|
|||||||
{
|
{
|
||||||
foreach (string[] directoryCollection in directoryCollections)
|
foreach (string[] directoryCollection in directoryCollections)
|
||||||
{
|
{
|
||||||
directoryInfo = new System.IO.DirectoryInfo(directoryCollection[0]);
|
directoryInfo = new DirectoryInfo(directoryCollection[0]);
|
||||||
if (!directoryInfo.Exists)
|
if (!directoryInfo.Exists)
|
||||||
continue;
|
continue;
|
||||||
fileInfoCollection = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
|
fileInfoCollection = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
|
||||||
@ -299,7 +294,7 @@ internal class E3_Rename
|
|||||||
if (json.Contains(oldValue))
|
if (json.Contains(oldValue))
|
||||||
{
|
{
|
||||||
json = json.Replace(oldValue, newValue);
|
json = json.Replace(oldValue, newValue);
|
||||||
if (!Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||||
continue;
|
continue;
|
||||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.LastWriteTime);
|
File.SetLastWriteTime(fileInfo.FullName, fileInfo.LastWriteTime);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using View_by_Distance.FaceRecognitionDotNet;
|
|||||||
using View_by_Distance.Metadata.Models;
|
using View_by_Distance.Metadata.Models;
|
||||||
using View_by_Distance.Property.Models;
|
using View_by_Distance.Property.Models;
|
||||||
using View_by_Distance.Resize.Models;
|
using View_by_Distance.Resize.Models;
|
||||||
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Properties;
|
using View_by_Distance.Shared.Models.Properties;
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
using WindowsShortcutFactory;
|
using WindowsShortcutFactory;
|
||||||
@ -30,14 +31,14 @@ internal class E_Distance
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<DistanceHolder> GetDistanceHolder(Item[] items, List<(string JSONDirectory, string TSVDirectory)> directories)
|
private static List<(DistanceHolder, FaceRecognitionDotNet.FaceEncoding?)> GetDistanceHolder(Item[] items, List<(string JSONDirectory, string TSVDirectory)> directories)
|
||||||
{
|
{
|
||||||
List<DistanceHolder> results = new();
|
List<(DistanceHolder, FaceRecognitionDotNet.FaceEncoding?)> results = new();
|
||||||
Item item;
|
Item item;
|
||||||
const int zero = 0;
|
const int zero = 0;
|
||||||
string tsvDirectory;
|
string tsvDirectory;
|
||||||
string jsonDirectory;
|
string jsonDirectory;
|
||||||
FaceEncoding? faceEncoding;
|
FaceRecognitionDotNet.FaceEncoding? faceEncoding;
|
||||||
if (items.Length != directories.Count)
|
if (items.Length != directories.Count)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
for (int i = 0; i < items.Length; i++)
|
for (int i = 0; i < items.Length; i++)
|
||||||
@ -48,38 +49,19 @@ internal class E_Distance
|
|||||||
continue;
|
continue;
|
||||||
tsvDirectory = directories[i].TSVDirectory;
|
tsvDirectory = directories[i].TSVDirectory;
|
||||||
jsonDirectory = directories[i].JSONDirectory;
|
jsonDirectory = directories[i].JSONDirectory;
|
||||||
foreach (IFace face in item.Faces)
|
foreach (Face face in item.Faces)
|
||||||
{
|
{
|
||||||
if (!face.Populated)
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
continue;
|
continue;
|
||||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||||
results.Add(new(face, faceEncoding, item.ImageFileHolder, item.Property.Id.Value, jsonDirectory, item.Faces[zero].Location, tsvDirectory));
|
results.Add(new(new(face, item.ImageFileHolder, item.Property.Id.Value, jsonDirectory, item.Faces[zero].Location, tsvDirectory), faceEncoding));
|
||||||
}
|
}
|
||||||
if (faceEncoding is null)
|
if (faceEncoding is null)
|
||||||
results.Add(new(item.Faces[zero], null, item.ImageFileHolder, item.Property.Id.Value, jsonDirectory, item.Faces[zero].Location, tsvDirectory));
|
results.Add(new(new(item.Faces[zero], item.ImageFileHolder, item.Property.Id.Value, jsonDirectory, item.Faces[zero].Location, tsvDirectory), null));
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Tuple<IFace, string>> GetOrderedNoFaceCollection(List<List<IFace>> faceCollections, int i, IFace face)
|
|
||||||
{
|
|
||||||
List<Tuple<IFace, string>> results = new() { new(face, string.Empty) };
|
|
||||||
for (int n = 0; n < faceCollections.Count; n++)
|
|
||||||
{
|
|
||||||
if (i == n)
|
|
||||||
continue;
|
|
||||||
for (int j = 0; j < faceCollections[n].Count; j++)
|
|
||||||
{
|
|
||||||
if (!faceCollections[n][j].Populated)
|
|
||||||
continue;
|
|
||||||
results.Add(new(faceCollections[n][j], string.Empty));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int r = results.Count - 1; r > _Configuration.MaxItemsInDistanceCollection; r--)
|
|
||||||
results.RemoveAt(r);
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteNoFaceCollection(bool updateDateWhenMatches, DateTime? updateToWhenMatches, List<Tuple<string, DateTime>> subFileTuples, List<DistanceHolder> distanceHolders)
|
private void WriteNoFaceCollection(bool updateDateWhenMatches, DateTime? updateToWhenMatches, List<Tuple<string, DateTime>> subFileTuples, List<DistanceHolder> distanceHolders)
|
||||||
{
|
{
|
||||||
string json;
|
string json;
|
||||||
@ -87,7 +69,7 @@ internal class E_Distance
|
|||||||
string jsonFile;
|
string jsonFile;
|
||||||
const int zero = 0;
|
const int zero = 0;
|
||||||
DistanceHolder distanceHolder;
|
DistanceHolder distanceHolder;
|
||||||
List<Tuple<IFace, string>> tupleCollection;
|
List<Tuple<Face, string>> tupleCollection;
|
||||||
for (int i = 0; i < distanceHolders.Count; i++)
|
for (int i = 0; i < distanceHolders.Count; i++)
|
||||||
{
|
{
|
||||||
distanceHolder = distanceHolders[i];
|
distanceHolder = distanceHolders[i];
|
||||||
@ -108,24 +90,24 @@ internal class E_Distance
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
json = JsonSerializer.Serialize(tupleCollection, _WriteIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(tupleCollection, _WriteIndentedJsonSerializerOptions);
|
||||||
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
|
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
|
||||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<FaceEncoding> GetFaceEncodings(List<DistanceHolder> distanceHolders)
|
private static List<FaceRecognitionDotNet.FaceEncoding> GetFaceEncodings((DistanceHolder, FaceRecognitionDotNet.FaceEncoding?)[] distanceHoldersAfterSort)
|
||||||
{
|
{
|
||||||
List<FaceEncoding> results = new();
|
List<FaceRecognitionDotNet.FaceEncoding> results = new();
|
||||||
foreach (DistanceHolder distanceHolder in distanceHolders)
|
foreach ((DistanceHolder distanceHolder, FaceRecognitionDotNet.FaceEncoding? faceEncoding) in distanceHoldersAfterSort)
|
||||||
{
|
{
|
||||||
if (!distanceHolder.Face.Populated || distanceHolder.FaceEncoding is null)
|
if (distanceHolder.Face.FaceEncoding is null || distanceHolder.Face.Location?.NormalizedPixelPercentage is null || faceEncoding is null)
|
||||||
continue;
|
continue;
|
||||||
results.Add(distanceHolder.FaceEncoding);
|
results.Add(faceEncoding);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveDistanceResults(bool updateDateWhenMatches, DateTime? updateToWhenMatches, List<Tuple<string, DateTime>> subFileTuples, List<DistanceHolder> distanceHolders)
|
private void SaveDistanceResults(bool updateDateWhenMatches, DateTime? updateToWhenMatches, List<Tuple<string, DateTime>> subFileTuples, List<(DistanceHolder DistanceHolder, FaceRecognitionDotNet.FaceEncoding? _)> distanceHolders)
|
||||||
{
|
{
|
||||||
string json;
|
string json;
|
||||||
string check;
|
string check;
|
||||||
@ -135,13 +117,16 @@ internal class E_Distance
|
|||||||
DistanceHolder distanceHolder;
|
DistanceHolder distanceHolder;
|
||||||
int normalizedPixelPercentage;
|
int normalizedPixelPercentage;
|
||||||
DistanceHolder[] sortedDistanceHolders;
|
DistanceHolder[] sortedDistanceHolders;
|
||||||
List<Tuple<IFace, string>> tupleCollection;
|
List<Tuple<Face, string>> tupleCollection;
|
||||||
List<(int Index, double Distance)> collection;
|
List<(int Index, double Distance)> collection;
|
||||||
distanceHolders = distanceHolders.OrderByDescending(l => l.Face.Populated).ToList();
|
FaceRecognitionDotNet.FaceEncoding? faceEncoding;
|
||||||
List<FaceEncoding> faceEncodings = GetFaceEncodings(distanceHolders);
|
(DistanceHolder DistanceHolder, FaceRecognitionDotNet.FaceEncoding? FaceEncoding)[] distanceHoldersAfterSort =
|
||||||
for (int i = 0; i < distanceHolders.Count; i++)
|
distanceHolders.OrderByDescending(l => l.DistanceHolder.Face.FaceEncoding is not null && l.DistanceHolder.Face.Location?.NormalizedPixelPercentage is not null).ToArray();
|
||||||
|
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings = GetFaceEncodings(distanceHoldersAfterSort);
|
||||||
|
for (int i = 0; i < distanceHoldersAfterSort.Length; i++)
|
||||||
{
|
{
|
||||||
distanceHolder = distanceHolders[i];
|
faceEncoding = distanceHoldersAfterSort[i].FaceEncoding;
|
||||||
|
distanceHolder = distanceHoldersAfterSort[i].DistanceHolder;
|
||||||
collection = new();
|
collection = new();
|
||||||
tupleCollection = new();
|
tupleCollection = new();
|
||||||
distanceHolder.Sort = 0d;
|
distanceHolder.Sort = 0d;
|
||||||
@ -149,7 +134,7 @@ internal class E_Distance
|
|||||||
locationIndex = 0;
|
locationIndex = 0;
|
||||||
else
|
else
|
||||||
locationIndex = distanceHolder.Face.LocationIndex.Value;
|
locationIndex = distanceHolder.Face.LocationIndex.Value;
|
||||||
if (!distanceHolder.Face.Populated || distanceHolder.Face.Location?.NormalizedPixelPercentage is null)
|
if (distanceHolder.Face.FaceEncoding is null || distanceHolder.Face.Location?.NormalizedPixelPercentage is null)
|
||||||
normalizedPixelPercentage = 0;
|
normalizedPixelPercentage = 0;
|
||||||
else
|
else
|
||||||
normalizedPixelPercentage = distanceHolder.Face.Location.NormalizedPixelPercentage.Value;
|
normalizedPixelPercentage = distanceHolder.Face.Location.NormalizedPixelPercentage.Value;
|
||||||
@ -161,27 +146,32 @@ internal class E_Distance
|
|||||||
File.Move(check, jsonFile);
|
File.Move(check, jsonFile);
|
||||||
if (faceEncodings.Count == 1)
|
if (faceEncodings.Count == 1)
|
||||||
faceDistances = new() { 0d };
|
faceDistances = new() { 0d };
|
||||||
else if (distanceHolder.FaceEncoding is null)
|
else if (faceEncoding is null)
|
||||||
faceDistances = Enumerable.Repeat(9d, faceEncodings.Count).ToList();
|
faceDistances = Enumerable.Repeat(9d, faceEncodings.Count).ToList();
|
||||||
else
|
else
|
||||||
faceDistances = FaceRecognition.FaceDistances(faceEncodings, distanceHolder.FaceEncoding);
|
faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncoding);
|
||||||
if (distanceHolder.Face.Populated && distanceHolder.FaceEncoding is not null && faceDistances[i] != 0d)
|
if (distanceHolder.Face.FaceEncoding is not null && faceEncoding is not null && faceDistances[i] != 0d)
|
||||||
faceDistances[i] = 0d;
|
faceDistances[i] = 0d;
|
||||||
for (int d = 0; d < faceDistances.Count; d++)
|
for (int d = 0; d < faceDistances.Count; d++)
|
||||||
collection.Add(new(d, faceDistances[d]));
|
collection.Add(new(d, faceDistances[d]));
|
||||||
collection = collection.OrderBy(l => l.Distance).ToList();
|
collection = collection.OrderBy(l => l.Distance).ToList();
|
||||||
foreach ((int index, double distance) in collection)
|
foreach ((int index, double distance) in collection)
|
||||||
distanceHolders[index].Sort = ((distance * _Configuration.DistanceFactor) + (distanceHolders[index].Location.Confidence * _Configuration.LocationConfidenceFactor)) / 10;
|
{
|
||||||
sortedDistanceHolders = distanceHolders.OrderBy(l => l.Sort).ToArray();
|
distanceHolder = distanceHoldersAfterSort[index].DistanceHolder;
|
||||||
|
if (distanceHolder.Location is null)
|
||||||
|
continue;
|
||||||
|
distanceHolder.Sort = ((distance * _Configuration.DistanceFactor) + (distanceHolder.Location.Confidence * _Configuration.LocationConfidenceFactor)) / 10;
|
||||||
|
}
|
||||||
|
sortedDistanceHolders = (from l in distanceHoldersAfterSort orderby l.DistanceHolder.Sort select l.DistanceHolder).ToArray();
|
||||||
for (int j = 0; j < sortedDistanceHolders.Length; j++)
|
for (int j = 0; j < sortedDistanceHolders.Length; j++)
|
||||||
{
|
{
|
||||||
distanceHolder = sortedDistanceHolders[j];
|
distanceHolder = sortedDistanceHolders[j];
|
||||||
tupleCollection.Add(new(distanceHolders[j].Face, string.Empty));
|
tupleCollection.Add(new(distanceHoldersAfterSort[j].DistanceHolder.Face, string.Empty));
|
||||||
if (tupleCollection.Count > _Configuration.MaxItemsInDistanceCollection)
|
if (tupleCollection.Count > _Configuration.MaxItemsInDistanceCollection)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
json = JsonSerializer.Serialize(tupleCollection, _WriteIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(tupleCollection, _WriteIndentedJsonSerializerOptions);
|
||||||
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
|
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
|
||||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,10 +186,12 @@ internal class E_Distance
|
|||||||
string usingRelativePath;
|
string usingRelativePath;
|
||||||
DateTime? dateTime = null;
|
DateTime? dateTime = null;
|
||||||
string dCollectionDirectory;
|
string dCollectionDirectory;
|
||||||
|
FileInfo[] fileInfoCollection;
|
||||||
bool updateDateWhenMatches = false;
|
bool updateDateWhenMatches = false;
|
||||||
System.IO.DirectoryInfo directoryInfo;
|
System.IO.DirectoryInfo directoryInfo;
|
||||||
System.IO.DirectoryInfo tvsDirectoryInfo;
|
System.IO.DirectoryInfo tvsDirectoryInfo;
|
||||||
IEnumerator<FileInfo> fileInfoCollection;
|
int?[] normalizedPixelPercentageCollection;
|
||||||
|
int normalizedPixelPercentageDistinctCount;
|
||||||
List<(string, string)> directories = new();
|
List<(string, string)> directories = new();
|
||||||
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 sourceDirectoryChanges where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
List<DateTime> dateTimes = (from l in sourceDirectoryChanges where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||||
@ -216,7 +208,7 @@ internal class E_Distance
|
|||||||
item = filteredItems[i];
|
item = filteredItems[i];
|
||||||
if (item.ImageFileHolder is null || item.Property?.Id is null)
|
if (item.ImageFileHolder is null || item.Property?.Id is null)
|
||||||
continue;
|
continue;
|
||||||
hasPopulatedFace = (from l in item.Faces where l.Populated select true).Any();
|
hasPopulatedFace = (from l in item.Faces where l.FaceEncoding is not null && l.Location?.NormalizedPixelPercentage is not null select true).Any();
|
||||||
usingRelativePath = Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), item.ImageFileHolder.NameWithoutExtension);
|
usingRelativePath = Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), item.ImageFileHolder.NameWithoutExtension);
|
||||||
dCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, "[]", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}");
|
dCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, "[]", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}");
|
||||||
directoryInfo = new System.IO.DirectoryInfo(dCollectionDirectory);
|
directoryInfo = new System.IO.DirectoryInfo(dCollectionDirectory);
|
||||||
@ -242,23 +234,30 @@ internal class E_Distance
|
|||||||
}
|
}
|
||||||
tvsDirectoryInfo = new System.IO.DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension));
|
tvsDirectoryInfo = new System.IO.DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension));
|
||||||
directories.Add(new(directoryInfo.FullName, tvsDirectoryInfo.FullName));
|
directories.Add(new(directoryInfo.FullName, tvsDirectoryInfo.FullName));
|
||||||
if (_Configuration.CheckJsonForDistanceResults && directoryInfo.Exists)
|
if (directoryInfo.Exists && (!check || _Configuration.CheckJsonForDistanceResults))
|
||||||
{
|
{
|
||||||
json = string.Empty;
|
json = string.Empty;
|
||||||
fileInfoCollection = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
|
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(item.Faces);
|
||||||
for (int j = 0; j < int.MaxValue; j++)
|
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||||
{
|
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
|
||||||
if (!fileInfoCollection.MoveNext())
|
|
||||||
break;
|
|
||||||
json = Shared.Models.Stateless.Methods.IIndex.GetJson(fileInfoCollection.Current.FullName, fileInfoCollection.Current);
|
|
||||||
if (!_Configuration.PropertiesChangedForDistance && Shared.Models.Stateless.Methods.IFace.GetFace(fileInfoCollection.Current.FullName) is null)
|
|
||||||
{
|
|
||||||
check = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!check && string.IsNullOrEmpty(json))
|
|
||||||
check = true;
|
check = true;
|
||||||
|
fileInfoCollection = directoryInfo.GetFiles($"{item.Property.Id.Value}*.json", SearchOption.TopDirectoryOnly);
|
||||||
|
if (fileInfoCollection.Length < normalizedPixelPercentageDistinctCount)
|
||||||
|
check = true;
|
||||||
|
if (!check && _Configuration.CheckJsonForDistanceResults)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < fileInfoCollection.Length; j++)
|
||||||
|
{
|
||||||
|
json = Shared.Models.Stateless.Methods.IIndex.GetJson(fileInfoCollection[j].FullName, fileInfoCollection[j]);
|
||||||
|
if (!_Configuration.PropertiesChangedForDistance && Shared.Models.Stateless.Methods.IFace.GetFace(fileInfoCollection[j].FullName) is null)
|
||||||
|
{
|
||||||
|
check = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!check && string.IsNullOrEmpty(json))
|
||||||
|
check = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (check)
|
if (check)
|
||||||
continue;
|
continue;
|
||||||
@ -278,23 +277,23 @@ internal class E_Distance
|
|||||||
{
|
{
|
||||||
DateTime? updateToWhenMatches = dateTime;
|
DateTime? updateToWhenMatches = dateTime;
|
||||||
List<Tuple<string, DateTime>> subFileTuples = new();
|
List<Tuple<string, DateTime>> subFileTuples = new();
|
||||||
List<DistanceHolder> distanceHolders = GetDistanceHolder(filteredItems, directories);
|
List<(DistanceHolder, FaceRecognitionDotNet.FaceEncoding?)> distanceHolders = GetDistanceHolder(filteredItems, directories);
|
||||||
SaveDistanceResults(updateDateWhenMatches, updateToWhenMatches, subFileTuples, distanceHolders);
|
SaveDistanceResults(updateDateWhenMatches, updateToWhenMatches, subFileTuples, distanceHolders);
|
||||||
}
|
}
|
||||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()"));
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> GetFiles(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution)
|
private List<(string, List<KeyValuePair<string, Face[]>>)> GetFiles(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution)
|
||||||
{
|
{
|
||||||
string json;
|
string json;
|
||||||
List<KeyValuePair<string, Shared.Models.Face[]>>? facesKeyValuePairCollection;
|
List<KeyValuePair<string, Face[]>>? facesKeyValuePairCollection;
|
||||||
List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> results = new();
|
List<(string, List<KeyValuePair<string, Face[]>>)> results = new();
|
||||||
string dFacesCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[[]]");
|
string dFacesCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[[]]");
|
||||||
string[] dFacesCollectionFiles = Directory.GetFiles(dFacesCollectionDirectory, "*.json", SearchOption.TopDirectoryOnly);
|
string[] dFacesCollectionFiles = Directory.GetFiles(dFacesCollectionDirectory, "*.json", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string dFacesCollectionFile in dFacesCollectionFiles)
|
foreach (string dFacesCollectionFile in dFacesCollectionFiles)
|
||||||
{
|
{
|
||||||
json = File.ReadAllText(dFacesCollectionFile);
|
json = File.ReadAllText(dFacesCollectionFile);
|
||||||
facesKeyValuePairCollection = JsonSerializer.Deserialize<List<KeyValuePair<string, Shared.Models.Face[]>>>(json);
|
facesKeyValuePairCollection = JsonSerializer.Deserialize<List<KeyValuePair<string, Face[]>>>(json);
|
||||||
if (facesKeyValuePairCollection is null)
|
if (facesKeyValuePairCollection is null)
|
||||||
continue;
|
continue;
|
||||||
results.Add(new(dFacesCollectionFile, facesKeyValuePairCollection));
|
results.Add(new(dFacesCollectionFile, facesKeyValuePairCollection));
|
||||||
@ -302,21 +301,21 @@ internal class E_Distance
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> GetMatches(List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> files)
|
private static List<(string, List<Face>, List<FaceRecognitionDotNet.FaceEncoding>)> GetMatches(List<(string, List<KeyValuePair<string, Face[]>>)> files)
|
||||||
{
|
{
|
||||||
List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> results = new();
|
List<(string, List<Face>, List<FaceRecognitionDotNet.FaceEncoding>)> results = new();
|
||||||
FaceEncoding faceEncoding;
|
FaceRecognitionDotNet.FaceEncoding faceEncoding;
|
||||||
List<Shared.Models.Face> faces;
|
List<Face> faces;
|
||||||
List<FaceEncoding> faceEncodings;
|
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings;
|
||||||
foreach ((string, List<KeyValuePair<string, Shared.Models.Face[]>>) file in files)
|
foreach ((string, List<KeyValuePair<string, Face[]>>) file in files)
|
||||||
{
|
{
|
||||||
faces = new();
|
faces = new();
|
||||||
faceEncodings = new();
|
faceEncodings = new();
|
||||||
foreach (KeyValuePair<string, Shared.Models.Face[]> keyValuePair in file.Item2)
|
foreach (KeyValuePair<string, Face[]> keyValuePair in file.Item2)
|
||||||
{
|
{
|
||||||
foreach (Shared.Models.Face face in keyValuePair.Value)
|
foreach (Face face in keyValuePair.Value)
|
||||||
{
|
{
|
||||||
if (!face.Populated)
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
continue;
|
continue;
|
||||||
faces.Add(face);
|
faces.Add(face);
|
||||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||||
@ -339,7 +338,7 @@ internal class E_Distance
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Save(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string eDistanceCollectionDirectory, int k, string relativePath, Shared.Models.Face face, List<Tuple<Shared.Models.Face, string>> faceAndFaceDistanceCollection)
|
private void Save(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string eDistanceCollectionDirectory, int k, string relativePath, Face face, List<Tuple<Face, string>> faceAndFaceDistanceCollection)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(eDistanceCollectionDirectory))
|
if (string.IsNullOrEmpty(eDistanceCollectionDirectory))
|
||||||
eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||||
@ -349,12 +348,12 @@ internal class E_Distance
|
|||||||
_ = Directory.CreateDirectory(jsonDirectory);
|
_ = Directory.CreateDirectory(jsonDirectory);
|
||||||
string json = JsonSerializer.Serialize(faceAndFaceDistanceCollection, _WriteIndentedJsonSerializerOptions);
|
string json = JsonSerializer.Serialize(faceAndFaceDistanceCollection, _WriteIndentedJsonSerializerOptions);
|
||||||
string jsonFile = Path.Combine(jsonDirectory, $"{k} - {fileNameWithoutExtension}.nosj");
|
string jsonFile = Path.Combine(jsonDirectory, $"{k} - {fileNameWithoutExtension}.nosj");
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Tuple<Shared.Models.Face, double> Get(FaceEncoding faceEncoding, (string, List<Shared.Models.Face>, List<FaceEncoding>) match)
|
private static Tuple<Face, double> Get(FaceRecognitionDotNet.FaceEncoding faceEncoding, (string, List<Face>, List<FaceRecognitionDotNet.FaceEncoding>) match)
|
||||||
{
|
{
|
||||||
Tuple<Shared.Models.Face, double> result;
|
Tuple<Face, double> result;
|
||||||
double[] faceDistances = FaceRecognition.FaceDistances(match.Item3, faceEncoding).ToArray();
|
double[] faceDistances = FaceRecognition.FaceDistances(match.Item3, faceEncoding).ToArray();
|
||||||
int index = GetIndex(faceDistances);
|
int index = GetIndex(faceDistances);
|
||||||
result = new(match.Item2[index], faceDistances[index]);
|
result = new(match.Item2[index], faceDistances[index]);
|
||||||
@ -366,14 +365,14 @@ internal class E_Distance
|
|||||||
if (_Log is null)
|
if (_Log is null)
|
||||||
throw new NullReferenceException(nameof(_Log));
|
throw new NullReferenceException(nameof(_Log));
|
||||||
string? relativePath;
|
string? relativePath;
|
||||||
Shared.Models.Face face;
|
Face face;
|
||||||
ParallelOptions parallelOptions = new();
|
ParallelOptions parallelOptions = new();
|
||||||
FaceEncoding faceEncoding;
|
FaceRecognitionDotNet.FaceEncoding faceEncoding;
|
||||||
string eDistanceCollectionDirectory = string.Empty;
|
string eDistanceCollectionDirectory = string.Empty;
|
||||||
Tuple<Shared.Models.Face, double> faceAndFaceDistance;
|
Tuple<Face, double> faceAndFaceDistance;
|
||||||
List<Tuple<Shared.Models.Face, string>> faceAndFaceDistanceCollection;
|
List<Tuple<Face, string>> faceAndFaceDistanceCollection;
|
||||||
List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> files = GetFiles(configuration, model, predictorModel, outputResolution);
|
List<(string, List<KeyValuePair<string, Face[]>>)> files = GetFiles(configuration, model, predictorModel, outputResolution);
|
||||||
List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> matches = GetMatches(files);
|
List<(string, List<Face>, List<FaceRecognitionDotNet.FaceEncoding>)> matches = GetMatches(files);
|
||||||
if (files.Count != matches.Count)
|
if (files.Count != matches.Count)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
int filesCount = files.Count;
|
int filesCount = files.Count;
|
||||||
@ -386,13 +385,15 @@ internal class E_Distance
|
|||||||
continue;
|
continue;
|
||||||
for (int k = 0; k < files[i].Item2[j].Value.Length; k++)
|
for (int k = 0; k < files[i].Item2[j].Value.Length; k++)
|
||||||
{
|
{
|
||||||
if (!files[i].Item2[j].Value[k].Populated)
|
|
||||||
continue;
|
|
||||||
face = files[i].Item2[j].Value[k];
|
face = files[i].Item2[j].Value[k];
|
||||||
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
|
continue;
|
||||||
faceAndFaceDistanceCollection = new(matches.Count);
|
faceAndFaceDistanceCollection = new(matches.Count);
|
||||||
relativePath = Path.GetDirectoryName(face.RelativePath);
|
relativePath = Path.GetDirectoryName(face.RelativePath);
|
||||||
if (string.IsNullOrEmpty(relativePath))
|
if (string.IsNullOrEmpty(relativePath))
|
||||||
continue;
|
continue;
|
||||||
|
if (face.FaceEncoding is null)
|
||||||
|
continue;
|
||||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||||
_ = Parallel.For(0, matches.Count, parallelOptions, z =>
|
_ = Parallel.For(0, matches.Count, parallelOptions, z =>
|
||||||
{
|
{
|
||||||
@ -423,32 +424,32 @@ internal class E_Distance
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FaceEncoding? GetFaceEncoding(IFace face)
|
private static FaceRecognitionDotNet.FaceEncoding? GetFaceEncoding(Face face)
|
||||||
{
|
{
|
||||||
FaceEncoding? result;
|
FaceRecognitionDotNet.FaceEncoding? result;
|
||||||
if (!face.Populated)
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
result = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
result = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (int index, double sum) GetIndexAndSum(int i, List<FaceEncoding> results)
|
private static (int index, double sum) GetIndexAndSum(int i, List<FaceRecognitionDotNet.FaceEncoding> results)
|
||||||
{
|
{
|
||||||
List<double> faceDistances = FaceRecognition.FaceDistances(results, results[i]);
|
List<double> faceDistances = FaceRecognition.FaceDistances(results, results[i]);
|
||||||
return new(i, faceDistances.Sum());
|
return new(i, faceDistances.Sum());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<FaceEncoding> GetFaceEncodings(int maxDegreeOfParallelism, List<(DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, IFace Face)> collection)
|
private static List<FaceRecognitionDotNet.FaceEncoding> GetFaceEncodings(int maxDegreeOfParallelism, List<(DateTime MinimumDateTime, bool? IsWrongYear, PersonBirthday PersonBirthday, Face Face)> collection)
|
||||||
{
|
{
|
||||||
List<FaceEncoding> results;
|
List<FaceRecognitionDotNet.FaceEncoding> results;
|
||||||
if (maxDegreeOfParallelism == 1)
|
if (maxDegreeOfParallelism == 1)
|
||||||
{
|
{
|
||||||
results = new();
|
results = new();
|
||||||
FaceEncoding faceEncoding;
|
FaceRecognitionDotNet.FaceEncoding faceEncoding;
|
||||||
foreach ((DateTime _, bool? _, Shared.Models.PersonBirthday _, IFace face) in collection)
|
foreach ((DateTime _, bool? _, PersonBirthday _, Face face) in collection)
|
||||||
{
|
{
|
||||||
if (!face.Populated)
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
continue;
|
continue;
|
||||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||||
results.Add(faceEncoding);
|
results.Add(faceEncoding);
|
||||||
@ -460,7 +461,7 @@ internal class E_Distance
|
|||||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||||
_ = Parallel.For(0, collection.Count, parallelOptions, i =>
|
_ = Parallel.For(0, collection.Count, parallelOptions, i =>
|
||||||
{
|
{
|
||||||
FaceEncoding? faceEncoding = GetFaceEncoding(collection[i].Face);
|
FaceRecognitionDotNet.FaceEncoding? faceEncoding = GetFaceEncoding(collection[i].Face);
|
||||||
if (faceEncoding is not null)
|
if (faceEncoding is not null)
|
||||||
{
|
{
|
||||||
lock (results)
|
lock (results)
|
||||||
@ -518,12 +519,12 @@ internal class E_Distance
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> GetThreeSigmaFaceEncodings(int maxDegreeOfParallelism, Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, IFace)>> keyValuePairs)
|
private static List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> GetThreeSigmaFaceEncodings(int maxDegreeOfParallelism, Dictionary<string, List<(DateTime, bool?, PersonBirthday, Face)>> keyValuePairs)
|
||||||
{
|
{
|
||||||
List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> results = new();
|
List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> results = new();
|
||||||
const int zero = 0;
|
const int zero = 0;
|
||||||
List<FaceEncoding> faceEncodings;
|
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings;
|
||||||
foreach (KeyValuePair<string, List<(DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, IFace _)>> keyValuePair in keyValuePairs)
|
foreach (KeyValuePair<string, List<(DateTime MinimumDateTime, bool? IsWrongYear, PersonBirthday PersonBirthday, Face _)>> keyValuePair in keyValuePairs)
|
||||||
{
|
{
|
||||||
faceEncodings = GetFaceEncodings(maxDegreeOfParallelism, keyValuePair.Value);
|
faceEncodings = GetFaceEncodings(maxDegreeOfParallelism, keyValuePair.Value);
|
||||||
results.Add(new(keyValuePair.Value[zero].MinimumDateTime, keyValuePair.Value[zero].IsWrongYear, keyValuePair.Value[zero].PersonBirthday, faceEncodings.ToArray()));
|
results.Add(new(keyValuePair.Value[zero].MinimumDateTime, keyValuePair.Value[zero].IsWrongYear, keyValuePair.Value[zero].PersonBirthday, faceEncodings.ToArray()));
|
||||||
@ -531,7 +532,7 @@ internal class E_Distance
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Closest? GetClosestParallelFor(DateTime minimumDateTime, bool? isWrongYear, IFace face, FaceEncoding faceEncoding, (DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, FaceEncoding[] FaceEncodings) tuple)
|
private static Closest? GetClosestParallelFor(DateTime minimumDateTime, bool? isWrongYear, Face face, FaceRecognitionDotNet.FaceEncoding faceEncoding, (DateTime MinimumDateTime, bool? IsWrongYear, PersonBirthday PersonBirthday, FaceRecognitionDotNet.FaceEncoding[] FaceEncodings) tuple)
|
||||||
{
|
{
|
||||||
Closest? result;
|
Closest? result;
|
||||||
if (isWrongYear.HasValue && !isWrongYear.Value && minimumDateTime < tuple.PersonBirthday.Value)
|
if (isWrongYear.HasValue && !isWrongYear.Value && minimumDateTime < tuple.PersonBirthday.Value)
|
||||||
@ -540,29 +541,31 @@ internal class E_Distance
|
|||||||
{
|
{
|
||||||
List<double> faceDistances = FaceRecognition.FaceDistances(tuple.FaceEncodings, faceEncoding);
|
List<double> faceDistances = FaceRecognition.FaceDistances(tuple.FaceEncodings, faceEncoding);
|
||||||
result = new(face.Location?.NormalizedPixelPercentage, tuple.MinimumDateTime, tuple.IsWrongYear, tuple.PersonBirthday, faceDistances);
|
result = new(face.Location?.NormalizedPixelPercentage, tuple.MinimumDateTime, tuple.IsWrongYear, tuple.PersonBirthday, faceDistances);
|
||||||
if (result.Minimum > Closest.MaximumMinimum)
|
if (result.Minimum > Shared.Models.Stateless.Methods.IClosest.MaximumMinimum)
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Closest[] GetClosestCollection(int maxDegreeOfParallelism, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, DateTime itemMinimumDateTime, bool? itemIsWrongYear, IFace face)
|
private static Closest[] GetClosestCollection(int maxDegreeOfParallelism, List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection, DateTime itemMinimumDateTime, bool? itemIsWrongYear, Face face)
|
||||||
{
|
{
|
||||||
Closest[] results;
|
Closest[] results;
|
||||||
List<Closest> closestCollection;
|
List<Closest> closestCollection;
|
||||||
FaceEncoding faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
if (face.FaceEncoding is null)
|
||||||
|
throw new NullReferenceException(nameof(face.FaceEncoding));
|
||||||
|
FaceRecognitionDotNet.FaceEncoding faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||||
if (maxDegreeOfParallelism == 1)
|
if (maxDegreeOfParallelism == 1)
|
||||||
{
|
{
|
||||||
closestCollection = new();
|
closestCollection = new();
|
||||||
Closest closest;
|
Closest closest;
|
||||||
List<double> faceDistances;
|
List<double> faceDistances;
|
||||||
foreach ((DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday, FaceEncoding[] faceEncodings) in collection)
|
foreach ((DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday, FaceRecognitionDotNet.FaceEncoding[] faceEncodings) in collection)
|
||||||
{
|
{
|
||||||
if (itemIsWrongYear.HasValue && !itemIsWrongYear.Value && itemMinimumDateTime < personBirthday.Value)
|
if (itemIsWrongYear.HasValue && !itemIsWrongYear.Value && itemMinimumDateTime < personBirthday.Value)
|
||||||
continue;
|
continue;
|
||||||
faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncoding);
|
faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncoding);
|
||||||
closest = new(face.Location?.NormalizedPixelPercentage, minimumDateTime, isWrongYear, personBirthday, faceDistances);
|
closest = new(face.Location?.NormalizedPixelPercentage, minimumDateTime, isWrongYear, personBirthday, faceDistances);
|
||||||
if (closest.Minimum > Closest.MaximumMinimum)
|
if (closest.Minimum > Shared.Models.Stateless.Methods.IClosest.MaximumMinimum)
|
||||||
continue;
|
continue;
|
||||||
closestCollection.Add(closest);
|
closestCollection.Add(closest);
|
||||||
}
|
}
|
||||||
@ -581,14 +584,14 @@ internal class E_Distance
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
results = Closest.Get(closestCollection);
|
results = Shared.Models.Stateless.Methods.IClosest.Get(closestCollection);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddClosest(int maxDegreeOfParallelism, string argZero, PropertyLogic propertyLogic, List<Container> containers, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection)
|
private static void AddClosest(int maxDegreeOfParallelism, string argZero, Map.Models.MapLogic mapLogic, List<Container> containers, List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection)
|
||||||
{
|
{
|
||||||
string key;
|
string key;
|
||||||
IFace face;
|
Face face;
|
||||||
Closest closest;
|
Closest closest;
|
||||||
string personKey;
|
string personKey;
|
||||||
bool? itemIsWrongYear;
|
bool? itemIsWrongYear;
|
||||||
@ -606,11 +609,11 @@ internal class E_Distance
|
|||||||
{
|
{
|
||||||
if (item.ImageFileHolder is null || item.Property is null || item.Named.Any())
|
if (item.ImageFileHolder is null || item.Property is null || item.Named.Any())
|
||||||
continue;
|
continue;
|
||||||
itemMinimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(item.Property);
|
itemMinimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||||
if (itemMinimumDateTime is null)
|
if (itemMinimumDateTime is null)
|
||||||
continue;
|
continue;
|
||||||
(itemIsWrongYear, _) = item.IsWrongYear();
|
(itemIsWrongYear, _) = Map.Models.MapLogic.IsWrongYear(item);
|
||||||
if (Closest.SkipIsWrongYear && itemIsWrongYear.HasValue && itemIsWrongYear.Value)
|
if (Shared.Models.Stateless.Methods.IClosest.SkipIsWrongYear && itemIsWrongYear.HasValue && itemIsWrongYear.Value)
|
||||||
continue;
|
continue;
|
||||||
item.Closest.Clear();
|
item.Closest.Clear();
|
||||||
for (int i = 0; i < item.Faces.Count; i++)
|
for (int i = 0; i < item.Faces.Count; i++)
|
||||||
@ -618,9 +621,9 @@ internal class E_Distance
|
|||||||
face = item.Faces[i];
|
face = item.Faces[i];
|
||||||
closest = new(face.Location?.NormalizedPixelPercentage, itemMinimumDateTime.Value, itemIsWrongYear);
|
closest = new(face.Location?.NormalizedPixelPercentage, itemMinimumDateTime.Value, itemIsWrongYear);
|
||||||
item.Closest.Add(closest);
|
item.Closest.Add(closest);
|
||||||
if (!face.Populated)
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
continue;
|
continue;
|
||||||
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face);
|
deterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetDeterministicHashCodeKey(item, face);
|
||||||
closestCollection = GetClosestCollection(maxDegreeOfParallelism, collection, itemMinimumDateTime.Value, itemIsWrongYear, face);
|
closestCollection = GetClosestCollection(maxDegreeOfParallelism, collection, itemMinimumDateTime.Value, itemIsWrongYear, face);
|
||||||
for (int j = 0; j < closestCollection.Length; j++)
|
for (int j = 0; j < closestCollection.Length; j++)
|
||||||
{
|
{
|
||||||
@ -628,12 +631,12 @@ internal class E_Distance
|
|||||||
if (closest.PersonBirthday is null)
|
if (closest.PersonBirthday is null)
|
||||||
continue;
|
continue;
|
||||||
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.PersonBirthday);
|
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.PersonBirthday);
|
||||||
if (propertyLogic.IncorrectDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey) && propertyLogic.IncorrectDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey].Contains(personKey))
|
if (mapLogic.IncorrectDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey) && mapLogic.IncorrectDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey].Contains(personKey))
|
||||||
continue;
|
continue;
|
||||||
key = Item.GetKey(closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday);
|
key = Map.Models.MapLogic.GetKey(closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday);
|
||||||
if (!results.ContainsKey(key))
|
if (!results.ContainsKey(key))
|
||||||
results.Add(key, 0);
|
results.Add(key, 0);
|
||||||
else if (results[key] > Closest.MaximumPer)
|
else if (results[key] > Shared.Models.Stateless.Methods.IClosest.MaximumPer)
|
||||||
continue;
|
continue;
|
||||||
results[key] += 1;
|
results[key] += 1;
|
||||||
item.Closest[0] = closest;
|
item.Closest[0] = closest;
|
||||||
@ -644,12 +647,12 @@ internal class E_Distance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> ParallelWork(int maxDegreeOfParallelism, string argZero, PropertyLogic propertyLogic, List<Container> containers)
|
internal static List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> ParallelWork(int maxDegreeOfParallelism, string argZero, Map.Models.MapLogic mapLogic, List<Container> containers)
|
||||||
{
|
{
|
||||||
List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> results;
|
List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> results;
|
||||||
Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, IFace)>> keyValuePairs = Item.GetKeyValuePairs(argZero, containers);
|
Dictionary<string, List<(DateTime, bool?, PersonBirthday, Face)>> keyValuePairs = Map.Models.MapLogic.GetKeyValuePairs(argZero, containers);
|
||||||
results = GetThreeSigmaFaceEncodings(maxDegreeOfParallelism, keyValuePairs);
|
results = GetThreeSigmaFaceEncodings(maxDegreeOfParallelism, keyValuePairs);
|
||||||
AddClosest(maxDegreeOfParallelism, argZero, propertyLogic, containers, results);
|
AddClosest(maxDegreeOfParallelism, argZero, mapLogic, containers, results);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,27 +680,27 @@ internal class E_Distance
|
|||||||
continue;
|
continue;
|
||||||
if (!fileInfo.Directory.Exists)
|
if (!fileInfo.Directory.Exists)
|
||||||
fileInfo.Directory.Create();
|
fileInfo.Directory.Create();
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SaveThreeSigmaFaceEncodings(List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceCollectionDirectory)
|
internal static void SaveThreeSigmaFaceEncodings(List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection, Dictionary<string, List<Person>> peopleCollection, string eDistanceCollectionDirectory)
|
||||||
{
|
{
|
||||||
string json;
|
string json;
|
||||||
string checkFile;
|
string checkFile;
|
||||||
string personKey;
|
string personKey;
|
||||||
string directory;
|
string directory;
|
||||||
List<double[]> rawEncodings;
|
List<double[]> rawEncodings;
|
||||||
Shared.Models.Person person;
|
Person person;
|
||||||
const string facePopulatedKey = "ThreeSigma";
|
const string facePopulatedKey = "ThreeSigma";
|
||||||
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
||||||
foreach ((DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday, FaceEncoding[] faceEncodings) in collection)
|
foreach ((DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday, FaceRecognitionDotNet.FaceEncoding[] faceEncodings) in collection)
|
||||||
{
|
{
|
||||||
rawEncodings = new();
|
rawEncodings = new();
|
||||||
checkFile = string.Empty;
|
checkFile = string.Empty;
|
||||||
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);
|
directory = Map.Models.MapLogic.GetDirectory(eDistanceCollectionDirectory, facePopulatedKey, minimumDateTime, isWrongYear, personBirthday, personKey);
|
||||||
if (!peopleCollection.ContainsKey(personKey))
|
if (!peopleCollection.ContainsKey(personKey))
|
||||||
continue;
|
continue;
|
||||||
person = peopleCollection[personKey][0];
|
person = peopleCollection[personKey][0];
|
||||||
@ -709,13 +712,14 @@ internal class E_Distance
|
|||||||
for (int i = 0; i < faceEncodings.Length; i++)
|
for (int i = 0; i < faceEncodings.Length; i++)
|
||||||
rawEncodings.Add(faceEncodings[i].GetRawEncoding());
|
rawEncodings.Add(faceEncodings[i].GetRawEncoding());
|
||||||
json = JsonSerializer.Serialize(rawEncodings, new JsonSerializerOptions { WriteIndented = true });
|
json = JsonSerializer.Serialize(rawEncodings, new JsonSerializerOptions { WriteIndented = true });
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<(FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> GetClosest(string argZero, List<Container> containers, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceContentDirectory, string dFacesContentDirectory)
|
internal static List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> GetClosest(string argZero, List<Container> containers, Dictionary<string, List<Person>> peopleCollection, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string eDistanceContentDirectory)
|
||||||
{
|
{
|
||||||
List<(FileHolder?, string, FileInfo?, string, string)> results = new();
|
List<(IFileHolder?, string, FileInfo?, string, string)> results = new();
|
||||||
|
Person person;
|
||||||
string checkFile;
|
string checkFile;
|
||||||
string directory;
|
string directory;
|
||||||
string personKey;
|
string personKey;
|
||||||
@ -725,7 +729,8 @@ internal class E_Distance
|
|||||||
string? directoryName;
|
string? directoryName;
|
||||||
string facesDirectory;
|
string facesDirectory;
|
||||||
string personDirectory;
|
string personDirectory;
|
||||||
Shared.Models.Person person;
|
FileInfo landmarkFileInfo;
|
||||||
|
string landmarksDirectory;
|
||||||
double deterministicHashCodeKey;
|
double deterministicHashCodeKey;
|
||||||
const string facePopulatedKey = "Closest";
|
const string facePopulatedKey = "Closest";
|
||||||
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
||||||
@ -749,7 +754,7 @@ internal class E_Distance
|
|||||||
if (closest.Average is null || closest.NormalizedPixelPercentage is null || closest.PersonBirthday is null)
|
if (closest.Average is null || closest.NormalizedPixelPercentage is null || closest.PersonBirthday is null)
|
||||||
continue;
|
continue;
|
||||||
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.PersonBirthday);
|
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.PersonBirthday);
|
||||||
directory = Item.GetDirectory(eDistanceContentDirectory, facePopulatedKey, closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday, personKey);
|
directory = Map.Models.MapLogic.GetDirectory(eDistanceContentDirectory, facePopulatedKey, closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday, personKey);
|
||||||
if (!peopleCollection.ContainsKey(personKey))
|
if (!peopleCollection.ContainsKey(personKey))
|
||||||
personDirectory = string.Empty;
|
personDirectory = string.Empty;
|
||||||
else
|
else
|
||||||
@ -760,9 +765,11 @@ internal class E_Distance
|
|||||||
results.Add(new(null, personDirectory, null, string.Empty, string.Empty));
|
results.Add(new(null, personDirectory, null, string.Empty, string.Empty));
|
||||||
}
|
}
|
||||||
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
|
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
|
||||||
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, closest);
|
landmarksDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
|
||||||
|
deterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetDeterministicHashCodeKey(item, closest);
|
||||||
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
|
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
|
||||||
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
|
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
|
||||||
|
landmarkFileInfo = new(Path.Combine(landmarksDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.gif"));
|
||||||
if (string.IsNullOrEmpty(personDirectory))
|
if (string.IsNullOrEmpty(personDirectory))
|
||||||
shortcutFile = string.Empty;
|
shortcutFile = string.Empty;
|
||||||
else
|
else
|
||||||
@ -774,10 +781,10 @@ internal class E_Distance
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SaveClosest(string argZero, List<Container> containers, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceContentDirectory, string dFacesContentDirectory)
|
internal static void SaveClosest(string argZero, List<Container> containers, Dictionary<string, List<Person>> peopleCollection, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string eDistanceContentDirectory)
|
||||||
{
|
{
|
||||||
WindowsShortcut windowsShortcut;
|
WindowsShortcut windowsShortcut;
|
||||||
List<(FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> collection = GetClosest(argZero, containers, peopleCollection, eDistanceContentDirectory, dFacesContentDirectory);
|
List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> collection = GetClosest(argZero, containers, peopleCollection, dFacesContentDirectory, d2ResultsFullGroupDirectory, eDistanceContentDirectory);
|
||||||
string[] directories = (from l in collection select l.directory).Distinct().ToArray();
|
string[] directories = (from l in collection select l.directory).Distinct().ToArray();
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
{
|
{
|
||||||
@ -786,7 +793,7 @@ internal class E_Distance
|
|||||||
if (!Directory.Exists(directory))
|
if (!Directory.Exists(directory))
|
||||||
_ = Directory.CreateDirectory(directory);
|
_ = Directory.CreateDirectory(directory);
|
||||||
}
|
}
|
||||||
foreach ((FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile) in collection)
|
foreach ((IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile) in collection)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null || faceFileInfo is null)
|
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null || faceFileInfo is null)
|
||||||
continue;
|
continue;
|
||||||
@ -797,7 +804,7 @@ internal class E_Distance
|
|||||||
else
|
else
|
||||||
File.Copy(resizedFileHolder.FullName, checkFile);
|
File.Copy(resizedFileHolder.FullName, checkFile);
|
||||||
}
|
}
|
||||||
foreach ((FileHolder? resizedFileHolder, string directory, FileInfo? _, string checkFile, string shortcutFile) in collection)
|
foreach ((IFileHolder? resizedFileHolder, string directory, FileInfo? _, string checkFile, string shortcutFile) in collection)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null)
|
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -28,8 +28,6 @@ internal class F_Random
|
|||||||
private bool IsIgnoreRelativePath(string directory)
|
private bool IsIgnoreRelativePath(string directory)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (_Configuration?.PropertyConfiguration is null)
|
|
||||||
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++)
|
||||||
{
|
{
|
||||||
@ -71,7 +69,7 @@ internal class F_Random
|
|||||||
relativePaths = (from l in relativePaths orderby random.NextDouble() select l).ToList();
|
relativePaths = (from l in relativePaths orderby random.NextDouble() select l).ToList();
|
||||||
jsonFile = Path.Combine(fRandomCollectionDirectory, $"{dateTime.AddDays(i):MM-dd}.json");
|
jsonFile = Path.Combine(fRandomCollectionDirectory, $"{dateTime.AddDays(i):MM-dd}.json");
|
||||||
json = JsonSerializer.Serialize(relativePaths, _WriteIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(relativePaths, _WriteIndentedJsonSerializerOptions);
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
|
||||||
if (!_Configuration.SaveFullYearOfRandomFiles)
|
if (!_Configuration.SaveFullYearOfRandomFiles)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -81,7 +79,7 @@ internal class F_Random
|
|||||||
ignoreRelativePaths = (from l in ignoreRelativePaths orderby random.NextDouble() select l).ToList();
|
ignoreRelativePaths = (from l in ignoreRelativePaths orderby random.NextDouble() select l).ToList();
|
||||||
jsonFile = Path.Combine(fRandomCollectionDirectory, "01-01.txt");
|
jsonFile = Path.Combine(fRandomCollectionDirectory, "01-01.txt");
|
||||||
json = JsonSerializer.Serialize(ignoreRelativePaths, _WriteIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(ignoreRelativePaths, _WriteIndentedJsonSerializerOptions);
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using Phares.Shared;
|
using Phares.Shared;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Property.Models;
|
|
||||||
using View_by_Distance.Shared.Models;
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
using View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
@ -103,7 +102,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
|||||||
json = JsonSerializer.Serialize(resultKeyValuePairs, _WriteIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(resultKeyValuePairs, _WriteIndentedJsonSerializerOptions);
|
||||||
if (!isEnvironment.DebuggerWasAttachedDuringConstructor)
|
if (!isEnvironment.DebuggerWasAttachedDuringConstructor)
|
||||||
throw new Exception("Only allowed when debugger is attached during constructor!");
|
throw new Exception("Only allowed when debugger is attached during constructor!");
|
||||||
_ = Property.Models.Stateless.IPath.WriteAllText(named.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(named.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +188,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
|||||||
string jsonFile;
|
string jsonFile;
|
||||||
string directoryFullName;
|
string directoryFullName;
|
||||||
string fileNameWithoutExtension;
|
string fileNameWithoutExtension;
|
||||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "{}");
|
||||||
string g2IdentifyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
|
string g2IdentifyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
|
||||||
Dictionary<string, List<KeyValuePair<string, string>>> keyValuePairs = new();
|
Dictionary<string, List<KeyValuePair<string, string>>> keyValuePairs = new();
|
||||||
foreach (G2_Identify identified in identifiedCollection)
|
foreach (G2_Identify identified in identifiedCollection)
|
||||||
@ -221,7 +220,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
|||||||
_ = Directory.CreateDirectory(directoryFullName);
|
_ = Directory.CreateDirectory(directoryFullName);
|
||||||
jsonFile = string.Concat(g2IdentifyCollectionDirectory, keyValuePair.Key, ".json");
|
jsonFile = string.Concat(g2IdentifyCollectionDirectory, keyValuePair.Key, ".json");
|
||||||
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
|
||||||
if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Property.Models;
|
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
using View_by_Distance.Shared.Models.Methods;
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
|
|
||||||
@ -76,11 +75,11 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteNeeded(List<int> indices, List<Tuple<List<string>, string, A_Property>> neededTuples)
|
private void WriteNeeded(List<int> indices, List<Tuple<List<string>, string, Shared.Models.Property>> neededTuples)
|
||||||
{
|
{
|
||||||
string json;
|
string json;
|
||||||
DateTime dateTime;
|
DateTime dateTime;
|
||||||
A_Property property;
|
Shared.Models.Property property;
|
||||||
G_Index indexInfo;
|
G_Index indexInfo;
|
||||||
int maxIndexPlusOne;
|
int maxIndexPlusOne;
|
||||||
DateTime?[] dateTimes;
|
DateTime?[] dateTimes;
|
||||||
@ -91,7 +90,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
|||||||
maxIndexPlusOne = 1000000;
|
maxIndexPlusOne = 1000000;
|
||||||
throw new Exception("Are you sure exception. Use debugger to step over.");
|
throw new Exception("Are you sure exception. Use debugger to step over.");
|
||||||
}
|
}
|
||||||
foreach (Tuple<List<string>, string, A_Property> tuple in neededTuples)
|
foreach (Tuple<List<string>, string, Shared.Models.Property> tuple in neededTuples)
|
||||||
{
|
{
|
||||||
maxIndexPlusOne += 1;
|
maxIndexPlusOne += 1;
|
||||||
property = tuple.Item3;
|
property = tuple.Item3;
|
||||||
@ -99,7 +98,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
|||||||
dateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
|
dateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
|
||||||
indexInfo = new(dateTime, maxIndexPlusOne, tuple.Item1);
|
indexInfo = new(dateTime, maxIndexPlusOne, tuple.Item1);
|
||||||
json = JsonSerializer.Serialize(indexInfo, _WriteIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(indexInfo, _WriteIndentedJsonSerializerOptions);
|
||||||
if (!Property.Models.Stateless.IPath.WriteAllText(tuple.Item2, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(tuple.Item2, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,24 +113,24 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
|||||||
indices = (from l in tuple.Item2 select l.Value).ToArray();
|
indices = (from l in tuple.Item2 select l.Value).ToArray();
|
||||||
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, tuple.Item1, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: string.Empty, collectionDescription: "Unknown A");
|
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, tuple.Item1, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: string.Empty, collectionDescription: "Unknown A");
|
||||||
json = JsonSerializer.Serialize(indices, _WriteIndentedJsonSerializerOptions);
|
json = JsonSerializer.Serialize(indices, _WriteIndentedJsonSerializerOptions);
|
||||||
if (!Property.Models.Stateless.IPath.WriteAllText(string.Concat(directoryInfoCollection[0].Replace("<>", "[]"), ".json"), json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(string.Concat(directoryInfoCollection[0].Replace("<>", "[]"), ".json"), json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AppendTSV(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, Dictionary<string, List<Tuple<string, A_Property>>> filePropertiesKeyValuePairs)
|
private void AppendTSV(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, Dictionary<string, List<Tuple<string, Shared.Models.Property>>> filePropertiesKeyValuePairs)
|
||||||
{
|
{
|
||||||
A_Property property;
|
Shared.Models.Property property;
|
||||||
DateTime?[] dateTimes;
|
DateTime?[] dateTimes;
|
||||||
DateTime? maximumDateTime;
|
DateTime? maximumDateTime;
|
||||||
DateTime? minimumDateTime;
|
DateTime? minimumDateTime;
|
||||||
List<string> directoryInfoCollection;
|
List<string> directoryInfoCollection;
|
||||||
long ticks = System.DateTime.Now.Ticks;
|
long ticks = System.DateTime.Now.Ticks;
|
||||||
foreach (KeyValuePair<string, List<Tuple<string, A_Property>>> tuples in filePropertiesKeyValuePairs)
|
foreach (KeyValuePair<string, List<Tuple<string, Shared.Models.Property>>> tuples in filePropertiesKeyValuePairs)
|
||||||
{
|
{
|
||||||
maximumDateTime = null;
|
maximumDateTime = null;
|
||||||
minimumDateTime = null;
|
minimumDateTime = null;
|
||||||
foreach (Tuple<string, A_Property> tuple in tuples.Value)
|
foreach (Tuple<string, Shared.Models.Property> tuple in tuples.Value)
|
||||||
{
|
{
|
||||||
property = tuple.Item2;
|
property = tuple.Item2;
|
||||||
dateTimes = new DateTime?[] { maximumDateTime, minimumDateTime, property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
|
dateTimes = new DateTime?[] { maximumDateTime, minimumDateTime, property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
|
||||||
@ -142,7 +141,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SetIndex(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, Dictionary<string, List<Tuple<string, A_Property>>> filePropertiesKeyValuePairs)
|
internal void SetIndex(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, Dictionary<string, List<Tuple<string, Shared.Models.Property>>> filePropertiesKeyValuePairs)
|
||||||
{
|
{
|
||||||
FileInfo fileInfo;
|
FileInfo fileInfo;
|
||||||
G_Index indexInfo;
|
G_Index indexInfo;
|
||||||
@ -151,7 +150,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
|||||||
Dictionary<int, G_Index> valuePairs;
|
Dictionary<int, G_Index> valuePairs;
|
||||||
List<string> directoryInfoCollection;
|
List<string> directoryInfoCollection;
|
||||||
List<string> parseExceptions = new();
|
List<string> parseExceptions = new();
|
||||||
List<Tuple<List<string>, string, A_Property>> neededTuples = new();
|
List<Tuple<List<string>, string, Shared.Models.Property>> neededTuples = new();
|
||||||
List<Tuple<string, Dictionary<int, G_Index>>> indexInfoTuples = new();
|
List<Tuple<string, Dictionary<int, G_Index>>> indexInfoTuples = new();
|
||||||
for (short i = 0; i < short.MaxValue; i++)
|
for (short i = 0; i < short.MaxValue; i++)
|
||||||
{
|
{
|
||||||
@ -164,11 +163,11 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
|||||||
parseExceptions.Clear();
|
parseExceptions.Clear();
|
||||||
}
|
}
|
||||||
neededTuples.Clear();
|
neededTuples.Clear();
|
||||||
foreach (KeyValuePair<string, List<Tuple<string, A_Property>>> tuples in filePropertiesKeyValuePairs)
|
foreach (KeyValuePair<string, List<Tuple<string, Shared.Models.Property>>> tuples in filePropertiesKeyValuePairs)
|
||||||
{
|
{
|
||||||
valuePairs = new Dictionary<int, G_Index>();
|
valuePairs = new Dictionary<int, G_Index>();
|
||||||
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, tuples.Key, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: "Unknown C", collectionDescription: string.Empty);
|
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, tuples.Key, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: "Unknown C", collectionDescription: string.Empty);
|
||||||
foreach (Tuple<string, A_Property> tuple in tuples.Value)
|
foreach (Tuple<string, Shared.Models.Property> tuple in tuples.Value)
|
||||||
{
|
{
|
||||||
fileInfo = new FileInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "{}"), string.Concat(Path.GetFileNameWithoutExtension(tuple.Item1), ".json")));
|
fileInfo = new FileInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "{}"), string.Concat(Path.GetFileNameWithoutExtension(tuple.Item1), ".json")));
|
||||||
if (!fileInfo.Exists)
|
if (!fileInfo.Exists)
|
||||||
@ -191,7 +190,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
|||||||
valuePairs.Add(indexInfo.Index.Value, indexInfo);
|
valuePairs.Add(indexInfo.Index.Value, indexInfo);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
neededTuples.Add(new Tuple<List<string>, string, A_Property>(new List<string> { tuple.Item1 }, fileInfo.FullName, tuple.Item2));
|
neededTuples.Add(new Tuple<List<string>, string, Shared.Models.Property>(new List<string> { tuple.Item1 }, fileInfo.FullName, tuple.Item2));
|
||||||
}
|
}
|
||||||
indexInfoTuples.Add(new Tuple<string, Dictionary<int, G_Index>>(tuples.Key, valuePairs));
|
indexInfoTuples.Add(new Tuple<string, Dictionary<int, G_Index>>(tuples.Key, valuePairs));
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
"Configuration": {
|
"Configuration": {
|
||||||
"CheckJsonForDistanceResults": false,
|
"CheckJsonForDistanceResults": false,
|
||||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||||
"DateGroup": "2022-08-14",
|
"DateGroup": "2022-08-22",
|
||||||
"DistanceFactor": 8,
|
"DistanceFactor": 8,
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForceFaceLastWriteTimeToCreationTime": false,
|
"ForceFaceLastWriteTimeToCreationTime": false,
|
||||||
@ -62,7 +62,7 @@
|
|||||||
"LoadOrCreateThenSaveIndex": false,
|
"LoadOrCreateThenSaveIndex": false,
|
||||||
"LocationConfidenceFactor": 2,
|
"LocationConfidenceFactor": 2,
|
||||||
"MappedMaxIndex": 1034720,
|
"MappedMaxIndex": 1034720,
|
||||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||||
"MaxItemsInDistanceCollection": 50,
|
"MaxItemsInDistanceCollection": 50,
|
||||||
"ModelDirectory": "C:/GitHub/dlib-models",
|
"ModelDirectory": "C:/GitHub/dlib-models",
|
||||||
"ModelName": "Hog",
|
"ModelName": "Hog",
|
||||||
@ -85,7 +85,7 @@
|
|||||||
"PropertiesChangedForResize": false,
|
"PropertiesChangedForResize": false,
|
||||||
"Reverse": false,
|
"Reverse": false,
|
||||||
"xRootDirectory": "C:/Tmp/phares/Pictures",
|
"xRootDirectory": "C:/Tmp/phares/Pictures",
|
||||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-08-14 - b756859b616424dc98b7742a64c15a8951632473 - III",
|
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-08-22 - b756859b616424dc98b7742a64c15a8951632473 - III",
|
||||||
"SaveFullYearOfRandomFiles": true,
|
"SaveFullYearOfRandomFiles": true,
|
||||||
"SaveResizedSubFiles": true,
|
"SaveResizedSubFiles": true,
|
||||||
"SkipSearch": false,
|
"SkipSearch": false,
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
"Configuration": {
|
"Configuration": {
|
||||||
"CheckJsonForDistanceResults": false,
|
"CheckJsonForDistanceResults": false,
|
||||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||||
"DateGroup": "2022-08-14",
|
"DateGroup": "2022-08-22",
|
||||||
"DistanceFactor": 8,
|
"DistanceFactor": 8,
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForceFaceLastWriteTimeToCreationTime": false,
|
"ForceFaceLastWriteTimeToCreationTime": false,
|
||||||
@ -62,7 +62,7 @@
|
|||||||
"LoadOrCreateThenSaveIndex": false,
|
"LoadOrCreateThenSaveIndex": false,
|
||||||
"LocationConfidenceFactor": 2,
|
"LocationConfidenceFactor": 2,
|
||||||
"MappedMaxIndex": 1034720,
|
"MappedMaxIndex": 1034720,
|
||||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||||
"MaxItemsInDistanceCollection": 50,
|
"MaxItemsInDistanceCollection": 50,
|
||||||
"ModelDirectory": "L:/GitHub/dlib-models",
|
"ModelDirectory": "L:/GitHub/dlib-models",
|
||||||
"ModelName": "Hog",
|
"ModelName": "Hog",
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
"Configuration": {
|
"Configuration": {
|
||||||
"CheckJsonForDistanceResults": false,
|
"CheckJsonForDistanceResults": false,
|
||||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||||
"DateGroup": "2022-08-14",
|
"DateGroup": "2022-08-22",
|
||||||
"DistanceFactor": 8,
|
"DistanceFactor": 8,
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForceFaceLastWriteTimeToCreationTime": false,
|
"ForceFaceLastWriteTimeToCreationTime": false,
|
||||||
@ -62,7 +62,7 @@
|
|||||||
"LoadOrCreateThenSaveIndex": false,
|
"LoadOrCreateThenSaveIndex": false,
|
||||||
"LocationConfidenceFactor": 2,
|
"LocationConfidenceFactor": 2,
|
||||||
"MappedMaxIndex": 1034720,
|
"MappedMaxIndex": 1034720,
|
||||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||||
"MaxItemsInDistanceCollection": 50,
|
"MaxItemsInDistanceCollection": 50,
|
||||||
"ModelDirectory": "C:/GitHub/dlib-models",
|
"ModelDirectory": "C:/GitHub/dlib-models",
|
||||||
"ModelName": "Hog",
|
"ModelName": "Hog",
|
||||||
|
7
Map/.vscode/settings.json
vendored
Normal file
7
Map/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"dlib",
|
||||||
|
"Exif",
|
||||||
|
"Serilog"
|
||||||
|
]
|
||||||
|
}
|
46
Map/Map.csproj
Normal file
46
Map/Map.csproj
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<LangVersion>10.0</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<OutputType>library</OutputType>
|
||||||
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<PackageId>Phares.View.by.Distance.Map</PackageId>
|
||||||
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
|
<Version>6.0.100.1</Version>
|
||||||
|
<Authors>Mike Phares</Authors>
|
||||||
|
<Company>Phares</Company>
|
||||||
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
|
||||||
|
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
|
||||||
|
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(IsWindows)'=='true'">
|
||||||
|
<DefineConstants>Windows</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(IsOSX)'=='true'">
|
||||||
|
<DefineConstants>OSX</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(IsLinux)'=='true'">
|
||||||
|
<DefineConstants>Linux</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
|
||||||
|
<SupportedPlatform Include="browser" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.Text.Json" Version="6.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||||
|
<ProjectReference Include="..\Property\Property.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
546
Map/Models/MapLogic.cs
Normal file
546
Map/Models/MapLogic.cs
Normal file
@ -0,0 +1,546 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text.Json;
|
||||||
|
using View_by_Distance.Property.Models;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Map.Models;
|
||||||
|
|
||||||
|
public class MapLogic
|
||||||
|
{
|
||||||
|
|
||||||
|
protected readonly List<(int, string[])> _AllCollection;
|
||||||
|
protected readonly Dictionary<int, int[]> _KeyValuePairs;
|
||||||
|
protected readonly Dictionary<int, int[]> _IndicesFromNew;
|
||||||
|
protected readonly string _DeterministicHashCodeRootDirectory;
|
||||||
|
protected readonly Dictionary<int, string[]> _SixCharacterNamedFaceInfo;
|
||||||
|
protected readonly Dictionary<int, string[]> _NamedFaceInfoDeterministicHashCodeKeyValuePairs;
|
||||||
|
protected readonly Dictionary<double, string[]> _NamedDeterministicHashCodeKeyValuePairs;
|
||||||
|
protected readonly Dictionary<double, string[]> _IncorrectDeterministicHashCodeKeyValuePairs;
|
||||||
|
|
||||||
|
public Dictionary<int, int[]> KeyValuePairs => _KeyValuePairs;
|
||||||
|
public Dictionary<int, int[]> IndicesFromNew => _IndicesFromNew;
|
||||||
|
public string DeterministicHashCodeRootDirectory => _DeterministicHashCodeRootDirectory;
|
||||||
|
public Dictionary<double, string[]> NamedDeterministicHashCodeKeyValuePairs => _NamedDeterministicHashCodeKeyValuePairs;
|
||||||
|
public Dictionary<double, string[]> IncorrectDeterministicHashCodeKeyValuePairs => _IncorrectDeterministicHashCodeKeyValuePairs;
|
||||||
|
public Dictionary<int, string[]> NamedFaceInfoDeterministicHashCodeKeyValuePairs => _NamedFaceInfoDeterministicHashCodeKeyValuePairs;
|
||||||
|
|
||||||
|
private readonly Serilog.ILogger? _Log;
|
||||||
|
private readonly Configuration _Configuration;
|
||||||
|
|
||||||
|
public MapLogic(int maxDegreeOfParallelism, Configuration configuration)
|
||||||
|
{
|
||||||
|
_AllCollection = new();
|
||||||
|
_Configuration = configuration;
|
||||||
|
_Log = Serilog.Log.ForContext<MapLogic>();
|
||||||
|
Dictionary<int, string[]>? namedFaceInfoDeterministicHashCode;
|
||||||
|
if (configuration.VerifyToSeason is null || !configuration.VerifyToSeason.Any())
|
||||||
|
throw new Exception();
|
||||||
|
string json;
|
||||||
|
string[] files;
|
||||||
|
string fullPath;
|
||||||
|
Dictionary<int, int[]>? keyValuePairs;
|
||||||
|
string deterministicHashCodeRootDirectory;
|
||||||
|
List<KeyValuePair<int, int[]>>? collection;
|
||||||
|
Dictionary<int, int[]> indicesFromNew = new();
|
||||||
|
Dictionary<int, string[]>? sixCharacterNamedFaceInfo;
|
||||||
|
Dictionary<double, string[]> namedDeterministicHashCode = new();
|
||||||
|
Dictionary<double, string[]> incorrectDeterministicHashCode = new();
|
||||||
|
string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory);
|
||||||
|
if (string.IsNullOrEmpty(rootDirectoryParent))
|
||||||
|
throw new NullReferenceException(nameof(rootDirectoryParent));
|
||||||
|
files = Directory.GetFiles(rootDirectoryParent, "*DeterministicHashCode*.json", SearchOption.TopDirectoryOnly);
|
||||||
|
if (files.Length != 1)
|
||||||
|
namedFaceInfoDeterministicHashCode = new();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
json = File.ReadAllText(files[0]);
|
||||||
|
namedFaceInfoDeterministicHashCode = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
|
||||||
|
if (namedFaceInfoDeterministicHashCode is null)
|
||||||
|
throw new NullReferenceException(nameof(namedFaceInfoDeterministicHashCode));
|
||||||
|
}
|
||||||
|
string[] directories = Directory.GetDirectories(rootDirectoryParent, "*DeterministicHashCode*", SearchOption.TopDirectoryOnly);
|
||||||
|
if (!directories.Any())
|
||||||
|
deterministicHashCodeRootDirectory = string.Empty;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dictionary<int, List<Shared.Models.Face>> faces = new();
|
||||||
|
deterministicHashCodeRootDirectory = directories[0];
|
||||||
|
SetKeyValuePairs(deterministicHashCodeRootDirectory, namedDeterministicHashCode, incorrectDeterministicHashCode, faces);
|
||||||
|
}
|
||||||
|
if (!namedFaceInfoDeterministicHashCode.Any())
|
||||||
|
sixCharacterNamedFaceInfo = new();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
files = Directory.GetFiles(rootDirectoryParent, "*SixCharacter*.json", SearchOption.TopDirectoryOnly);
|
||||||
|
if (files.Length != 1)
|
||||||
|
sixCharacterNamedFaceInfo = new();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
json = File.ReadAllText(files[0]);
|
||||||
|
sixCharacterNamedFaceInfo = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
|
||||||
|
if (sixCharacterNamedFaceInfo is null)
|
||||||
|
throw new NullReferenceException(nameof(sixCharacterNamedFaceInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly);
|
||||||
|
if (files.Length != 1)
|
||||||
|
keyValuePairs = new();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
json = File.ReadAllText(files[0]);
|
||||||
|
keyValuePairs = JsonSerializer.Deserialize<Dictionary<int, int[]>>(json);
|
||||||
|
if (keyValuePairs is null)
|
||||||
|
throw new NullReferenceException(nameof(keyValuePairs));
|
||||||
|
}
|
||||||
|
foreach (string propertyContentCollectionFile in configuration.PropertyContentCollectionFiles)
|
||||||
|
{
|
||||||
|
fullPath = Path.GetFullPath(string.Concat(rootDirectoryParent, propertyContentCollectionFile));
|
||||||
|
if (fullPath.Contains(configuration.RootDirectory))
|
||||||
|
continue;
|
||||||
|
if (!File.Exists(fullPath))
|
||||||
|
continue;
|
||||||
|
json = File.ReadAllText(fullPath);
|
||||||
|
collection = JsonSerializer.Deserialize<List<KeyValuePair<int, int[]>>>(json);
|
||||||
|
if (collection is null)
|
||||||
|
throw new NullReferenceException(nameof(collection));
|
||||||
|
foreach (KeyValuePair<int, int[]> keyValuePair in collection)
|
||||||
|
{
|
||||||
|
if (indicesFromNew.ContainsKey(keyValuePair.Key))
|
||||||
|
continue;
|
||||||
|
indicesFromNew.Add(keyValuePair.Key, keyValuePair.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_KeyValuePairs = keyValuePairs;
|
||||||
|
_IndicesFromNew = indicesFromNew;
|
||||||
|
_SixCharacterNamedFaceInfo = sixCharacterNamedFaceInfo;
|
||||||
|
_NamedDeterministicHashCodeKeyValuePairs = namedDeterministicHashCode;
|
||||||
|
_DeterministicHashCodeRootDirectory = deterministicHashCodeRootDirectory;
|
||||||
|
_IncorrectDeterministicHashCodeKeyValuePairs = incorrectDeterministicHashCode;
|
||||||
|
_NamedFaceInfoDeterministicHashCodeKeyValuePairs = namedFaceInfoDeterministicHashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetKeyValuePairs(string deterministicHashCodeRootDirectory, List<(string, double)> named, List<(string, double)> incorrect, Dictionary<int, List<Shared.Models.Face>> keyValuePairs)
|
||||||
|
{
|
||||||
|
string[] files;
|
||||||
|
string fileName;
|
||||||
|
string personKey;
|
||||||
|
string? checkFile;
|
||||||
|
string[] yearDirectories;
|
||||||
|
string[] personKeyDirectories;
|
||||||
|
string[] personNameDirectories;
|
||||||
|
double? idAndNormalizedPixelPercentage;
|
||||||
|
string[] ticksDirectories = Directory.GetDirectories(deterministicHashCodeRootDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (string ticksDirectory in ticksDirectories)
|
||||||
|
{
|
||||||
|
if (!ticksDirectory.EndsWith(')'))
|
||||||
|
continue;
|
||||||
|
personKeyDirectories = Directory.GetDirectories(ticksDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (string personKeyDirectory in personKeyDirectories)
|
||||||
|
{
|
||||||
|
personKey = Path.GetFileName(personKeyDirectory);
|
||||||
|
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (string yearDirectory in yearDirectories)
|
||||||
|
{
|
||||||
|
files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (string file in files)
|
||||||
|
{
|
||||||
|
if (file.EndsWith(".lnk"))
|
||||||
|
continue;
|
||||||
|
fileName = Path.GetFileName(file);
|
||||||
|
idAndNormalizedPixelPercentage = Shared.Models.Stateless.Methods.INamed.GetReversedDeterministicHashCode(fileName);
|
||||||
|
if (idAndNormalizedPixelPercentage is null)
|
||||||
|
{
|
||||||
|
(checkFile, idAndNormalizedPixelPercentage) = Shared.Models.Stateless.Methods.INamed.GetReversedDeterministicHashCode(keyValuePairs, file);
|
||||||
|
if (idAndNormalizedPixelPercentage is null)
|
||||||
|
break;
|
||||||
|
if (!string.IsNullOrEmpty(checkFile))
|
||||||
|
File.Move(file, checkFile);
|
||||||
|
}
|
||||||
|
incorrect.Add(new(personKey, idAndNormalizedPixelPercentage.Value));
|
||||||
|
}
|
||||||
|
foreach (string personNameDirectory in personNameDirectories)
|
||||||
|
{
|
||||||
|
files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (string file in files)
|
||||||
|
{
|
||||||
|
if (file.EndsWith(".lnk"))
|
||||||
|
continue;
|
||||||
|
fileName = Path.GetFileName(file);
|
||||||
|
idAndNormalizedPixelPercentage = Shared.Models.Stateless.Methods.INamed.GetReversedDeterministicHashCode(fileName);
|
||||||
|
if (idAndNormalizedPixelPercentage is null)
|
||||||
|
{
|
||||||
|
(checkFile, idAndNormalizedPixelPercentage) = Shared.Models.Stateless.Methods.INamed.GetReversedDeterministicHashCode(keyValuePairs, file);
|
||||||
|
if (idAndNormalizedPixelPercentage is null)
|
||||||
|
break;
|
||||||
|
if (!string.IsNullOrEmpty(checkFile))
|
||||||
|
File.Move(file, checkFile);
|
||||||
|
}
|
||||||
|
named.Add(new(personKey, idAndNormalizedPixelPercentage.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetKeyValuePairs(string deterministicHashCodeRootDirectory, Dictionary<double, string[]> namedDeterministicHashCode, Dictionary<double, string[]> incorrectDeterministicHashCode, Dictionary<int, List<Shared.Models.Face>> keyValuePairs)
|
||||||
|
{
|
||||||
|
Dictionary<double, List<string>> namedKeyValuePairs = new();
|
||||||
|
Dictionary<double, List<string>> incorrectKeyValuePairs = new();
|
||||||
|
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> named = new();
|
||||||
|
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> incorrect = new();
|
||||||
|
SetKeyValuePairs(deterministicHashCodeRootDirectory, named, incorrect, keyValuePairs);
|
||||||
|
named = (from l in named orderby l.IdAndNormalizedPixelPercentage select l).ToList();
|
||||||
|
incorrect = (from l in incorrect orderby l.IdAndNormalizedPixelPercentage select l).ToList();
|
||||||
|
foreach ((string personKey, double idAndNormalizedPixelPercentage) in named)
|
||||||
|
{
|
||||||
|
if (!namedKeyValuePairs.ContainsKey(idAndNormalizedPixelPercentage))
|
||||||
|
namedKeyValuePairs.Add(idAndNormalizedPixelPercentage, new());
|
||||||
|
namedKeyValuePairs[idAndNormalizedPixelPercentage].Add(personKey);
|
||||||
|
}
|
||||||
|
foreach ((string personKey, double idAndNormalizedPixelPercentage) in incorrect)
|
||||||
|
{
|
||||||
|
if (!incorrectKeyValuePairs.ContainsKey(idAndNormalizedPixelPercentage))
|
||||||
|
incorrectKeyValuePairs.Add(idAndNormalizedPixelPercentage, new());
|
||||||
|
incorrectKeyValuePairs[idAndNormalizedPixelPercentage].Add(personKey);
|
||||||
|
}
|
||||||
|
foreach (KeyValuePair<double, List<string>> keyValuePair in namedKeyValuePairs)
|
||||||
|
namedDeterministicHashCode.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray());
|
||||||
|
foreach (KeyValuePair<double, List<string>> keyValuePair in incorrectKeyValuePairs)
|
||||||
|
incorrectDeterministicHashCode.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateKeyValuePairs(List<Shared.Models.Container> containers)
|
||||||
|
{
|
||||||
|
Dictionary<int, List<Shared.Models.Face>> keyValuePairs = new();
|
||||||
|
Dictionary<double, string[]> namedDeterministicHashCode = new();
|
||||||
|
Dictionary<double, string[]> incorrectDeterministicHashCode = new();
|
||||||
|
foreach (Shared.Models.Container container in containers)
|
||||||
|
{
|
||||||
|
foreach (Shared.Models.Item item in container.Items)
|
||||||
|
{
|
||||||
|
if (item.ImageFileHolder is null || item.Property?.Id is null || !item.Faces.Any())
|
||||||
|
continue;
|
||||||
|
if (keyValuePairs.ContainsKey(item.Property.Id.Value))
|
||||||
|
{
|
||||||
|
if (keyValuePairs[item.Property.Id.Value].Count != item.Faces.Count)
|
||||||
|
throw new Exception();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
keyValuePairs.Add(item.Property.Id.Value, item.Faces);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetKeyValuePairs(_DeterministicHashCodeRootDirectory, namedDeterministicHashCode, incorrectDeterministicHashCode, keyValuePairs);
|
||||||
|
foreach (KeyValuePair<double, string[]> keyValuePair in namedDeterministicHashCode)
|
||||||
|
_NamedDeterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value);
|
||||||
|
foreach (KeyValuePair<double, string[]> keyValuePair in incorrectDeterministicHashCode)
|
||||||
|
_IncorrectDeterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long LogDelta(long ticks, string? methodName)
|
||||||
|
{
|
||||||
|
long result;
|
||||||
|
if (_Log is null)
|
||||||
|
throw new NullReferenceException(nameof(_Log));
|
||||||
|
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
|
||||||
|
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
|
||||||
|
result = DateTime.Now.Ticks;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddToMapLogicAllCollection(Shared.Models.Item[] filteredItems)
|
||||||
|
{
|
||||||
|
if (_SixCharacterNamedFaceInfo.Any())
|
||||||
|
{
|
||||||
|
string[] keys;
|
||||||
|
Shared.Models.Item item;
|
||||||
|
for (int i = 0; i < filteredItems.Length; i++)
|
||||||
|
{
|
||||||
|
item = filteredItems[i];
|
||||||
|
if (item.Property?.Id is null)
|
||||||
|
continue;
|
||||||
|
foreach (int sixCharacterIndex in item.Property.Indices)
|
||||||
|
{
|
||||||
|
if (!_SixCharacterNamedFaceInfo.ContainsKey(sixCharacterIndex))
|
||||||
|
continue;
|
||||||
|
keys = _SixCharacterNamedFaceInfo[sixCharacterIndex];
|
||||||
|
_AllCollection.Add(new(item.Property.Id.Value, keys));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveAllCollection()
|
||||||
|
{
|
||||||
|
if (_AllCollection.Any())
|
||||||
|
{
|
||||||
|
string[] keys;
|
||||||
|
long ticks = DateTime.Now.Ticks;
|
||||||
|
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.RootDirectory);
|
||||||
|
if (string.IsNullOrEmpty(rootDirectoryParent))
|
||||||
|
throw new NullReferenceException(nameof(rootDirectoryParent));
|
||||||
|
Dictionary<int, string[]> namedFaceInfoDeterministicHashCodeIndices = new();
|
||||||
|
List<(int, string[])> allCollection = _AllCollection.OrderBy(l => l.Item1).ToList();
|
||||||
|
foreach ((int deterministicHashCode, string[] values) in allCollection)
|
||||||
|
{
|
||||||
|
if (namedFaceInfoDeterministicHashCodeIndices.ContainsKey(deterministicHashCode))
|
||||||
|
{
|
||||||
|
keys = namedFaceInfoDeterministicHashCodeIndices[deterministicHashCode];
|
||||||
|
if (JsonSerializer.Serialize(values) == JsonSerializer.Serialize(keys))
|
||||||
|
continue;
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
namedFaceInfoDeterministicHashCodeIndices.Add(deterministicHashCode, values);
|
||||||
|
}
|
||||||
|
string json = JsonSerializer.Serialize(namedFaceInfoDeterministicHashCodeIndices, new JsonSerializerOptions { WriteIndented = true });
|
||||||
|
string checkFile = Path.Combine(rootDirectoryParent, "NamedFaceInfoDeterministicHashCodeIndices.json");
|
||||||
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||||
|
_ = LogDelta(ticks, new StackFrame().GetMethod()?.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddToNamed(MapLogic mapLogic, List<Shared.Models.Item> items)
|
||||||
|
{
|
||||||
|
bool? isWrongYear;
|
||||||
|
DateTime minimumDateTime;
|
||||||
|
double deterministicHashCodeKey;
|
||||||
|
List<string> personKeys = new();
|
||||||
|
Shared.Models.PersonBirthday? personBirthday;
|
||||||
|
foreach (Shared.Models.Item item in items)
|
||||||
|
{
|
||||||
|
if (item.ImageFileHolder is null)
|
||||||
|
continue;
|
||||||
|
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||||
|
continue;
|
||||||
|
foreach (Shared.Models.Face face in item.Faces)
|
||||||
|
{
|
||||||
|
personKeys.Clear();
|
||||||
|
if (face.LocationIndex is null)
|
||||||
|
continue;
|
||||||
|
deterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetDeterministicHashCodeKey(item, face);
|
||||||
|
if (!mapLogic.NamedDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey))
|
||||||
|
continue;
|
||||||
|
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||||
|
personKeys.AddRange(mapLogic.NamedDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey]);
|
||||||
|
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
|
||||||
|
for (int i = 0; i < personKeys.Count; i++)
|
||||||
|
{
|
||||||
|
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKeys[i]);
|
||||||
|
if (personBirthday is null)
|
||||||
|
continue;
|
||||||
|
if (face.Location is null)
|
||||||
|
continue;
|
||||||
|
item.Named.Add(new(isWrongYear, minimumDateTime, face.Location.NormalizedPixelPercentage, personBirthday));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!personKeys.Any())
|
||||||
|
{
|
||||||
|
if (!mapLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.ContainsKey(item.Property.Id.Value))
|
||||||
|
continue;
|
||||||
|
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||||
|
personKeys.AddRange(mapLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs[item.Property.Id.Value]);
|
||||||
|
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
|
||||||
|
for (int i = 0; i < personKeys.Count; i++)
|
||||||
|
{
|
||||||
|
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKeys[i]);
|
||||||
|
if (personBirthday is null)
|
||||||
|
continue;
|
||||||
|
item.Named.Add(new(isWrongYear, minimumDateTime, personBirthday));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<(Shared.Models.Item, (string, Shared.Models.Face?, (string, string, string, string))[])> GetCollection(MapLogic mapLogic, List<Shared.Models.Item> items, string dFacesContentDirectory)
|
||||||
|
{
|
||||||
|
List<(Shared.Models.Item, (string, Shared.Models.Face?, (string, string, string, string))[])> results = new();
|
||||||
|
string[] keys;
|
||||||
|
string directory;
|
||||||
|
string personKey;
|
||||||
|
bool? isWrongYear;
|
||||||
|
const int zero = 0;
|
||||||
|
TimeSpan? timeSpan;
|
||||||
|
string copyFileName;
|
||||||
|
string copyDirectory;
|
||||||
|
string? relativePath;
|
||||||
|
string isWrongYearFlag;
|
||||||
|
Shared.Models.Face face;
|
||||||
|
string shortcutFileName;
|
||||||
|
Shared.Models.Item item;
|
||||||
|
string subDirectoryName;
|
||||||
|
List<int> indices = new();
|
||||||
|
DateTime? minimumDateTime;
|
||||||
|
List<Shared.Models.Face> faceCollection;
|
||||||
|
Shared.Models.PersonBirthday? personBirthday;
|
||||||
|
List<(string, Shared.Models.Face?, (string, string, string, string))> collection;
|
||||||
|
for (int i = 0; i < items.Count; i++)
|
||||||
|
{
|
||||||
|
indices.Clear();
|
||||||
|
copyFileName = string.Empty;
|
||||||
|
copyDirectory = string.Empty;
|
||||||
|
item = items[i];
|
||||||
|
if (item.ImageFileHolder is null)
|
||||||
|
continue;
|
||||||
|
relativePath = Path.GetDirectoryName($"C:{item.RelativePath}");
|
||||||
|
if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3)
|
||||||
|
continue;
|
||||||
|
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||||
|
continue;
|
||||||
|
collection = new();
|
||||||
|
if (!mapLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.ContainsKey(item.Property.Id.Value))
|
||||||
|
{
|
||||||
|
faceCollection = new();
|
||||||
|
personKey = string.Empty;
|
||||||
|
directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
faceCollection = item.Faces;
|
||||||
|
keys = mapLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs[item.Property.Id.Value];
|
||||||
|
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||||
|
if (minimumDateTime is null)
|
||||||
|
continue;
|
||||||
|
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime.Value);
|
||||||
|
isWrongYearFlag = Shared.Models.Stateless.Methods.IItem.GetWrongYearFlag(isWrongYear);
|
||||||
|
subDirectoryName = $"{isWrongYearFlag}{minimumDateTime.Value:yyyy}";
|
||||||
|
if (!faceCollection.Any())
|
||||||
|
{
|
||||||
|
personKey = string.Empty;
|
||||||
|
directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName);
|
||||||
|
}
|
||||||
|
else if (keys.Length != 1)
|
||||||
|
{
|
||||||
|
personKey = string.Empty;
|
||||||
|
directory = Path.Combine(dFacesContentDirectory, $"Not Supported{relativePath[2..]}", subDirectoryName);
|
||||||
|
}
|
||||||
|
else if (faceCollection.Count != 1)
|
||||||
|
{
|
||||||
|
personKey = string.Empty;
|
||||||
|
directory = Path.Combine(dFacesContentDirectory, $"Many{relativePath[2..]}", subDirectoryName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
indices.Add(zero);
|
||||||
|
personKey = keys[zero];
|
||||||
|
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
|
||||||
|
if (personBirthday is null)
|
||||||
|
continue;
|
||||||
|
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime.Value, isWrongYear, personBirthday);
|
||||||
|
if (timeSpan.HasValue)
|
||||||
|
{
|
||||||
|
if (timeSpan.Value.Ticks < 0)
|
||||||
|
subDirectoryName = "!---";
|
||||||
|
else
|
||||||
|
subDirectoryName = $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}";
|
||||||
|
}
|
||||||
|
face = faceCollection[zero];
|
||||||
|
directory = Path.Combine(dFacesContentDirectory, "Shortcuts", personKey, subDirectoryName);
|
||||||
|
if (face.FaceEncoding is not null && face.Location?.NormalizedPixelPercentage is not null)
|
||||||
|
copyDirectory = Path.Combine(dFacesContentDirectory, "Images", personKey, subDirectoryName);
|
||||||
|
else
|
||||||
|
copyDirectory = Path.Combine(dFacesContentDirectory, "ImagesBut", personKey, subDirectoryName);
|
||||||
|
copyFileName = Path.Combine(copyDirectory, $"{item.Property.Id.Value}{item.ResizedFileHolder.ExtensionLowered}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shortcutFileName = Path.Combine(directory, $"{item.Property.Id.Value}.lnk");
|
||||||
|
if (string.IsNullOrEmpty(personKey) || !indices.Any())
|
||||||
|
collection.Add(new(personKey, null, (directory, copyDirectory, copyFileName, shortcutFileName)));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (int index in indices)
|
||||||
|
collection.Add(new(personKey, faceCollection[index], (directory, copyDirectory, copyFileName, shortcutFileName)));
|
||||||
|
}
|
||||||
|
results.Add(new(item, collection.ToArray()));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetKey(DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday)
|
||||||
|
{
|
||||||
|
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 = Shared.Models.Stateless.Methods.IItem.GetWrongYearFlag(isWrongYear);
|
||||||
|
result = string.Concat(personKey, $"{isWrongYearFlag}{minimumDateTime:yyyy}");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetDirectory(string directory, string subDirectory, DateTime minimumDateTime, bool? isWrongYear, Shared.Models.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 = Shared.Models.Stateless.Methods.IItem.GetWrongYearFlag(isWrongYear);
|
||||||
|
result = Path.Combine(directory, subDirectory, personKey, $"{isWrongYearFlag}{minimumDateTime:yyyy}");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, Shared.Models.Face)>> GetKeyValuePairs(string argZero, List<Shared.Models.Container> containers)
|
||||||
|
{
|
||||||
|
Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, Shared.Models.Face)>> results = new();
|
||||||
|
string key;
|
||||||
|
foreach (Shared.Models.Container container in containers)
|
||||||
|
{
|
||||||
|
if (!container.Items.Any())
|
||||||
|
continue;
|
||||||
|
if (!container.SourceDirectory.StartsWith(argZero))
|
||||||
|
continue;
|
||||||
|
foreach (Shared.Models.Item item in container.Items)
|
||||||
|
{
|
||||||
|
if (item.ImageFileHolder is null || item.Property is null || !item.Named.Any())
|
||||||
|
continue;
|
||||||
|
foreach (Shared.Models.Named named in item.Named)
|
||||||
|
{
|
||||||
|
if (named.NormalizedPixelPercentage is null && (item.Named.Count != 1 || item.Faces.Count != 1))
|
||||||
|
continue;
|
||||||
|
foreach (Shared.Models.Face face in item.Faces)
|
||||||
|
{
|
||||||
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
|
continue;
|
||||||
|
if (named.PersonBirthday is null)
|
||||||
|
continue;
|
||||||
|
if (named.NormalizedPixelPercentage.HasValue && named.NormalizedPixelPercentage.Value != face.Location?.NormalizedPixelPercentage)
|
||||||
|
continue;
|
||||||
|
key = GetKey(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday);
|
||||||
|
if (!results.ContainsKey(key))
|
||||||
|
results.Add(key, new());
|
||||||
|
results[key].Add(new(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday, face));
|
||||||
|
if (named.NormalizedPixelPercentage is null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (bool?, string[]) IsWrongYear(Shared.Models.Item item)
|
||||||
|
{
|
||||||
|
(bool?, string[]) result;
|
||||||
|
if (item.Property is null || item.ImageFileHolder is null)
|
||||||
|
throw new NullReferenceException();
|
||||||
|
DateTime? minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||||
|
result = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
10
Map/Models/Stateless/SerilogExtensionMethods.cs
Normal file
10
Map/Models/Stateless/SerilogExtensionMethods.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace View_by_Distance.Map.Models.Stateless;
|
||||||
|
|
||||||
|
internal static class SerilogExtensionMethods
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate);
|
||||||
|
|
||||||
|
internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate);
|
||||||
|
|
||||||
|
}
|
@ -10,7 +10,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Phares.View.by.Distance.Metadata</PackageId>
|
<PackageId>Phares.View.by.Distance.Metadata</PackageId>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<Version>5.0.402.104</Version>
|
<Version>6.0.100.1</Version>
|
||||||
<Authors>Mike Phares</Authors>
|
<Authors>Mike Phares</Authors>
|
||||||
<Company>Phares</Company>
|
<Company>Phares</Company>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
@ -78,7 +78,7 @@ public class B_Metadata
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public (int, List<KeyValuePair<string, string>>) GetMetadataCollection(string bResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Property.Models.Item item)
|
public (int, List<KeyValuePair<string, string>>) GetMetadataCollection(string bResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Item item)
|
||||||
{
|
{
|
||||||
List<KeyValuePair<string, string>> results = new();
|
List<KeyValuePair<string, string>> results = new();
|
||||||
if (item.Property?.Id is null)
|
if (item.Property?.Id is null)
|
||||||
@ -151,7 +151,7 @@ public class B_Metadata
|
|||||||
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();
|
||||||
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
||||||
{
|
{
|
||||||
if (!_ForceMetadataLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
|
if (!_ForceMetadataLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
|
||||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(B_Metadata), DateTime.Now));
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(B_Metadata), DateTime.Now));
|
||||||
@ -171,29 +171,4 @@ public class B_Metadata
|
|||||||
return new(dictionary.Count, results);
|
return new(dictionary.Count, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<KeyValuePair<string, string>> GetFiltered(List<KeyValuePair<string, string>> metadataCollection)
|
|
||||||
{
|
|
||||||
List<KeyValuePair<string, string>> results = new();
|
|
||||||
foreach (KeyValuePair<string, string> keyValuePair in metadataCollection)
|
|
||||||
{
|
|
||||||
if (keyValuePair.Key.Contains("File") || keyValuePair.Key.Contains("JPEG") || keyValuePair.Key.Contains("Orientation") || keyValuePair.Key.Contains("Thumbnail"))
|
|
||||||
continue;
|
|
||||||
results.Add(new(keyValuePair.Key, keyValuePair.Value));
|
|
||||||
}
|
|
||||||
if (!results.Any())
|
|
||||||
results = metadataCollection;
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetUniqueImageId(List<KeyValuePair<string, string>> metadataCollection)
|
|
||||||
{
|
|
||||||
string result = string.Empty;
|
|
||||||
const string exifSubIFD = "Exif SubIFD";
|
|
||||||
const string uniqueImageID = "42016\tUnique Image ID";
|
|
||||||
List<string> uniqueImageIDs = (from l in metadataCollection where l.Key.StartsWith(exifSubIFD) && l.Key.EndsWith(uniqueImageID) select l.Value).ToList();
|
|
||||||
if (uniqueImageIDs.Any())
|
|
||||||
result = uniqueImageIDs[0];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -26,23 +26,22 @@ public class NotCopyCopy
|
|||||||
_AppSettings = appSettings;
|
_AppSettings = appSettings;
|
||||||
_IsEnvironment = isEnvironment;
|
_IsEnvironment = isEnvironment;
|
||||||
_Log = Serilog.Log.ForContext<NotCopyCopy>();
|
_Log = Serilog.Log.ForContext<NotCopyCopy>();
|
||||||
Property.Models.Configuration propertyConfiguration = Property.Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory);
|
Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
|
||||||
Property.Models.Configuration.Verify(propertyConfiguration);
|
Property.Models.Configuration.Verify(propertyConfiguration);
|
||||||
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);
|
||||||
bool reverse = false;
|
bool reverse = false;
|
||||||
Model? model = null;
|
Model? model = null;
|
||||||
PredictorModel? predictorModel = null;
|
string outputExtension = ".jpg";
|
||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
if (propertyConfiguration.PopulatePropertyId is null)
|
PredictorModel? predictorModel = null;
|
||||||
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(reverse, model, predictorModel);
|
A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, predictorModel);
|
||||||
propertyConfiguration.ChangeRootDirectory(configuration.CompareSource);
|
propertyConfiguration.ChangeRootDirectory(configuration.CompareSource);
|
||||||
List<Container> compareContainers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic);
|
List<Shared.Models.Container> compareContainers = A_Property.Get(propertyConfiguration, propertyLogic);
|
||||||
propertyConfiguration.ChangeRootDirectory(configuration.SelectedSource);
|
propertyConfiguration.ChangeRootDirectory(configuration.SelectedSource);
|
||||||
List<Container> selectedContainers = Property.Models.Stateless.A_Property.Get(propertyConfiguration, propertyLogic);
|
List<Shared.Models.Container> selectedContainers = A_Property.Get(propertyConfiguration, propertyLogic);
|
||||||
if (compareContainers.Count == selectedContainers.Count)
|
if (compareContainers.Count == selectedContainers.Count)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
string directoryName;
|
string directoryName;
|
||||||
@ -103,12 +102,12 @@ public class NotCopyCopy
|
|||||||
throw new NullReferenceException(nameof(configuration.SelectedSource));
|
throw new NullReferenceException(nameof(configuration.SelectedSource));
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel)
|
private A_Property GetPropertyLogic(bool reverse, Model? model, string outputExtension, PredictorModel? predictorModel)
|
||||||
{
|
{
|
||||||
PropertyLogic result;
|
A_Property result;
|
||||||
if (_Configuration?.PropertyConfiguration is null)
|
if (_Configuration?.PropertyConfiguration is null)
|
||||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||||
result = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
|
result = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, outputExtension, reverse, model, predictorModel);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,12 +118,12 @@ public class NotCopyCopy
|
|||||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||||
string key;
|
string key;
|
||||||
string fileName;
|
string fileName;
|
||||||
A_Property? property;
|
Shared.Models.Property? property;
|
||||||
string destinationDirectory;
|
string destinationDirectory;
|
||||||
List<string> directoryNames;
|
List<string> directoryNames;
|
||||||
List<string> destinationCollection;
|
List<string> destinationCollection;
|
||||||
string filteredSourceDirectoryFile;
|
string filteredSourceDirectoryFile;
|
||||||
Dictionary<string, A_Property> keyValuePairs = new();
|
Dictionary<string, Shared.Models.Property> keyValuePairs = new();
|
||||||
foreach (Property.Models.DirectoryInfo group in compareSourceGroupCollection)
|
foreach (Property.Models.DirectoryInfo group in compareSourceGroupCollection)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < group.SourceDirectoryFileHolderCollection.Length; i++)
|
for (int i = 0; i < group.SourceDirectoryFileHolderCollection.Length; i++)
|
||||||
@ -150,7 +149,7 @@ public class NotCopyCopy
|
|||||||
if (keyValuePairs.ContainsKey(key) && keyValuePairs[key].LastWriteTime == property.LastWriteTime)
|
if (keyValuePairs.ContainsKey(key) && keyValuePairs[key].LastWriteTime == property.LastWriteTime)
|
||||||
continue;
|
continue;
|
||||||
destinationDirectory = string.Concat(_Configuration.EmptyDestination, group.SourceDirectory[_Configuration.SelectedSource.Length..]);
|
destinationDirectory = string.Concat(_Configuration.EmptyDestination, group.SourceDirectory[_Configuration.SelectedSource.Length..]);
|
||||||
directoryNames = Property.Models.Stateless.IPath.GetDirectoryNames(destinationDirectory);
|
directoryNames = Shared.Models.Stateless.Methods.IPath.GetDirectoryNames(destinationDirectory);
|
||||||
destinationCollection.AddRange(directoryNames);
|
destinationCollection.AddRange(directoryNames);
|
||||||
destinationCollection.Add(fileName);
|
destinationCollection.Add(fileName);
|
||||||
results.Add(new(filteredSourceDirectoryFile, destinationCollection.ToArray()));
|
results.Add(new(filteredSourceDirectoryFile, destinationCollection.ToArray()));
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Phares.View.by.Distance.Not.Copy.Copy</PackageId>
|
<PackageId>Phares.View.by.Distance.Not.Copy.Copy</PackageId>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<Version>5.0.402.104</Version>
|
<Version>6.0.100.1</Version>
|
||||||
<Authors>Mike Phares</Authors>
|
<Authors>Mike Phares</Authors>
|
||||||
<Company>Phares</Company>
|
<Company>Phares</Company>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
@ -39,60 +39,60 @@ public class Program
|
|||||||
if (args is null)
|
if (args is null)
|
||||||
throw new Exception("args is null!");
|
throw new Exception("args is null!");
|
||||||
#nullable disable
|
#nullable disable
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("-".Split(' '), "2021").Item1.HasValue)
|
if (IProperty.IsWrongYear("-".Split(' '), "2021").Item1.HasValue)
|
||||||
throw new Exception("-");
|
throw new Exception("-");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Christmass".Split(' '), "2021").Item1.HasValue)
|
if (IProperty.IsWrongYear("Christmass".Split(' '), "2021").Item1.HasValue)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Christmass 2021".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Christmass 2021".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Christmass ~2021".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Christmass ~2021".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Christmass ~2021.4".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Christmass ~2021.4".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Christmass 2021".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Christmass 2021".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Christmass ~2021".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Christmass ~2021".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Christmass ~2021.4".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Christmass ~2021.4".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Christmass");
|
throw new Exception("Christmass");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("England 2017".Split(' '), "2017").Item1.Value)
|
if (IProperty.IsWrongYear("England 2017".Split(' '), "2017").Item1.Value)
|
||||||
throw new Exception("England");
|
throw new Exception("England");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael".Split(' '), "2021").Item1.HasValue)
|
if (IProperty.IsWrongYear("Logan Michael".Split(' '), "2021").Item1.HasValue)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael 2021".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Logan Michael 2021".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael ~2021".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Logan Michael ~2021".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2021").Item1.Value)
|
if (IProperty.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2021").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael 2021".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Logan Michael 2021".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael ~2021".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Logan Michael ~2021".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (!Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2025").Item1.Value)
|
if (!IProperty.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2025").Item1.Value)
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2021").Item2[0] != "~2021.4")
|
if (IProperty.IsWrongYear("Logan Michael ~2021.4".Split(' '), "2021").Item2[0] != "~2021.4")
|
||||||
throw new Exception("Logan Michael");
|
throw new Exception("Logan Michael");
|
||||||
if (Property.Models.Stateless.A_Property.IsWrongYear("Chelsea's 2nd Birthday =2014".Split(' '), "2014").Item1.Value)
|
if (IProperty.IsWrongYear("Chelsea's 2nd Birthday =2014".Split(' '), "2014").Item1.Value)
|
||||||
throw new Exception("Chelsea");
|
throw new Exception("Chelsea");
|
||||||
#nullable restore
|
#nullable restore
|
||||||
if (Property.Models.Stateless.IPath.GetDirectoryNames(@"C:\Tmp")[0] != @"C:\")
|
if (IPath.GetDirectoryNames(@"C:\Tmp")[0] != @"C:\")
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (Property.Models.Stateless.IPath.GetDirectoryNames(@"C:\Tmp")[1] != "Tmp")
|
if (IPath.GetDirectoryNames(@"C:\Tmp")[1] != "Tmp")
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (Property.Models.Stateless.IPath.GetDirectoryNames(@"C:\Tmp\mike.txt")[1] != "Tmp")
|
if (IPath.GetDirectoryNames(@"C:\Tmp\mike.txt")[1] != "Tmp")
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (Property.Models.Stateless.IPath.GetDirectoryNames(@"C:\Tmp\a.txt")[1] != "Tmp")
|
if (IPath.GetDirectoryNames(@"C:\Tmp\a.txt")[1] != "Tmp")
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (Property.Models.Stateless.IPath.GetDirectoryNames(@"C:\Tmp\Mike\a.txt")[2] != "Mike")
|
if (IPath.GetDirectoryNames(@"C:\Tmp\Mike\a.txt")[2] != "Mike")
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (Property.Models.Stateless.IPath.GetDirectoryNames(@"I:\Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - II\=2010.2 Summer\Dsc_8558.jpg")[0] != @"I:\")
|
if (IPath.GetDirectoryNames(@"I:\Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - II\=2010.2 Summer\Dsc_8558.jpg")[0] != @"I:\")
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (Property.Models.Stateless.IPath.GetDirectoryNames(@"I:\Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - II\=2010.2 Summer\Dsc_8558.jpg")[1] != @"Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - II")
|
if (IPath.GetDirectoryNames(@"I:\Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - II\=2010.2 Summer\Dsc_8558.jpg")[1] != @"Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - II")
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (Property.Models.Stateless.IPath.GetDirectoryNames(@"I:\Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - II\=2010.2 Summer\Dsc_8558.jpg")[2] != @"=2010.2 Summer")
|
if (IPath.GetDirectoryNames(@"I:\Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - II\=2010.2 Summer\Dsc_8558.jpg")[2] != @"=2010.2 Summer")
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (Property.Models.Stateless.IPath.GetDirectoryNames(@"I:\Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - II\=2010.2 Summer")[2] != @"=2010.2 Summer")
|
if (IPath.GetDirectoryNames(@"I:\Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - II\=2010.2 Summer")[2] != @"=2010.2 Summer")
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
Shared.Models.Console console = new();
|
Shared.Models.Console console = new();
|
||||||
NotCopyCopy _ = new(args, isEnvironment, configurationRoot, appSettings, workingDirectory, silentIndex > -1, console);
|
NotCopyCopy _ = new(args, isEnvironment, configurationRoot, appSettings, workingDirectory, silentIndex > -1, console);
|
||||||
|
@ -50,10 +50,10 @@
|
|||||||
"WorkingDirectoryName": "PharesApps",
|
"WorkingDirectoryName": "PharesApps",
|
||||||
"Windows": {
|
"Windows": {
|
||||||
"Configuration": {
|
"Configuration": {
|
||||||
"DateGroup": "2022-08-14",
|
"DateGroup": "2022-08-22",
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||||
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
||||||
"PopulatePropertyId": false,
|
"PopulatePropertyId": false,
|
||||||
"PropertiesChangedForProperty": false,
|
"PropertiesChangedForProperty": false,
|
||||||
|
@ -3,7 +3,6 @@ using Phares.Shared;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using View_by_Distance.PrepareForOld.Models;
|
using View_by_Distance.PrepareForOld.Models;
|
||||||
using View_by_Distance.Property.Models;
|
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
using View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
namespace View_by_Distance.PrepareForOld;
|
namespace View_by_Distance.PrepareForOld;
|
||||||
@ -15,10 +14,10 @@ public class PrepareForOld
|
|||||||
private readonly AppSettings _AppSettings;
|
private readonly AppSettings _AppSettings;
|
||||||
private readonly List<string> _Exceptions;
|
private readonly List<string> _Exceptions;
|
||||||
private readonly IsEnvironment _IsEnvironment;
|
private readonly IsEnvironment _IsEnvironment;
|
||||||
private readonly Models.Configuration _Configuration;
|
private readonly Configuration _Configuration;
|
||||||
private readonly List<KeyValuePair<string, string>> _FileKeyValuePairs;
|
private readonly List<KeyValuePair<string, string>> _FileKeyValuePairs;
|
||||||
private readonly List<(string Find, string Replace)> _SpellingFindReplace;
|
private readonly List<(string Find, string Replace)> _SpellingFindReplace;
|
||||||
private readonly Dictionary<string, List<Tuple<string, A_Property>>> _FilePropertiesKeyValuePairs;
|
private readonly Dictionary<string, List<Tuple<string, Shared.Models.Property>>> _FilePropertiesKeyValuePairs;
|
||||||
|
|
||||||
public PrepareForOld(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
public PrepareForOld(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
||||||
{
|
{
|
||||||
@ -34,10 +33,10 @@ public class PrepareForOld
|
|||||||
_Exceptions = new List<string>();
|
_Exceptions = new List<string>();
|
||||||
_Log = Serilog.Log.ForContext<PrepareForOld>();
|
_Log = Serilog.Log.ForContext<PrepareForOld>();
|
||||||
_FileKeyValuePairs = new List<KeyValuePair<string, string>>();
|
_FileKeyValuePairs = new List<KeyValuePair<string, string>>();
|
||||||
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, A_Property>>>();
|
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, Shared.Models.Property>>>();
|
||||||
Property.Models.Configuration propertyConfiguration = Property.Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory);
|
Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
|
||||||
Property.Models.Configuration.Verify(propertyConfiguration);
|
Property.Models.Configuration.Verify(propertyConfiguration);
|
||||||
Models.Configuration configuration = Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory, propertyConfiguration);
|
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 NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions));
|
throw new NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions));
|
||||||
@ -53,7 +52,7 @@ public class PrepareForOld
|
|||||||
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);
|
||||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A_Property), "{}");
|
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(Property.Models.A_Property), "{}");
|
||||||
if (!Directory.Exists(aPropertySingletonDirectory))
|
if (!Directory.Exists(aPropertySingletonDirectory))
|
||||||
throw new Exception(aPropertySingletonDirectory);
|
throw new Exception(aPropertySingletonDirectory);
|
||||||
ConsoleKey? consoleKey = null;
|
ConsoleKey? consoleKey = null;
|
||||||
@ -104,7 +103,7 @@ public class PrepareForOld
|
|||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Verify(Models.Configuration configuration)
|
private static void Verify(Configuration configuration)
|
||||||
{
|
{
|
||||||
if (configuration.Spelling is null || !configuration.Spelling.Any())
|
if (configuration.Spelling is null || !configuration.Spelling.Any())
|
||||||
throw new NullReferenceException(nameof(configuration.Spelling));
|
throw new NullReferenceException(nameof(configuration.Spelling));
|
||||||
@ -157,7 +156,7 @@ public class PrepareForOld
|
|||||||
indexInfoFiles.AddRange(Directory.GetFiles(infoDirectoryExtra, "IndexInfo.json", SearchOption.AllDirectories));
|
indexInfoFiles.AddRange(Directory.GetFiles(infoDirectoryExtra, "IndexInfo.json", SearchOption.AllDirectories));
|
||||||
foreach (Models.SaveTabSeparatedValues.ImageExifInfo exifInfo in exifCollection)
|
foreach (Models.SaveTabSeparatedValues.ImageExifInfo exifInfo in exifCollection)
|
||||||
{
|
{
|
||||||
dateTimes = Property.Models.Stateless.A_Property.GetDateTimes(exifInfo.CreationTime, exifInfo.LastWriteTime, exifInfo.DateTime, exifInfo.DateTimeDigitized, exifInfo.DateTimeOriginal, exifInfo.GPSDateStamp);
|
dateTimes = Shared.Models.Stateless.Methods.IProperty.GetDateTimes(exifInfo.CreationTime, exifInfo.LastWriteTime, exifInfo.DateTime, exifInfo.DateTimeDigitized, exifInfo.DateTimeOriginal, exifInfo.GPSDateStamp);
|
||||||
if (!checkDistinct && keyValuePairs.ContainsKey(exifInfo.Index))
|
if (!checkDistinct && keyValuePairs.ContainsKey(exifInfo.Index))
|
||||||
continue;
|
continue;
|
||||||
keyValuePairs.Add(exifInfo.Index, dateTimes.Min().Ticks);
|
keyValuePairs.Add(exifInfo.Index, dateTimes.Min().Ticks);
|
||||||
@ -252,7 +251,7 @@ public class PrepareForOld
|
|||||||
{
|
{
|
||||||
long ticks = DateTime.Now.Ticks;
|
long ticks = DateTime.Now.Ticks;
|
||||||
string[] lines = (from l in propertyCompareCollection select l.GetSelect()).ToArray();
|
string[] lines = (from l in propertyCompareCollection select l.GetSelect()).ToArray();
|
||||||
string aPropertyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "[{}]");
|
string aPropertyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "[{}]");
|
||||||
File.WriteAllLines(Path.Join(aPropertyCollectionDirectory, $". . . Ids - {ticks}.txt"), lines);
|
File.WriteAllLines(Path.Join(aPropertyCollectionDirectory, $". . . Ids - {ticks}.txt"), lines);
|
||||||
string json = JsonSerializer.Serialize(propertyCompareCollection, new JsonSerializerOptions { WriteIndented = true });
|
string json = JsonSerializer.Serialize(propertyCompareCollection, new JsonSerializerOptions { WriteIndented = true });
|
||||||
File.WriteAllText(Path.Join(aPropertyCollectionDirectory, $". . . Ids - {ticks}.nosj"), json);
|
File.WriteAllText(Path.Join(aPropertyCollectionDirectory, $". . . Ids - {ticks}.nosj"), json);
|
||||||
@ -611,7 +610,7 @@ public class PrepareForOld
|
|||||||
{
|
{
|
||||||
long ticks = DateTime.Now.Ticks;
|
long ticks = DateTime.Now.Ticks;
|
||||||
string[] lines = (from l in propertyCompareCollection select l.GetSelect()).ToArray();
|
string[] lines = (from l in propertyCompareCollection select l.GetSelect()).ToArray();
|
||||||
string aPropertyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "[{}]");
|
string aPropertyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "[{}]");
|
||||||
File.WriteAllLines(Path.Join(aPropertyCollectionDirectory, $". . . Ids - {ticks}.txt"), lines);
|
File.WriteAllLines(Path.Join(aPropertyCollectionDirectory, $". . . Ids - {ticks}.txt"), lines);
|
||||||
string json = JsonSerializer.Serialize(propertyCompareCollection, new JsonSerializerOptions { WriteIndented = true });
|
string json = JsonSerializer.Serialize(propertyCompareCollection, new JsonSerializerOptions { WriteIndented = true });
|
||||||
File.WriteAllText(Path.Join(aPropertyCollectionDirectory, $". . . Ids - {ticks}.nosj"), json);
|
File.WriteAllText(Path.Join(aPropertyCollectionDirectory, $". . . Ids - {ticks}.nosj"), json);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Phares.View.by.Distance.PrepareForOld</PackageId>
|
<PackageId>Phares.View.by.Distance.PrepareForOld</PackageId>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<Version>5.0.402.104</Version>
|
<Version>6.0.100.1</Version>
|
||||||
<Authors>Mike Phares</Authors>
|
<Authors>Mike Phares</Authors>
|
||||||
<Company>Phares</Company>
|
<Company>Phares</Company>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
@ -50,11 +50,11 @@
|
|||||||
"WorkingDirectoryName": "PharesApps",
|
"WorkingDirectoryName": "PharesApps",
|
||||||
"Windows": {
|
"Windows": {
|
||||||
"Configuration": {
|
"Configuration": {
|
||||||
"DateGroup": "2022-08-14",
|
"DateGroup": "2022-08-22",
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||||
"KeepFullPath": false,
|
"KeepFullPath": false,
|
||||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||||
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
||||||
"PopulatePropertyId": false,
|
"PopulatePropertyId": false,
|
||||||
"PropertiesChangedForProperty": false,
|
"PropertiesChangedForProperty": false,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using View_by_Distance.Property.Models;
|
|
||||||
|
|
||||||
namespace View_by_Distance.PropertyCompare.Models;
|
namespace View_by_Distance.PropertyCompare.Models;
|
||||||
|
|
||||||
@ -11,7 +10,7 @@ public partial class PropertyCompare
|
|||||||
protected readonly bool _IsArg;
|
protected readonly bool _IsArg;
|
||||||
protected DateTime _MinimumDateTime;
|
protected DateTime _MinimumDateTime;
|
||||||
protected readonly List<long> _Numbers;
|
protected readonly List<long> _Numbers;
|
||||||
protected A_Property? _Property;
|
protected Shared.Models.Property? _Property;
|
||||||
protected string _RegexResult;
|
protected string _RegexResult;
|
||||||
protected string _RelativeDirectory;
|
protected string _RelativeDirectory;
|
||||||
protected readonly List<string> _Strings;
|
protected readonly List<string> _Strings;
|
||||||
@ -21,12 +20,12 @@ public partial class PropertyCompare
|
|||||||
public bool IsArg => _IsArg;
|
public bool IsArg => _IsArg;
|
||||||
public DateTime MinimumDateTime => _MinimumDateTime;
|
public DateTime MinimumDateTime => _MinimumDateTime;
|
||||||
public List<long> Numbers => _Numbers;
|
public List<long> Numbers => _Numbers;
|
||||||
public A_Property? Property => _Property;
|
public Shared.Models.Property? Property => _Property;
|
||||||
public string RegexResult => _RegexResult;
|
public string RegexResult => _RegexResult;
|
||||||
public string RelativeDirectory => _RelativeDirectory;
|
public string RelativeDirectory => _RelativeDirectory;
|
||||||
public List<string> Strings => _Strings;
|
public List<string> Strings => _Strings;
|
||||||
|
|
||||||
public PropertyCompare(string extension, string fileNameWithoutExtension, bool isArg, DateTime minimumDateTime, List<long> numbers, A_Property property, string regexResult, string relativeDirectory, List<string> strings)
|
public PropertyCompare(string extension, string fileNameWithoutExtension, bool isArg, DateTime minimumDateTime, List<long> numbers, Shared.Models.Property property, string regexResult, string relativeDirectory, List<string> strings)
|
||||||
{
|
{
|
||||||
_IsArg = isArg;
|
_IsArg = isArg;
|
||||||
_Numbers = numbers;
|
_Numbers = numbers;
|
||||||
@ -49,7 +48,7 @@ public partial class PropertyCompare
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
public string GetSelect() => string.Concat(_RelativeDirectory, _FileNameWithoutExtension, _Extension, '\t', _Property.CreationTime.Ticks, '\t', View_by_Distance.Property.Models.Stateless.A_Property.GetDateTime(_Property).ToString("yyyy-MM-dd_HH-mm-ss"), '\t', _Property.Id, '\t', _Property.FileSize, '\t', _Property.Width, '\t', _Property.Height);
|
public string GetSelect() => string.Concat(_RelativeDirectory, _FileNameWithoutExtension, _Extension, '\t', _Property.CreationTime.Ticks, '\t', Shared.Models.Stateless.Methods.IProperty.GetDateTime(_Property).ToString("yyyy-MM-dd_HH-mm-ss"), '\t', _Property.Id, '\t', _Property.FileSize, '\t', _Property.Width, '\t', _Property.Height);
|
||||||
|
|
||||||
#nullable restore
|
#nullable restore
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
using View_by_Distance.Property.Models;
|
|
||||||
|
|
||||||
namespace View_by_Distance.PropertyCompare.Models;
|
namespace View_by_Distance.PropertyCompare.Models;
|
||||||
|
|
||||||
internal class PropertyCompareItem
|
internal class PropertyCompareItem
|
||||||
@ -9,16 +7,16 @@ internal class PropertyCompareItem
|
|||||||
protected readonly bool _IsArg;
|
protected readonly bool _IsArg;
|
||||||
protected readonly string _JsonFileNameWithoutExtension;
|
protected readonly string _JsonFileNameWithoutExtension;
|
||||||
protected readonly long[] _Numbers;
|
protected readonly long[] _Numbers;
|
||||||
protected readonly A_Property _Property;
|
protected readonly Shared.Models.Property _Property;
|
||||||
protected readonly string[] _Strings;
|
protected readonly string[] _Strings;
|
||||||
public string ImageFileName => _ImageFileName;
|
public string ImageFileName => _ImageFileName;
|
||||||
public bool IsArg => _IsArg;
|
public bool IsArg => _IsArg;
|
||||||
public string JsonFileNameWithoutExtension => _JsonFileNameWithoutExtension;
|
public string JsonFileNameWithoutExtension => _JsonFileNameWithoutExtension;
|
||||||
public long[] Numbers => _Numbers;
|
public long[] Numbers => _Numbers;
|
||||||
public A_Property Property => _Property;
|
public Shared.Models.Property Property => _Property;
|
||||||
public string[] Strings => _Strings;
|
public string[] Strings => _Strings;
|
||||||
|
|
||||||
public PropertyCompareItem(string imageFileName, bool isArg, string jsonFileNameWithoutExtension, long[] numbers, A_Property property, string[] strings)
|
public PropertyCompareItem(string imageFileName, bool isArg, string jsonFileNameWithoutExtension, long[] numbers, Shared.Models.Property property, string[] strings)
|
||||||
{
|
{
|
||||||
_ImageFileName = imageFileName;
|
_ImageFileName = imageFileName;
|
||||||
_IsArg = isArg;
|
_IsArg = isArg;
|
||||||
|
@ -19,7 +19,7 @@ public class PropertyCompareLogic
|
|||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
_DiffRootDirectory = diffRootDirectory;
|
_DiffRootDirectory = diffRootDirectory;
|
||||||
_SpellingFindReplace = spellingFindReplace;
|
_SpellingFindReplace = spellingFindReplace;
|
||||||
_Log = Serilog.Log.ForContext<A_Property>();
|
_Log = Serilog.Log.ForContext<PropertyCompareLogic>();
|
||||||
_MaxDegreeOfParallelism = Math.Abs(maxDegreeOfParallelism);
|
_MaxDegreeOfParallelism = Math.Abs(maxDegreeOfParallelism);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,10 +175,10 @@ public class PropertyCompareLogic
|
|||||||
else
|
else
|
||||||
extension = Path.GetExtension(files[index]);
|
extension = Path.GetExtension(files[index]);
|
||||||
string json = File.ReadAllText(jsonFile);
|
string json = File.ReadAllText(jsonFile);
|
||||||
A_Property? property = JsonSerializer.Deserialize<A_Property>(json);
|
Shared.Models.Property? property = JsonSerializer.Deserialize<Shared.Models.Property>(json);
|
||||||
if (property?.Id is null)
|
if (property?.Id is null)
|
||||||
throw new NullReferenceException(nameof(property));
|
throw new NullReferenceException(nameof(property));
|
||||||
DateTime minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(property);
|
DateTime minimumDateTime = Shared.Models.Stateless.Methods.IProperty.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())
|
||||||
{
|
{
|
||||||
@ -200,17 +200,17 @@ public class PropertyCompareLogic
|
|||||||
2 => property.Id.Value,
|
2 => property.Id.Value,
|
||||||
3 => property.Id.Value,
|
3 => property.Id.Value,
|
||||||
4 => property.Id.Value,
|
4 => property.Id.Value,
|
||||||
5 => Property.Models.Stateless.A_Property.GetDateTime(property).Ticks,
|
5 => Shared.Models.Stateless.Methods.IProperty.GetDateTime(property).Ticks,
|
||||||
6 => property.CreationTime.Ticks,
|
6 => property.CreationTime.Ticks,
|
||||||
7 => property.FileSize,
|
7 => property.FileSize,
|
||||||
8 => Property.Models.Stateless.A_Property.GetDateTime(property).Ticks,
|
8 => Shared.Models.Stateless.Methods.IProperty.GetDateTime(property).Ticks,
|
||||||
9 => property.FileSize,
|
9 => property.FileSize,
|
||||||
_ => throw new Exception()
|
_ => throw new Exception()
|
||||||
};
|
};
|
||||||
s = i switch
|
s = i switch
|
||||||
{
|
{
|
||||||
0 => $"{jsonFileNameWithoutExtension.ToLower()}",
|
0 => $"{jsonFileNameWithoutExtension.ToLower()}",
|
||||||
1 => $"{property.FileSize}{Property.Models.Stateless.A_Property.GetDateTime(property).Ticks}",
|
1 => $"{property.FileSize}{Shared.Models.Stateless.Methods.IProperty.GetDateTime(property).Ticks}",
|
||||||
2 => $"{property.FileSize}{property.CreationTime:yyyy-MM-dd_HH-mm-ss}",
|
2 => $"{property.FileSize}{property.CreationTime:yyyy-MM-dd_HH-mm-ss}",
|
||||||
3 => $"{property.FileSize}{property.Width}{property.Height}",
|
3 => $"{property.FileSize}{property.Width}{property.Height}",
|
||||||
4 => string.Empty,
|
4 => string.Empty,
|
||||||
@ -313,7 +313,7 @@ public class PropertyCompareLogic
|
|||||||
}
|
}
|
||||||
if (exceptionCount != 0)
|
if (exceptionCount != 0)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
return (from l in results orderby Property.Models.Stateless.A_Property.GetMinimumDateTime(l.Property).Ticks select l).ToArray();
|
return (from l in results orderby Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(l.Property).Ticks select l).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MoveFiles(string[] directories, List<string[]> fromThenToCollection)
|
private void MoveFiles(string[] directories, List<string[]> fromThenToCollection)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Phares.View.by.Distance.Property.Compare</PackageId>
|
<PackageId>Phares.View.by.Distance.Property.Compare</PackageId>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<Version>5.0.402.104</Version>
|
<Version>6.0.100.1</Version>
|
||||||
<Authors>Mike Phares</Authors>
|
<Authors>Mike Phares</Authors>
|
||||||
<Company>Phares</Company>
|
<Company>Phares</Company>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
@ -1,84 +1,62 @@
|
|||||||
|
using ShellProgressBar;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using View_by_Distance.Property.Models.Stateless;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
using View_by_Distance.Shared.Models;
|
||||||
|
using View_by_Distance.Shared.Models.Properties;
|
||||||
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
|
|
||||||
namespace View_by_Distance.Property.Models;
|
namespace View_by_Distance.Property.Models;
|
||||||
|
|
||||||
/// <summary>
|
public class A_Property
|
||||||
// A_Property
|
|
||||||
/// </summary>
|
|
||||||
public class A_Property : Shared.Models.Properties.IProperty, IProperty
|
|
||||||
{
|
{
|
||||||
|
|
||||||
protected DateTime _CreationTime;
|
protected readonly List<string> _ExceptionsDirectories;
|
||||||
protected DateTime? _DateTime;
|
protected readonly Dictionary<int, int[]> _KeyValuePairs;
|
||||||
protected DateTime? _DateTimeDigitized;
|
protected readonly Dictionary<int, int[]> _IndicesFromNew;
|
||||||
protected DateTime? _DateTimeOriginal;
|
|
||||||
protected long _FileSize;
|
|
||||||
protected DateTime? _GPSDateStamp;
|
|
||||||
protected int? _Height;
|
|
||||||
protected int? _Id;
|
|
||||||
protected int[] _Indices;
|
|
||||||
protected DateTime _LastWriteTime;
|
|
||||||
protected string _Make;
|
|
||||||
protected string _Model;
|
|
||||||
protected string _Orientation;
|
|
||||||
protected int? _Width;
|
|
||||||
public DateTime CreationTime => _CreationTime;
|
|
||||||
public DateTime? DateTime => _DateTime;
|
|
||||||
public DateTime? DateTimeDigitized => _DateTimeDigitized;
|
|
||||||
public DateTime? DateTimeOriginal => _DateTimeOriginal;
|
|
||||||
public long FileSize => _FileSize;
|
|
||||||
public DateTime? GPSDateStamp => _GPSDateStamp;
|
|
||||||
public int? Height => _Height;
|
|
||||||
public int? Id => _Id;
|
|
||||||
public int[] Indices => _Indices;
|
|
||||||
public DateTime LastWriteTime => _LastWriteTime;
|
|
||||||
public string Make => _Make;
|
|
||||||
public string Model => _Model;
|
|
||||||
public string Orientation => _Orientation;
|
|
||||||
public int? Width => _Width;
|
|
||||||
|
|
||||||
[JsonConstructor]
|
public bool Reverse { get; }
|
||||||
public A_Property(DateTime creationTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeOriginal, long fileSize, DateTime? gpsDateStamp, int? height, int? id, int[] indices, DateTime lastWriteTime, string make, string model, string orientation, int? width)
|
public List<string> AngleBracketCollection { get; }
|
||||||
|
public List<string> ExceptionsDirectories => _ExceptionsDirectories;
|
||||||
|
|
||||||
|
private readonly Model? _Model;
|
||||||
|
private readonly Serilog.ILogger? _Log;
|
||||||
|
private readonly string _OutputExtension;
|
||||||
|
private readonly string[] _VerifyToSeason;
|
||||||
|
private readonly int _MaxDegreeOfParallelism;
|
||||||
|
private readonly ASCIIEncoding _ASCIIEncoding;
|
||||||
|
private readonly Configuration _Configuration;
|
||||||
|
private readonly PredictorModel? _PredictorModel;
|
||||||
|
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||||
|
|
||||||
|
public A_Property(int maxDegreeOfParallelism, Configuration configuration, string outputExtension, bool reverse, Model? model, PredictorModel? predictorModel, Dictionary<int, int[]> indicesFromNew, Dictionary<int, int[]> keyValuePairs)
|
||||||
{
|
{
|
||||||
_CreationTime = creationTime;
|
|
||||||
_DateTime = dateTime;
|
|
||||||
_DateTimeDigitized = dateTimeDigitized;
|
|
||||||
_DateTimeOriginal = dateTimeOriginal;
|
|
||||||
_FileSize = fileSize;
|
|
||||||
_GPSDateStamp = gpsDateStamp;
|
|
||||||
_Height = height;
|
|
||||||
_Id = id;
|
|
||||||
_Indices = indices;
|
|
||||||
_LastWriteTime = lastWriteTime;
|
|
||||||
_Make = make;
|
|
||||||
_Model = model;
|
_Model = model;
|
||||||
_Orientation = orientation;
|
Reverse = reverse;
|
||||||
_Width = width;
|
_KeyValuePairs = keyValuePairs;
|
||||||
|
_Configuration = configuration;
|
||||||
|
_ExceptionsDirectories = new();
|
||||||
|
_IndicesFromNew = indicesFromNew;
|
||||||
|
_PredictorModel = predictorModel;
|
||||||
|
_OutputExtension = outputExtension;
|
||||||
|
_ASCIIEncoding = new ASCIIEncoding();
|
||||||
|
AngleBracketCollection = new List<string>();
|
||||||
|
_Log = Serilog.Log.ForContext<A_Property>();
|
||||||
|
_MaxDegreeOfParallelism = maxDegreeOfParallelism;
|
||||||
|
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||||
|
if (configuration.VerifyToSeason is null || !configuration.VerifyToSeason.Any())
|
||||||
|
throw new Exception();
|
||||||
|
_VerifyToSeason = configuration.VerifyToSeason.Select(l => Path.Combine(configuration.RootDirectory, l)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
#nullable disable
|
public A_Property(int maxDegreeOfParallelism, Configuration configuration, string outputExtension, bool reverse, Model? model, PredictorModel? predictorModel) :
|
||||||
|
this(maxDegreeOfParallelism, configuration, outputExtension, reverse, model, predictorModel, new(), new())
|
||||||
public A_Property()
|
{ }
|
||||||
{
|
|
||||||
_CreationTime = System.DateTime.MinValue;
|
|
||||||
_DateTime = null;
|
|
||||||
_DateTimeDigitized = null;
|
|
||||||
_DateTimeOriginal = null;
|
|
||||||
_FileSize = long.MinValue;
|
|
||||||
_GPSDateStamp = null;
|
|
||||||
_Height = null;
|
|
||||||
_Id = null;
|
|
||||||
_Indices = Array.Empty<int>();
|
|
||||||
_LastWriteTime = System.DateTime.MinValue;
|
|
||||||
_Make = string.Empty;
|
|
||||||
_Model = string.Empty;
|
|
||||||
_Orientation = string.Empty;
|
|
||||||
_Width = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -86,38 +64,658 @@ public class A_Property : Shared.Models.Properties.IProperty, IProperty
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DateTime> GetDateTimes() => Stateless.A_Property.GetDateTimes(_CreationTime, _LastWriteTime, _DateTime, _DateTimeDigitized, _DateTimeOriginal, _GPSDateStamp);
|
private long LogDelta(long ticks, string? methodName)
|
||||||
|
|
||||||
public (bool?, string[]) IsWrongYear(string filteredSourceDirectoryFile, DateTime? minimumDateTime)
|
|
||||||
{
|
{
|
||||||
string[] results = Array.Empty<string>();
|
long result;
|
||||||
bool? result = null;
|
if (_Log is null)
|
||||||
string year;
|
throw new NullReferenceException(nameof(_Log));
|
||||||
string directoryName;
|
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
|
||||||
string[] directorySegments;
|
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
|
||||||
string? check = Path.GetFullPath(filteredSourceDirectoryFile);
|
result = DateTime.Now.Ticks;
|
||||||
string? pathRoot = Path.GetPathRoot(filteredSourceDirectoryFile);
|
return result;
|
||||||
if (string.IsNullOrEmpty(pathRoot))
|
}
|
||||||
throw new Exception();
|
|
||||||
if (minimumDateTime.HasValue)
|
public static List<DateTime> GetMetadataDateTimesByPattern(string dateTimeFormat, string filteredSourceDirectoryFile)
|
||||||
year = minimumDateTime.Value.ToString("yyyy");
|
{
|
||||||
|
List<DateTime> results = new();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DateTime checkDateTime;
|
||||||
|
DateTime kristy = new(1976, 3, 8);
|
||||||
|
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(filteredSourceDirectoryFile);
|
||||||
|
foreach (MetadataExtractor.Directory directory in directories)
|
||||||
|
{
|
||||||
|
foreach (MetadataExtractor.Tag tag in directory.Tags)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(tag.Description) || tag.Description.Length != dateTimeFormat.Length)
|
||||||
|
continue;
|
||||||
|
if (!DateTime.TryParseExact(tag.Description, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||||
|
continue;
|
||||||
|
if (checkDateTime < kristy)
|
||||||
|
continue;
|
||||||
|
results.Add(checkDateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception) { }
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<DateTime> GetMetadataDateTimesByPattern(string dateTimeFormat, IFileHolder filteredSourceDirectoryFileHolder)
|
||||||
|
{
|
||||||
|
List<DateTime> results = GetMetadataDateTimesByPattern(dateTimeFormat, filteredSourceDirectoryFileHolder.FullName);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1416
|
||||||
|
|
||||||
|
private Shared.Models.Property GetImageProperty(IFileHolder filteredSourceDirectoryFileHolder, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List<int> indices)
|
||||||
|
{
|
||||||
|
Shared.Models.Property result;
|
||||||
|
if (_Log is null)
|
||||||
|
throw new NullReferenceException(nameof(_Log));
|
||||||
|
long ticks;
|
||||||
|
byte[] bytes;
|
||||||
|
string value;
|
||||||
|
long fileLength;
|
||||||
|
int encodingHash;
|
||||||
|
int? width = null;
|
||||||
|
int? height = null;
|
||||||
|
string dateTimeFormat;
|
||||||
|
DateTime checkDateTime;
|
||||||
|
DateTime? dateTime = null;
|
||||||
|
PropertyItem? propertyItem;
|
||||||
|
string make = string.Empty;
|
||||||
|
string model = string.Empty;
|
||||||
|
DateTime? gpsDateStamp = null;
|
||||||
|
DateTime? dateTimeOriginal = null;
|
||||||
|
string orientation = string.Empty;
|
||||||
|
DateTime? dateTimeDigitized = null;
|
||||||
|
if (!isValidImageFormatExtension && isValidMetadataExtensions)
|
||||||
|
{
|
||||||
|
dateTimeFormat = "ddd MMM dd HH:mm:ss yyyy";
|
||||||
|
List<DateTime> dateTimes = GetMetadataDateTimesByPattern(dateTimeFormat, filteredSourceDirectoryFileHolder);
|
||||||
|
if (dateTimes.Any())
|
||||||
|
dateTimeOriginal = dateTimes.Min();
|
||||||
|
}
|
||||||
|
else if (!isIgnoreExtension && isValidImageFormatExtension)
|
||||||
|
{
|
||||||
|
if (populateId && (id is null || !indices.Any()) && !_IndicesFromNew.Any() && !_KeyValuePairs.Any())
|
||||||
|
throw new Exception("In order to keep six character indices at least one need to have an item!");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using Image image = Image.FromFile(filteredSourceDirectoryFileHolder.FullName);
|
||||||
|
if (populateId && (id is null || !indices.Any()))
|
||||||
|
{
|
||||||
|
using Bitmap bitmap = new(image);
|
||||||
|
string angleBracket = AngleBracketCollection[0];
|
||||||
|
Rectangle rectangle = new(0, 0, image.Width, image.Height);
|
||||||
|
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||||
|
IntPtr intPtr = bitmapData.Scan0;
|
||||||
|
int length = bitmapData.Stride * bitmap.Height;
|
||||||
|
bytes = new byte[length];
|
||||||
|
Marshal.Copy(intPtr, bytes, 0, length);
|
||||||
|
bitmap.UnlockBits(bitmapData);
|
||||||
|
if (id is null)
|
||||||
|
{
|
||||||
|
ticks = DateTime.Now.Ticks;
|
||||||
|
id = Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode(bytes);
|
||||||
|
if (_MaxDegreeOfParallelism < 2)
|
||||||
|
ticks = LogDelta(ticks, nameof(Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode));
|
||||||
|
}
|
||||||
|
if (_Configuration.WriteBitmapDataBytes)
|
||||||
|
{
|
||||||
|
FileInfo contentFileInfo = new(Path.Combine(angleBracket.Replace("<>", "()"), filteredSourceDirectoryFileHolder.Name));
|
||||||
|
File.WriteAllBytes(Path.ChangeExtension(contentFileInfo.FullName, string.Empty), bytes);
|
||||||
|
}
|
||||||
|
if (_IndicesFromNew.ContainsKey(id.Value) && _IndicesFromNew[id.Value].Any())
|
||||||
|
indices.AddRange(_IndicesFromNew[id.Value]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ticks = DateTime.Now.Ticks;
|
||||||
|
string encoding = Encoding.Default.GetString(bytes);
|
||||||
|
if (_MaxDegreeOfParallelism < 2)
|
||||||
|
ticks = LogDelta(ticks, nameof(Encoding.Default.GetString));
|
||||||
|
encodingHash = Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode(encoding);
|
||||||
|
if (_MaxDegreeOfParallelism < 2)
|
||||||
|
ticks = LogDelta(ticks, nameof(Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode));
|
||||||
|
if (!_KeyValuePairs.ContainsKey(encodingHash))
|
||||||
|
indices.Add(encodingHash);
|
||||||
|
else
|
||||||
|
indices.AddRange(_KeyValuePairs[encodingHash]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
width = image.Width;
|
||||||
|
height = image.Height;
|
||||||
|
dateTimeFormat = Shared.Models.Stateless.Methods.IProperty.DateTimeFormat();
|
||||||
|
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTime))
|
||||||
|
{
|
||||||
|
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime);
|
||||||
|
if (propertyItem?.Value is not null)
|
||||||
|
{
|
||||||
|
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||||
|
if (value.Length > dateTimeFormat.Length)
|
||||||
|
value = value[..dateTimeFormat.Length];
|
||||||
|
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||||
|
dateTime = checkDateTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeDigitized))
|
||||||
|
{
|
||||||
|
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized);
|
||||||
|
if (propertyItem?.Value is not null)
|
||||||
|
{
|
||||||
|
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||||
|
if (value.Length > dateTimeFormat.Length)
|
||||||
|
value = value[..dateTimeFormat.Length];
|
||||||
|
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||||
|
dateTimeDigitized = checkDateTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeOriginal))
|
||||||
|
{
|
||||||
|
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal);
|
||||||
|
if (propertyItem?.Value is not null)
|
||||||
|
{
|
||||||
|
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||||
|
if (value.Length > dateTimeFormat.Length)
|
||||||
|
value = value[..dateTimeFormat.Length];
|
||||||
|
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||||
|
dateTimeOriginal = checkDateTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (image.PropertyIdList.Contains((int)IExif.Tags.GPSDateStamp))
|
||||||
|
{
|
||||||
|
propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp);
|
||||||
|
if (propertyItem?.Value is not null)
|
||||||
|
{
|
||||||
|
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||||
|
if (value.Length > dateTimeFormat.Length)
|
||||||
|
value = value[..dateTimeFormat.Length];
|
||||||
|
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||||
|
gpsDateStamp = checkDateTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (image.PropertyIdList.Contains((int)IExif.Tags.Make))
|
||||||
|
{
|
||||||
|
propertyItem = image.GetPropertyItem((int)IExif.Tags.Make);
|
||||||
|
if (propertyItem?.Value is not null)
|
||||||
|
{
|
||||||
|
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||||
|
make = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (image.PropertyIdList.Contains((int)IExif.Tags.Model))
|
||||||
|
{
|
||||||
|
propertyItem = image.GetPropertyItem((int)IExif.Tags.Model);
|
||||||
|
if (propertyItem?.Value is not null)
|
||||||
|
{
|
||||||
|
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||||
|
model = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (image.PropertyIdList.Contains((int)IExif.Tags.Orientation))
|
||||||
|
{
|
||||||
|
propertyItem = image.GetPropertyItem((int)IExif.Tags.Orientation);
|
||||||
|
if (propertyItem?.Value is not null)
|
||||||
|
{
|
||||||
|
value = BitConverter.ToInt16(propertyItem.Value, 0).ToString();
|
||||||
|
orientation = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
_Log.Info(string.Concat(new StackFrame().GetMethod()?.Name, " <", filteredSourceDirectoryFileHolder.Name, ">"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dateTimeOriginal = null;
|
||||||
|
if (filteredSourceDirectoryFileHolder.Length is null)
|
||||||
|
fileLength = 0;
|
||||||
|
else
|
||||||
|
fileLength = filteredSourceDirectoryFileHolder.Length.Value;
|
||||||
|
result = new(filteredSourceDirectoryFileHolder.CreationTime, dateTime, dateTimeDigitized, dateTimeOriginal, fileLength, gpsDateStamp, height, id, indices.ToArray(), filteredSourceDirectoryFileHolder.LastWriteTime, make, model, orientation, width);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning restore CA1416
|
||||||
|
|
||||||
|
private Shared.Models.Property GetPropertyOfPrivate(Item item, bool firstPass, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension, bool isValidMetadataExtensions)
|
||||||
|
{
|
||||||
|
Shared.Models.Property? result;
|
||||||
|
if (item.ImageFileHolder is null)
|
||||||
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
|
string json;
|
||||||
|
int? id = null;
|
||||||
|
List<int> indices = new();
|
||||||
|
bool hasWrongYearProperty = false;
|
||||||
|
string[] changesFrom = Array.Empty<string>();
|
||||||
|
string angleBracket = AngleBracketCollection[0];
|
||||||
|
bool populateId = !firstPass && _Configuration.PopulatePropertyId;
|
||||||
|
string without = Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}.json");
|
||||||
|
FileInfo fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
|
||||||
|
if (item.ValidImageFormatExtension && File.Exists(without))
|
||||||
|
{
|
||||||
|
File.Move(without, fileInfo.FullName);
|
||||||
|
fileInfo.Refresh();
|
||||||
|
}
|
||||||
|
List<DateTime> dateTimes = (from l in filteredSourceDirectoryFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||||
|
if (!fileInfo.Exists)
|
||||||
|
{
|
||||||
|
if (fileInfo.Directory?.Parent is null)
|
||||||
|
throw new Exception();
|
||||||
|
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
|
||||||
|
if (File.Exists(parentCheck))
|
||||||
|
{
|
||||||
|
File.Move(parentCheck, fileInfo.FullName);
|
||||||
|
fileInfo.Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
||||||
|
{
|
||||||
|
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
||||||
|
fileInfo.Refresh();
|
||||||
|
}
|
||||||
|
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime)
|
||||||
|
{
|
||||||
|
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
||||||
|
fileInfo.Refresh();
|
||||||
|
}
|
||||||
|
if (_Configuration.PropertiesChangedForProperty)
|
||||||
|
result = null;
|
||||||
|
else if (!fileInfo.Exists)
|
||||||
|
result = null;
|
||||||
|
else if (!fileInfo.FullName.EndsWith(".json") && !fileInfo.FullName.EndsWith(".old"))
|
||||||
|
throw new ArgumentException("must be a *.json file");
|
||||||
|
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||||
|
result = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<DateTime> dateTimes = GetDateTimes();
|
json = File.ReadAllText(fileInfo.FullName);
|
||||||
year = dateTimes.Min().ToString("yyyy");
|
try
|
||||||
|
{
|
||||||
|
if (item.ImageFileHolder is null)
|
||||||
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
|
bool check = true;
|
||||||
|
Shared.Models.Property? property = JsonSerializer.Deserialize<Shared.Models.Property>(json);
|
||||||
|
if (!isIgnoreExtension && item.ValidImageFormatExtension && ((populateId && property?.Id is null) || property?.Width is null || property?.Height is null))
|
||||||
|
{
|
||||||
|
check = false;
|
||||||
|
id = property?.Id;
|
||||||
|
if (property is not null && property.Indices.Any())
|
||||||
|
indices = property.Indices.ToList();
|
||||||
|
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||||
|
}
|
||||||
|
if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && property is not null && !property.Indices.Any())
|
||||||
|
{
|
||||||
|
check = false;
|
||||||
|
id = property?.Id;
|
||||||
|
if (property is not null && property.Indices.Any())
|
||||||
|
indices = property.Indices.ToList();
|
||||||
|
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||||
|
}
|
||||||
|
if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && property is not null && property.LastWriteTime != item.ImageFileHolder.LastWriteTime)
|
||||||
|
{
|
||||||
|
check = false;
|
||||||
|
id = null;
|
||||||
|
indices.Clear();
|
||||||
|
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||||
|
}
|
||||||
|
if (!isIgnoreExtension && item.ValidImageFormatExtension && property?.Width is not null && property?.Height is not null && property.Width.Value == property.Height.Value && item.ImageFileHolder.Exists)
|
||||||
|
{
|
||||||
|
check = false;
|
||||||
|
id = property?.Id;
|
||||||
|
if (property is not null && property.Indices.Any())
|
||||||
|
indices = property.Indices.ToList();
|
||||||
|
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||||
|
if (property?.Width is not null && property?.Height is not null && property.Width.Value != property.Height.Value)
|
||||||
|
throw new Exception("Was square!");
|
||||||
|
}
|
||||||
|
// if (filteredSourceDirectoryFileFileInfo.CreationTime != property?.CreationTime || filteredSourceDirectoryFileFileInfo.LastWriteTime != property?.LastWriteTime)
|
||||||
|
// {
|
||||||
|
// check = false;
|
||||||
|
// id = null;
|
||||||
|
// indices.Clear();
|
||||||
|
// property = GetImagePropertyB(filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||||
|
// }
|
||||||
|
if (json.Contains("WrongYear"))
|
||||||
|
{
|
||||||
|
id = property?.Id;
|
||||||
|
hasWrongYearProperty = true;
|
||||||
|
}
|
||||||
|
if (property is null)
|
||||||
|
throw new Exception();
|
||||||
|
if (!check)
|
||||||
|
result = null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = property;
|
||||||
|
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.LastWriteTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
parseExceptions.Add(nameof(A_Property));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < int.MaxValue; i++)
|
if (result is null)
|
||||||
{
|
{
|
||||||
check = Path.GetDirectoryName(check);
|
if (item.ImageFileHolder is null)
|
||||||
if (string.IsNullOrEmpty(check) || check == pathRoot)
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
break;
|
result = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||||
directoryName = Path.GetFileName(check);
|
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
|
||||||
directorySegments = directoryName.Split(' ');
|
if (populateId && Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||||
(result, results) = Stateless.A_Property.IsWrongYear(directorySegments, year);
|
{
|
||||||
if (result.HasValue)
|
if (!_Configuration.ForcePropertyLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
|
||||||
break;
|
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
||||||
|
fileInfo.Refresh();
|
||||||
|
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.CreationTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new(result, results);
|
else if (hasWrongYearProperty)
|
||||||
|
{
|
||||||
|
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
|
||||||
|
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||||
|
{
|
||||||
|
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
||||||
|
fileInfo.Refresh();
|
||||||
|
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.CreationTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool AnyFilesMoved(string sourceDirectory, Item[] filteredItems)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if (_Log is null)
|
||||||
|
throw new NullReferenceException(nameof(_Log));
|
||||||
|
int season;
|
||||||
|
string[] matches;
|
||||||
|
string deleteFile;
|
||||||
|
bool? isWrongYear;
|
||||||
|
string seasonName;
|
||||||
|
DateTime dateTime;
|
||||||
|
string destinationFile;
|
||||||
|
DateTime minimumDateTime;
|
||||||
|
string destinationDirectory;
|
||||||
|
string[] sourceDirectorySegments;
|
||||||
|
DateTime directoryMaximumOfMinimumDateTime = DateTime.MinValue;
|
||||||
|
foreach (Item filteredItem in filteredItems)
|
||||||
|
{
|
||||||
|
if (!filteredItem.ValidImageFormatExtension || filteredItem.Property is null || filteredItem.ImageFileHolder is null)
|
||||||
|
continue;
|
||||||
|
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(filteredItem.Property);
|
||||||
|
if (minimumDateTime > directoryMaximumOfMinimumDateTime)
|
||||||
|
directoryMaximumOfMinimumDateTime = minimumDateTime;
|
||||||
|
if (minimumDateTime != filteredItem.ImageFileHolder.CreationTime)
|
||||||
|
{
|
||||||
|
(isWrongYear, matches) = Shared.Models.Stateless.Methods.IProperty.IsWrongYear(filteredItem.ImageFileHolder.FullName, minimumDateTime);
|
||||||
|
if (isWrongYear is null || !isWrongYear.Value)
|
||||||
|
dateTime = minimumDateTime;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!matches.Any())
|
||||||
|
continue;
|
||||||
|
if (!DateTime.TryParseExact(matches[0], "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{ File.SetCreationTime(filteredItem.ImageFileHolder.FullName, dateTime); }
|
||||||
|
catch (Exception)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
if (!_VerifyToSeason.Contains(sourceDirectory))
|
||||||
|
continue;
|
||||||
|
if (!filteredItem.ImageFileHolder.FullName.Contains("zzz ") && !filteredItem.ImageFileHolder.FullName.Contains("Camera ") && filteredItem.Property.DateTimeOriginal.HasValue)
|
||||||
|
{
|
||||||
|
TimeSpan timeSpan = new(filteredItem.Property.DateTimeOriginal.Value.Ticks - filteredItem.Property.LastWriteTime.Ticks);
|
||||||
|
if (timeSpan.TotalHours > 6)
|
||||||
|
{
|
||||||
|
_Log.Warning($"*** propertyHolder.FileInfo.FullName <{filteredItem.ImageFileHolder.FullName}>");
|
||||||
|
_Log.Warning($"*** DateTimeOriginal <{filteredItem.Property.DateTimeOriginal.Value}>");
|
||||||
|
_Log.Warning($"*** LastWriteTime <{filteredItem.Property.LastWriteTime}>");
|
||||||
|
_Log.Warning($"*** TotalHours <{timeSpan.TotalHours}>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceDirectorySegments = Path.GetFileName(sourceDirectory).Split(' ');
|
||||||
|
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(minimumDateTime.DayOfYear);
|
||||||
|
if (sourceDirectorySegments[0] == "zzz")
|
||||||
|
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"zzz ={minimumDateTime:yyyy}.{season} {seasonName} {string.Join(' ', sourceDirectorySegments.Skip(3))}");
|
||||||
|
else if (sourceDirectorySegments.Length > 2)
|
||||||
|
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName} {string.Join(' ', sourceDirectorySegments.Skip(2))}");
|
||||||
|
else
|
||||||
|
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName}");
|
||||||
|
if (destinationDirectory == sourceDirectory)
|
||||||
|
continue;
|
||||||
|
lock (filteredItem)
|
||||||
|
filteredItem.SetMoved(true);
|
||||||
|
if (!result)
|
||||||
|
result = true;
|
||||||
|
if (!Directory.Exists(destinationDirectory))
|
||||||
|
_ = Directory.CreateDirectory(destinationDirectory);
|
||||||
|
destinationFile = Path.Combine(destinationDirectory, filteredItem.ImageFileHolder.Name);
|
||||||
|
if (File.Exists(destinationFile))
|
||||||
|
{
|
||||||
|
if (_OutputExtension is not ".jpg" and not ".jpeg")
|
||||||
|
throw new Exception();
|
||||||
|
if (destinationFile.EndsWith(".jpg", ignoreCase: true, CultureInfo.CurrentCulture))
|
||||||
|
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(filteredItem.ImageFileHolder.Name, ".jpeg"));
|
||||||
|
else if (destinationFile.EndsWith(".jpeg", ignoreCase: true, CultureInfo.CurrentCulture))
|
||||||
|
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(filteredItem.ImageFileHolder.Name, ".jpg"));
|
||||||
|
}
|
||||||
|
if (File.Exists(destinationFile))
|
||||||
|
{
|
||||||
|
_Log.Information($"*** source <{filteredItem.ImageFileHolder.FullName}>");
|
||||||
|
_Log.Information($"*** destination <{destinationFile}>");
|
||||||
|
if (filteredItem.ImageFileHolder.Exists)
|
||||||
|
{
|
||||||
|
deleteFile = Path.ChangeExtension(filteredItem.ImageFileHolder.FullName, ".delete");
|
||||||
|
if (File.Exists(deleteFile))
|
||||||
|
File.Delete(deleteFile);
|
||||||
|
File.Move(filteredItem.ImageFileHolder.FullName, deleteFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
File.Move(filteredItem.ImageFileHolder.FullName, destinationFile);
|
||||||
|
if (filteredItem.ImageFileHolder.Exists)
|
||||||
|
{
|
||||||
|
deleteFile = Path.ChangeExtension(filteredItem.ImageFileHolder.FullName, ".delete");
|
||||||
|
if (File.Exists(deleteFile))
|
||||||
|
File.Delete(deleteFile);
|
||||||
|
File.Move(filteredItem.ImageFileHolder.FullName, deleteFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (directoryMaximumOfMinimumDateTime != DateTime.MinValue)
|
||||||
|
{
|
||||||
|
System.IO.DirectoryInfo directoryInfo = new(sourceDirectory);
|
||||||
|
if (directoryInfo.LastWriteTime != directoryMaximumOfMinimumDateTime)
|
||||||
|
Directory.SetLastWriteTime(sourceDirectory, directoryMaximumOfMinimumDateTime);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParallelForWork(bool firstPass, string sourceDirectory, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item item)
|
||||||
|
{
|
||||||
|
if (item.ImageFileHolder is null)
|
||||||
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
|
Shared.Models.Property property;
|
||||||
|
List<string> parseExceptions = new();
|
||||||
|
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||||
|
bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||||
|
string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}");
|
||||||
|
if (item.ValidImageFormatExtension && item.ImageFileHolder.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && item.ImageFileHolder.FullName != filteredSourceDirectoryFileExtensionLowered)
|
||||||
|
File.Move(item.ImageFileHolder.FullName, filteredSourceDirectoryFileExtensionLowered);
|
||||||
|
if (item.Changed is null || item.Changed.Value || item.Property is null)
|
||||||
|
{
|
||||||
|
property = GetPropertyOfPrivate(item, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions);
|
||||||
|
lock (sourceDirectoryChanges)
|
||||||
|
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
|
||||||
|
lock (item)
|
||||||
|
item.Update(property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParallelWork(bool firstPass, List<Exception> exceptions, List<Tuple<string, DateTime>> sourceDirectoryChanges, int containersCount, Shared.Models.Container container, Item[] filteredItems, int totalSeconds)
|
||||||
|
{
|
||||||
|
List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples = new();
|
||||||
|
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism };
|
||||||
|
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||||
|
string message = $"{container.R:000}.{container.G} / {containersCount:000}) {filteredItems.Length:000} file(s) - {totalSeconds} total second(s) - {container.SourceDirectory}";
|
||||||
|
using ProgressBar progressBar = new(filteredItems.Length, message, options);
|
||||||
|
_ = Parallel.For(0, filteredItems.Length, parallelOptions, i =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long ticks = DateTime.Now.Ticks;
|
||||||
|
DateTime dateTime = DateTime.Now;
|
||||||
|
List<Tuple<string, DateTime>> collection;
|
||||||
|
ParallelForWork(firstPass, container.SourceDirectory, sourceDirectoryChanges, filteredSourceDirectoryFileTuples, filteredItems[i]);
|
||||||
|
if (i == 0 || sourceDirectoryChanges.Any())
|
||||||
|
progressBar.Tick();
|
||||||
|
lock (filteredSourceDirectoryFileTuples)
|
||||||
|
collection = (from l in filteredSourceDirectoryFileTuples where l.Item2 > dateTime select l).ToList();
|
||||||
|
lock (sourceDirectoryChanges)
|
||||||
|
sourceDirectoryChanges.AddRange(collection);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
lock (exceptions)
|
||||||
|
exceptions.Add(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetAngleBracketCollection(string sourceDirectory)
|
||||||
|
{
|
||||||
|
AngleBracketCollection.Clear();
|
||||||
|
AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(_Configuration,
|
||||||
|
_Model,
|
||||||
|
_PredictorModel,
|
||||||
|
sourceDirectory,
|
||||||
|
nameof(A_Property),
|
||||||
|
string.Empty,
|
||||||
|
includeResizeGroup: false,
|
||||||
|
includeModel: false,
|
||||||
|
includePredictorModel: false,
|
||||||
|
contentDescription: string.Empty,
|
||||||
|
singletonDescription: "Properties for each image",
|
||||||
|
collectionDescription: string.Empty));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ParallelWork(long ticks, List<Shared.Models.Container> containers, bool firstPass)
|
||||||
|
{
|
||||||
|
if (_Log is null)
|
||||||
|
throw new NullReferenceException(nameof(_Log));
|
||||||
|
int totalSeconds;
|
||||||
|
bool? anyFilesMoved;
|
||||||
|
Item[] filteredItems;
|
||||||
|
List<Exception> exceptions = new();
|
||||||
|
int containersCount = containers.Count;
|
||||||
|
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
|
||||||
|
string propertyRoot = IResult.GetResultsGroupDirectory(_Configuration, nameof(A_Property));
|
||||||
|
foreach (Shared.Models.Container container in containers)
|
||||||
|
{
|
||||||
|
if (!container.Items.Any())
|
||||||
|
continue;
|
||||||
|
sourceDirectoryChanges.Clear();
|
||||||
|
if (firstPass)
|
||||||
|
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
|
||||||
|
filteredItems = (from l in container.Items where l.ImageFileHolder is not null && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray();
|
||||||
|
if (!filteredItems.Any())
|
||||||
|
continue;
|
||||||
|
totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||||
|
SetAngleBracketCollection(container.SourceDirectory);
|
||||||
|
ParallelWork(firstPass, exceptions, sourceDirectoryChanges, containersCount, container, filteredItems, totalSeconds);
|
||||||
|
foreach (Exception exception in exceptions)
|
||||||
|
_Log.Error(string.Concat(container.SourceDirectory, Environment.NewLine, exception.Message, Environment.NewLine, exception.StackTrace), exception);
|
||||||
|
if (exceptions.Count == filteredItems.Length)
|
||||||
|
throw new Exception(string.Concat("All in [", container.SourceDirectory, "]failed!"));
|
||||||
|
if (exceptions.Count != 0)
|
||||||
|
_ExceptionsDirectories.Add(container.SourceDirectory);
|
||||||
|
if (!firstPass || exceptions.Count != 0)
|
||||||
|
anyFilesMoved = null;
|
||||||
|
else
|
||||||
|
anyFilesMoved = AnyFilesMoved(container.SourceDirectory, filteredItems);
|
||||||
|
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
|
||||||
|
{
|
||||||
|
for (int y = 0; y < int.MaxValue; y++)
|
||||||
|
{
|
||||||
|
_Log.Information("Press \"Y\" key when ready to continue or close console");
|
||||||
|
if (System.Console.ReadKey().Key == ConsoleKey.Y)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_Log.Information(". . .");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Shared.Models.Property GetProperty(Item item, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions)
|
||||||
|
{
|
||||||
|
Shared.Models.Property result;
|
||||||
|
if (item.ImageFileHolder is null)
|
||||||
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
|
bool firstPass = false;
|
||||||
|
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||||
|
bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||||
|
result = GetPropertyOfPrivate(item, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] GetPropertyIds(List<DirectoryInfo> groupCollection, bool saveToCollection)
|
||||||
|
{
|
||||||
|
List<(long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)> results = new();
|
||||||
|
int level;
|
||||||
|
string checkDirectory;
|
||||||
|
List<string> directories;
|
||||||
|
string propertyDirectory;
|
||||||
|
Shared.Models.Property? property;
|
||||||
|
string angleBracket = AngleBracketCollection[0];
|
||||||
|
foreach (DirectoryInfo group in groupCollection)
|
||||||
|
{
|
||||||
|
SetAngleBracketCollection(group.SourceDirectory);
|
||||||
|
if (string.IsNullOrEmpty(group.SourceDirectory))
|
||||||
|
throw new Exception();
|
||||||
|
if (!saveToCollection)
|
||||||
|
propertyDirectory = angleBracket.Replace("<>", "()");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(level, directories) = Shared.Models.Stateless.Methods.IPath.Get(_Configuration.RootDirectory, group.SourceDirectory);
|
||||||
|
checkDirectory = Shared.Models.Stateless.Methods.IPath.GetDirectory(angleBracket, level, "[()]");
|
||||||
|
propertyDirectory = Path.Combine(checkDirectory, string.Join(_Configuration.FileNameDirectorySeparator, directories));
|
||||||
|
}
|
||||||
|
if (!Directory.Exists(propertyDirectory))
|
||||||
|
_ = Directory.CreateDirectory(propertyDirectory);
|
||||||
|
for (int i = 0; i < group.SourceDirectoryFileHolderCollection.Length; i++)
|
||||||
|
{
|
||||||
|
property = group.PropertyCollection[i];
|
||||||
|
if (property?.Id is null)
|
||||||
|
continue;
|
||||||
|
results.Add(new(property.GetDateTimes().Min().Ticks, group.FilteredSourceDirectoryFiles[i], propertyDirectory, property.Id.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results.OrderBy(l => l.Ticks).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Shared.Models.Container> Get(Configuration configuration, A_Property propertyLogic)
|
||||||
|
{
|
||||||
|
List<Shared.Models.Container> results;
|
||||||
|
long ticks = DateTime.Now.Ticks;
|
||||||
|
List<string> exceptionsDirectories = new();
|
||||||
|
results = Stateless.Container.GetContainers(configuration, propertyLogic);
|
||||||
|
propertyLogic.ParallelWork(ticks, results, firstPass: false);
|
||||||
|
if (exceptionsDirectories.Any())
|
||||||
|
throw new Exception();
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Phares.Shared;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
@ -6,6 +8,8 @@ namespace View_by_Distance.Property.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
[Display(Name = "Date Group"), Required] public string DateGroup { get; set; }
|
[Display(Name = "Date Group"), Required] public string DateGroup { get; set; }
|
||||||
[Display(Name = "File Name Directory Separator"), Required] public string FileNameDirectorySeparator { get; set; }
|
[Display(Name = "File Name Directory Separator"), Required] public string FileNameDirectorySeparator { get; set; }
|
||||||
[Display(Name = "Force Property Last Write Time to Creation Time"), Required] public bool? ForcePropertyLastWriteTimeToCreationTime { get; set; }
|
[Display(Name = "Force Property Last Write Time to Creation Time"), Required] public bool? ForcePropertyLastWriteTimeToCreationTime { get; set; }
|
||||||
@ -21,23 +25,7 @@ public class Configuration
|
|||||||
[Display(Name = "Verify to Season"), Required] public string[] VerifyToSeason { get; set; }
|
[Display(Name = "Verify to Season"), Required] public string[] VerifyToSeason { get; set; }
|
||||||
[Display(Name = "Write Bitmap Data Bytes"), Required] public bool? WriteBitmapDataBytes { get; set; }
|
[Display(Name = "Write Bitmap Data Bytes"), Required] public bool? WriteBitmapDataBytes { get; set; }
|
||||||
|
|
||||||
public Configuration()
|
#nullable restore
|
||||||
{
|
|
||||||
DateGroup = string.Empty;
|
|
||||||
FileNameDirectorySeparator = string.Empty;
|
|
||||||
ForcePropertyLastWriteTimeToCreationTime = null;
|
|
||||||
IgnoreExtensions = Array.Empty<string>();
|
|
||||||
MaxImagesInDirectoryForTopLevelFirstPass = null;
|
|
||||||
Pattern = string.Empty;
|
|
||||||
PopulatePropertyId = null;
|
|
||||||
PropertiesChangedForProperty = null;
|
|
||||||
PropertyContentCollectionFiles = Array.Empty<string>();
|
|
||||||
RootDirectory = string.Empty;
|
|
||||||
ValidImageFormatExtensions = Array.Empty<string>();
|
|
||||||
ValidMetadataExtensions = Array.Empty<string>();
|
|
||||||
VerifyToSeason = Array.Empty<string>();
|
|
||||||
WriteBitmapDataBytes = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -45,4 +33,61 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Models.Configuration Get(Configuration configuration)
|
||||||
|
{
|
||||||
|
Models.Configuration result;
|
||||||
|
if (configuration.ForcePropertyLastWriteTimeToCreationTime is null)
|
||||||
|
throw new NullReferenceException(nameof(configuration.ForcePropertyLastWriteTimeToCreationTime));
|
||||||
|
if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null)
|
||||||
|
throw new NullReferenceException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass));
|
||||||
|
if (configuration.PopulatePropertyId is null)
|
||||||
|
throw new NullReferenceException(nameof(configuration.PopulatePropertyId));
|
||||||
|
if (configuration.PropertiesChangedForProperty is null)
|
||||||
|
throw new NullReferenceException(nameof(configuration.PropertiesChangedForProperty));
|
||||||
|
if (configuration.WriteBitmapDataBytes is null)
|
||||||
|
throw new NullReferenceException(nameof(configuration.WriteBitmapDataBytes));
|
||||||
|
if (configuration.IgnoreExtensions is null)
|
||||||
|
configuration.IgnoreExtensions = Array.Empty<string>();
|
||||||
|
if (configuration.PropertyContentCollectionFiles is null)
|
||||||
|
configuration.PropertyContentCollectionFiles = Array.Empty<string>();
|
||||||
|
if (configuration.ValidImageFormatExtensions is null)
|
||||||
|
configuration.ValidImageFormatExtensions = Array.Empty<string>();
|
||||||
|
if (configuration.ValidMetadataExtensions is null)
|
||||||
|
configuration.ValidMetadataExtensions = Array.Empty<string>();
|
||||||
|
if (configuration.VerifyToSeason is null)
|
||||||
|
configuration.VerifyToSeason = Array.Empty<string>();
|
||||||
|
result = new(configuration.DateGroup,
|
||||||
|
configuration.FileNameDirectorySeparator,
|
||||||
|
configuration.ForcePropertyLastWriteTimeToCreationTime.Value,
|
||||||
|
configuration.IgnoreExtensions,
|
||||||
|
configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value,
|
||||||
|
configuration.Pattern,
|
||||||
|
configuration.PopulatePropertyId.Value,
|
||||||
|
configuration.PropertiesChangedForProperty.Value,
|
||||||
|
configuration.PropertyContentCollectionFiles,
|
||||||
|
configuration.RootDirectory,
|
||||||
|
configuration.ValidImageFormatExtensions,
|
||||||
|
configuration.ValidMetadataExtensions,
|
||||||
|
configuration.VerifyToSeason,
|
||||||
|
configuration.WriteBitmapDataBytes.Value);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Models.Configuration Get(IsEnvironment isEnvironment, IConfigurationRoot configurationRoot)
|
||||||
|
{
|
||||||
|
Models.Configuration result;
|
||||||
|
Configuration configuration;
|
||||||
|
if (isEnvironment is null)
|
||||||
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
}
|
||||||
|
result = Get(configuration);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -6,52 +6,40 @@ namespace View_by_Distance.Property.Models;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
protected readonly string _DateGroup;
|
|
||||||
protected readonly string _FileNameDirectorySeparator;
|
|
||||||
protected readonly bool? _ForcePropertyLastWriteTimeToCreationTime;
|
|
||||||
protected readonly string[] _IgnoreExtensions;
|
|
||||||
protected readonly int? _MaxImagesInDirectoryForTopLevelFirstPass;
|
|
||||||
protected readonly string _Pattern;
|
|
||||||
protected readonly bool? _PopulatePropertyId;
|
|
||||||
protected readonly bool? _PropertiesChangedForProperty;
|
|
||||||
protected readonly string[] _PropertyContentCollectionFiles;
|
|
||||||
protected string _RootDirectory;
|
protected string _RootDirectory;
|
||||||
protected readonly string[] _ValidImageFormatExtensions;
|
|
||||||
protected readonly string[] _ValidMetadataExtensions;
|
|
||||||
protected readonly string[] _VerifyToSeason;
|
|
||||||
protected readonly bool? _WriteBitmapDataBytes;
|
|
||||||
public string DateGroup => _DateGroup;
|
|
||||||
public string FileNameDirectorySeparator => _FileNameDirectorySeparator;
|
|
||||||
public bool? ForcePropertyLastWriteTimeToCreationTime => _ForcePropertyLastWriteTimeToCreationTime;
|
|
||||||
public string[] IgnoreExtensions => _IgnoreExtensions;
|
|
||||||
public int? MaxImagesInDirectoryForTopLevelFirstPass => _MaxImagesInDirectoryForTopLevelFirstPass;
|
|
||||||
public string Pattern => _Pattern;
|
|
||||||
public bool? PopulatePropertyId => _PopulatePropertyId;
|
|
||||||
public bool? PropertiesChangedForProperty => _PropertiesChangedForProperty;
|
|
||||||
public string[] PropertyContentCollectionFiles => _PropertyContentCollectionFiles;
|
|
||||||
public string RootDirectory => _RootDirectory;
|
public string RootDirectory => _RootDirectory;
|
||||||
public string[] ValidImageFormatExtensions => _ValidImageFormatExtensions;
|
|
||||||
public string[] ValidMetadataExtensions => _ValidMetadataExtensions;
|
public string DateGroup { init; get; }
|
||||||
public string[] VerifyToSeason => _VerifyToSeason;
|
public string FileNameDirectorySeparator { init; get; }
|
||||||
public bool? WriteBitmapDataBytes => _WriteBitmapDataBytes;
|
public bool ForcePropertyLastWriteTimeToCreationTime { init; get; }
|
||||||
|
public string[] IgnoreExtensions { init; get; }
|
||||||
|
public int MaxImagesInDirectoryForTopLevelFirstPass { init; get; }
|
||||||
|
public string Pattern { init; get; }
|
||||||
|
public bool PopulatePropertyId { init; get; }
|
||||||
|
public bool PropertiesChangedForProperty { init; get; }
|
||||||
|
public string[] PropertyContentCollectionFiles { init; get; }
|
||||||
|
public string[] ValidImageFormatExtensions { init; get; }
|
||||||
|
public string[] ValidMetadataExtensions { init; get; }
|
||||||
|
public string[] VerifyToSeason { init; get; }
|
||||||
|
public bool WriteBitmapDataBytes { init; get; }
|
||||||
|
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
public Configuration(string dateGroup, string fileNameDirectorySeparator, bool? forcePropertyLastWriteTimeToCreationTime, string[] ignoreExtensions, int? maxImagesInDirectoryForTopLevelFirstPass, string pattern, bool? populatePropertyId, bool? propertiesChangedForProperty, string[] propertyContentCollectionFiles, string rootDirectory, string[] validImageFormatExtensions, string[] validMetadataExtensions, string[] verifyToSeason, bool? writeBitmapDataBytes)
|
public Configuration(string dateGroup, string fileNameDirectorySeparator, bool forcePropertyLastWriteTimeToCreationTime, string[] ignoreExtensions, int maxImagesInDirectoryForTopLevelFirstPass, string pattern, bool populatePropertyId, bool propertiesChangedForProperty, string[] propertyContentCollectionFiles, string rootDirectory, string[] validImageFormatExtensions, string[] validMetadataExtensions, string[] verifyToSeason, bool writeBitmapDataBytes)
|
||||||
{
|
{
|
||||||
_DateGroup = dateGroup;
|
DateGroup = dateGroup;
|
||||||
_FileNameDirectorySeparator = fileNameDirectorySeparator;
|
FileNameDirectorySeparator = fileNameDirectorySeparator;
|
||||||
_ForcePropertyLastWriteTimeToCreationTime = forcePropertyLastWriteTimeToCreationTime;
|
ForcePropertyLastWriteTimeToCreationTime = forcePropertyLastWriteTimeToCreationTime;
|
||||||
_IgnoreExtensions = ignoreExtensions;
|
IgnoreExtensions = ignoreExtensions;
|
||||||
_MaxImagesInDirectoryForTopLevelFirstPass = maxImagesInDirectoryForTopLevelFirstPass;
|
MaxImagesInDirectoryForTopLevelFirstPass = maxImagesInDirectoryForTopLevelFirstPass;
|
||||||
_Pattern = pattern;
|
Pattern = pattern;
|
||||||
_PopulatePropertyId = populatePropertyId;
|
PopulatePropertyId = populatePropertyId;
|
||||||
_PropertiesChangedForProperty = propertiesChangedForProperty;
|
PropertiesChangedForProperty = propertiesChangedForProperty;
|
||||||
_PropertyContentCollectionFiles = propertyContentCollectionFiles;
|
PropertyContentCollectionFiles = propertyContentCollectionFiles;
|
||||||
_RootDirectory = rootDirectory;
|
_RootDirectory = rootDirectory;
|
||||||
_ValidImageFormatExtensions = validImageFormatExtensions;
|
ValidImageFormatExtensions = validImageFormatExtensions;
|
||||||
_ValidMetadataExtensions = validMetadataExtensions;
|
ValidMetadataExtensions = validMetadataExtensions;
|
||||||
_VerifyToSeason = verifyToSeason;
|
VerifyToSeason = verifyToSeason;
|
||||||
_WriteBitmapDataBytes = writeBitmapDataBytes;
|
WriteBitmapDataBytes = writeBitmapDataBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
@ -62,18 +50,14 @@ public class Configuration
|
|||||||
|
|
||||||
public void Update() => _RootDirectory = Path.GetFullPath(_RootDirectory);
|
public void Update() => _RootDirectory = Path.GetFullPath(_RootDirectory);
|
||||||
|
|
||||||
public static void Verify(Configuration? propertyConfiguration)
|
public void ChangeRootDirectory(string rootDirectory) => _RootDirectory = rootDirectory;
|
||||||
|
|
||||||
|
public static void Verify(Configuration propertyConfiguration)
|
||||||
{
|
{
|
||||||
if (propertyConfiguration is null)
|
if (propertyConfiguration is null)
|
||||||
throw new NullReferenceException(nameof(propertyConfiguration));
|
throw new NullReferenceException(nameof(propertyConfiguration));
|
||||||
if (propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime is null)
|
|
||||||
throw new NullReferenceException(nameof(propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime));
|
|
||||||
if (propertyConfiguration.IgnoreExtensions is null || !propertyConfiguration.IgnoreExtensions.Any())
|
if (propertyConfiguration.IgnoreExtensions is null || !propertyConfiguration.IgnoreExtensions.Any())
|
||||||
throw new NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions));
|
throw new NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions));
|
||||||
if (propertyConfiguration.PopulatePropertyId is null)
|
|
||||||
throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId));
|
|
||||||
if (propertyConfiguration.PropertiesChangedForProperty is null)
|
|
||||||
throw new NullReferenceException(nameof(propertyConfiguration.PropertiesChangedForProperty));
|
|
||||||
if (propertyConfiguration.PropertyContentCollectionFiles is null)
|
if (propertyConfiguration.PropertyContentCollectionFiles is null)
|
||||||
throw new NullReferenceException(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())
|
||||||
@ -82,8 +66,6 @@ public class Configuration
|
|||||||
throw new NullReferenceException(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 NullReferenceException(nameof(propertyConfiguration.VerifyToSeason));
|
throw new NullReferenceException(nameof(propertyConfiguration.VerifyToSeason));
|
||||||
if (propertyConfiguration.WriteBitmapDataBytes is null)
|
|
||||||
throw new NullReferenceException(nameof(propertyConfiguration.WriteBitmapDataBytes));
|
|
||||||
if (Path.GetPathRoot(propertyConfiguration.RootDirectory) == propertyConfiguration.RootDirectory)
|
if (Path.GetPathRoot(propertyConfiguration.RootDirectory) == propertyConfiguration.RootDirectory)
|
||||||
throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory));
|
throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory));
|
||||||
if (propertyConfiguration is null)
|
if (propertyConfiguration is null)
|
||||||
@ -98,6 +80,4 @@ public class Configuration
|
|||||||
throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory));
|
throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeRootDirectory(string rootDirectory) => _RootDirectory = rootDirectory;
|
|
||||||
|
|
||||||
}
|
}
|
@ -3,24 +3,24 @@ namespace View_by_Distance.Property.Models;
|
|||||||
public class DirectoryInfo
|
public class DirectoryInfo
|
||||||
{
|
{
|
||||||
|
|
||||||
protected readonly FileHolder[] _SourceDirectoryFileHolderCollection;
|
protected readonly Shared.Models.FileHolder[] _SourceDirectoryFileHolderCollection;
|
||||||
protected readonly string[] _FilteredSourceDirectoryFiles;
|
protected readonly string[] _FilteredSourceDirectoryFiles;
|
||||||
protected readonly int _G;
|
protected readonly int _G;
|
||||||
protected readonly bool[] _Moved;
|
protected readonly bool[] _Moved;
|
||||||
protected readonly bool?[] _Changed;
|
protected readonly bool?[] _Changed;
|
||||||
protected readonly A_Property?[] _PropertyCollection;
|
protected readonly Shared.Models.Property?[] _PropertyCollection;
|
||||||
protected readonly FileInfo?[] _PropertyFileHolderCollection;
|
protected readonly FileInfo?[] _PropertyFileHolderCollection;
|
||||||
protected readonly int _R;
|
protected readonly int _R;
|
||||||
protected readonly string _SourceDirectory;
|
protected readonly string _SourceDirectory;
|
||||||
protected readonly bool[] _ValidImageFormatExtensionCollection;
|
protected readonly bool[] _ValidImageFormatExtensionCollection;
|
||||||
protected readonly bool[] _WrongYear;
|
protected readonly bool[] _WrongYear;
|
||||||
public FileHolder[] SourceDirectoryFileHolderCollection => _SourceDirectoryFileHolderCollection;
|
public Shared.Models.FileHolder[] SourceDirectoryFileHolderCollection => _SourceDirectoryFileHolderCollection;
|
||||||
[Obsolete($"Use {nameof(SourceDirectoryFileHolderCollection)}")]
|
[Obsolete($"Use {nameof(SourceDirectoryFileHolderCollection)}")]
|
||||||
public string[] FilteredSourceDirectoryFiles => _FilteredSourceDirectoryFiles;
|
public string[] FilteredSourceDirectoryFiles => _FilteredSourceDirectoryFiles;
|
||||||
public int G => _G;
|
public int G => _G;
|
||||||
public bool[] Moved => _Moved;
|
public bool[] Moved => _Moved;
|
||||||
public bool?[] Changed => _Changed;
|
public bool?[] Changed => _Changed;
|
||||||
public A_Property?[] PropertyCollection => _PropertyCollection;
|
public Shared.Models.Property?[] PropertyCollection => _PropertyCollection;
|
||||||
public FileInfo?[] PropertyFileHolderCollection => _PropertyFileHolderCollection;
|
public FileInfo?[] PropertyFileHolderCollection => _PropertyFileHolderCollection;
|
||||||
public int R => _R;
|
public int R => _R;
|
||||||
public string SourceDirectory => _SourceDirectory;
|
public string SourceDirectory => _SourceDirectory;
|
||||||
@ -37,10 +37,11 @@ public class DirectoryInfo
|
|||||||
_Moved = Enumerable.Repeat(false, length).ToArray();
|
_Moved = Enumerable.Repeat(false, length).ToArray();
|
||||||
_WrongYear = Enumerable.Repeat(false, length).ToArray();
|
_WrongYear = Enumerable.Repeat(false, length).ToArray();
|
||||||
_FilteredSourceDirectoryFiles = filteredSourceDirectoryFiles;
|
_FilteredSourceDirectoryFiles = filteredSourceDirectoryFiles;
|
||||||
_PropertyCollection = Enumerable.Repeat<A_Property?>(null, length).ToArray();
|
|
||||||
_ValidImageFormatExtensionCollection = Enumerable.Repeat(false, length).ToArray();
|
_ValidImageFormatExtensionCollection = Enumerable.Repeat(false, length).ToArray();
|
||||||
_PropertyFileHolderCollection = Enumerable.Repeat<FileInfo?>(null, length).ToArray();
|
_PropertyFileHolderCollection = Enumerable.Repeat<FileInfo?>(null, length).ToArray();
|
||||||
_SourceDirectoryFileHolderCollection = (from l in filteredSourceDirectoryFiles select new FileHolder(l)).ToArray();
|
_PropertyCollection = Enumerable.Repeat<Shared.Models.Property?>(null, length).ToArray();
|
||||||
|
_SourceDirectoryFileHolderCollection = (from l in filteredSourceDirectoryFiles select new Shared.Models.FileHolder(l)).ToArray();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,318 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
using View_by_Distance.Shared.Models;
|
|
||||||
using View_by_Distance.Shared.Models.Properties;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Property.Models;
|
|
||||||
|
|
||||||
public class Item
|
|
||||||
{
|
|
||||||
|
|
||||||
protected readonly bool? _Abandoned;
|
|
||||||
protected readonly bool? _Changed;
|
|
||||||
protected List<Closest> _Closest;
|
|
||||||
protected List<IFace> _Faces;
|
|
||||||
protected readonly FileHolder? _ImageFileHolder;
|
|
||||||
protected bool? _Moved;
|
|
||||||
protected List<Named> _Named;
|
|
||||||
protected readonly bool? _NoJson;
|
|
||||||
protected A_Property? _Property;
|
|
||||||
protected readonly string _RelativePath;
|
|
||||||
protected FileHolder? _ResizedFileHolder;
|
|
||||||
protected readonly string _SourceDirectoryFile;
|
|
||||||
protected bool _ValidImageFormatExtension;
|
|
||||||
public bool? Abandoned => _Abandoned;
|
|
||||||
public bool? Changed => _Changed;
|
|
||||||
public List<Closest> Closest => _Closest;
|
|
||||||
public List<IFace> Faces => _Faces;
|
|
||||||
public FileHolder? ImageFileHolder => _ImageFileHolder;
|
|
||||||
public bool? Moved => _Moved;
|
|
||||||
public bool? NoJson => _NoJson;
|
|
||||||
public List<Named> Named => _Named;
|
|
||||||
public A_Property? Property => _Property;
|
|
||||||
public string RelativePath => _RelativePath;
|
|
||||||
public FileHolder? ResizedFileHolder => _ResizedFileHolder;
|
|
||||||
public string SourceDirectoryFile => _SourceDirectoryFile;
|
|
||||||
public bool ValidImageFormatExtension => _ValidImageFormatExtension;
|
|
||||||
|
|
||||||
[JsonConstructor]
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
_Abandoned = abandoned;
|
|
||||||
_Changed = changed;
|
|
||||||
_Closest = closest;
|
|
||||||
_Faces = faces;
|
|
||||||
_ImageFileHolder = imageFileHolder;
|
|
||||||
_Moved = moved;
|
|
||||||
_Named = named;
|
|
||||||
_NoJson = noJson;
|
|
||||||
_Property = property;
|
|
||||||
_RelativePath = relativePath;
|
|
||||||
_ResizedFileHolder = resizedFileHolder;
|
|
||||||
_SourceDirectoryFile = sourceDirectoryFile;
|
|
||||||
_ValidImageFormatExtension = validImageFormatExtension;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Item(string sourceDirectoryFile, string relativePath, FileHolder? imageFileInfo, bool isValidImageFormatExtension, A_Property? property, bool? abandoned, bool? changed)
|
|
||||||
{
|
|
||||||
_Faces = new();
|
|
||||||
_Named = new();
|
|
||||||
_Closest = new();
|
|
||||||
_Changed = changed;
|
|
||||||
_Property = property;
|
|
||||||
_Abandoned = abandoned;
|
|
||||||
_NoJson = abandoned is null;
|
|
||||||
_RelativePath = relativePath;
|
|
||||||
_ImageFileHolder = imageFileInfo;
|
|
||||||
_SourceDirectoryFile = sourceDirectoryFile;
|
|
||||||
_ValidImageFormatExtension = isValidImageFormatExtension;
|
|
||||||
if (relativePath.EndsWith(".json"))
|
|
||||||
throw new ArgumentException("Can not be a *.json file!");
|
|
||||||
if (imageFileInfo is not null && imageFileInfo.ExtensionLowered is ".json")
|
|
||||||
throw new ArgumentException("Can not be a *.json file!");
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void SetMoved(bool moved) => _Moved = moved;
|
|
||||||
|
|
||||||
public static string GetWrongYearFlag(bool? isWrongYear) => isWrongYear is null ? "#" : isWrongYear.Value ? "~" : "=";
|
|
||||||
|
|
||||||
public void SetResizedFileHolder(FileHolder fileHolder) => _ResizedFileHolder = fileHolder;
|
|
||||||
|
|
||||||
public bool Any() => (_Abandoned.HasValue && _Abandoned.Value) || (_Changed.HasValue && _Changed.Value) || (_Moved.HasValue && _Moved.Value) || (_NoJson.HasValue && _NoJson.Value);
|
|
||||||
|
|
||||||
public void Update(A_Property property) => _Property = property;
|
|
||||||
|
|
||||||
public (bool?, string[]) IsWrongYear()
|
|
||||||
{
|
|
||||||
(bool?, string[]) result;
|
|
||||||
if (_Property is null || _ImageFileHolder is null)
|
|
||||||
throw new NullReferenceException();
|
|
||||||
DateTime? minimumDateTime = Stateless.A_Property.GetMinimumDateTime(_Property);
|
|
||||||
result = _Property.IsWrongYear(_ImageFileHolder.FullName, minimumDateTime);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AddToNamed(PropertyLogic propertyLogic, List<Item> items)
|
|
||||||
{
|
|
||||||
bool? isWrongYear;
|
|
||||||
DateTime minimumDateTime;
|
|
||||||
PersonBirthday? personBirthday;
|
|
||||||
double deterministicHashCodeKey;
|
|
||||||
List<string> personKeys = new();
|
|
||||||
foreach (Item item in items)
|
|
||||||
{
|
|
||||||
if (item.ImageFileHolder is null)
|
|
||||||
continue;
|
|
||||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
|
||||||
continue;
|
|
||||||
foreach (IFace face in item.Faces)
|
|
||||||
{
|
|
||||||
personKeys.Clear();
|
|
||||||
if (face.LocationIndex is null)
|
|
||||||
continue;
|
|
||||||
deterministicHashCodeKey = Models.Named.GetDeterministicHashCodeKey(item, face);
|
|
||||||
if (!propertyLogic.NamedDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey))
|
|
||||||
continue;
|
|
||||||
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property);
|
|
||||||
personKeys.AddRange(propertyLogic.NamedDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey]);
|
|
||||||
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
|
|
||||||
for (int i = 0; i < personKeys.Count; i++)
|
|
||||||
{
|
|
||||||
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKeys[i]);
|
|
||||||
if (personBirthday is null)
|
|
||||||
continue;
|
|
||||||
item.Named.Add(new(isWrongYear, minimumDateTime, face.Location.NormalizedPixelPercentage, personBirthday));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!personKeys.Any())
|
|
||||||
{
|
|
||||||
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.ContainsKey(item.Property.Id.Value))
|
|
||||||
continue;
|
|
||||||
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property);
|
|
||||||
personKeys.AddRange(propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs[item.Property.Id.Value]);
|
|
||||||
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
|
|
||||||
for (int i = 0; i < personKeys.Count; i++)
|
|
||||||
{
|
|
||||||
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKeys[i]);
|
|
||||||
if (personBirthday is null)
|
|
||||||
continue;
|
|
||||||
item.Named.Add(new(isWrongYear, minimumDateTime, personBirthday));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<(Item, (string, IFace?, (string, string, string, string))[])> GetCollection(PropertyLogic propertyLogic, List<Item> items, string dFacesContentDirectory)
|
|
||||||
{
|
|
||||||
List<(Item, (string, IFace?, (string, string, string, string))[])> results = new();
|
|
||||||
Item item;
|
|
||||||
string[] keys;
|
|
||||||
string directory;
|
|
||||||
string personKey;
|
|
||||||
bool? isWrongYear;
|
|
||||||
const int zero = 0;
|
|
||||||
TimeSpan? timeSpan;
|
|
||||||
string copyFileName;
|
|
||||||
string copyDirectory;
|
|
||||||
string? relativePath;
|
|
||||||
string isWrongYearFlag;
|
|
||||||
string shortcutFileName;
|
|
||||||
string subDirectoryName;
|
|
||||||
List<int> indices = new();
|
|
||||||
DateTime? minimumDateTime;
|
|
||||||
List<IFace> faceCollection;
|
|
||||||
PersonBirthday? personBirthday;
|
|
||||||
List<(string, IFace?, (string, string, string, string))> collection;
|
|
||||||
for (int i = 0; i < items.Count; i++)
|
|
||||||
{
|
|
||||||
indices.Clear();
|
|
||||||
copyFileName = string.Empty;
|
|
||||||
copyDirectory = string.Empty;
|
|
||||||
item = items[i];
|
|
||||||
if (item.ImageFileHolder is null)
|
|
||||||
continue;
|
|
||||||
relativePath = Path.GetDirectoryName($"C:{item.RelativePath}");
|
|
||||||
if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3)
|
|
||||||
continue;
|
|
||||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
|
||||||
continue;
|
|
||||||
collection = new();
|
|
||||||
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.ContainsKey(item.Property.Id.Value))
|
|
||||||
{
|
|
||||||
faceCollection = new();
|
|
||||||
personKey = string.Empty;
|
|
||||||
directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
faceCollection = item.Faces;
|
|
||||||
keys = propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs[item.Property.Id.Value];
|
|
||||||
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property);
|
|
||||||
if (minimumDateTime is null)
|
|
||||||
continue;
|
|
||||||
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime.Value);
|
|
||||||
isWrongYearFlag = GetWrongYearFlag(isWrongYear);
|
|
||||||
subDirectoryName = $"{isWrongYearFlag}{minimumDateTime.Value:yyyy}";
|
|
||||||
if (!faceCollection.Any())
|
|
||||||
{
|
|
||||||
personKey = string.Empty;
|
|
||||||
directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName);
|
|
||||||
}
|
|
||||||
else if (keys.Length != 1)
|
|
||||||
{
|
|
||||||
personKey = string.Empty;
|
|
||||||
directory = Path.Combine(dFacesContentDirectory, $"Not Supported{relativePath[2..]}", subDirectoryName);
|
|
||||||
}
|
|
||||||
else if (faceCollection.Count != 1)
|
|
||||||
{
|
|
||||||
personKey = string.Empty;
|
|
||||||
directory = Path.Combine(dFacesContentDirectory, $"Many{relativePath[2..]}", subDirectoryName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
indices.Add(zero);
|
|
||||||
personKey = keys[zero];
|
|
||||||
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
|
|
||||||
if (personBirthday is null)
|
|
||||||
continue;
|
|
||||||
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime.Value, isWrongYear, personBirthday);
|
|
||||||
if (timeSpan.HasValue)
|
|
||||||
{
|
|
||||||
if (timeSpan.Value.Ticks < 0)
|
|
||||||
subDirectoryName = "!---";
|
|
||||||
else
|
|
||||||
subDirectoryName = $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}";
|
|
||||||
}
|
|
||||||
directory = Path.Combine(dFacesContentDirectory, "Shortcuts", personKey, subDirectoryName);
|
|
||||||
if (faceCollection[zero].Populated)
|
|
||||||
copyDirectory = Path.Combine(dFacesContentDirectory, "Images", personKey, subDirectoryName);
|
|
||||||
else
|
|
||||||
copyDirectory = Path.Combine(dFacesContentDirectory, "ImagesBut", personKey, subDirectoryName);
|
|
||||||
copyFileName = Path.Combine(copyDirectory, $"{item.Property.Id.Value}{item.ResizedFileHolder.ExtensionLowered}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shortcutFileName = Path.Combine(directory, $"{item.Property.Id.Value}.lnk");
|
|
||||||
if (string.IsNullOrEmpty(personKey) || !indices.Any())
|
|
||||||
collection.Add(new(personKey, null, (directory, copyDirectory, copyFileName, shortcutFileName)));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (int index in indices)
|
|
||||||
collection.Add(new(personKey, faceCollection[index], (directory, copyDirectory, copyFileName, shortcutFileName)));
|
|
||||||
}
|
|
||||||
results.Add(new(item, collection.ToArray()));
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetKey(DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
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.Named.Any())
|
|
||||||
continue;
|
|
||||||
foreach (Named named in item.Named)
|
|
||||||
{
|
|
||||||
if (named.NormalizedPixelPercentage is null && (item.Named.Count != 1 || item.Faces.Count != 1))
|
|
||||||
continue;
|
|
||||||
foreach (IFace face in item.Faces)
|
|
||||||
{
|
|
||||||
if (!face.Populated)
|
|
||||||
continue;
|
|
||||||
if (named.PersonBirthday is null)
|
|
||||||
continue;
|
|
||||||
if (named.NormalizedPixelPercentage.HasValue && named.NormalizedPixelPercentage.Value != face.Location?.NormalizedPixelPercentage)
|
|
||||||
continue;
|
|
||||||
key = GetKey(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday);
|
|
||||||
if (!results.ContainsKey(key))
|
|
||||||
results.Add(key, new());
|
|
||||||
results[key].Add(new(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday, face));
|
|
||||||
if (named.NormalizedPixelPercentage is null)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,142 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
using View_by_Distance.Shared.Models;
|
|
||||||
using View_by_Distance.Shared.Models.Properties;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Property.Models;
|
|
||||||
|
|
||||||
public class Named
|
|
||||||
{
|
|
||||||
|
|
||||||
protected readonly bool? _IsWrongYear;
|
|
||||||
protected readonly DateTime _MinimumDateTime;
|
|
||||||
protected readonly int? _NormalizedPixelPercentage;
|
|
||||||
protected readonly PersonBirthday? _PersonBirthday;
|
|
||||||
public bool? IsWrongYear => _IsWrongYear;
|
|
||||||
public DateTime MinimumDateTime => _MinimumDateTime;
|
|
||||||
public int? NormalizedPixelPercentage => _NormalizedPixelPercentage;
|
|
||||||
public PersonBirthday? PersonBirthday => _PersonBirthday;
|
|
||||||
|
|
||||||
[JsonConstructor]
|
|
||||||
public Named(bool? isWrongYear, DateTime minimumDateTime, int? normalizedPixelPercentage, PersonBirthday? personBirthday)
|
|
||||||
{
|
|
||||||
_IsWrongYear = isWrongYear;
|
|
||||||
_MinimumDateTime = minimumDateTime;
|
|
||||||
_NormalizedPixelPercentage = normalizedPixelPercentage;
|
|
||||||
_PersonBirthday = personBirthday;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Named(bool? isWrongYear, DateTime minimumDateTime, PersonBirthday? personBirthday) :
|
|
||||||
this(isWrongYear, minimumDateTime, null, personBirthday)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
private static double GetDeterministicHashCodeFileName(int id, int normalizedPixelPercentage)
|
|
||||||
=> double.Parse($"{id}.{normalizedPixelPercentage}");
|
|
||||||
|
|
||||||
public static double GetDeterministicHashCodeKey(Item item, Closest closest)
|
|
||||||
{
|
|
||||||
double result;
|
|
||||||
if (item.Property?.Id is null || item.ImageFileHolder is null || closest.NormalizedPixelPercentage is null)
|
|
||||||
throw new NullReferenceException();
|
|
||||||
result = GetDeterministicHashCodeFileName(item.Property.Id.Value, closest.NormalizedPixelPercentage.Value);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double GetDeterministicHashCodeKey(Item item, IFace face)
|
|
||||||
{
|
|
||||||
double result;
|
|
||||||
if (item.Property?.Id is null || item.ImageFileHolder is null || face.Location?.NormalizedPixelPercentage is null)
|
|
||||||
throw new NullReferenceException();
|
|
||||||
result = GetDeterministicHashCodeFileName(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double? GetReversedDeterministicHashCode(string fileName)
|
|
||||||
{
|
|
||||||
double? result;
|
|
||||||
if (fileName.Length < 2 || fileName[1..].Contains('-'))
|
|
||||||
result = null;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string[] segments = fileName.Split('.');
|
|
||||||
if (segments.Length < 2)
|
|
||||||
throw new Exception();
|
|
||||||
string id = segments[0];
|
|
||||||
string normalizedPixelPercentage = segments[1];
|
|
||||||
if (!double.TryParse(string.Concat(id, '.', normalizedPixelPercentage), out double resultValue))
|
|
||||||
result = null;
|
|
||||||
else
|
|
||||||
result = resultValue;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static (string?, double?) GetReversedDeterministicHashCode(Dictionary<int, List<IFace>> keyValuePairs, string file)
|
|
||||||
{
|
|
||||||
double? result;
|
|
||||||
string? check;
|
|
||||||
string fileName = Path.GetFileName(file);
|
|
||||||
if (!fileName.Contains('-'))
|
|
||||||
{
|
|
||||||
check = null;
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string id;
|
|
||||||
int? normalizedPixelPercentage;
|
|
||||||
if (!keyValuePairs.Any())
|
|
||||||
{
|
|
||||||
check = null;
|
|
||||||
id = string.Empty;
|
|
||||||
normalizedPixelPercentage = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string[] segments = fileName.Split(' ');
|
|
||||||
if (segments.Length < 3)
|
|
||||||
throw new Exception();
|
|
||||||
id = segments[2].Split('.')[0];
|
|
||||||
string locationIdex = segments[0];
|
|
||||||
if (!int.TryParse(id, out int idValue) || !int.TryParse(locationIdex, out int locationIndexValue) || !keyValuePairs.ContainsKey(idValue))
|
|
||||||
{
|
|
||||||
check = null;
|
|
||||||
id = string.Empty;
|
|
||||||
normalizedPixelPercentage = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
List<IFace> faces = keyValuePairs[idValue];
|
|
||||||
if (faces.Count <= locationIndexValue)
|
|
||||||
{
|
|
||||||
check = null;
|
|
||||||
id = string.Empty;
|
|
||||||
normalizedPixelPercentage = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IFace face = faces[locationIndexValue];
|
|
||||||
if (face.Location?.NormalizedPixelPercentage is null)
|
|
||||||
{
|
|
||||||
check = null;
|
|
||||||
id = string.Empty;
|
|
||||||
normalizedPixelPercentage = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string extensionLowered = Path.GetExtension(file).ToLower();
|
|
||||||
normalizedPixelPercentage = face.Location.NormalizedPixelPercentage.Value;
|
|
||||||
double deterministicHashCodeKey = GetDeterministicHashCodeFileName(idValue, normalizedPixelPercentage.Value);
|
|
||||||
check = Path.Combine(string.Concat(Path.GetDirectoryName(file)), $"{deterministicHashCodeKey}{extensionLowered}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (normalizedPixelPercentage is null || !double.TryParse(string.Concat(id, '.', normalizedPixelPercentage.Value), out double resultValue))
|
|
||||||
result = null;
|
|
||||||
else
|
|
||||||
result = resultValue;
|
|
||||||
}
|
|
||||||
return new(check, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,972 +0,0 @@
|
|||||||
using ShellProgressBar;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
|
||||||
using View_by_Distance.Property.Models.Stateless;
|
|
||||||
using View_by_Distance.Shared.Models.Properties;
|
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Property.Models;
|
|
||||||
|
|
||||||
public class PropertyLogic
|
|
||||||
{
|
|
||||||
|
|
||||||
protected readonly List<(int, string[])> _AllCollection;
|
|
||||||
protected readonly List<string> _ExceptionsDirectories;
|
|
||||||
protected readonly Dictionary<int, int[]> _KeyValuePairs;
|
|
||||||
protected readonly Dictionary<int, int[]> _IndicesFromNew;
|
|
||||||
protected readonly string _DeterministicHashCodeRootDirectory;
|
|
||||||
protected readonly Dictionary<int, string[]> _SixCharacterNamedFaceInfo;
|
|
||||||
protected readonly Dictionary<int, string[]> _NamedFaceInfoDeterministicHashCodeKeyValuePairs;
|
|
||||||
protected readonly Dictionary<double, string[]> _NamedDeterministicHashCodeKeyValuePairs;
|
|
||||||
protected readonly Dictionary<double, string[]> _IncorrectDeterministicHashCodeKeyValuePairs;
|
|
||||||
|
|
||||||
public bool Reverse { get; }
|
|
||||||
public List<string> AngleBracketCollection { get; }
|
|
||||||
public Dictionary<int, int[]> KeyValuePairs => _KeyValuePairs;
|
|
||||||
public Dictionary<int, int[]> IndicesFromNew => _IndicesFromNew;
|
|
||||||
public List<string> ExceptionsDirectories => _ExceptionsDirectories;
|
|
||||||
public string DeterministicHashCodeRootDirectory => _DeterministicHashCodeRootDirectory;
|
|
||||||
public Dictionary<double, string[]> NamedDeterministicHashCodeKeyValuePairs => _NamedDeterministicHashCodeKeyValuePairs;
|
|
||||||
public Dictionary<double, string[]> IncorrectDeterministicHashCodeKeyValuePairs => _IncorrectDeterministicHashCodeKeyValuePairs;
|
|
||||||
public Dictionary<int, string[]> NamedFaceInfoDeterministicHashCodeKeyValuePairs => _NamedFaceInfoDeterministicHashCodeKeyValuePairs;
|
|
||||||
|
|
||||||
private readonly Model? _Model;
|
|
||||||
private readonly Serilog.ILogger? _Log;
|
|
||||||
private readonly string[] _VerifyToSeason;
|
|
||||||
private readonly int _MaxDegreeOfParallelism;
|
|
||||||
private readonly ASCIIEncoding _ASCIIEncoding;
|
|
||||||
private readonly Configuration _Configuration;
|
|
||||||
private readonly PredictorModel? _PredictorModel;
|
|
||||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
|
||||||
|
|
||||||
public PropertyLogic(int maxDegreeOfParallelism, Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel)
|
|
||||||
{
|
|
||||||
_Model = model;
|
|
||||||
Reverse = reverse;
|
|
||||||
_AllCollection = new();
|
|
||||||
_Configuration = configuration;
|
|
||||||
_ExceptionsDirectories = new();
|
|
||||||
_PredictorModel = predictorModel;
|
|
||||||
_ASCIIEncoding = new ASCIIEncoding();
|
|
||||||
AngleBracketCollection = new List<string>();
|
|
||||||
_Log = Serilog.Log.ForContext<A_Property>();
|
|
||||||
_MaxDegreeOfParallelism = maxDegreeOfParallelism;
|
|
||||||
Dictionary<int, string[]>? namedFaceInfoDeterministicHashCode;
|
|
||||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
|
||||||
if (configuration.VerifyToSeason is null || !configuration.VerifyToSeason.Any())
|
|
||||||
throw new Exception();
|
|
||||||
_VerifyToSeason = configuration.VerifyToSeason.Select(l => Path.Combine(configuration.RootDirectory, l)).ToArray();
|
|
||||||
string json;
|
|
||||||
string[] files;
|
|
||||||
string fullPath;
|
|
||||||
Dictionary<int, int[]>? keyValuePairs;
|
|
||||||
string deterministicHashCodeRootDirectory;
|
|
||||||
List<KeyValuePair<int, int[]>>? collection;
|
|
||||||
Dictionary<int, int[]> indicesFromNew = new();
|
|
||||||
Dictionary<int, string[]>? sixCharacterNamedFaceInfo;
|
|
||||||
Dictionary<double, string[]> namedDeterministicHashCode = new();
|
|
||||||
Dictionary<double, string[]> incorrectDeterministicHashCode = new();
|
|
||||||
string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory);
|
|
||||||
if (string.IsNullOrEmpty(rootDirectoryParent))
|
|
||||||
throw new NullReferenceException(nameof(rootDirectoryParent));
|
|
||||||
files = Directory.GetFiles(rootDirectoryParent, "*DeterministicHashCode*.json", SearchOption.TopDirectoryOnly);
|
|
||||||
if (files.Length != 1)
|
|
||||||
namedFaceInfoDeterministicHashCode = new();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
json = File.ReadAllText(files[0]);
|
|
||||||
namedFaceInfoDeterministicHashCode = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
|
|
||||||
if (namedFaceInfoDeterministicHashCode is null)
|
|
||||||
throw new NullReferenceException(nameof(namedFaceInfoDeterministicHashCode));
|
|
||||||
}
|
|
||||||
string[] directories = Directory.GetDirectories(rootDirectoryParent, "*DeterministicHashCode*", SearchOption.TopDirectoryOnly);
|
|
||||||
if (!directories.Any())
|
|
||||||
deterministicHashCodeRootDirectory = string.Empty;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<int, List<IFace>> faces = new();
|
|
||||||
deterministicHashCodeRootDirectory = directories[0];
|
|
||||||
SetKeyValuePairs(deterministicHashCodeRootDirectory, namedDeterministicHashCode, incorrectDeterministicHashCode, faces);
|
|
||||||
}
|
|
||||||
if (!namedFaceInfoDeterministicHashCode.Any())
|
|
||||||
sixCharacterNamedFaceInfo = new();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
files = Directory.GetFiles(rootDirectoryParent, "*SixCharacter*.json", SearchOption.TopDirectoryOnly);
|
|
||||||
if (files.Length != 1)
|
|
||||||
sixCharacterNamedFaceInfo = new();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
json = File.ReadAllText(files[0]);
|
|
||||||
sixCharacterNamedFaceInfo = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
|
|
||||||
if (sixCharacterNamedFaceInfo is null)
|
|
||||||
throw new NullReferenceException(nameof(sixCharacterNamedFaceInfo));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly);
|
|
||||||
if (files.Length != 1)
|
|
||||||
keyValuePairs = new();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
json = File.ReadAllText(files[0]);
|
|
||||||
keyValuePairs = JsonSerializer.Deserialize<Dictionary<int, int[]>>(json);
|
|
||||||
if (keyValuePairs is null)
|
|
||||||
throw new NullReferenceException(nameof(keyValuePairs));
|
|
||||||
}
|
|
||||||
foreach (string propertyContentCollectionFile in configuration.PropertyContentCollectionFiles)
|
|
||||||
{
|
|
||||||
fullPath = Path.GetFullPath(string.Concat(rootDirectoryParent, propertyContentCollectionFile));
|
|
||||||
if (fullPath.Contains(configuration.RootDirectory))
|
|
||||||
continue;
|
|
||||||
if (!File.Exists(fullPath))
|
|
||||||
continue;
|
|
||||||
json = File.ReadAllText(fullPath);
|
|
||||||
collection = JsonSerializer.Deserialize<List<KeyValuePair<int, int[]>>>(json);
|
|
||||||
if (collection is null)
|
|
||||||
throw new NullReferenceException(nameof(collection));
|
|
||||||
foreach (KeyValuePair<int, int[]> keyValuePair in collection)
|
|
||||||
{
|
|
||||||
if (indicesFromNew.ContainsKey(keyValuePair.Key))
|
|
||||||
continue;
|
|
||||||
indicesFromNew.Add(keyValuePair.Key, keyValuePair.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_KeyValuePairs = keyValuePairs;
|
|
||||||
_IndicesFromNew = indicesFromNew;
|
|
||||||
_SixCharacterNamedFaceInfo = sixCharacterNamedFaceInfo;
|
|
||||||
_NamedDeterministicHashCodeKeyValuePairs = namedDeterministicHashCode;
|
|
||||||
_DeterministicHashCodeRootDirectory = deterministicHashCodeRootDirectory;
|
|
||||||
_IncorrectDeterministicHashCodeKeyValuePairs = incorrectDeterministicHashCode;
|
|
||||||
_NamedFaceInfoDeterministicHashCodeKeyValuePairs = namedFaceInfoDeterministicHashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SetKeyValuePairs(string deterministicHashCodeRootDirectory, List<(string, double)> named, List<(string, double)> incorrect, Dictionary<int, List<IFace>> keyValuePairs)
|
|
||||||
{
|
|
||||||
string[] files;
|
|
||||||
string fileName;
|
|
||||||
string personKey;
|
|
||||||
string? checkFile;
|
|
||||||
string[] yearDirectories;
|
|
||||||
string[] personKeyDirectories;
|
|
||||||
string[] personNameDirectories;
|
|
||||||
double? idAndNormalizedPixelPercentage;
|
|
||||||
string[] ticksDirectories = Directory.GetDirectories(deterministicHashCodeRootDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
foreach (string ticksDirectory in ticksDirectories)
|
|
||||||
{
|
|
||||||
if (!ticksDirectory.EndsWith(')'))
|
|
||||||
continue;
|
|
||||||
personKeyDirectories = Directory.GetDirectories(ticksDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
foreach (string personKeyDirectory in personKeyDirectories)
|
|
||||||
{
|
|
||||||
personKey = Path.GetFileName(personKeyDirectory);
|
|
||||||
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
foreach (string yearDirectory in yearDirectories)
|
|
||||||
{
|
|
||||||
files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
foreach (string file in files)
|
|
||||||
{
|
|
||||||
if (file.EndsWith(".lnk"))
|
|
||||||
continue;
|
|
||||||
fileName = Path.GetFileName(file);
|
|
||||||
idAndNormalizedPixelPercentage = Named.GetReversedDeterministicHashCode(fileName);
|
|
||||||
if (idAndNormalizedPixelPercentage is null)
|
|
||||||
{
|
|
||||||
(checkFile, idAndNormalizedPixelPercentage) = Named.GetReversedDeterministicHashCode(keyValuePairs, file);
|
|
||||||
if (idAndNormalizedPixelPercentage is null)
|
|
||||||
break;
|
|
||||||
if (!string.IsNullOrEmpty(checkFile))
|
|
||||||
File.Move(file, checkFile);
|
|
||||||
}
|
|
||||||
incorrect.Add(new(personKey, idAndNormalizedPixelPercentage.Value));
|
|
||||||
}
|
|
||||||
foreach (string personNameDirectory in personNameDirectories)
|
|
||||||
{
|
|
||||||
files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
foreach (string file in files)
|
|
||||||
{
|
|
||||||
if (file.EndsWith(".lnk"))
|
|
||||||
continue;
|
|
||||||
fileName = Path.GetFileName(file);
|
|
||||||
idAndNormalizedPixelPercentage = Named.GetReversedDeterministicHashCode(fileName);
|
|
||||||
if (idAndNormalizedPixelPercentage is null)
|
|
||||||
{
|
|
||||||
(checkFile, idAndNormalizedPixelPercentage) = Named.GetReversedDeterministicHashCode(keyValuePairs, file);
|
|
||||||
if (idAndNormalizedPixelPercentage is null)
|
|
||||||
break;
|
|
||||||
if (!string.IsNullOrEmpty(checkFile))
|
|
||||||
File.Move(file, checkFile);
|
|
||||||
}
|
|
||||||
named.Add(new(personKey, idAndNormalizedPixelPercentage.Value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SetKeyValuePairs(string deterministicHashCodeRootDirectory, Dictionary<double, string[]> namedDeterministicHashCode, Dictionary<double, string[]> incorrectDeterministicHashCode, Dictionary<int, List<IFace>> keyValuePairs)
|
|
||||||
{
|
|
||||||
Dictionary<double, List<string>> namedKeyValuePairs = new();
|
|
||||||
Dictionary<double, List<string>> incorrectKeyValuePairs = new();
|
|
||||||
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> named = new();
|
|
||||||
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> incorrect = new();
|
|
||||||
SetKeyValuePairs(deterministicHashCodeRootDirectory, named, incorrect, keyValuePairs);
|
|
||||||
named = (from l in named orderby l.IdAndNormalizedPixelPercentage select l).ToList();
|
|
||||||
incorrect = (from l in incorrect orderby l.IdAndNormalizedPixelPercentage select l).ToList();
|
|
||||||
foreach ((string personKey, double idAndNormalizedPixelPercentage) in named)
|
|
||||||
{
|
|
||||||
if (!namedKeyValuePairs.ContainsKey(idAndNormalizedPixelPercentage))
|
|
||||||
namedKeyValuePairs.Add(idAndNormalizedPixelPercentage, new());
|
|
||||||
namedKeyValuePairs[idAndNormalizedPixelPercentage].Add(personKey);
|
|
||||||
}
|
|
||||||
foreach ((string personKey, double idAndNormalizedPixelPercentage) in incorrect)
|
|
||||||
{
|
|
||||||
if (!incorrectKeyValuePairs.ContainsKey(idAndNormalizedPixelPercentage))
|
|
||||||
incorrectKeyValuePairs.Add(idAndNormalizedPixelPercentage, new());
|
|
||||||
incorrectKeyValuePairs[idAndNormalizedPixelPercentage].Add(personKey);
|
|
||||||
}
|
|
||||||
foreach (KeyValuePair<double, List<string>> keyValuePair in namedKeyValuePairs)
|
|
||||||
namedDeterministicHashCode.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray());
|
|
||||||
foreach (KeyValuePair<double, List<string>> keyValuePair in incorrectKeyValuePairs)
|
|
||||||
incorrectDeterministicHashCode.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateKeyValuePairs(List<Container> containers)
|
|
||||||
{
|
|
||||||
Dictionary<int, List<IFace>> keyValuePairs = new();
|
|
||||||
Dictionary<double, string[]> namedDeterministicHashCode = new();
|
|
||||||
Dictionary<double, string[]> incorrectDeterministicHashCode = new();
|
|
||||||
foreach (Container container in containers)
|
|
||||||
{
|
|
||||||
foreach (Item item in container.Items)
|
|
||||||
{
|
|
||||||
if (item.ImageFileHolder is null || item.Property?.Id is null || !item.Faces.Any())
|
|
||||||
continue;
|
|
||||||
if (keyValuePairs.ContainsKey(item.Property.Id.Value))
|
|
||||||
{
|
|
||||||
if (keyValuePairs[item.Property.Id.Value].Count != item.Faces.Count)
|
|
||||||
throw new Exception();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
keyValuePairs.Add(item.Property.Id.Value, item.Faces);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SetKeyValuePairs(_DeterministicHashCodeRootDirectory, namedDeterministicHashCode, incorrectDeterministicHashCode, keyValuePairs);
|
|
||||||
foreach (KeyValuePair<double, string[]> keyValuePair in namedDeterministicHashCode)
|
|
||||||
_NamedDeterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value);
|
|
||||||
foreach (KeyValuePair<double, string[]> keyValuePair in incorrectDeterministicHashCode)
|
|
||||||
_IncorrectDeterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private long LogDelta(long ticks, string methodName)
|
|
||||||
{
|
|
||||||
long result;
|
|
||||||
if (_Log is null)
|
|
||||||
throw new NullReferenceException(nameof(_Log));
|
|
||||||
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
|
|
||||||
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
|
|
||||||
result = DateTime.Now.Ticks;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<DateTime> GetMetadataDateTimesByPattern(string dateTimeFormat, string filteredSourceDirectoryFile)
|
|
||||||
{
|
|
||||||
List<DateTime> results = new();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DateTime checkDateTime;
|
|
||||||
DateTime kristy = new(1976, 3, 8);
|
|
||||||
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(filteredSourceDirectoryFile);
|
|
||||||
foreach (MetadataExtractor.Directory directory in directories)
|
|
||||||
{
|
|
||||||
foreach (MetadataExtractor.Tag tag in directory.Tags)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(tag.Description) || tag.Description.Length != dateTimeFormat.Length)
|
|
||||||
continue;
|
|
||||||
if (!DateTime.TryParseExact(tag.Description, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
|
||||||
continue;
|
|
||||||
if (checkDateTime < kristy)
|
|
||||||
continue;
|
|
||||||
results.Add(checkDateTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception) { }
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<DateTime> GetMetadataDateTimesByPattern(string dateTimeFormat, FileHolder filteredSourceDirectoryFileHolder)
|
|
||||||
{
|
|
||||||
List<DateTime> results = GetMetadataDateTimesByPattern(dateTimeFormat, filteredSourceDirectoryFileHolder.FullName);
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning disable CA1416
|
|
||||||
|
|
||||||
private A_Property GetImageProperty(FileHolder filteredSourceDirectoryFileHolder, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List<int> indices)
|
|
||||||
{
|
|
||||||
A_Property result;
|
|
||||||
if (_Log is null)
|
|
||||||
throw new NullReferenceException(nameof(_Log));
|
|
||||||
if (_Configuration.WriteBitmapDataBytes is null)
|
|
||||||
throw new NullReferenceException(nameof(_Configuration.WriteBitmapDataBytes));
|
|
||||||
long ticks;
|
|
||||||
byte[] bytes;
|
|
||||||
string value;
|
|
||||||
long fileLength;
|
|
||||||
int encodingHash;
|
|
||||||
int? width = null;
|
|
||||||
int? height = null;
|
|
||||||
string dateTimeFormat;
|
|
||||||
DateTime checkDateTime;
|
|
||||||
DateTime? dateTime = null;
|
|
||||||
PropertyItem? propertyItem;
|
|
||||||
string make = string.Empty;
|
|
||||||
string model = string.Empty;
|
|
||||||
DateTime? gpsDateStamp = null;
|
|
||||||
DateTime? dateTimeOriginal = null;
|
|
||||||
string orientation = string.Empty;
|
|
||||||
DateTime? dateTimeDigitized = null;
|
|
||||||
if (!isValidImageFormatExtension && isValidMetadataExtensions)
|
|
||||||
{
|
|
||||||
dateTimeFormat = "ddd MMM dd HH:mm:ss yyyy";
|
|
||||||
List<DateTime> dateTimes = GetMetadataDateTimesByPattern(dateTimeFormat, filteredSourceDirectoryFileHolder);
|
|
||||||
if (dateTimes.Any())
|
|
||||||
dateTimeOriginal = dateTimes.Min();
|
|
||||||
}
|
|
||||||
else if (!isIgnoreExtension && isValidImageFormatExtension)
|
|
||||||
{
|
|
||||||
if (populateId && (id is null || !indices.Any()) && !_IndicesFromNew.Any() && !_KeyValuePairs.Any())
|
|
||||||
throw new Exception("In order to keep six character indices at least one need to have an item!");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using Image image = Image.FromFile(filteredSourceDirectoryFileHolder.FullName);
|
|
||||||
if (populateId && (id is null || !indices.Any()))
|
|
||||||
{
|
|
||||||
using Bitmap bitmap = new(image);
|
|
||||||
string angleBracket = AngleBracketCollection[0];
|
|
||||||
Rectangle rectangle = new(0, 0, image.Width, image.Height);
|
|
||||||
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
|
||||||
IntPtr intPtr = bitmapData.Scan0;
|
|
||||||
int length = bitmapData.Stride * bitmap.Height;
|
|
||||||
bytes = new byte[length];
|
|
||||||
Marshal.Copy(intPtr, bytes, 0, length);
|
|
||||||
bitmap.UnlockBits(bitmapData);
|
|
||||||
if (id is null)
|
|
||||||
{
|
|
||||||
ticks = DateTime.Now.Ticks;
|
|
||||||
id = Stateless.A_Property.GetDeterministicHashCode(bytes);
|
|
||||||
if (_MaxDegreeOfParallelism < 2)
|
|
||||||
ticks = LogDelta(ticks, nameof(Stateless.A_Property.GetDeterministicHashCode));
|
|
||||||
}
|
|
||||||
if (_Configuration.WriteBitmapDataBytes.Value)
|
|
||||||
{
|
|
||||||
FileInfo contentFileInfo = new(Path.Combine(angleBracket.Replace("<>", "()"), filteredSourceDirectoryFileHolder.Name));
|
|
||||||
File.WriteAllBytes(Path.ChangeExtension(contentFileInfo.FullName, string.Empty), bytes);
|
|
||||||
}
|
|
||||||
if (_IndicesFromNew.ContainsKey(id.Value) && _IndicesFromNew[id.Value].Any())
|
|
||||||
indices.AddRange(_IndicesFromNew[id.Value]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ticks = DateTime.Now.Ticks;
|
|
||||||
string encoding = Encoding.Default.GetString(bytes);
|
|
||||||
if (_MaxDegreeOfParallelism < 2)
|
|
||||||
ticks = LogDelta(ticks, nameof(Encoding.Default.GetString));
|
|
||||||
encodingHash = Stateless.A_Property.GetDeterministicHashCode(encoding);
|
|
||||||
if (_MaxDegreeOfParallelism < 2)
|
|
||||||
ticks = LogDelta(ticks, nameof(Stateless.A_Property.GetDeterministicHashCode));
|
|
||||||
if (!_KeyValuePairs.ContainsKey(encodingHash))
|
|
||||||
indices.Add(encodingHash);
|
|
||||||
else
|
|
||||||
indices.AddRange(_KeyValuePairs[encodingHash]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
width = image.Width;
|
|
||||||
height = image.Height;
|
|
||||||
dateTimeFormat = Stateless.A_Property.DateTimeFormat();
|
|
||||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTime))
|
|
||||||
{
|
|
||||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime);
|
|
||||||
if (propertyItem?.Value is not null)
|
|
||||||
{
|
|
||||||
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
|
||||||
if (value.Length > dateTimeFormat.Length)
|
|
||||||
value = value[..dateTimeFormat.Length];
|
|
||||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
|
||||||
dateTime = checkDateTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeDigitized))
|
|
||||||
{
|
|
||||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized);
|
|
||||||
if (propertyItem?.Value is not null)
|
|
||||||
{
|
|
||||||
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
|
||||||
if (value.Length > dateTimeFormat.Length)
|
|
||||||
value = value[..dateTimeFormat.Length];
|
|
||||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
|
||||||
dateTimeDigitized = checkDateTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeOriginal))
|
|
||||||
{
|
|
||||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal);
|
|
||||||
if (propertyItem?.Value is not null)
|
|
||||||
{
|
|
||||||
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
|
||||||
if (value.Length > dateTimeFormat.Length)
|
|
||||||
value = value[..dateTimeFormat.Length];
|
|
||||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
|
||||||
dateTimeOriginal = checkDateTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (image.PropertyIdList.Contains((int)IExif.Tags.GPSDateStamp))
|
|
||||||
{
|
|
||||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp);
|
|
||||||
if (propertyItem?.Value is not null)
|
|
||||||
{
|
|
||||||
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
|
||||||
if (value.Length > dateTimeFormat.Length)
|
|
||||||
value = value[..dateTimeFormat.Length];
|
|
||||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
|
||||||
gpsDateStamp = checkDateTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (image.PropertyIdList.Contains((int)IExif.Tags.Make))
|
|
||||||
{
|
|
||||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.Make);
|
|
||||||
if (propertyItem?.Value is not null)
|
|
||||||
{
|
|
||||||
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
|
||||||
make = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (image.PropertyIdList.Contains((int)IExif.Tags.Model))
|
|
||||||
{
|
|
||||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.Model);
|
|
||||||
if (propertyItem?.Value is not null)
|
|
||||||
{
|
|
||||||
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
|
||||||
model = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (image.PropertyIdList.Contains((int)IExif.Tags.Orientation))
|
|
||||||
{
|
|
||||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.Orientation);
|
|
||||||
if (propertyItem?.Value is not null)
|
|
||||||
{
|
|
||||||
value = BitConverter.ToInt16(propertyItem.Value, 0).ToString();
|
|
||||||
orientation = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
_Log.Info(string.Concat(new StackFrame().GetMethod()?.Name, " <", filteredSourceDirectoryFileHolder.Name, ">"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dateTimeOriginal = null;
|
|
||||||
if (filteredSourceDirectoryFileHolder.Length is null)
|
|
||||||
fileLength = 0;
|
|
||||||
else
|
|
||||||
fileLength = filteredSourceDirectoryFileHolder.Length.Value;
|
|
||||||
result = new(filteredSourceDirectoryFileHolder.CreationTime, dateTime, dateTimeDigitized, dateTimeOriginal, fileLength, gpsDateStamp, height, id, indices.ToArray(), filteredSourceDirectoryFileHolder.LastWriteTime, make, model, orientation, width);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning restore CA1416
|
|
||||||
|
|
||||||
private A_Property GetPropertyOfPrivate(Item item, bool firstPass, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension, bool isValidMetadataExtensions)
|
|
||||||
{
|
|
||||||
A_Property? result;
|
|
||||||
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime is null)
|
|
||||||
throw new NullReferenceException(nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime));
|
|
||||||
if (_Configuration.PopulatePropertyId is null)
|
|
||||||
throw new NullReferenceException(nameof(_Configuration.PopulatePropertyId));
|
|
||||||
if (_Configuration.PropertiesChangedForProperty is null)
|
|
||||||
throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForProperty));
|
|
||||||
if (item.ImageFileHolder is null)
|
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
|
||||||
string json;
|
|
||||||
int? id = null;
|
|
||||||
List<int> indices = new();
|
|
||||||
bool hasWrongYearProperty = false;
|
|
||||||
string[] changesFrom = Array.Empty<string>();
|
|
||||||
string angleBracket = AngleBracketCollection[0];
|
|
||||||
bool populateId = !firstPass && _Configuration.PopulatePropertyId.Value;
|
|
||||||
string without = Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}.json");
|
|
||||||
FileInfo fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
|
|
||||||
if (item.ValidImageFormatExtension && File.Exists(without))
|
|
||||||
{
|
|
||||||
File.Move(without, fileInfo.FullName);
|
|
||||||
fileInfo.Refresh();
|
|
||||||
}
|
|
||||||
List<DateTime> dateTimes = (from l in filteredSourceDirectoryFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
|
||||||
if (!fileInfo.Exists)
|
|
||||||
{
|
|
||||||
if (fileInfo.Directory?.Parent is null)
|
|
||||||
throw new Exception();
|
|
||||||
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
|
|
||||||
if (File.Exists(parentCheck))
|
|
||||||
{
|
|
||||||
File.Move(parentCheck, fileInfo.FullName);
|
|
||||||
fileInfo.Refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime.Value && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
|
||||||
{
|
|
||||||
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
|
||||||
fileInfo.Refresh();
|
|
||||||
}
|
|
||||||
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime.Value && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime)
|
|
||||||
{
|
|
||||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
|
||||||
fileInfo.Refresh();
|
|
||||||
}
|
|
||||||
if (_Configuration.PropertiesChangedForProperty.Value)
|
|
||||||
result = null;
|
|
||||||
else if (!fileInfo.Exists)
|
|
||||||
result = null;
|
|
||||||
else if (!fileInfo.FullName.EndsWith(".json") && !fileInfo.FullName.EndsWith(".old"))
|
|
||||||
throw new ArgumentException("must be a *.json file");
|
|
||||||
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
|
||||||
result = null;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
json = File.ReadAllText(fileInfo.FullName);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (item.ImageFileHolder is null)
|
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
|
||||||
bool check = true;
|
|
||||||
A_Property? property = JsonSerializer.Deserialize<A_Property>(json);
|
|
||||||
if (!isIgnoreExtension && item.ValidImageFormatExtension && ((populateId && property?.Id is null) || property?.Width is null || property?.Height is null))
|
|
||||||
{
|
|
||||||
check = false;
|
|
||||||
id = property?.Id;
|
|
||||||
if (property is not null && property.Indices.Any())
|
|
||||||
indices = property.Indices.ToList();
|
|
||||||
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
|
||||||
}
|
|
||||||
if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && property is not null && !property.Indices.Any())
|
|
||||||
{
|
|
||||||
check = false;
|
|
||||||
id = property?.Id;
|
|
||||||
if (property is not null && property.Indices.Any())
|
|
||||||
indices = property.Indices.ToList();
|
|
||||||
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
|
||||||
}
|
|
||||||
if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && property is not null && property.LastWriteTime != item.ImageFileHolder.LastWriteTime)
|
|
||||||
{
|
|
||||||
check = false;
|
|
||||||
id = null;
|
|
||||||
indices.Clear();
|
|
||||||
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
|
||||||
}
|
|
||||||
if (!isIgnoreExtension && item.ValidImageFormatExtension && property?.Width is not null && property?.Height is not null && property.Width.Value == property.Height.Value && item.ImageFileHolder.Exists)
|
|
||||||
{
|
|
||||||
check = false;
|
|
||||||
id = property?.Id;
|
|
||||||
if (property is not null && property.Indices.Any())
|
|
||||||
indices = property.Indices.ToList();
|
|
||||||
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
|
||||||
if (property?.Width is not null && property?.Height is not null && property.Width.Value != property.Height.Value)
|
|
||||||
throw new Exception("Was square!");
|
|
||||||
}
|
|
||||||
// if (filteredSourceDirectoryFileFileInfo.CreationTime != property?.CreationTime || filteredSourceDirectoryFileFileInfo.LastWriteTime != property?.LastWriteTime)
|
|
||||||
// {
|
|
||||||
// check = false;
|
|
||||||
// id = null;
|
|
||||||
// indices.Clear();
|
|
||||||
// property = GetImagePropertyB(filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
|
||||||
// }
|
|
||||||
if (json.Contains("WrongYear"))
|
|
||||||
{
|
|
||||||
id = property?.Id;
|
|
||||||
hasWrongYearProperty = true;
|
|
||||||
}
|
|
||||||
if (property is null)
|
|
||||||
throw new Exception();
|
|
||||||
if (!check)
|
|
||||||
result = null;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = property;
|
|
||||||
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.LastWriteTime));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
parseExceptions.Add(nameof(A_Property));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (result is null)
|
|
||||||
{
|
|
||||||
if (item.ImageFileHolder is null)
|
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
|
||||||
result = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
|
||||||
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
|
|
||||||
if (populateId && IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
|
||||||
{
|
|
||||||
if (!_Configuration.ForcePropertyLastWriteTimeToCreationTime.Value && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
|
|
||||||
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
|
||||||
fileInfo.Refresh();
|
|
||||||
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.CreationTime));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (hasWrongYearProperty)
|
|
||||||
{
|
|
||||||
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
|
|
||||||
if (IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
|
||||||
{
|
|
||||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
|
||||||
fileInfo.Refresh();
|
|
||||||
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.CreationTime));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool AnyFilesMoved(string sourceDirectory, Item[] filteredItems)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
if (_Log is null)
|
|
||||||
throw new NullReferenceException(nameof(_Log));
|
|
||||||
int season;
|
|
||||||
string[] matches;
|
|
||||||
string deleteFile;
|
|
||||||
bool? isWrongYear;
|
|
||||||
string seasonName;
|
|
||||||
DateTime dateTime;
|
|
||||||
string destinationFile;
|
|
||||||
DateTime minimumDateTime;
|
|
||||||
string destinationDirectory;
|
|
||||||
string[] sourceDirectorySegments;
|
|
||||||
DateTime directoryMaximumOfMinimumDateTime = DateTime.MinValue;
|
|
||||||
foreach (Item filteredItem in filteredItems)
|
|
||||||
{
|
|
||||||
if (!filteredItem.ValidImageFormatExtension || filteredItem.Property is null || filteredItem.ImageFileHolder is null)
|
|
||||||
continue;
|
|
||||||
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(filteredItem.Property);
|
|
||||||
if (minimumDateTime > directoryMaximumOfMinimumDateTime)
|
|
||||||
directoryMaximumOfMinimumDateTime = minimumDateTime;
|
|
||||||
if (minimumDateTime != filteredItem.ImageFileHolder.CreationTime)
|
|
||||||
{
|
|
||||||
(isWrongYear, matches) = filteredItem.Property.IsWrongYear(filteredItem.ImageFileHolder.FullName, minimumDateTime);
|
|
||||||
if (isWrongYear is null || !isWrongYear.Value)
|
|
||||||
dateTime = minimumDateTime;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!matches.Any())
|
|
||||||
continue;
|
|
||||||
if (!DateTime.TryParseExact(matches[0], "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{ File.SetCreationTime(filteredItem.ImageFileHolder.FullName, dateTime); }
|
|
||||||
catch (Exception)
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
if (!_VerifyToSeason.Contains(sourceDirectory))
|
|
||||||
continue;
|
|
||||||
if (!filteredItem.ImageFileHolder.FullName.Contains("zzz ") && !filteredItem.ImageFileHolder.FullName.Contains("Camera ") && filteredItem.Property.DateTimeOriginal.HasValue)
|
|
||||||
{
|
|
||||||
TimeSpan timeSpan = new(filteredItem.Property.DateTimeOriginal.Value.Ticks - filteredItem.Property.LastWriteTime.Ticks);
|
|
||||||
if (timeSpan.TotalHours > 6)
|
|
||||||
{
|
|
||||||
_Log.Warning($"*** propertyHolder.FileInfo.FullName <{filteredItem.ImageFileHolder.FullName}>");
|
|
||||||
_Log.Warning($"*** DateTimeOriginal <{filteredItem.Property.DateTimeOriginal.Value}>");
|
|
||||||
_Log.Warning($"*** LastWriteTime <{filteredItem.Property.LastWriteTime}>");
|
|
||||||
_Log.Warning($"*** TotalHours <{timeSpan.TotalHours}>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sourceDirectorySegments = Path.GetFileName(sourceDirectory).Split(' ');
|
|
||||||
(season, seasonName) = Stateless.A_Property.GetSeason(minimumDateTime.DayOfYear);
|
|
||||||
if (sourceDirectorySegments[0] == "zzz")
|
|
||||||
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"zzz ={minimumDateTime:yyyy}.{season} {seasonName} {string.Join(' ', sourceDirectorySegments.Skip(3))}");
|
|
||||||
else if (sourceDirectorySegments.Length > 2)
|
|
||||||
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName} {string.Join(' ', sourceDirectorySegments.Skip(2))}");
|
|
||||||
else
|
|
||||||
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName}");
|
|
||||||
if (destinationDirectory == sourceDirectory)
|
|
||||||
continue;
|
|
||||||
lock (filteredItem)
|
|
||||||
filteredItem.SetMoved(true);
|
|
||||||
if (!result)
|
|
||||||
result = true;
|
|
||||||
if (!Directory.Exists(destinationDirectory))
|
|
||||||
_ = Directory.CreateDirectory(destinationDirectory);
|
|
||||||
destinationFile = Path.Combine(destinationDirectory, filteredItem.ImageFileHolder.Name);
|
|
||||||
if (File.Exists(destinationFile))
|
|
||||||
{
|
|
||||||
if (destinationFile.EndsWith(".jpg", ignoreCase: true, CultureInfo.CurrentCulture))
|
|
||||||
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(filteredItem.ImageFileHolder.Name, ".jpeg"));
|
|
||||||
else if (destinationFile.EndsWith(".jpeg", ignoreCase: true, CultureInfo.CurrentCulture))
|
|
||||||
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(filteredItem.ImageFileHolder.Name, ".jpg"));
|
|
||||||
}
|
|
||||||
if (File.Exists(destinationFile))
|
|
||||||
{
|
|
||||||
_Log.Information($"*** source <{filteredItem.ImageFileHolder.FullName}>");
|
|
||||||
_Log.Information($"*** destination <{destinationFile}>");
|
|
||||||
if (filteredItem.ImageFileHolder.Exists)
|
|
||||||
{
|
|
||||||
deleteFile = Path.ChangeExtension(filteredItem.ImageFileHolder.FullName, ".delete");
|
|
||||||
if (File.Exists(deleteFile))
|
|
||||||
File.Delete(deleteFile);
|
|
||||||
File.Move(filteredItem.ImageFileHolder.FullName, deleteFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
File.Move(filteredItem.ImageFileHolder.FullName, destinationFile);
|
|
||||||
if (filteredItem.ImageFileHolder.Exists)
|
|
||||||
{
|
|
||||||
deleteFile = Path.ChangeExtension(filteredItem.ImageFileHolder.FullName, ".delete");
|
|
||||||
if (File.Exists(deleteFile))
|
|
||||||
File.Delete(deleteFile);
|
|
||||||
File.Move(filteredItem.ImageFileHolder.FullName, deleteFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (directoryMaximumOfMinimumDateTime != DateTime.MinValue)
|
|
||||||
{
|
|
||||||
System.IO.DirectoryInfo directoryInfo = new(sourceDirectory);
|
|
||||||
if (directoryInfo.LastWriteTime != directoryMaximumOfMinimumDateTime)
|
|
||||||
Directory.SetLastWriteTime(sourceDirectory, directoryMaximumOfMinimumDateTime);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ParallelForWork(bool firstPass, string sourceDirectory, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item item)
|
|
||||||
{
|
|
||||||
if (item.ImageFileHolder is null)
|
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
|
||||||
A_Property property;
|
|
||||||
List<string> parseExceptions = new();
|
|
||||||
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
|
||||||
bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
|
||||||
string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}");
|
|
||||||
if (item.ValidImageFormatExtension && item.ImageFileHolder.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && item.ImageFileHolder.FullName != filteredSourceDirectoryFileExtensionLowered)
|
|
||||||
File.Move(item.ImageFileHolder.FullName, filteredSourceDirectoryFileExtensionLowered);
|
|
||||||
if (item.Changed is null || item.Changed.Value || item.Property is null)
|
|
||||||
{
|
|
||||||
property = GetPropertyOfPrivate(item, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions);
|
|
||||||
lock (sourceDirectoryChanges)
|
|
||||||
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
|
|
||||||
lock (item)
|
|
||||||
item.Update(property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism };
|
|
||||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
|
||||||
string message = $"{container.R:000}.{container.G} / {containersCount:000}) {filteredItems.Length:000} file(s) - {totalSeconds} total second(s) - {container.SourceDirectory}";
|
|
||||||
using ProgressBar progressBar = new(filteredItems.Length, message, options);
|
|
||||||
_ = Parallel.For(0, filteredItems.Length, parallelOptions, i =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
long ticks = DateTime.Now.Ticks;
|
|
||||||
DateTime dateTime = DateTime.Now;
|
|
||||||
List<Tuple<string, DateTime>> collection;
|
|
||||||
ParallelForWork(firstPass, container.SourceDirectory, sourceDirectoryChanges, filteredSourceDirectoryFileTuples, filteredItems[i]);
|
|
||||||
if (i == 0 || sourceDirectoryChanges.Any())
|
|
||||||
progressBar.Tick();
|
|
||||||
lock (filteredSourceDirectoryFileTuples)
|
|
||||||
collection = (from l in filteredSourceDirectoryFileTuples where l.Item2 > dateTime select l).ToList();
|
|
||||||
lock (sourceDirectoryChanges)
|
|
||||||
sourceDirectoryChanges.AddRange(collection);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
lock (exceptions)
|
|
||||||
exceptions.Add(ex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetAngleBracketCollection(string sourceDirectory)
|
|
||||||
{
|
|
||||||
AngleBracketCollection.Clear();
|
|
||||||
AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(_Configuration,
|
|
||||||
_Model,
|
|
||||||
_PredictorModel,
|
|
||||||
sourceDirectory,
|
|
||||||
nameof(A_Property),
|
|
||||||
string.Empty,
|
|
||||||
includeResizeGroup: false,
|
|
||||||
includeModel: false,
|
|
||||||
includePredictorModel: false,
|
|
||||||
contentDescription: string.Empty,
|
|
||||||
singletonDescription: "Properties for each image",
|
|
||||||
collectionDescription: string.Empty));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ParallelWork(long ticks, List<Container> containers, bool firstPass)
|
|
||||||
{
|
|
||||||
if (_Log is null)
|
|
||||||
throw new NullReferenceException(nameof(_Log));
|
|
||||||
if (_Configuration.PopulatePropertyId is null)
|
|
||||||
throw new NullReferenceException(nameof(_Configuration.PopulatePropertyId));
|
|
||||||
int totalSeconds;
|
|
||||||
bool? anyFilesMoved;
|
|
||||||
Item[] filteredItems;
|
|
||||||
List<Exception> exceptions = new();
|
|
||||||
int containersCount = containers.Count;
|
|
||||||
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
|
|
||||||
string propertyRoot = IResult.GetResultsGroupDirectory(_Configuration, nameof(A_Property));
|
|
||||||
foreach (Container container in containers)
|
|
||||||
{
|
|
||||||
if (!container.Items.Any())
|
|
||||||
continue;
|
|
||||||
sourceDirectoryChanges.Clear();
|
|
||||||
if (firstPass)
|
|
||||||
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
|
|
||||||
filteredItems = (from l in container.Items where l.ImageFileHolder is not null && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray();
|
|
||||||
if (!filteredItems.Any())
|
|
||||||
continue;
|
|
||||||
totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
|
||||||
SetAngleBracketCollection(container.SourceDirectory);
|
|
||||||
ParallelWork(firstPass, exceptions, sourceDirectoryChanges, containersCount, container, filteredItems, totalSeconds);
|
|
||||||
foreach (Exception exception in exceptions)
|
|
||||||
_Log.Error(string.Concat(container.SourceDirectory, Environment.NewLine, exception.Message, Environment.NewLine, exception.StackTrace), exception);
|
|
||||||
if (exceptions.Count == filteredItems.Length)
|
|
||||||
throw new Exception(string.Concat("All in [", container.SourceDirectory, "]failed!"));
|
|
||||||
if (exceptions.Count != 0)
|
|
||||||
_ExceptionsDirectories.Add(container.SourceDirectory);
|
|
||||||
if (!firstPass || exceptions.Count != 0)
|
|
||||||
anyFilesMoved = null;
|
|
||||||
else
|
|
||||||
anyFilesMoved = AnyFilesMoved(container.SourceDirectory, filteredItems);
|
|
||||||
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
|
|
||||||
{
|
|
||||||
for (int y = 0; y < int.MaxValue; y++)
|
|
||||||
{
|
|
||||||
_Log.Information("Press \"Y\" key when ready to continue or close console");
|
|
||||||
if (Console.ReadKey().Key == ConsoleKey.Y)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_Log.Information(". . .");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public A_Property GetProperty(Item item, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions)
|
|
||||||
{
|
|
||||||
A_Property result;
|
|
||||||
if (item.ImageFileHolder is null)
|
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
|
||||||
bool firstPass = false;
|
|
||||||
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
|
||||||
bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
|
||||||
result = GetPropertyOfPrivate(item, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] GetPropertyIds(List<DirectoryInfo> groupCollection, bool saveToCollection)
|
|
||||||
{
|
|
||||||
List<(long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)> results = new();
|
|
||||||
int level;
|
|
||||||
A_Property? property;
|
|
||||||
string checkDirectory;
|
|
||||||
List<string> directories;
|
|
||||||
string propertyDirectory;
|
|
||||||
string angleBracket = AngleBracketCollection[0];
|
|
||||||
foreach (DirectoryInfo group in groupCollection)
|
|
||||||
{
|
|
||||||
SetAngleBracketCollection(group.SourceDirectory);
|
|
||||||
if (string.IsNullOrEmpty(group.SourceDirectory))
|
|
||||||
throw new Exception();
|
|
||||||
if (!saveToCollection)
|
|
||||||
propertyDirectory = angleBracket.Replace("<>", "()");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(level, directories) = IPath.Get(_Configuration.RootDirectory, group.SourceDirectory);
|
|
||||||
checkDirectory = IPath.GetDirectory(angleBracket, level, "[()]");
|
|
||||||
propertyDirectory = Path.Combine(checkDirectory, string.Join(_Configuration.FileNameDirectorySeparator, directories));
|
|
||||||
}
|
|
||||||
if (!Directory.Exists(propertyDirectory))
|
|
||||||
_ = Directory.CreateDirectory(propertyDirectory);
|
|
||||||
for (int i = 0; i < group.SourceDirectoryFileHolderCollection.Length; i++)
|
|
||||||
{
|
|
||||||
property = group.PropertyCollection[i];
|
|
||||||
if (property?.Id is null)
|
|
||||||
continue;
|
|
||||||
results.Add(new(property.GetDateTimes().Min().Ticks, group.FilteredSourceDirectoryFiles[i], propertyDirectory, property.Id.Value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results.OrderBy(l => l.Ticks).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddToPropertyLogicAllCollection(Item[] filteredItems)
|
|
||||||
{
|
|
||||||
if (_SixCharacterNamedFaceInfo.Any())
|
|
||||||
{
|
|
||||||
string[] keys;
|
|
||||||
Item item;
|
|
||||||
for (int i = 0; i < filteredItems.Length; i++)
|
|
||||||
{
|
|
||||||
item = filteredItems[i];
|
|
||||||
if (item.Property?.Id is null)
|
|
||||||
continue;
|
|
||||||
foreach (int sixCharacterIndex in item.Property.Indices)
|
|
||||||
{
|
|
||||||
if (!_SixCharacterNamedFaceInfo.ContainsKey(sixCharacterIndex))
|
|
||||||
continue;
|
|
||||||
keys = _SixCharacterNamedFaceInfo[sixCharacterIndex];
|
|
||||||
_AllCollection.Add(new(item.Property.Id.Value, keys));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveAllCollection()
|
|
||||||
{
|
|
||||||
if (_AllCollection.Any())
|
|
||||||
{
|
|
||||||
string[] keys;
|
|
||||||
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.RootDirectory);
|
|
||||||
if (string.IsNullOrEmpty(rootDirectoryParent))
|
|
||||||
throw new NullReferenceException(nameof(rootDirectoryParent));
|
|
||||||
Dictionary<int, string[]> namedFaceInfoDeterministicHashCodeIndices = new();
|
|
||||||
List<(int, string[])> allCollection = _AllCollection.OrderBy(l => l.Item1).ToList();
|
|
||||||
foreach ((int deterministicHashCode, string[] values) in allCollection)
|
|
||||||
{
|
|
||||||
if (namedFaceInfoDeterministicHashCodeIndices.ContainsKey(deterministicHashCode))
|
|
||||||
{
|
|
||||||
keys = namedFaceInfoDeterministicHashCodeIndices[deterministicHashCode];
|
|
||||||
if (JsonSerializer.Serialize(values) == JsonSerializer.Serialize(keys))
|
|
||||||
continue;
|
|
||||||
throw new Exception();
|
|
||||||
}
|
|
||||||
namedFaceInfoDeterministicHashCodeIndices.Add(deterministicHashCode, values);
|
|
||||||
}
|
|
||||||
string json = JsonSerializer.Serialize(namedFaceInfoDeterministicHashCodeIndices, new JsonSerializerOptions { WriteIndented = true });
|
|
||||||
string checkFile = Path.Combine(rootDirectoryParent, "NamedFaceInfoDeterministicHashCodeIndices.json");
|
|
||||||
_ = IPath.WriteAllText(checkFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Phares.Shared;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Property.Models.Stateless;
|
|
||||||
|
|
||||||
public abstract class Configuration
|
|
||||||
{
|
|
||||||
|
|
||||||
public static Models.Configuration Get(IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, string workingDirectory)
|
|
||||||
{
|
|
||||||
Models.Configuration? result;
|
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
|
||||||
string section = string.Concat(environmentName, ":", nameof(Binder.Configuration));
|
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
|
||||||
Binder.Configuration configuration = configurationSection.Get<Binder.Configuration>();
|
|
||||||
string json = JsonSerializer.Serialize(configuration, new JsonSerializerOptions() { WriteIndented = true });
|
|
||||||
result = JsonSerializer.Deserialize<Models.Configuration>(json);
|
|
||||||
if (result is null)
|
|
||||||
throw new Exception(json);
|
|
||||||
string jsonThis = result.ToString();
|
|
||||||
if (jsonThis != json)
|
|
||||||
{
|
|
||||||
int? check = null;
|
|
||||||
int min = new int[] { json.Length, jsonThis.Length }.Min();
|
|
||||||
for (int i = 0; i < min; i++)
|
|
||||||
{
|
|
||||||
if (json[i] == jsonThis[i])
|
|
||||||
continue;
|
|
||||||
check = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (check is null)
|
|
||||||
throw new Exception();
|
|
||||||
string a = json[..check.Value].Split(',')[^1];
|
|
||||||
string b = json[check.Value..].Split(',')[0];
|
|
||||||
throw new Exception($"{a}{b}");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
namespace View_by_Distance.Property.Models.Stateless;
|
namespace View_by_Distance.Property.Models.Stateless;
|
||||||
|
|
||||||
@ -98,67 +99,61 @@ public class Container
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetJsonGroupCollection(Models.Configuration configuration, PropertyLogic propertyLogic, string rootDirectory)
|
private static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetJsonGroupCollection(Configuration configuration, A_Property propertyLogic, string rootDirectory)
|
||||||
{
|
{
|
||||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results;
|
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results;
|
||||||
if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null)
|
|
||||||
throw new NullReferenceException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass));
|
|
||||||
string searchPattern = "*.json";
|
string searchPattern = "*.json";
|
||||||
List<string> topDirectories = new();
|
List<string> topDirectories = new();
|
||||||
results = GetGroupCollection(rootDirectory, configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value, propertyLogic.Reverse, searchPattern, topDirectories);
|
results = GetGroupCollection(rootDirectory, configuration.MaxImagesInDirectoryForTopLevelFirstPass, propertyLogic.Reverse, searchPattern, topDirectories);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> GetFileHolderGroupCollection(Models.Configuration configuration, PropertyLogic propertyLogic, string searchPattern, List<string> topDirectories)
|
private static List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> GetFileHolderGroupCollection(Configuration configuration, A_Property propertyLogic, string searchPattern, List<string> topDirectories)
|
||||||
{
|
{
|
||||||
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> results = new();
|
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> results = new();
|
||||||
if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null)
|
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)>? collection = GetGroupCollection(configuration.RootDirectory, configuration.MaxImagesInDirectoryForTopLevelFirstPass, propertyLogic.Reverse, searchPattern, topDirectories);
|
||||||
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)
|
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));
|
results.Add(new(g, sourceDirectory, (from l in sourceDirectoryFiles select new FileHolder(l)).ToArray(), r));
|
||||||
return results;
|
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)
|
private static void ParallelFor(List<(int, string, string[], int)> jsonCollection, int i, int length, List<(int, string, List<(string, Shared.Models.Property?)>, int)> results)
|
||||||
{
|
{
|
||||||
string key;
|
string key;
|
||||||
string json;
|
string json;
|
||||||
Models.A_Property? property;
|
Shared.Models.Property? property;
|
||||||
(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) = jsonCollection[i];
|
(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) = jsonCollection[i];
|
||||||
List<(string, Models.A_Property?)> collection = new();
|
List<(string, Shared.Models.Property?)> collection = new();
|
||||||
foreach (string sourceDirectoryFile in sourceDirectoryFiles)
|
foreach (string sourceDirectoryFile in sourceDirectoryFiles)
|
||||||
{
|
{
|
||||||
json = File.ReadAllText(sourceDirectoryFile);
|
json = File.ReadAllText(sourceDirectoryFile);
|
||||||
key = XPath.GetRelativePath(sourceDirectoryFile, length);
|
key = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFile, length);
|
||||||
property = JsonSerializer.Deserialize<Models.A_Property>(json);
|
property = JsonSerializer.Deserialize<Shared.Models.Property>(json);
|
||||||
collection.Add(new(sourceDirectoryFile, property));
|
collection.Add(new(sourceDirectoryFile, property));
|
||||||
}
|
}
|
||||||
lock (results)
|
lock (results)
|
||||||
results.Add(new(g, sourceDirectory, collection, r));
|
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)
|
private static List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Shared.Models.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();
|
List<(int, string, List<(string, Shared.Models.Property?)>, int)> results = new();
|
||||||
int length = rootDirectory.Length;
|
int length = rootDirectory.Length;
|
||||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = Environment.ProcessorCount };
|
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = Environment.ProcessorCount };
|
||||||
_ = Parallel.For(0, jsonCollection.Count, parallelOptions, i => ParallelFor(jsonCollection, i, length, results));
|
_ = Parallel.For(0, jsonCollection.Count, parallelOptions, i => ParallelFor(jsonCollection, i, length, results));
|
||||||
return 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)
|
private static List<Shared.Models.Container> GetContainers(Configuration configuration, string aPropertySingletonDirectory, List<(int, string, FileHolder[], int)> fileHolderGroupCollection, List<(int, string, List<(string, Shared.Models.Property?)>, int)> collectionFromJson)
|
||||||
{
|
{
|
||||||
List<Models.Container> results = new();
|
List<Shared.Models.Container> results = new();
|
||||||
if (configuration.PropertiesChangedForProperty is null)
|
|
||||||
throw new Exception($"{configuration.PropertiesChangedForProperty} is null");
|
|
||||||
int length;
|
int length;
|
||||||
string key;
|
string key;
|
||||||
string inferred;
|
string inferred;
|
||||||
List<Item> items;
|
List<Item> items;
|
||||||
string relativePath;
|
string relativePath;
|
||||||
FileHolder keyFileHolder;
|
FileHolder keyFileHolder;
|
||||||
Models.Container container;
|
Shared.Models.Container container;
|
||||||
bool isValidImageFormatExtension;
|
bool isValidImageFormatExtension;
|
||||||
List<string> keySourceDirectories;
|
List<string> keySourceDirectories;
|
||||||
Dictionary<string, (string SourceDirectory, FileHolder FileHolder)> fileHolderKeyValuePairs = new();
|
Dictionary<string, (string SourceDirectory, FileHolder FileHolder)> fileHolderKeyValuePairs = new();
|
||||||
@ -167,21 +162,21 @@ public class Container
|
|||||||
{
|
{
|
||||||
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
|
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
|
||||||
{
|
{
|
||||||
relativePath = XPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length);
|
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length);
|
||||||
key = string.Concat(relativePath, ".json");
|
key = string.Concat(relativePath, ".json");
|
||||||
fileHolderKeyValuePairs.Add(key, new(sourceDirectory, sourceDirectoryFileHolder));
|
fileHolderKeyValuePairs.Add(key, new(sourceDirectory, sourceDirectoryFileHolder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
length = aPropertySingletonDirectory.Length;
|
length = aPropertySingletonDirectory.Length;
|
||||||
foreach ((int g, string _, List<(string, Models.A_Property?)> collection, int r) in collectionFromJson)
|
foreach ((int g, string _, List<(string, Shared.Models.Property?)> collection, int r) in collectionFromJson)
|
||||||
{
|
{
|
||||||
if (!collection.Any())
|
if (!collection.Any())
|
||||||
continue;
|
continue;
|
||||||
items = new();
|
items = new();
|
||||||
keySourceDirectories = new();
|
keySourceDirectories = new();
|
||||||
foreach ((string sourceDirectoryFile, Models.A_Property? property) in collection)
|
foreach ((string sourceDirectoryFile, Shared.Models.Property? property) in collection)
|
||||||
{
|
{
|
||||||
key = XPath.GetRelativePath(sourceDirectoryFile, length);
|
key = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFile, length);
|
||||||
relativePath = key[..^5];
|
relativePath = key[..^5];
|
||||||
if (!fileHolderKeyValuePairs.ContainsKey(key))
|
if (!fileHolderKeyValuePairs.ContainsKey(key))
|
||||||
{
|
{
|
||||||
@ -204,7 +199,7 @@ public class Container
|
|||||||
isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered);
|
isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered);
|
||||||
if (property?.Id is null || property?.Width is null || property?.Height is null)
|
if (property?.Id is null || property?.Width is null || property?.Height is null)
|
||||||
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, null));
|
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, null));
|
||||||
else if (configuration.PropertiesChangedForProperty.Value || property.LastWriteTime != keyFileHolder.LastWriteTime || property.FileSize != keyFileHolder.Length)
|
else if (configuration.PropertiesChangedForProperty || property.LastWriteTime != keyFileHolder.LastWriteTime || property.FileSize != keyFileHolder.Length)
|
||||||
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, true));
|
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, true));
|
||||||
else
|
else
|
||||||
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, false));
|
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, false));
|
||||||
@ -224,7 +219,7 @@ public class Container
|
|||||||
items = new();
|
items = new();
|
||||||
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
|
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
|
||||||
{
|
{
|
||||||
relativePath = XPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length);
|
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length);
|
||||||
key = string.Concat(relativePath, ".json");
|
key = string.Concat(relativePath, ".json");
|
||||||
if (!fileHolderKeyValuePairs.ContainsKey(key))
|
if (!fileHolderKeyValuePairs.ContainsKey(key))
|
||||||
continue;
|
continue;
|
||||||
@ -247,16 +242,15 @@ public class Container
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Models.Container> GetContainers(Models.Configuration configuration, PropertyLogic propertyLogic)
|
public static List<Shared.Models.Container> GetContainers(Configuration configuration, A_Property propertyLogic)
|
||||||
{
|
{
|
||||||
List<Models.Container> results;
|
List<Shared.Models.Container> results;
|
||||||
string searchPattern = "*";
|
string searchPattern = "*";
|
||||||
long ticks = DateTime.Now.Ticks;
|
|
||||||
List<string> topDirectories = new();
|
List<string> topDirectories = new();
|
||||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> jsonCollection;
|
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> jsonCollection;
|
||||||
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> fileHolderGroupCollection;
|
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> fileHolderGroupCollection;
|
||||||
string aPropertySingletonDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
string aPropertySingletonDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||||
List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Models.A_Property? property)> collection, int r)> collectionFromJson;
|
List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Shared.Models.Property? property)> collection, int r)> collectionFromJson;
|
||||||
jsonCollection = GetJsonGroupCollection(configuration, propertyLogic, aPropertySingletonDirectory);
|
jsonCollection = GetJsonGroupCollection(configuration, propertyLogic, aPropertySingletonDirectory);
|
||||||
fileHolderGroupCollection = GetFileHolderGroupCollection(configuration, propertyLogic, searchPattern, topDirectories);
|
fileHolderGroupCollection = GetFileHolderGroupCollection(configuration, propertyLogic, searchPattern, topDirectories);
|
||||||
collectionFromJson = GetCollection(aPropertySingletonDirectory, jsonCollection);
|
collectionFromJson = GetCollection(aPropertySingletonDirectory, jsonCollection);
|
||||||
|
@ -10,32 +10,32 @@ public interface IResult
|
|||||||
public const string Collection = "[]";
|
public const string Collection = "[]";
|
||||||
public const string AllInOne = "_ _ _";
|
public const string AllInOne = "_ _ _";
|
||||||
|
|
||||||
string TestStatic_GetRelativePath(Models.Configuration configuration, string path);
|
string TestStatic_GetRelativePath(Configuration configuration, string path);
|
||||||
static string GetRelativePath(Models.Configuration configuration, string path)
|
static string GetRelativePath(Configuration configuration, string path)
|
||||||
=> Result.GetRelativePath(configuration, path);
|
=> Result.GetRelativePath(configuration, path);
|
||||||
|
|
||||||
string TestStatic_GetResultsGroupDirectory(Models.Configuration configuration, string description);
|
string TestStatic_GetResultsGroupDirectory(Configuration configuration, string description);
|
||||||
static string GetResultsGroupDirectory(Models.Configuration configuration, string description)
|
static string GetResultsGroupDirectory(Configuration configuration, string description)
|
||||||
=> Result.GetResultsGroupDirectory(configuration, description);
|
=> Result.GetResultsGroupDirectory(configuration, description);
|
||||||
|
|
||||||
string TestStatic_GetResultsDateGroupDirectory(Models.Configuration configuration, string description);
|
string TestStatic_GetResultsDateGroupDirectory(Configuration configuration, string description);
|
||||||
static string GetResultsDateGroupDirectory(Models.Configuration configuration, string description)
|
static string GetResultsDateGroupDirectory(Configuration configuration, string description)
|
||||||
=> Result.GetResultsDateGroupDirectory(configuration, description);
|
=> Result.GetResultsDateGroupDirectory(configuration, description);
|
||||||
|
|
||||||
string TestStatic_GetResultsDateGroupDirectory(Models.Configuration configuration, string description, string jsonGroup);
|
string TestStatic_GetResultsDateGroupDirectory(Configuration configuration, string description, string jsonGroup);
|
||||||
static string GetResultsDateGroupDirectory(Models.Configuration configuration, string description, string jsonGroup)
|
static string GetResultsDateGroupDirectory(Configuration configuration, string description, string jsonGroup)
|
||||||
=> Result.GetResultsDateGroupDirectory(configuration, description, jsonGroup);
|
=> Result.GetResultsDateGroupDirectory(configuration, description, jsonGroup);
|
||||||
|
|
||||||
List<string> TestStatic_GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription);
|
List<string> TestStatic_GetDirectoryInfoCollection(Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription);
|
||||||
static List<string> GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted)
|
static List<string> GetDirectoryInfoCollection(Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted)
|
||||||
=> Result.GetDirectoryInfoCollection(configuration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted);
|
=> Result.GetDirectoryInfoCollection(configuration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted);
|
||||||
|
|
||||||
string TestStatic_GetResultsFullGroupDirectory(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel);
|
string TestStatic_GetResultsFullGroupDirectory(Configuration configuration, Model? model, PredictorModel? predictorModel, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel);
|
||||||
static string GetResultsFullGroupDirectory(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel)
|
static string GetResultsFullGroupDirectory(Configuration configuration, Model? model, PredictorModel? predictorModel, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel)
|
||||||
=> Result.GetResultsFullGroupDirectory(configuration, model, predictorModel, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
|
=> Result.GetResultsFullGroupDirectory(configuration, model, predictorModel, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
|
||||||
|
|
||||||
List<string> TestStatic_GetDirectoryInfoCollection(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription);
|
List<string> TestStatic_GetDirectoryInfoCollection(Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription);
|
||||||
static List<string> GetDirectoryInfoCollection(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription)
|
static List<string> GetDirectoryInfoCollection(Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription)
|
||||||
=> Result.GetDirectoryInfoCollection(configuration, model, predictorModel, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription);
|
=> Result.GetDirectoryInfoCollection(configuration, model, predictorModel, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription);
|
||||||
|
|
||||||
}
|
}
|
@ -5,13 +5,13 @@ namespace View_by_Distance.Property.Models.Stateless;
|
|||||||
internal class Result
|
internal class Result
|
||||||
{
|
{
|
||||||
|
|
||||||
internal static string GetRelativePath(Models.Configuration configuration, string path)
|
internal static string GetRelativePath(Configuration configuration, string path)
|
||||||
{
|
{
|
||||||
string result = XPath.GetRelativePath(path, configuration.RootDirectory.Length);
|
string result = Shared.Models.Stateless.Methods.IPath.GetRelativePath(path, configuration.RootDirectory.Length);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string GetResultsGroupDirectory(Models.Configuration configuration, string description)
|
internal static string GetResultsGroupDirectory(Configuration configuration, string description)
|
||||||
{
|
{
|
||||||
string result = Path.Combine($"{configuration.RootDirectory} - Results", description.Replace("_", ") "));
|
string result = Path.Combine($"{configuration.RootDirectory} - Results", description.Replace("_", ") "));
|
||||||
if (!Directory.Exists(result))
|
if (!Directory.Exists(result))
|
||||||
@ -19,7 +19,7 @@ internal class Result
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string GetResultsDateGroupDirectory(Models.Configuration configuration, string description)
|
internal static string GetResultsDateGroupDirectory(Configuration configuration, string description)
|
||||||
{
|
{
|
||||||
string result = Path.Combine(GetResultsGroupDirectory(configuration, description), configuration.DateGroup);
|
string result = Path.Combine(GetResultsGroupDirectory(configuration, description), configuration.DateGroup);
|
||||||
if (!Directory.Exists(result))
|
if (!Directory.Exists(result))
|
||||||
@ -27,7 +27,7 @@ internal class Result
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string GetResultsDateGroupDirectory(Models.Configuration configuration, string description, string jsonGroup)
|
internal static string GetResultsDateGroupDirectory(Configuration configuration, string description, string jsonGroup)
|
||||||
{
|
{
|
||||||
string result = Path.Combine(GetResultsDateGroupDirectory(configuration, description), jsonGroup);
|
string result = Path.Combine(GetResultsDateGroupDirectory(configuration, description), jsonGroup);
|
||||||
if (!Directory.Exists(result))
|
if (!Directory.Exists(result))
|
||||||
@ -35,7 +35,7 @@ internal class Result
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string GetResultsFullGroupDirectory(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel)
|
internal static string GetResultsFullGroupDirectory(Configuration configuration, Model? model, PredictorModel? predictorModel, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel)
|
||||||
{
|
{
|
||||||
string result = GetResultsDateGroupDirectory(configuration, description);
|
string result = GetResultsDateGroupDirectory(configuration, description);
|
||||||
if (includeResizeGroup)
|
if (includeResizeGroup)
|
||||||
@ -64,59 +64,69 @@ internal class Result
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<string> GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted)
|
private static void CheckContent(string dateGroupDirectory, string contentDescription, string result)
|
||||||
|
{
|
||||||
|
string checkDirectory;
|
||||||
|
checkDirectory = Path.Combine(dateGroupDirectory, IResult.Content, IResult.AllInOne);
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
string contentDirectory = new(result.Replace("<>", IResult.Content));
|
||||||
|
if (!Directory.Exists(contentDirectory))
|
||||||
|
_ = Directory.CreateDirectory(contentDirectory);
|
||||||
|
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("() - ", contentDescription));
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CheckSingleton(string dateGroupDirectory, string singletonDescription, bool converted, string result)
|
||||||
|
{
|
||||||
|
string checkDirectory;
|
||||||
|
checkDirectory = Path.Combine(dateGroupDirectory, IResult.Singleton, IResult.AllInOne);
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
if (!converted)
|
||||||
|
{
|
||||||
|
string singletonDirectory = new(result.Replace("<>", IResult.Singleton));
|
||||||
|
if (!Directory.Exists(singletonDirectory))
|
||||||
|
_ = Directory.CreateDirectory(singletonDirectory);
|
||||||
|
}
|
||||||
|
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("{} - ", singletonDescription));
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CheckCollection(string dateGroupDirectory, string collectionDescription, bool converted, string result)
|
||||||
|
{
|
||||||
|
string checkDirectory = Path.Combine(dateGroupDirectory, IResult.Collection, IResult.AllInOne);
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
if (!converted)
|
||||||
|
{
|
||||||
|
string collectionDirectory = new(result.Replace("<>", IResult.Collection));
|
||||||
|
if (!Directory.Exists(collectionDirectory))
|
||||||
|
_ = Directory.CreateDirectory(collectionDirectory);
|
||||||
|
}
|
||||||
|
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("[] - ", collectionDescription));
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static List<string> GetDirectoryInfoCollection(Configuration configuration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted)
|
||||||
{
|
{
|
||||||
List<string> results = new();
|
List<string> results = new();
|
||||||
string checkDirectory;
|
|
||||||
string sourceDirectorySegment = GetRelativePath(configuration, sourceDirectory);
|
string sourceDirectorySegment = GetRelativePath(configuration, sourceDirectory);
|
||||||
string result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment);
|
string result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment);
|
||||||
if (!string.IsNullOrEmpty(contentDescription))
|
if (!string.IsNullOrEmpty(contentDescription))
|
||||||
{
|
CheckContent(dateGroupDirectory, contentDescription, result);
|
||||||
checkDirectory = Path.Combine(dateGroupDirectory, IResult.Content, IResult.AllInOne);
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
string contentDirectory = new(result.Replace("<>", IResult.Content));
|
|
||||||
if (!Directory.Exists(contentDirectory))
|
|
||||||
_ = Directory.CreateDirectory(contentDirectory);
|
|
||||||
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("() - ", contentDescription));
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
}
|
|
||||||
if (!string.IsNullOrEmpty(singletonDescription))
|
if (!string.IsNullOrEmpty(singletonDescription))
|
||||||
{
|
CheckSingleton(dateGroupDirectory, singletonDescription, converted, result);
|
||||||
checkDirectory = Path.Combine(dateGroupDirectory, IResult.Singleton, IResult.AllInOne);
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
if (!converted)
|
|
||||||
{
|
|
||||||
string singletonDirectory = new(result.Replace("<>", IResult.Singleton));
|
|
||||||
if (!Directory.Exists(singletonDirectory))
|
|
||||||
_ = Directory.CreateDirectory(singletonDirectory);
|
|
||||||
}
|
|
||||||
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("{} - ", singletonDescription));
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
}
|
|
||||||
if (!string.IsNullOrEmpty(collectionDescription))
|
if (!string.IsNullOrEmpty(collectionDescription))
|
||||||
{
|
CheckCollection(dateGroupDirectory, collectionDescription, converted, result);
|
||||||
checkDirectory = Path.Combine(dateGroupDirectory, IResult.Collection, IResult.AllInOne);
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
if (!converted)
|
|
||||||
{
|
|
||||||
string collectionDirectory = new(result.Replace("<>", IResult.Collection));
|
|
||||||
if (!Directory.Exists(collectionDirectory))
|
|
||||||
_ = Directory.CreateDirectory(collectionDirectory);
|
|
||||||
}
|
|
||||||
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("[] - ", collectionDescription));
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
}
|
|
||||||
results.Add(result);
|
results.Add(result);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<string> GetDirectoryInfoCollection(Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription)
|
internal static List<string> GetDirectoryInfoCollection(Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription)
|
||||||
{
|
{
|
||||||
List<string> results;
|
List<string> results;
|
||||||
bool converted = false;
|
bool converted = false;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Phares.View.by.Distance.Property</PackageId>
|
<PackageId>Phares.View.by.Distance.Property</PackageId>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<Version>5.0.402.104</Version>
|
<Version>6.0.100.1</Version>
|
||||||
<Authors>Mike Phares</Authors>
|
<Authors>Mike Phares</Authors>
|
||||||
<Company>Phares</Company>
|
<Company>Phares</Company>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
@ -6,7 +6,6 @@ using System.Runtime.InteropServices;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using View_by_Distance.Metadata.Models;
|
using View_by_Distance.Metadata.Models;
|
||||||
using View_by_Distance.Property.Models;
|
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
|
|
||||||
namespace View_by_Distance.Resize.Models;
|
namespace View_by_Distance.Resize.Models;
|
||||||
@ -19,6 +18,9 @@ public class C_Resize
|
|||||||
|
|
||||||
public List<string> AngleBracketCollection { get; }
|
public List<string> AngleBracketCollection { get; }
|
||||||
|
|
||||||
|
protected readonly string _FilenameExtension;
|
||||||
|
public string FilenameExtension => _FilenameExtension;
|
||||||
|
|
||||||
private readonly Serilog.ILogger? _Log;
|
private readonly Serilog.ILogger? _Log;
|
||||||
private readonly int _TempResolutionWidth;
|
private readonly int _TempResolutionWidth;
|
||||||
private readonly int _TempResolutionHeight;
|
private readonly int _TempResolutionHeight;
|
||||||
@ -35,7 +37,7 @@ public class C_Resize
|
|||||||
private readonly bool _ForceResizeLastWriteTimeToCreationTime;
|
private readonly bool _ForceResizeLastWriteTimeToCreationTime;
|
||||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||||
|
|
||||||
public C_Resize(bool forceResizeLastWriteTimeToCreationTime, bool overrideForResizeImages, bool propertiesChangedForResize, string[] validResolutions, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters)
|
public C_Resize(bool forceResizeLastWriteTimeToCreationTime, bool overrideForResizeImages, bool propertiesChangedForResize, string[] validResolutions, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension)
|
||||||
{
|
{
|
||||||
_TempResolutionWidth = 3;
|
_TempResolutionWidth = 3;
|
||||||
_TempResolutionHeight = 4;
|
_TempResolutionHeight = 4;
|
||||||
@ -46,6 +48,7 @@ public class C_Resize
|
|||||||
_ValidResolutions = validResolutions;
|
_ValidResolutions = validResolutions;
|
||||||
_OutputResolutionOrientationIndex = 2;
|
_OutputResolutionOrientationIndex = 2;
|
||||||
_EncoderParameters = encoderParameters;
|
_EncoderParameters = encoderParameters;
|
||||||
|
_FilenameExtension = filenameExtension;
|
||||||
_Log = Serilog.Log.ForContext<C_Resize>();
|
_Log = Serilog.Log.ForContext<C_Resize>();
|
||||||
AngleBracketCollection = new List<string>();
|
AngleBracketCollection = new List<string>();
|
||||||
_OverrideForResizeImages = overrideForResizeImages;
|
_OverrideForResizeImages = overrideForResizeImages;
|
||||||
@ -66,14 +69,44 @@ public class C_Resize
|
|||||||
|
|
||||||
#pragma warning disable CA1416
|
#pragma warning disable CA1416
|
||||||
|
|
||||||
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters) GetTuple(string outputExtension, int outputQuality)
|
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetGifLowQuality()
|
||||||
{
|
{
|
||||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters) result;
|
(ImageCodecInfo, EncoderParameters, string) result;
|
||||||
|
System.Drawing.Imaging.ImageFormat imageFormat = System.Drawing.Imaging.ImageFormat.Gif;
|
||||||
|
ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
|
||||||
|
EncoderParameters encoderParameters = new(1);
|
||||||
|
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
|
||||||
|
if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
|
||||||
|
throw new NullReferenceException(nameof(imageCodecInfo.FilenameExtension));
|
||||||
|
result = new(imageCodecInfo, encoderParameters, imageCodecInfo.FilenameExtension.Split(';')[0].ToLower()[1..]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetPngLowQuality()
|
||||||
|
{
|
||||||
|
(ImageCodecInfo, EncoderParameters, string) result;
|
||||||
|
System.Drawing.Imaging.ImageFormat imageFormat = System.Drawing.Imaging.ImageFormat.Png;
|
||||||
|
ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
|
||||||
|
EncoderParameters encoderParameters = new(1);
|
||||||
|
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
|
||||||
|
if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
|
||||||
|
throw new NullReferenceException(nameof(imageCodecInfo.FilenameExtension));
|
||||||
|
result = new(imageCodecInfo, encoderParameters, imageCodecInfo.FilenameExtension.Split(';')[0].ToLower()[1..]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetTuple(string outputExtension, int outputQuality)
|
||||||
|
{
|
||||||
|
(ImageCodecInfo, EncoderParameters, string) result;
|
||||||
System.Drawing.Imaging.ImageFormat imageFormat = outputExtension switch
|
System.Drawing.Imaging.ImageFormat imageFormat = outputExtension switch
|
||||||
{
|
{
|
||||||
".gif" => System.Drawing.Imaging.ImageFormat.Gif,
|
".gif" => System.Drawing.Imaging.ImageFormat.Gif,
|
||||||
|
".jfif" => System.Drawing.Imaging.ImageFormat.Jpeg,
|
||||||
|
".jpe" => System.Drawing.Imaging.ImageFormat.Jpeg,
|
||||||
|
".jpeg" => System.Drawing.Imaging.ImageFormat.Jpeg,
|
||||||
".jpg" => System.Drawing.Imaging.ImageFormat.Jpeg,
|
".jpg" => System.Drawing.Imaging.ImageFormat.Jpeg,
|
||||||
".png" => System.Drawing.Imaging.ImageFormat.Png,
|
".png" => System.Drawing.Imaging.ImageFormat.Png,
|
||||||
|
".tif" => System.Drawing.Imaging.ImageFormat.Tiff,
|
||||||
".tiff" => System.Drawing.Imaging.ImageFormat.Tiff,
|
".tiff" => System.Drawing.Imaging.ImageFormat.Tiff,
|
||||||
_ => throw new Exception(),
|
_ => throw new Exception(),
|
||||||
};
|
};
|
||||||
@ -82,7 +115,9 @@ public class C_Resize
|
|||||||
// encoderParameters.Param[0] = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, CType(75L, Int32)) 'Default
|
// encoderParameters.Param[0] = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, CType(75L, Int32)) 'Default
|
||||||
// encoderParameters.Param[0] = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, CType(95L, Int32)) 'Paint
|
// encoderParameters.Param[0] = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, CType(95L, Int32)) 'Paint
|
||||||
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, outputQuality);
|
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, outputQuality);
|
||||||
result = new(imageCodecInfo, encoderParameters);
|
if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
|
||||||
|
throw new NullReferenceException(nameof(imageCodecInfo.FilenameExtension));
|
||||||
|
result = new(imageCodecInfo, encoderParameters, imageCodecInfo.FilenameExtension.Split(';')[0].ToLower()[1..]);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +164,7 @@ public class C_Resize
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] SaveResizedSubfile3(string subFile, int[] resize, byte[] bytes, FileHolder? fileHolder)
|
private byte[] SaveResizedSubfile3(string subFile, int[] resize, byte[] bytes, Shared.Models.FileHolder? fileHolder)
|
||||||
{
|
{
|
||||||
byte[] results;
|
byte[] results;
|
||||||
Bitmap bitmap;
|
Bitmap bitmap;
|
||||||
@ -181,7 +216,7 @@ public class C_Resize
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] SaveResizedSubfile5(string subFile, int[] resize, byte[] bytes, FileHolder? fileHolder)
|
private byte[] SaveResizedSubfile5(string subFile, int[] resize, byte[] bytes, Shared.Models.FileHolder? fileHolder)
|
||||||
{
|
{
|
||||||
byte[] results;
|
byte[] results;
|
||||||
Bitmap bitmap;
|
Bitmap bitmap;
|
||||||
@ -248,11 +283,11 @@ public class C_Resize
|
|||||||
|
|
||||||
#pragma warning restore CA1416
|
#pragma warning restore CA1416
|
||||||
|
|
||||||
private byte[] SaveResizedSubfile(string subFile, A_Property property, int[] resize, FileHolder? fileHolder)
|
private byte[] SaveResizedSubfile(string subFile, Shared.Models.Property property, int[] resize, Shared.Models.FileHolder? fileHolder)
|
||||||
{
|
{
|
||||||
byte[] results;
|
byte[] results;
|
||||||
string dateTimeFormat = Property.Models.Stateless.A_Property.DateTimeFormat();
|
string dateTimeFormat = Shared.Models.Stateless.Methods.IProperty.DateTimeFormat();
|
||||||
DateTime dateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(property);
|
DateTime dateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(property);
|
||||||
string dateTimeValue = dateTime.ToString(dateTimeFormat);
|
string dateTimeValue = dateTime.ToString(dateTimeFormat);
|
||||||
byte[] bytes = _ASCIIEncoding.GetBytes(dateTimeValue);
|
byte[] bytes = _ASCIIEncoding.GetBytes(dateTimeValue);
|
||||||
if (_ASCIIEncoding.GetString(bytes, 0, bytes.Length) != dateTimeValue)
|
if (_ASCIIEncoding.GetString(bytes, 0, bytes.Length) != dateTimeValue)
|
||||||
@ -284,7 +319,7 @@ public class C_Resize
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetResizedBytes(string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Item item, A_Property property, Dictionary<string, int[]> imageResizes)
|
public byte[] GetResizedBytes(string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Shared.Models.Item item, Shared.Models.Property property, Dictionary<string, int[]> imageResizes)
|
||||||
{
|
{
|
||||||
byte[] results;
|
byte[] results;
|
||||||
if (item.ImageFileHolder is null)
|
if (item.ImageFileHolder is null)
|
||||||
@ -300,7 +335,7 @@ public class C_Resize
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveResizedSubfile(string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Item item, string original, Dictionary<string, int[]> imageResizes)
|
public void SaveResizedSubfile(string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Shared.Models.Item item, string original, Dictionary<string, int[]> imageResizes)
|
||||||
{
|
{
|
||||||
if (item.Property is null)
|
if (item.Property is null)
|
||||||
throw new NullReferenceException(nameof(item.Property));
|
throw new NullReferenceException(nameof(item.Property));
|
||||||
@ -308,7 +343,7 @@ public class C_Resize
|
|||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
if (item.ResizedFileHolder is null)
|
if (item.ResizedFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(item.ResizedFileHolder));
|
throw new NullReferenceException(nameof(item.ResizedFileHolder));
|
||||||
FileHolder fileHolder = item.ResizedFileHolder;
|
Shared.Models.FileHolder fileHolder = item.ResizedFileHolder;
|
||||||
if (!imageResizes.ContainsKey(outputResolution))
|
if (!imageResizes.ContainsKey(outputResolution))
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (!fileHolder.Exists)
|
if (!fileHolder.Exists)
|
||||||
@ -320,7 +355,7 @@ public class C_Resize
|
|||||||
if (File.Exists(parentCheck))
|
if (File.Exists(parentCheck))
|
||||||
{
|
{
|
||||||
File.Move(parentCheck, fileInfo.FullName);
|
File.Move(parentCheck, fileInfo.FullName);
|
||||||
item.SetResizedFileHolder(FileHolder.Refresh(fileHolder));
|
item.SetResizedFileHolder(_FilenameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(fileHolder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int[] resize = imageResizes[outputResolution];
|
int[] resize = imageResizes[outputResolution];
|
||||||
@ -339,7 +374,7 @@ public class C_Resize
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool check = false;
|
bool check = false;
|
||||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
|
string[] changesFrom = new string[] { nameof(Property.Models.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();
|
||||||
if (_OverrideForResizeImages)
|
if (_OverrideForResizeImages)
|
||||||
check = true;
|
check = true;
|
||||||
@ -378,7 +413,7 @@ public class C_Resize
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, int[]> GetImageResizes(A_Property property, List<KeyValuePair<string, string>> metadataCollection, string original)
|
private Dictionary<string, int[]> GetImageResizes(Shared.Models.Property property, List<KeyValuePair<string, string>> metadataCollection, string original)
|
||||||
{
|
{
|
||||||
Dictionary<string, int[]> results = new();
|
Dictionary<string, int[]> results = new();
|
||||||
int[] desired;
|
int[] desired;
|
||||||
@ -424,7 +459,7 @@ public class C_Resize
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, int[]> GetResizeKeyValuePairs(string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string original, List<KeyValuePair<string, string>> metadataCollection, Item item)
|
public Dictionary<string, int[]> GetResizeKeyValuePairs(string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string original, List<KeyValuePair<string, string>> metadataCollection, Shared.Models.Item item)
|
||||||
{
|
{
|
||||||
Dictionary<string, int[]> results;
|
Dictionary<string, int[]> results;
|
||||||
if (item.Property?.Id is null)
|
if (item.Property?.Id is null)
|
||||||
@ -432,7 +467,7 @@ public class C_Resize
|
|||||||
if (item.ImageFileHolder is null)
|
if (item.ImageFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
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(Property.Models.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();
|
||||||
string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "{}"), string.Concat(item.ImageFileHolder.NameWithoutExtension, ".json"));
|
string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "{}"), string.Concat(item.ImageFileHolder.NameWithoutExtension, ".json"));
|
||||||
string cResizeSingletonFile = Path.Combine(cResultsFullGroupDirectory, "{}", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
|
string cResizeSingletonFile = Path.Combine(cResultsFullGroupDirectory, "{}", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
|
||||||
@ -504,7 +539,7 @@ public class C_Resize
|
|||||||
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();
|
||||||
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
||||||
{
|
{
|
||||||
if (!_ForceResizeLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
|
if (!_ForceResizeLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
|
||||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Phares.View.by.Distance.Resize</PackageId>
|
<PackageId>Phares.View.by.Distance.Resize</PackageId>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<Version>5.0.402.104</Version>
|
<Version>6.0.100.1</Version>
|
||||||
<Authors>Mike Phares</Authors>
|
<Authors>Mike Phares</Authors>
|
||||||
<Company>Phares</Company>
|
<Company>Phares</Company>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
1
Shared/.vscode/format-report.json
vendored
Normal file
1
Shared/.vscode/format-report.json
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
[]
|
@ -1,14 +1,10 @@
|
|||||||
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Shared.Models;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Property.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class Closest
|
public class Closest : Properties.IClosest
|
||||||
{
|
{
|
||||||
public const int MaximumPer = 50;
|
|
||||||
public const float MaximumMinimum = 0.50f;
|
|
||||||
public const bool SkipIsWrongYear = true;
|
|
||||||
public const float MinimumMinimum = 0.05f;
|
|
||||||
|
|
||||||
protected readonly double? _Average;
|
protected readonly double? _Average;
|
||||||
protected readonly int? _NormalizedPixelPercentage;
|
protected readonly int? _NormalizedPixelPercentage;
|
||||||
@ -36,14 +32,16 @@ public class Closest
|
|||||||
|
|
||||||
public Closest(int? normalizedPixelPercentage, DateTime minimumDateTime, bool? isWrongYear) :
|
public Closest(int? normalizedPixelPercentage, DateTime minimumDateTime, bool? isWrongYear) :
|
||||||
this(null, normalizedPixelPercentage, isWrongYear, null, minimumDateTime, null)
|
this(null, normalizedPixelPercentage, isWrongYear, null, minimumDateTime, null)
|
||||||
{
|
{ }
|
||||||
}
|
|
||||||
|
|
||||||
public Closest(int? normalizedPixelPercentage, DateTime minimumDateTime, bool? isWrongYear, PersonBirthday? personBirthday, List<double> faceDistances) :
|
public Closest(int? normalizedPixelPercentage, DateTime minimumDateTime, bool? isWrongYear, PersonBirthday? personBirthday, List<double> faceDistances) :
|
||||||
this(faceDistances.Average(), normalizedPixelPercentage, isWrongYear, faceDistances.Min(), minimumDateTime, personBirthday)
|
this(faceDistances.Average(), normalizedPixelPercentage, isWrongYear, faceDistances.Min(), minimumDateTime, personBirthday)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Closest[] Get(List<Closest> collection) => (from l in collection orderby l.Minimum < MinimumMinimum, l.Average select l).ToArray();
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,8 +1,9 @@
|
|||||||
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace View_by_Distance.Property.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class Container
|
public class Container : Properties.IContainer
|
||||||
{
|
{
|
||||||
|
|
||||||
protected readonly int _G;
|
protected readonly int _G;
|
||||||
@ -31,4 +32,10 @@ public class Container
|
|||||||
_SourceDirectory = sourceDirectory;
|
_SourceDirectory = sourceDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,10 +1,9 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class DirectoryFileSystem : FileSystem, Properties.IDirectoryFileSystem, IDirectoryFileSystem
|
public class DirectoryFileSystem : FileSystem, Properties.IDirectoryFileSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
// protected new string _ClassName;
|
// protected new string _ClassName;
|
||||||
|
@ -1,38 +1,32 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.FaceRecognitionDotNet;
|
|
||||||
using View_by_Distance.Property.Models;
|
|
||||||
using View_by_Distance.Shared.Models.Properties;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Instance.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
internal class DistanceHolder
|
public class DistanceHolder : Properties.IDistanceHolder
|
||||||
{
|
{
|
||||||
|
|
||||||
public IFace Face { init; get; }
|
public Face Face { init; get; }
|
||||||
public FaceEncoding? FaceEncoding { init; get; }
|
|
||||||
public FileHolder FileHolder { init; get; }
|
public FileHolder FileHolder { init; get; }
|
||||||
public int Id { init; get; }
|
public int Id { init; get; }
|
||||||
public string JSONDirectory { init; get; }
|
public string JSONDirectory { init; get; }
|
||||||
public ILocation Location { init; get; }
|
public Location? Location { init; get; }
|
||||||
public string TSVDirectory { init; get; }
|
public string TSVDirectory { init; get; }
|
||||||
public double Sort { get; set; }
|
public double Sort { get; set; }
|
||||||
|
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
public DistanceHolder(
|
public DistanceHolder(
|
||||||
IFace face,
|
Face face,
|
||||||
FaceEncoding? faceEncoding,
|
|
||||||
FileHolder fileHolder,
|
FileHolder fileHolder,
|
||||||
int id,
|
int id,
|
||||||
string jsonDirectory,
|
string jsonDirectory,
|
||||||
ILocation location,
|
Location? location,
|
||||||
string tsvDirectory
|
string tsvDirectory
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FileHolder = fileHolder;
|
FileHolder = fileHolder;
|
||||||
Sort = double.MaxValue;
|
Sort = double.MaxValue;
|
||||||
Face = face;
|
Face = face;
|
||||||
FaceEncoding = faceEncoding;
|
|
||||||
Id = id;
|
Id = id;
|
||||||
JSONDirectory = jsonDirectory;
|
JSONDirectory = jsonDirectory;
|
||||||
Location = location;
|
Location = location;
|
@ -1,52 +1,68 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class Face : Properties.IFace, IFace
|
public class Face : Properties.IFace
|
||||||
{
|
{
|
||||||
|
|
||||||
protected double? _Α;
|
|
||||||
protected DateTime _DateTime;
|
protected DateTime _DateTime;
|
||||||
protected FaceEncoding _FaceEncoding;
|
protected FaceEncoding? _FaceEncoding;
|
||||||
protected Dictionary<string, FacePoint[]> _FaceLandmarks;
|
protected Dictionary<Stateless.FacePart, FacePoint[]>? _FaceParts;
|
||||||
protected OutputResolution _OutputResolution;
|
protected readonly OutputResolution? _OutputResolution;
|
||||||
protected Location _Location;
|
protected Location? _Location;
|
||||||
protected int? _LocationIndex;
|
protected readonly int? _LocationIndex;
|
||||||
protected bool _Populated;
|
protected readonly string _RelativePath;
|
||||||
protected string _RelativePath;
|
|
||||||
public double? α => _Α;
|
|
||||||
public DateTime DateTime => _DateTime;
|
public DateTime DateTime => _DateTime;
|
||||||
public FaceEncoding FaceEncoding => _FaceEncoding;
|
public FaceEncoding? FaceEncoding => _FaceEncoding;
|
||||||
public Dictionary<string, FacePoint[]> FaceLandmarks => _FaceLandmarks;
|
public Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts => _FaceParts;
|
||||||
public OutputResolution OutputResolution => _OutputResolution;
|
public Location? Location => _Location;
|
||||||
public Location Location => _Location;
|
|
||||||
public int? LocationIndex => _LocationIndex;
|
public int? LocationIndex => _LocationIndex;
|
||||||
public bool Populated => _Populated;
|
public OutputResolution? OutputResolution => _OutputResolution;
|
||||||
public string RelativePath => _RelativePath;
|
public string RelativePath => _RelativePath;
|
||||||
|
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
public Face(double? α, DateTime dateTime, FaceEncoding faceEncoding, Dictionary<string, FacePoint[]> faceLandmarks, OutputResolution outputResolution, Location location, int? locationIndex, bool populated, string relativePath)
|
public Face(DateTime dateTime, FaceEncoding? faceEncoding, Dictionary<Stateless.FacePart, FacePoint[]>? faceParts, Location? location, int? locationIndex, OutputResolution? outputResolution, string relativePath)
|
||||||
{
|
{
|
||||||
_Α = α;
|
|
||||||
_DateTime = dateTime;
|
_DateTime = dateTime;
|
||||||
_FaceEncoding = faceEncoding;
|
_FaceEncoding = faceEncoding;
|
||||||
_FaceLandmarks = faceLandmarks;
|
_FaceParts = faceParts;
|
||||||
_Location = location;
|
_Location = location;
|
||||||
_LocationIndex = locationIndex;
|
_LocationIndex = locationIndex;
|
||||||
_OutputResolution = outputResolution;
|
_OutputResolution = outputResolution;
|
||||||
_Populated = populated;
|
|
||||||
_RelativePath = relativePath;
|
_RelativePath = relativePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Stateless.Methods.IFace.TestStatic_Getα(int x1, int x2, int y1, int y2) => throw new NotImplementedException();
|
public Face() :
|
||||||
|
this(DateTime.MinValue, null, null, null, null, null, string.Empty)
|
||||||
|
{ }
|
||||||
|
|
||||||
string Stateless.Methods.IFace.TestStatic_GetJson(string jsonFileFullName) => throw new NotImplementedException();
|
public Face(Location location) :
|
||||||
|
this(DateTime.MinValue, null, null, location, null, null, string.Empty)
|
||||||
|
{ }
|
||||||
|
|
||||||
Face Stateless.Methods.IFace.TestStatic_GetFace(string jsonFileFullName) => throw new NotImplementedException();
|
public Face(int facesCount, Face face) :
|
||||||
|
this(face.DateTime, face.FaceEncoding, face.FaceParts, face.Location, face.LocationIndex, face.OutputResolution, face.RelativePath)
|
||||||
|
{
|
||||||
|
if (face.Location?.Confidence is not null && face.OutputResolution is not null)
|
||||||
|
_Location = new(face.Location.Confidence, face.OutputResolution.Height, face.Location, face.OutputResolution.Width, facesCount);
|
||||||
|
}
|
||||||
|
|
||||||
Face[] Stateless.Methods.IFace.TestStatic_GetFaces(string jsonFileFullName) => throw new NotImplementedException();
|
public Face(int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, Face face) :
|
||||||
|
this(face.DateTime, face.FaceEncoding, face.FaceParts, face.Location, face.LocationIndex, null, face.RelativePath)
|
||||||
|
{
|
||||||
|
if (outputResolutionHeight > 0)
|
||||||
|
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Face(Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string relativePath, int? i, Location? location) :
|
||||||
|
this(DateTime.MinValue, null, null, location, i, null, relativePath)
|
||||||
|
{
|
||||||
|
DateTime?[] dateTimes;
|
||||||
|
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
|
||||||
|
dateTimes = new DateTime?[] { property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
|
||||||
|
_DateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -54,4 +70,7 @@ public class Face : Properties.IFace, IFace
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetFaceEncoding(FaceEncoding faceEncoding) => _FaceEncoding = faceEncoding;
|
||||||
|
|
||||||
|
public void SetFaceParts(Dictionary<Stateless.FacePart, FacePoint[]> faceParts) => _FaceParts = faceParts;
|
||||||
}
|
}
|
@ -1,10 +1,9 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class FaceEncoding : Properties.IFaceEncoding, IFaceEncoding
|
public class FaceEncoding : Properties.IFaceEncoding
|
||||||
{
|
{
|
||||||
|
|
||||||
protected double[] _RawEncoding;
|
protected double[] _RawEncoding;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem, IFaceFileSystem
|
public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
// protected new string _ClassName;
|
// protected new string _ClassName;
|
||||||
@ -77,6 +76,38 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem, IFaceFileS
|
|||||||
_SourceSize = sourceSize;
|
_SourceSize = sourceSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void FileExists(Face face, int? faceBottom, int? faceRight, out int imageHeight, out int imageWidth, out long sourceSize, FileInfo fileInfo)
|
||||||
|
{
|
||||||
|
sourceSize = fileInfo.Length;
|
||||||
|
if (face.OutputResolution is not null)
|
||||||
|
{
|
||||||
|
imageWidth = face.OutputResolution.Width;
|
||||||
|
imageHeight = face.OutputResolution.Height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.Drawing.Size size = Stateless.Methods.ImageHelper.GetDimensions(fileInfo.FullName, faceRight, faceBottom);
|
||||||
|
imageWidth = size.Width;
|
||||||
|
imageHeight = size.Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FileDoesNotExist(string dataFullFileName, Face face, out int imageHeight, out int imageWidth, out long sourceSize, FileInfo fileInfo)
|
||||||
|
{
|
||||||
|
sourceSize = 0;
|
||||||
|
if (face.OutputResolution is null)
|
||||||
|
{
|
||||||
|
imageWidth = 0;
|
||||||
|
imageHeight = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
imageWidth = face.OutputResolution.Width;
|
||||||
|
imageHeight = face.OutputResolution.Height;
|
||||||
|
}
|
||||||
|
Stateless.Methods.IFaceFileSystem.SearchForMissingFile(fileInfo.FullName, fileInfo, dataFullFileName);
|
||||||
|
}
|
||||||
|
|
||||||
internal FaceFileSystem(string requestPath, int rootResultsDirectoryAbsoluteUriLength, string cResizeContent, string dFacesContentDirectory, string dataFullFileName, Face face) : base(string.Empty, string.Empty, dataFullFileName, string.Empty, DateTime.MinValue)
|
internal FaceFileSystem(string requestPath, int rootResultsDirectoryAbsoluteUriLength, string cResizeContent, string dFacesContentDirectory, string dataFullFileName, Face face) : base(string.Empty, string.Empty, dataFullFileName, string.Empty, DateTime.MinValue)
|
||||||
{
|
{
|
||||||
string confidence;
|
string confidence;
|
||||||
@ -130,38 +161,12 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem, IFaceFileS
|
|||||||
string faceRelativePath = string.Concat(requestPath, new Uri(faceFullFileName).AbsoluteUri[rootResultsDirectoryAbsoluteUriLength..]);
|
string faceRelativePath = string.Concat(requestPath, new Uri(faceFullFileName).AbsoluteUri[rootResultsDirectoryAbsoluteUriLength..]);
|
||||||
string sourceRelativePath = string.Concat(requestPath, new Uri(sourceFullFileName).AbsoluteUri[rootResultsDirectoryAbsoluteUriLength..]);
|
string sourceRelativePath = string.Concat(requestPath, new Uri(sourceFullFileName).AbsoluteUri[rootResultsDirectoryAbsoluteUriLength..]);
|
||||||
FileInfo fileInfo = new(sourceFullFileName);
|
FileInfo fileInfo = new(sourceFullFileName);
|
||||||
if (face.Populated && !File.Exists(faceFullFileName))
|
if (face.FaceEncoding is not null && face.Location?.NormalizedPixelPercentage is not null && !File.Exists(faceFullFileName))
|
||||||
Stateless.Methods.IFaceFileSystem.SearchForMissingFile(faceFullFileName, fileInfo: new FileInfo(string.Empty), dataFullFileName);
|
Stateless.Methods.IFaceFileSystem.SearchForMissingFile(faceFullFileName, fileInfo: new FileInfo(string.Empty), dataFullFileName);
|
||||||
if (!fileInfo.Exists)
|
if (fileInfo.Exists)
|
||||||
{
|
FileExists(face, faceBottom, faceRight, out imageHeight, out imageWidth, out sourceSize, fileInfo);
|
||||||
sourceSize = 0;
|
|
||||||
if (face.OutputResolution is null)
|
|
||||||
{
|
|
||||||
imageWidth = 0;
|
|
||||||
imageHeight = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
imageWidth = face.OutputResolution.Width;
|
|
||||||
imageHeight = face.OutputResolution.Height;
|
|
||||||
}
|
|
||||||
Stateless.Methods.IFaceFileSystem.SearchForMissingFile(fileInfo.FullName, fileInfo, dataFullFileName);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
FileDoesNotExist(dataFullFileName, face, out imageHeight, out imageWidth, out sourceSize, fileInfo);
|
||||||
sourceSize = fileInfo.Length;
|
|
||||||
if (face.OutputResolution is not null)
|
|
||||||
{
|
|
||||||
imageWidth = face.OutputResolution.Width;
|
|
||||||
imageHeight = face.OutputResolution.Height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.Drawing.Size size = Stateless.Methods.ImageHelper.GetDimensions(fileInfo.FullName, faceRight, faceBottom);
|
|
||||||
imageWidth = size.Width;
|
|
||||||
imageHeight = size.Height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ClassName = "file";
|
_ClassName = "file";
|
||||||
_FaceBottom = faceBottom;
|
_FaceBottom = faceBottom;
|
||||||
_Confidence = confidence;
|
_Confidence = confidence;
|
||||||
@ -176,7 +181,7 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem, IFaceFileS
|
|||||||
_FaceLeft = faceLeft;
|
_FaceLeft = faceLeft;
|
||||||
_LocationDisplayIndex = locationDisplayIndex;
|
_LocationDisplayIndex = locationDisplayIndex;
|
||||||
_LocationIndex = face.LocationIndex;
|
_LocationIndex = face.LocationIndex;
|
||||||
_Populated = face.Populated;
|
_Populated = face.FaceEncoding is not null && face.Location?.NormalizedPixelPercentage is not null;
|
||||||
_RelativePath = string.Empty;
|
_RelativePath = string.Empty;
|
||||||
_FaceRight = faceRight;
|
_FaceRight = faceRight;
|
||||||
_SourceFullFileName = sourceFullFileName;
|
_SourceFullFileName = sourceFullFileName;
|
||||||
@ -187,13 +192,13 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem, IFaceFileS
|
|||||||
_ImageWidth = imageWidth;
|
_ImageWidth = imageWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
string IFileSystem.GetDate()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
string result = _LastModified.ToString("MM/dd/yyyy hh:mm:ss tt");
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
string IFaceFileSystem.GetSize()
|
public string GetSize()
|
||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
if (_SourceSize is null)
|
if (_SourceSize is null)
|
||||||
@ -208,19 +213,9 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem, IFaceFileS
|
|||||||
order++;
|
order++;
|
||||||
len /= 1024;
|
len /= 1024;
|
||||||
}
|
}
|
||||||
result = String.Format("{0:0.##} {1}", len, sizes[order]);
|
result = string.Format("{0:0.##} {1}", len, sizes[order]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stateless.Methods.IFaceFileSystem.TestStatic_SearchForMissingFile(string fullFileName, FileInfo fileInfo, string dataFullFileName) => throw new NotImplementedException();
|
|
||||||
|
|
||||||
FaceFileSystem[][] Stateless.Methods.IFaceFileSystem.TestStatic_GetFaceFileSystemCollection(string requestPath, string rootResultsDirectory, (string RootResultsDirectoryAbsoluteUri, string C_ResizeContentDirectory, string D_FacesContentDirectory, string E_DistanceCollectionDirectory) tuple, string selectedFileFullName) => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,11 +1,10 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class FacePoint : Properties.IFacePoint, IFacePoint
|
public class FacePoint : Properties.IFacePoint
|
||||||
{
|
{
|
||||||
|
|
||||||
protected int _Index;
|
protected int _Index;
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
namespace View_by_Distance.Property.Models;
|
using System.Text.Json;
|
||||||
|
|
||||||
public class FileHolder
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public class FileHolder : Properties.IFileHolder
|
||||||
{
|
{
|
||||||
|
|
||||||
protected readonly DateTime _CreationTime;
|
protected readonly DateTime _CreationTime;
|
||||||
protected readonly string? _DirectoryName;
|
protected readonly string? _DirectoryName;
|
||||||
protected readonly bool _Exists;
|
protected readonly bool _Exists;
|
||||||
@ -65,6 +68,10 @@ public class FileHolder
|
|||||||
_NameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
|
_NameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FileHolder Refresh(FileHolder fileHolder) => new(fileHolder.FullName);
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,10 +1,9 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class FileSystem : Properties.IFileSystem, IFileSystem
|
public class FileSystem : Properties.IFileSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
protected string _ClassName;
|
protected string _ClassName;
|
||||||
@ -37,14 +36,12 @@ public class FileSystem : Properties.IFileSystem, IFileSystem
|
|||||||
_LastModified = DateTime.Now;
|
_LastModified = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
string IFileSystem.GetDate()
|
public string GetDate()
|
||||||
{
|
{
|
||||||
string result = _LastModified.ToString("MM/dd/yyyy hh:mm:ss tt");
|
string result = _LastModified.ToString("MM/dd/yyyy hh:mm:ss tt");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<FileSystem> Stateless.Methods.IFileSystem.TestStatic_GetFileSystemCollection(string requestPath, string rootResultsDirectory, (string RootResultsDirectoryAbsoluteUri, string C_ResizeContentDirectory, string D_FacesContentDirectory, string E_DistanceCollectionDirectory) tuple, string[] directories, string[] files, bool all) => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
95
Shared/Models/Item.cs
Normal file
95
Shared/Models/Item.cs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public class Item : Properties.IItem
|
||||||
|
{
|
||||||
|
|
||||||
|
protected readonly bool? _Abandoned;
|
||||||
|
protected readonly bool? _Changed;
|
||||||
|
protected List<Closest> _Closest;
|
||||||
|
protected List<Face> _Faces;
|
||||||
|
protected readonly FileHolder? _ImageFileHolder;
|
||||||
|
protected bool? _Moved;
|
||||||
|
protected List<Named> _Named;
|
||||||
|
protected readonly bool? _NoJson;
|
||||||
|
protected Property? _Property;
|
||||||
|
protected readonly string _RelativePath;
|
||||||
|
protected FileHolder? _ResizedFileHolder;
|
||||||
|
protected readonly string _SourceDirectoryFile;
|
||||||
|
protected bool _ValidImageFormatExtension;
|
||||||
|
public bool? Abandoned => _Abandoned;
|
||||||
|
public bool? Changed => _Changed;
|
||||||
|
public List<Closest> Closest => _Closest;
|
||||||
|
public List<Face> Faces => _Faces;
|
||||||
|
public FileHolder? ImageFileHolder => _ImageFileHolder;
|
||||||
|
public bool? Moved => _Moved;
|
||||||
|
public bool? NoJson => _NoJson;
|
||||||
|
public List<Named> Named => _Named;
|
||||||
|
public Property? Property => _Property;
|
||||||
|
public string RelativePath => _RelativePath;
|
||||||
|
public FileHolder? ResizedFileHolder => _ResizedFileHolder;
|
||||||
|
public string SourceDirectoryFile => _SourceDirectoryFile;
|
||||||
|
public bool ValidImageFormatExtension => _ValidImageFormatExtension;
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public Item(bool? abandoned, bool? changed, List<Closest> closest, List<Face> faces, FileHolder? imageFileHolder, bool? moved, List<Named> named, bool? noJson, Property? property, string relativePath, FileHolder? resizedFileHolder, string sourceDirectoryFile, bool validImageFormatExtension)
|
||||||
|
{
|
||||||
|
_Abandoned = abandoned;
|
||||||
|
_Changed = changed;
|
||||||
|
_Closest = closest;
|
||||||
|
_Faces = faces;
|
||||||
|
_ImageFileHolder = imageFileHolder;
|
||||||
|
_Moved = moved;
|
||||||
|
_Named = named;
|
||||||
|
_NoJson = noJson;
|
||||||
|
_Property = property;
|
||||||
|
_RelativePath = relativePath;
|
||||||
|
_ResizedFileHolder = resizedFileHolder;
|
||||||
|
_SourceDirectoryFile = sourceDirectoryFile;
|
||||||
|
_ValidImageFormatExtension = validImageFormatExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item(string sourceDirectoryFile, string relativePath, FileHolder? imageFileInfo, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? changed)
|
||||||
|
{
|
||||||
|
_Faces = new();
|
||||||
|
_Named = new();
|
||||||
|
_Closest = new();
|
||||||
|
_Changed = changed;
|
||||||
|
_Property = property;
|
||||||
|
_Abandoned = abandoned;
|
||||||
|
_NoJson = abandoned is null;
|
||||||
|
_RelativePath = relativePath;
|
||||||
|
_ImageFileHolder = imageFileInfo;
|
||||||
|
_SourceDirectoryFile = sourceDirectoryFile;
|
||||||
|
_ValidImageFormatExtension = isValidImageFormatExtension;
|
||||||
|
if (relativePath.EndsWith(".json"))
|
||||||
|
throw new ArgumentException("Can not be a *.json file!");
|
||||||
|
if (imageFileInfo is not null && imageFileInfo.ExtensionLowered is ".json")
|
||||||
|
throw new ArgumentException("Can not be a *.json file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMoved(bool moved) => _Moved = moved;
|
||||||
|
|
||||||
|
public void SetResizedFileHolder(string filenameExtension, FileHolder fileHolder)
|
||||||
|
{
|
||||||
|
if (fileHolder.ExtensionLowered == filenameExtension)
|
||||||
|
_ResizedFileHolder = fileHolder;
|
||||||
|
else if (fileHolder.ExtensionLowered.Length > 3 && fileHolder.ExtensionLowered[3] == 'e' && fileHolder.ExtensionLowered.Remove(3, 1) == filenameExtension)
|
||||||
|
_ResizedFileHolder = fileHolder;
|
||||||
|
else
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Any() => (_Abandoned.HasValue && _Abandoned.Value) || (_Changed.HasValue && _Changed.Value) || (_Moved.HasValue && _Moved.Value) || (_NoJson.HasValue && _NoJson.Value);
|
||||||
|
|
||||||
|
public void Update(Property property) => _Property = property;
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,9 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class Location : Properties.ILocation, ILocation, IEquatable<Location>
|
public class Location : Properties.ILocation, IEquatable<Location>
|
||||||
{
|
{
|
||||||
|
|
||||||
protected int _Bottom;
|
protected int _Bottom;
|
||||||
@ -13,8 +12,8 @@ public class Location : Properties.ILocation, ILocation, IEquatable<Location>
|
|||||||
protected readonly int? _NormalizedPixelPercentage;
|
protected readonly int? _NormalizedPixelPercentage;
|
||||||
protected int _Right;
|
protected int _Right;
|
||||||
protected int _Top;
|
protected int _Top;
|
||||||
public int Bottom => _Bottom;
|
|
||||||
public double Confidence => _Confidence;
|
public double Confidence => _Confidence;
|
||||||
|
public int Bottom => _Bottom;
|
||||||
public int Left => _Left;
|
public int Left => _Left;
|
||||||
public int? NormalizedPixelPercentage => _NormalizedPixelPercentage;
|
public int? NormalizedPixelPercentage => _NormalizedPixelPercentage;
|
||||||
public int Right => _Right;
|
public int Right => _Right;
|
||||||
@ -23,27 +22,22 @@ public class Location : Properties.ILocation, ILocation, IEquatable<Location>
|
|||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
public Location(int bottom, double confidence, int left, int? normalizedPixelPercentage, int right, int top)
|
public Location(int bottom, double confidence, int left, int? normalizedPixelPercentage, int right, int top)
|
||||||
{
|
{
|
||||||
if (normalizedPixelPercentage < 0)
|
|
||||||
normalizedPixelPercentage = 3;
|
|
||||||
_Confidence = confidence;
|
_Confidence = confidence;
|
||||||
_Bottom = bottom;
|
_Bottom = bottom;
|
||||||
_Left = left;
|
_Left = left;
|
||||||
_NormalizedPixelPercentage = normalizedPixelPercentage;
|
_NormalizedPixelPercentage = normalizedPixelPercentage;
|
||||||
_Right = right;
|
_Right = right;
|
||||||
_Top = top;
|
_Top = top;
|
||||||
|
Check(bottom, left, normalizedPixelPercentage, right, top, zCount: 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location(double confidence, int bottom, int left, int right, int top, int width, int height) :
|
public Location(double confidence, int height, Location location, int width, int zCount) :
|
||||||
this(bottom, confidence, left, GetNormalizedPixelPercentage(bottom, height, left, right, top, width), right, top)
|
this(location.Bottom, confidence, location.Left, GetNormalizedPixelPercentage(location.Bottom, height, location.Left, location.Right, location.Top, width, zCount), location.Right, location.Top) =>
|
||||||
{ }
|
Check(_Bottom, _Left, _NormalizedPixelPercentage, _Right, _Top, zCount);
|
||||||
|
|
||||||
public Location(double confidence, Location location, int width, int height) :
|
public Location(int bottom, double confidence, int height, int left, int right, int top, int width, int zCount) :
|
||||||
this(location.Bottom, confidence, location.Left, GetNormalizedPixelPercentage(location.Bottom, height, location.Left, location.Right, location.Top, width), location.Right, location.Top)
|
this(bottom, confidence, left, GetNormalizedPixelPercentage(bottom, height, left, right, top, width, zCount), right, top) =>
|
||||||
{ }
|
Check(_Bottom, height, _Left, _NormalizedPixelPercentage, _Right, _Top, width, zCount);
|
||||||
|
|
||||||
public Location(int left, int top, int right, int bottom, int width, int height) :
|
|
||||||
this(bottom, -1.0d, left, GetNormalizedPixelPercentage(bottom, height, left, right, top, width), right, top)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public override bool Equals(object? obj) => Equals(obj as Location);
|
public override bool Equals(object? obj) => Equals(obj as Location);
|
||||||
|
|
||||||
@ -53,6 +47,53 @@ public class Location : Properties.ILocation, ILocation, IEquatable<Location>
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void Check(int bottom, int left, int right, int top, int zCount)
|
||||||
|
{
|
||||||
|
if (left < 0)
|
||||||
|
throw new Exception();
|
||||||
|
if (right < 0)
|
||||||
|
throw new Exception();
|
||||||
|
if (right < left)
|
||||||
|
throw new Exception();
|
||||||
|
if (top < 0)
|
||||||
|
throw new Exception();
|
||||||
|
if (bottom < 0)
|
||||||
|
throw new Exception();
|
||||||
|
if (bottom < top)
|
||||||
|
throw new Exception();
|
||||||
|
if (zCount < 0)
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Check(int bottom, int height, int left, int right, int top, int width, int zCount)
|
||||||
|
{
|
||||||
|
if (bottom > height)
|
||||||
|
throw new Exception();
|
||||||
|
if (left > width)
|
||||||
|
throw new Exception();
|
||||||
|
if (right > width)
|
||||||
|
throw new Exception();
|
||||||
|
if (top > height)
|
||||||
|
throw new Exception();
|
||||||
|
if (zCount < 0)
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Check(int bottom, int left, int? normalizedPixelPercentage, int right, int top, int zCount)
|
||||||
|
{
|
||||||
|
Check(bottom, left, right, top, zCount);
|
||||||
|
if (normalizedPixelPercentage.HasValue && normalizedPixelPercentage.Value < 0)
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Check(int bottom, int height, int left, int? normalizedPixelPercentage, int right, int top, int width, int zCount)
|
||||||
|
{
|
||||||
|
Check(bottom, left, right, top, zCount);
|
||||||
|
Check(bottom, height, left, right, top, width, zCount);
|
||||||
|
if (normalizedPixelPercentage.HasValue && normalizedPixelPercentage.Value < 0)
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
int hashCode = -773114317;
|
int hashCode = -773114317;
|
||||||
@ -63,16 +104,21 @@ public class Location : Properties.ILocation, ILocation, IEquatable<Location>
|
|||||||
return hashCode;
|
return hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetNormalizedPixelPercentage(int bottom, int height, int left, int right, int top, int width)
|
public static int GetNormalizedPixelPercentage(int bottom, int height, int left, int right, int top, int width, int zCount)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
double value;
|
double value;
|
||||||
|
int decimals = 6;
|
||||||
|
int factor = 1000000;
|
||||||
|
double total = width * height;
|
||||||
|
Check(bottom, left, right, top, zCount);
|
||||||
double xCenter = left + ((right - left) / 2);
|
double xCenter = left + ((right - left) / 2);
|
||||||
double yCenter = top + ((bottom - top) / 2);
|
double yCenter = top + ((bottom - top) / 2);
|
||||||
value = ((yCenter * width) + xCenter) / (width * height);
|
double at = ((yCenter - 1) * width) + xCenter;
|
||||||
|
value = at / total;
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
value = 3;
|
value = 3;
|
||||||
result = (int)(Math.Round((decimal)value, 4) * Stateless.Methods.ILocation.Factor);
|
result = (int)(Math.Round(value, decimals) * factor);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
Shared/Models/Methods/IClosest.cs
Normal file
8
Shared/Models/Methods/IClosest.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
|
public interface IClosest : Stateless.Methods.IClosest
|
||||||
|
{ // ...
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
8
Shared/Models/Methods/IContainer.cs
Normal file
8
Shared/Models/Methods/IContainer.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
|
public interface IContainer : Stateless.Methods.IContainer
|
||||||
|
{ // ...
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
8
Shared/Models/Methods/IDistanceHolder.cs
Normal file
8
Shared/Models/Methods/IDistanceHolder.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
|
public interface IDistanceHolder : Stateless.Methods.IDistanceHolder
|
||||||
|
{ // ...
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,6 @@
|
|||||||
namespace View_by_Distance.Shared.Models.Methods;
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
public interface IFaceFileSystem : Stateless.Methods.IFaceFileSystem, IFileSystem
|
public interface IFaceFileSystem : Stateless.Methods.IFaceFileSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
string GetSize();
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
namespace View_by_Distance.Shared.Models.Methods;
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
public interface IFacePoint
|
public interface IFacePoint : Stateless.Methods.IFacePoint
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
8
Shared/Models/Methods/IFileHolder.cs
Normal file
8
Shared/Models/Methods/IFileHolder.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
|
public interface IFileHolder : Stateless.Methods.IFileHolder
|
||||||
|
{ // ...
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
@ -3,6 +3,4 @@ namespace View_by_Distance.Shared.Models.Methods;
|
|||||||
public interface IFileSystem : Stateless.Methods.IFileSystem
|
public interface IFileSystem : Stateless.Methods.IFileSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
string GetDate();
|
|
||||||
|
|
||||||
}
|
}
|
8
Shared/Models/Methods/IItem.cs
Normal file
8
Shared/Models/Methods/IItem.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
|
public interface IItem : Stateless.Methods.IItem
|
||||||
|
{ // ...
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
namespace View_by_Distance.Shared.Models.Methods;
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
public interface ILocation
|
public interface ILocation : Stateless.Methods.ILocation
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
8
Shared/Models/Methods/INamed.cs
Normal file
8
Shared/Models/Methods/INamed.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
|
public interface INamed : Stateless.Methods.INamed
|
||||||
|
{ // ...
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
namespace View_by_Distance.Shared.Models.Methods;
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
public interface IOutputResolution
|
public interface IOutputResolution : Stateless.Methods.IPerson
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
8
Shared/Models/Methods/IPath.cs
Normal file
8
Shared/Models/Methods/IPath.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
|
public interface IPath : Stateless.Methods.IPath
|
||||||
|
{ // ...
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
namespace View_by_Distance.Shared.Models.Methods;
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
public interface IProperty
|
public interface IProperty : Stateless.Methods.IProperty
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
namespace View_by_Distance.Shared.Models.Methods;
|
namespace View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
public interface IRelativePaths
|
public interface IRelativePaths : Stateless.Methods.IRelativePaths
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
37
Shared/Models/Named.cs
Normal file
37
Shared/Models/Named.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public class Named : Properties.INamed
|
||||||
|
{
|
||||||
|
|
||||||
|
protected readonly bool? _IsWrongYear;
|
||||||
|
protected readonly DateTime _MinimumDateTime;
|
||||||
|
protected readonly int? _NormalizedPixelPercentage;
|
||||||
|
protected readonly PersonBirthday? _PersonBirthday;
|
||||||
|
public bool? IsWrongYear => _IsWrongYear;
|
||||||
|
public DateTime MinimumDateTime => _MinimumDateTime;
|
||||||
|
public int? NormalizedPixelPercentage => _NormalizedPixelPercentage;
|
||||||
|
public PersonBirthday? PersonBirthday => _PersonBirthday;
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public Named(bool? isWrongYear, DateTime minimumDateTime, int? normalizedPixelPercentage, PersonBirthday? personBirthday)
|
||||||
|
{
|
||||||
|
_IsWrongYear = isWrongYear;
|
||||||
|
_MinimumDateTime = minimumDateTime;
|
||||||
|
_NormalizedPixelPercentage = normalizedPixelPercentage;
|
||||||
|
_PersonBirthday = personBirthday;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Named(bool? isWrongYear, DateTime minimumDateTime, PersonBirthday? personBirthday) :
|
||||||
|
this(isWrongYear, minimumDateTime, null, personBirthday)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,9 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class OutputResolution : Properties.IOutputResolution, IOutputResolution
|
public class OutputResolution : Properties.IOutputResolution
|
||||||
{
|
{
|
||||||
|
|
||||||
protected int _Height;
|
protected int _Height;
|
||||||
|
13
Shared/Models/Properties/IClosest.cs
Normal file
13
Shared/Models/Properties/IClosest.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Properties;
|
||||||
|
|
||||||
|
public interface IClosest
|
||||||
|
{
|
||||||
|
|
||||||
|
public double? Average { get; }
|
||||||
|
public int? NormalizedPixelPercentage { get; }
|
||||||
|
public bool? IsWrongYear { get; }
|
||||||
|
public double? Minimum { get; }
|
||||||
|
public DateTime MinimumDateTime { get; }
|
||||||
|
public PersonBirthday? PersonBirthday { get; }
|
||||||
|
|
||||||
|
}
|
@ -1,45 +0,0 @@
|
|||||||
// using View_by_Distance.Shared.Models.Methods;
|
|
||||||
|
|
||||||
// namespace View_by_Distance.Shared.Models.Properties;
|
|
||||||
|
|
||||||
// public interface IConfiguration
|
|
||||||
// {
|
|
||||||
|
|
||||||
// public bool? checkJsonForDistanceResults;
|
|
||||||
// public string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions;
|
|
||||||
// public string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions;
|
|
||||||
// public bool? loadOrCreateThenSaveIndex;
|
|
||||||
// public bool? overrideForFaceImages;
|
|
||||||
// public bool? overrideForFaceLandmarkImages;
|
|
||||||
// public bool? overrideForResizeImages;
|
|
||||||
// public bool? propertiesChangedForDistance;
|
|
||||||
// public bool? propertiesChangedForFaces;
|
|
||||||
// public bool? propertiesChangedForIndex;
|
|
||||||
// public bool? propertiesChangedForMetadata;
|
|
||||||
// public bool? propertiesChangedForProperty;
|
|
||||||
// public bool? propertiesChangedForResize;
|
|
||||||
// public bool? reverse;
|
|
||||||
// public bool? saveFullYearOfRandomFiles;
|
|
||||||
// public bool? testDistanceResults;
|
|
||||||
// public int? distanceFactor;
|
|
||||||
// public int? locationConfidenceFactor;
|
|
||||||
// public int? mappedMaxIndex;
|
|
||||||
// public int? maxImagesInDirectoryForTopLevelFirstPass;
|
|
||||||
// public int? maxItemsInDistanceCollection;
|
|
||||||
// public int? numberOfJitters;
|
|
||||||
// public int? outputQuality;
|
|
||||||
// public int? paddingLoops;
|
|
||||||
// public string dateGroup;
|
|
||||||
// public string modelDirectory;
|
|
||||||
// public string modelName;
|
|
||||||
// public string outputExtension;
|
|
||||||
// public string predictorModelName;
|
|
||||||
// public string rootDirectory;
|
|
||||||
// public string[] ignoreExtensions;
|
|
||||||
// public string[] ignoreRelativePaths;
|
|
||||||
// public string[] mixedYearRelativePaths;
|
|
||||||
// public string[] outputResolutions;
|
|
||||||
// public string[] saveFaceLandmarkForOutputResolutions;
|
|
||||||
// public string[] validResolutions;
|
|
||||||
|
|
||||||
// }
|
|
11
Shared/Models/Properties/IContainer.cs
Normal file
11
Shared/Models/Properties/IContainer.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Properties;
|
||||||
|
|
||||||
|
public interface IContainer
|
||||||
|
{
|
||||||
|
|
||||||
|
public int G { get; }
|
||||||
|
public List<Item> Items { get; }
|
||||||
|
public int R { get; }
|
||||||
|
public string SourceDirectory { get; }
|
||||||
|
|
||||||
|
}
|
@ -3,10 +3,4 @@ namespace View_by_Distance.Shared.Models.Properties;
|
|||||||
public interface IDirectoryFileSystem
|
public interface IDirectoryFileSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
// protected new string ClassName { get; }
|
|
||||||
// protected new string DataDisplayFileName { get; }
|
|
||||||
// protected new string DataFullFileName { get; }
|
|
||||||
// protected new string Display { get; }
|
|
||||||
// protected new DateTime LastModified { get; }
|
|
||||||
|
|
||||||
}
|
}
|
14
Shared/Models/Properties/IDistanceHolder.cs
Normal file
14
Shared/Models/Properties/IDistanceHolder.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Properties;
|
||||||
|
|
||||||
|
public interface IDistanceHolder
|
||||||
|
{
|
||||||
|
|
||||||
|
public Face Face { init; get; }
|
||||||
|
public FileHolder FileHolder { init; get; }
|
||||||
|
public int Id { init; get; }
|
||||||
|
public string JSONDirectory { init; get; }
|
||||||
|
public Location? Location { init; get; }
|
||||||
|
public string TSVDirectory { init; get; }
|
||||||
|
public double Sort { get; set; }
|
||||||
|
|
||||||
|
}
|
@ -3,16 +3,12 @@ namespace View_by_Distance.Shared.Models.Properties;
|
|||||||
public interface IFace
|
public interface IFace
|
||||||
{
|
{
|
||||||
|
|
||||||
#pragma warning disable IDE1006
|
|
||||||
public double? α { get; }
|
|
||||||
#pragma warning restore IDE1006
|
|
||||||
public DateTime DateTime { get; }
|
public DateTime DateTime { get; }
|
||||||
public FaceEncoding FaceEncoding { get; }
|
public FaceEncoding? FaceEncoding { get; }
|
||||||
public Dictionary<string, FacePoint[]> FaceLandmarks { get; }
|
public Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts { get; }
|
||||||
public Location Location { get; }
|
public Location? Location { get; }
|
||||||
public int? LocationIndex { get; }
|
public int? LocationIndex { get; }
|
||||||
public OutputResolution OutputResolution { get; }
|
public OutputResolution? OutputResolution { get; }
|
||||||
public bool Populated { get; }
|
|
||||||
public string RelativePath { get; }
|
public string RelativePath { get; }
|
||||||
|
|
||||||
}
|
}
|
16
Shared/Models/Properties/IFileHolder.cs
Normal file
16
Shared/Models/Properties/IFileHolder.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Properties;
|
||||||
|
|
||||||
|
public interface IFileHolder
|
||||||
|
{
|
||||||
|
|
||||||
|
public DateTime CreationTime { get; }
|
||||||
|
public string? DirectoryName { get; }
|
||||||
|
public bool Exists { get; }
|
||||||
|
public string ExtensionLowered { get; }
|
||||||
|
public string FullName { get; }
|
||||||
|
public DateTime LastWriteTime { get; }
|
||||||
|
public long? Length { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public string NameWithoutExtension { get; }
|
||||||
|
|
||||||
|
}
|
20
Shared/Models/Properties/IItem.cs
Normal file
20
Shared/Models/Properties/IItem.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Properties;
|
||||||
|
|
||||||
|
public interface IItem
|
||||||
|
{
|
||||||
|
|
||||||
|
public bool? Abandoned { get; }
|
||||||
|
public bool? Changed { get; }
|
||||||
|
public List<Closest> Closest { get; }
|
||||||
|
public List<Face> Faces { get; }
|
||||||
|
public FileHolder? ImageFileHolder { get; }
|
||||||
|
public bool? Moved { get; }
|
||||||
|
public bool? NoJson { get; }
|
||||||
|
public List<Named> Named { get; }
|
||||||
|
public Property? Property { get; }
|
||||||
|
public string RelativePath { get; }
|
||||||
|
public FileHolder? ResizedFileHolder { get; }
|
||||||
|
public string SourceDirectoryFile { get; }
|
||||||
|
public bool ValidImageFormatExtension { get; }
|
||||||
|
|
||||||
|
}
|
11
Shared/Models/Properties/INamed.cs
Normal file
11
Shared/Models/Properties/INamed.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Properties;
|
||||||
|
|
||||||
|
public interface INamed
|
||||||
|
{
|
||||||
|
|
||||||
|
public bool? IsWrongYear { get; }
|
||||||
|
public DateTime MinimumDateTime { get; }
|
||||||
|
public int? NormalizedPixelPercentage { get; }
|
||||||
|
public PersonBirthday? PersonBirthday { get; }
|
||||||
|
|
||||||
|
}
|
6
Shared/Models/Properties/IPath.cs
Normal file
6
Shared/Models/Properties/IPath.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Properties;
|
||||||
|
|
||||||
|
public interface IPath
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -6,61 +6,52 @@ namespace View_by_Distance.Shared.Models;
|
|||||||
public class Property : Properties.IProperty
|
public class Property : Properties.IProperty
|
||||||
{
|
{
|
||||||
|
|
||||||
protected bool? _WrongYear;
|
|
||||||
protected DateTime _CreationTime;
|
protected DateTime _CreationTime;
|
||||||
protected DateTime _LastWriteTime;
|
|
||||||
protected DateTime? _DateTime;
|
protected DateTime? _DateTime;
|
||||||
protected DateTime? _DateTimeDigitized;
|
protected DateTime? _DateTimeDigitized;
|
||||||
protected DateTime? _DateTimeOriginal;
|
protected DateTime? _DateTimeOriginal;
|
||||||
protected long _FileSize;
|
protected long _FileSize;
|
||||||
protected DateTime? _GPSDateStamp;
|
protected DateTime? _GPSDateStamp;
|
||||||
|
protected int? _Height;
|
||||||
protected int? _Id;
|
protected int? _Id;
|
||||||
protected int[] _Indices;
|
protected int[] _Indices;
|
||||||
protected int? _Height;
|
protected DateTime _LastWriteTime;
|
||||||
protected int? _Width;
|
|
||||||
protected string _Make;
|
protected string _Make;
|
||||||
protected int? _MetadataGroups;
|
|
||||||
protected string _Model;
|
protected string _Model;
|
||||||
protected string _Orientation;
|
protected string _Orientation;
|
||||||
protected string _UniqueImageId;
|
protected int? _Width;
|
||||||
public bool? WrongYear => _WrongYear;
|
|
||||||
public DateTime CreationTime => _CreationTime;
|
public DateTime CreationTime => _CreationTime;
|
||||||
public DateTime LastWriteTime => _LastWriteTime;
|
|
||||||
public DateTime? DateTime => _DateTime;
|
public DateTime? DateTime => _DateTime;
|
||||||
public DateTime? DateTimeDigitized => _DateTimeDigitized;
|
public DateTime? DateTimeDigitized => _DateTimeDigitized;
|
||||||
public DateTime? DateTimeOriginal => _DateTimeOriginal;
|
public DateTime? DateTimeOriginal => _DateTimeOriginal;
|
||||||
public long FileSize => _FileSize;
|
public long FileSize => _FileSize;
|
||||||
public DateTime? GPSDateStamp => _GPSDateStamp;
|
public DateTime? GPSDateStamp => _GPSDateStamp;
|
||||||
|
public int? Height => _Height;
|
||||||
public int? Id => _Id;
|
public int? Id => _Id;
|
||||||
public int[] Indices => _Indices;
|
public int[] Indices => _Indices;
|
||||||
public int? Height => _Height;
|
public DateTime LastWriteTime => _LastWriteTime;
|
||||||
public int? Width => _Width;
|
|
||||||
public string Make => _Make;
|
public string Make => _Make;
|
||||||
public int? MetadataGroups => _MetadataGroups;
|
|
||||||
public string Model => _Model;
|
public string Model => _Model;
|
||||||
public string Orientation => _Orientation;
|
public string Orientation => _Orientation;
|
||||||
public string UniqueImageId => _UniqueImageId;
|
public int? Width => _Width;
|
||||||
|
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
public Property(bool? wrongYear, DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeOriginal, DateTime? gpsDateStamp, long fileSize, int? id, int[] indices, int? height, int? width, string make, int? metadataGroups, string model, string orientation, string uniqueImageId)
|
public Property(DateTime creationTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeOriginal, long fileSize, DateTime? gpsDateStamp, int? height, int? id, int[] indices, DateTime lastWriteTime, string make, string model, string orientation, int? width)
|
||||||
{
|
{
|
||||||
_CreationTime = creationTime;
|
_CreationTime = creationTime;
|
||||||
_DateTime = dateTime;
|
_DateTime = dateTime;
|
||||||
_DateTimeDigitized = dateTimeDigitized;
|
_DateTimeDigitized = dateTimeDigitized;
|
||||||
_DateTimeOriginal = dateTimeOriginal;
|
_DateTimeOriginal = dateTimeOriginal;
|
||||||
_GPSDateStamp = gpsDateStamp;
|
|
||||||
_FileSize = fileSize;
|
_FileSize = fileSize;
|
||||||
|
_GPSDateStamp = gpsDateStamp;
|
||||||
_Height = height;
|
_Height = height;
|
||||||
_Id = id;
|
_Id = id;
|
||||||
_Indices = indices;
|
_Indices = indices;
|
||||||
_LastWriteTime = lastWriteTime;
|
_LastWriteTime = lastWriteTime;
|
||||||
_Make = make;
|
_Make = make;
|
||||||
_MetadataGroups = metadataGroups;
|
|
||||||
_Model = model;
|
_Model = model;
|
||||||
_Orientation = orientation;
|
_Orientation = orientation;
|
||||||
_Width = width;
|
_Width = width;
|
||||||
_WrongYear = wrongYear;
|
|
||||||
_UniqueImageId = uniqueImageId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
@ -69,4 +60,38 @@ public class Property : Properties.IProperty
|
|||||||
return result;
|
return result;
|
||||||
} // ...
|
} // ...
|
||||||
|
|
||||||
|
public List<DateTime> GetDateTimes() => Stateless.Methods.Property.GetDateTimes(_CreationTime, _LastWriteTime, _DateTime, _DateTimeDigitized, _DateTimeOriginal, _GPSDateStamp);
|
||||||
|
|
||||||
|
public (bool?, string[]) IsWrongYear(string filteredSourceDirectoryFile, DateTime? minimumDateTime)
|
||||||
|
{
|
||||||
|
string[] results = Array.Empty<string>();
|
||||||
|
bool? result = null;
|
||||||
|
string year;
|
||||||
|
string directoryName;
|
||||||
|
string[] directorySegments;
|
||||||
|
string? check = Path.GetFullPath(filteredSourceDirectoryFile);
|
||||||
|
string? pathRoot = Path.GetPathRoot(filteredSourceDirectoryFile);
|
||||||
|
if (string.IsNullOrEmpty(pathRoot))
|
||||||
|
throw new Exception();
|
||||||
|
if (minimumDateTime.HasValue)
|
||||||
|
year = minimumDateTime.Value.ToString("yyyy");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<DateTime> dateTimes = GetDateTimes();
|
||||||
|
year = dateTimes.Min().ToString("yyyy");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < int.MaxValue; i++)
|
||||||
|
{
|
||||||
|
check = Path.GetDirectoryName(check);
|
||||||
|
if (string.IsNullOrEmpty(check) || check == pathRoot)
|
||||||
|
break;
|
||||||
|
directoryName = Path.GetFileName(check);
|
||||||
|
directorySegments = directoryName.Split(' ');
|
||||||
|
(result, results) = Stateless.Methods.Property.IsWrongYear(directorySegments, year);
|
||||||
|
if (result.HasValue)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new(result, results);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,10 +1,9 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public class RelativePaths : Properties.IRelativePaths, IRelativePaths
|
public class RelativePaths : Properties.IRelativePaths
|
||||||
{
|
{
|
||||||
|
|
||||||
protected string _Value;
|
protected string _Value;
|
||||||
|
8
Shared/Models/Stateless/Methods/Closest.cs
Normal file
8
Shared/Models/Stateless/Methods/Closest.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||||
|
|
||||||
|
internal abstract class Closest
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static Models.Closest[] Get(List<Models.Closest> collection) => (from l in collection orderby l.Minimum < IClosest.MinimumMinimum, l.Average select l).ToArray();
|
||||||
|
|
||||||
|
}
|
8
Shared/Models/Stateless/Methods/Container.cs
Normal file
8
Shared/Models/Stateless/Methods/Container.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||||
|
|
||||||
|
internal abstract class Container
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static double GetDefaultValue() => throw new Exception();
|
||||||
|
|
||||||
|
}
|
8
Shared/Models/Stateless/Methods/DistanceHolder.cs
Normal file
8
Shared/Models/Stateless/Methods/DistanceHolder.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||||
|
|
||||||
|
internal abstract class DistanceHolder
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static double GetDefaultValue() => throw new Exception();
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user