Distance bug fix

This commit is contained in:
2022-09-29 13:13:41 -07:00
parent 152612bacb
commit 4568d3fbc6
21 changed files with 933 additions and 879 deletions

View File

@ -58,7 +58,7 @@ public class Compare
string a2PeopleSingletonDirectory = string.Empty; string a2PeopleSingletonDirectory = string.Empty;
Map.Models.Configuration? mapConfiguration = null; Map.Models.Configuration? mapConfiguration = null;
Shared.Models.PersonContainer[] personContainers = Array.Empty<Shared.Models.PersonContainer>(); Shared.Models.PersonContainer[] personContainers = Array.Empty<Shared.Models.PersonContainer>();
Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, propertyConfiguration, mapConfiguration, outputExtension, ticks, personContainers, a2PeopleSingletonDirectory, eResultsFullGroupDirectory); Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, propertyConfiguration, mapConfiguration, ticks, personContainers, a2PeopleSingletonDirectory, eResultsFullGroupDirectory);
A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, predictorModel, mapLogic); A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, predictorModel, mapLogic);
foreach (string spelling in configuration.Spelling) foreach (string spelling in configuration.Spelling)
{ {

View File

@ -10,21 +10,35 @@ namespace View_by_Distance.Distance.Models;
public class E_Distance : Shared.Models.Methods.IFaceDistance public class E_Distance : Shared.Models.Methods.IFaceDistance
{ {
private readonly List<string> _Moved;
private readonly List<double?> _Debug;
private readonly List<string> _Renamed;
private readonly Serilog.ILogger? _Log; private readonly Serilog.ILogger? _Log;
private readonly string _ResultAllInOne; private readonly string _ResultAllInOne;
private readonly int _FaceDistancePermyriad; private readonly int _FaceDistancePermyriad;
private readonly bool _DistanceRenameToMatch;
private readonly double _FaceDistanceTolerance; private readonly double _FaceDistanceTolerance;
private readonly int _SortingDaysDeltaTolerance; private readonly int _SortingDaysDeltaTolerance;
private readonly bool _DistanceMoveUnableToMatch; private readonly bool _DistanceMoveUnableToMatch;
private readonly List<string> _AllMappedFaceFiles;
private readonly int _DistancePixelDistanceTolerance; private readonly int _DistancePixelDistanceTolerance;
private readonly List<string> _AllMappedFaceFileNames;
private readonly double _FaceDistanceMinimumConfidence; private readonly double _FaceDistanceMinimumConfidence;
private readonly List<string> _DuplicateMappedFaceFiles;
private readonly int _FaceDistanceAreaPermilleTolerance; private readonly int _FaceDistanceAreaPermilleTolerance;
private readonly int _SortingMaximumPerFaceShouldBeHigh; private readonly int _SortingMaximumPerFaceShouldBeHigh;
public E_Distance(bool distanceMoveUnableToMatch, int distancePixelDistanceTolerance, int faceDistanceAreaPermilleTolerance, double faceDistanceMinimumConfidence, int faceDistancePermyriad, double faceDistanceTolerance, string resultAllInOne, int sortingDaysDeltaTolerance, int sortingMaximumPerFaceShouldBeHigh) public E_Distance(bool distanceMoveUnableToMatch, int distancePixelDistanceTolerance, bool distanceRenameToMatch, int faceDistanceAreaPermilleTolerance, double faceDistanceMinimumConfidence, int faceDistancePermyriad, double faceDistanceTolerance, string resultAllInOne, int sortingDaysDeltaTolerance, int sortingMaximumPerFaceShouldBeHigh)
{ {
_Debug = new();
_Moved = new();
_Renamed = new();
_AllMappedFaceFiles = new();
_AllMappedFaceFileNames = new();
_ResultAllInOne = resultAllInOne; _ResultAllInOne = resultAllInOne;
_DuplicateMappedFaceFiles = new();
_Log = Serilog.Log.ForContext<E_Distance>(); _Log = Serilog.Log.ForContext<E_Distance>();
_DistanceRenameToMatch = distanceRenameToMatch;
_FaceDistancePermyriad = faceDistancePermyriad; _FaceDistancePermyriad = faceDistancePermyriad;
_FaceDistanceTolerance = faceDistanceTolerance; _FaceDistanceTolerance = faceDistanceTolerance;
_DistanceMoveUnableToMatch = distanceMoveUnableToMatch; _DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
@ -314,17 +328,16 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
} }
} }
private void MoveUnableToMatch(string eDistanceContentDirectory, string file) private void MoveUnableToMatch(string eDistanceContentDirectory, string mappedFaceFile, string mappedFaceFileName)
{ {
bool result; bool check;
string? fileName = Path.GetFileName(file); string? directoryName = Path.GetDirectoryName(mappedFaceFile);
string? directoryName = Path.GetDirectoryName(file); if (mappedFaceFileName is null || directoryName is null)
if (fileName is null || directoryName is null) check = false;
result = false;
else else
{ {
if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(directoryName) || !directoryName.Contains(eDistanceContentDirectory)) if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(directoryName) || !directoryName.Contains(eDistanceContentDirectory))
result = false; check = false;
else else
{ {
List<string> directoryNames = new(); List<string> directoryNames = new();
@ -342,8 +355,8 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
} }
if (string.IsNullOrEmpty(checkDirectoryName) || !directoryNames.Any() || !long.TryParse(directoryNames[^1][1..^1], out long directoryTicks)) if (string.IsNullOrEmpty(checkDirectoryName) || !directoryNames.Any() || !long.TryParse(directoryNames[^1][1..^1], out long directoryTicks))
{ {
result = false; check = false;
File.Delete(file); File.Delete(mappedFaceFile);
} }
else else
{ {
@ -352,45 +365,13 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
checkDirectoryName = Path.Combine(checkDirectoryName, directoryNames[i]); checkDirectoryName = Path.Combine(checkDirectoryName, directoryNames[i]);
if (!Directory.Exists(checkDirectoryName)) if (!Directory.Exists(checkDirectoryName))
_ = Directory.CreateDirectory(checkDirectoryName); _ = Directory.CreateDirectory(checkDirectoryName);
File.Move(file, Path.Combine(checkDirectoryName, fileName)); File.Move(mappedFaceFile, Path.Combine(checkDirectoryName, mappedFaceFileName));
result = true; check = true;
} }
} }
} }
if (result) if (check)
{ } _Moved.Add(mappedFaceFile);
}
private static string[] GetMatchingDuplicates(string[] mappedFaceFiles, List<string> duplicateMappedFaceFiles, string mappedFaceFile)
{
string[] results;
string checkFile;
FileInfo fileInfo = new(mappedFaceFile);
List<(long Length, string FullName)> collection = new();
if (fileInfo.Exists)
collection.Add(new(fileInfo.Length, fileInfo.FullName));
string fileName = Path.GetFileName(mappedFaceFile);
foreach (string file in mappedFaceFiles)
{
if (duplicateMappedFaceFiles.Contains(file))
continue;
if (file == mappedFaceFile || !file.EndsWith(fileName))
continue;
fileInfo = new(file);
if (!fileInfo.Exists)
continue;
collection.Add(new(fileInfo.Length, fileInfo.FullName));
}
collection = collection.OrderBy(l => l.Length).ToList();
for (int i = 0; i < collection.Count - 1; i++)
{
checkFile = string.Concat(collection[i].FullName, ".dup");
if (File.Exists(checkFile))
continue;
File.Move(collection[i].FullName, checkFile);
}
results = (from l in collection select l.FullName).ToArray();
return results;
} }
public static string? GetFaceEncoding(string file) public static string? GetFaceEncoding(string file)
@ -419,6 +400,32 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
return result; return result;
} }
public static string? GetFaceLocation(string file)
{
string? result;
List<string> results = new();
const string artist = "Artist: ";
if (File.Exists(file))
{
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file);
foreach (MetadataExtractor.Directory directory in directories)
{
if (directory.Name != "PNG-tEXt")
continue;
foreach (MetadataExtractor.Tag tag in directory.Tags)
{
if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description))
continue;
if (!tag.Description.StartsWith(artist))
continue;
results.Add(tag.Description);
}
}
}
result = results.Any() ? results[0][artist.Length..] : null;
return result;
}
private static FaceDistanceContainer[] GetOrderedFaceDistanceContainers(MappingFromItem mappingFromItem, List<Face> faces) private static FaceDistanceContainer[] GetOrderedFaceDistanceContainers(MappingFromItem mappingFromItem, List<Face> faces)
{ {
FaceDistanceContainer[] results; FaceDistanceContainer[] results;
@ -447,9 +454,9 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
return results; return results;
} }
private List<(Face Face, double Length)> GetValues(MappingFromItem mappingFromItem, List<Face> faces, string json) private static List<(Face Face, double? Length)> GetValues(MappingFromItem mappingFromItem, List<Face> faces, string json)
{ {
List<(Face Face, double Length)> results = new(); List<(Face Face, double? Length)> results = new();
Face face; Face face;
FaceDistance faceDistanceLength; FaceDistance faceDistanceLength;
Shared.Models.FaceEncoding? modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json); Shared.Models.FaceEncoding? modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
@ -473,64 +480,99 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
faceDistanceLength = faceDistanceLengths[i]; faceDistanceLength = faceDistanceLengths[i];
if (faceDistanceLength.Length is null) if (faceDistanceLength.Length is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (faceDistanceLength.Length.Value > _FaceDistanceTolerance)
continue;
results.Add(new(face, faceDistanceLength.Length.Value)); results.Add(new(face, faceDistanceLength.Length.Value));
} }
return results; return results;
} }
private Face[] GetMatchingFaces(MappingFromItem mappingFromItem, List<Face> faces, string json) private (Face, double?)[] GetClosestFaceByDistanceIgnoringTolerance(MappingFromItem mappingFromItem, List<Face> faces, string json)
{ {
Face[] results; (Face, double?)[] results;
List<(Face Face, double Length)> collection = GetValues(mappingFromItem, faces, json); List<(Face Face, double? Length)> collection = GetValues(mappingFromItem, faces, json);
if (!collection.Any()) results = (from l in collection orderby l.Length select l).Take(1).ToArray();
results = Array.Empty<Face>(); (Face face, double? length) = results.First();
else lock (_Debug)
results = (from l in collection orderby l.Length select l.Face).Take(1).ToArray(); _Debug.Add(length);
return results; return results;
} }
private static Face[] GetMatchingFaces(int pixelDistanceTolerance, List<Face> faces) static (int?, int?) GetXY(int normalizedPixelPercentage, OutputResolution? outputResolution)
{ {
Face[] results;
int? x; int? x;
int? y; int? y;
if (outputResolution is null)
{
x = null;
y = null;
}
else
{
string normalizedPixelPercentagePadded = Shared.Models.Stateless.Methods.ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = Shared.Models.Stateless.Methods.ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, outputResolution.Width, outputResolution.Height, normalizedPixelPercentagePadded);
}
return new(x, y);
}
private (Face, double?)[] GetClosestFaceByPixel(List<Face> faces, int? x1, int? y1)
{
(Face, double?)[] results;
int? x2;
int? y2;
double distance; double distance;
double center = 2f; int normalizedPixelPercentageLoop;
double xCenterValue;
double yCenterValue;
int normalizedPixelPercentage;
string normalizedPixelPercentagePadded; string normalizedPixelPercentagePadded;
List<(double Order, Face Face)> collection = new(); List<(Face Face, double? Order)> collection = new();
if (x1 is null || y1 is null)
throw new NotSupportedException();
foreach (Face face in faces) foreach (Face face in faces)
{ {
if (face.Location is null || face.OutputResolution is null) if (face.Location is null || face.OutputResolution is null)
throw new NotSupportedException(); throw new NotSupportedException();
xCenterValue = (face.Location.Left + face.Location.Right) / center; normalizedPixelPercentageLoop = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
yCenterValue = (face.Location.Top + face.Location.Bottom) / center; normalizedPixelPercentagePadded = Shared.Models.Stateless.Methods.ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentageLoop);
if (xCenterValue < face.Location.Left || xCenterValue > face.Location.Right) (x2, y2) = Shared.Models.Stateless.Methods.ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution.Width, face.OutputResolution.Height, normalizedPixelPercentagePadded);
throw new Exception(); if (x2 is null || y2 is null)
if (yCenterValue < face.Location.Top || yCenterValue > face.Location.Bottom)
throw new Exception();
normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
normalizedPixelPercentagePadded = Shared.Models.Stateless.Methods.ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = Shared.Models.Stateless.Methods.ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution.Width, face.OutputResolution.Height, normalizedPixelPercentagePadded);
if (x is null || y is null)
throw new NotSupportedException(); throw new NotSupportedException();
distance = Math.Sqrt(Math.Pow(xCenterValue - x.Value, 2) + Math.Pow(yCenterValue - y.Value, 2)); distance = Math.Sqrt(Math.Pow(x1.Value - x2.Value, 2) + Math.Pow(y1.Value - y2.Value, 2));
collection.Add(new(distance, face)); collection.Add(new(face, distance));
} }
if (!collection.Any()) results = (from l in collection orderby l.Order where l.Order < _DistancePixelDistanceTolerance select l).Take(1).ToArray();
results = Array.Empty<Face>();
else
results = (from l in collection orderby l.Order where l.Order < pixelDistanceTolerance select l.Face).Take(1).ToArray();
return results; return results;
} }
private static List<Face> GetMatchingFaces(List<Face> faces, string? json) private (Face, double?)[] GetClosestFaceByPixel(List<Face> faces, int normalizedPixelPercentage)
{ {
List<Face> results = new(); if (!faces.Any())
throw new NotSupportedException();
(Face, double?)[] results;
const int zero = 0;
OutputResolution? outputResolution = faces[zero].OutputResolution;
(int? x1, int? y1) = GetXY(normalizedPixelPercentage, outputResolution);
results = GetClosestFaceByPixel(faces, x1, y1);
return results;
}
private (Face, double?)[] GetClosestFaceByPixel(List<Face> faces, string json)
{
if (!faces.Any())
throw new NotSupportedException();
(Face, double?)[] results;
const int zero = 0;
OutputResolution? outputResolution = faces[zero].OutputResolution;
if (outputResolution is null)
throw new NullReferenceException(nameof(outputResolution));
Location? location = JsonSerializer.Deserialize<Location>(json);
if (location is null)
throw new NullReferenceException(nameof(location));
int normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, outputResolution);
(int? x1, int? y1) = GetXY(normalizedPixelPercentage, outputResolution);
results = GetClosestFaceByPixel(faces, x1, y1);
return results;
}
private static List<(Face, double?)> GetMatchingFacesByFaceEncoding(List<Face> faces, string? json)
{
List<(Face, double?)> results = new();
string check; string check;
foreach (Face face in faces) foreach (Face face in faces)
{ {
@ -541,18 +583,18 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
check = JsonSerializer.Serialize(face.FaceEncoding); check = JsonSerializer.Serialize(face.FaceEncoding);
if (check != json) if (check != json)
continue; continue;
results.Add(face); results.Add(new(face, 0));
} }
return results; return results;
} }
private static FileInfo? CheckFileThenGetFileInfo(string facesFileNameExtension, MappingFromItem mappingFromItem, string mappedFaceFile, List<Face> checkFaces) private static FileInfo? CheckFileThenGetFileInfo(string facesFileNameExtension, MappingFromItem mappingFromItem, string mappedFaceFile, List<(Face, double?)> checkFaces)
{ {
FileInfo? result = null; FileInfo? result = null;
string checkFile; string checkFile;
string? mappedFaceDirectory; string? mappedFaceDirectory;
string deterministicHashCodeKey; string deterministicHashCodeKey;
foreach (Face face in checkFaces) foreach ((Face face, _) in checkFaces)
{ {
if (checkFaces.Count != 1) if (checkFaces.Count != 1)
break; break;
@ -566,112 +608,127 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
if (checkFile == mappedFaceFile) if (checkFile == mappedFaceFile)
continue; continue;
result = new FileInfo(checkFile); result = new FileInfo(checkFile);
if (!result.Exists)
continue;
File.Delete(result.FullName);
result = null;
} }
return result; return result;
} }
private static List<Face> GetMatchingFaces(List<Face> faces, string[] mappedFaceFiles, List<int> debugChecks, int normalizedPixelPercentageValue, List<int> normalizedPixelPercentages, List<string> duplicateMappedFaceFiles, string mappedFaceFile) private void AppendMatchingDuplicates(string mappedFaceFile, string[] matches)
{ {
List<Face> results = new(); string checkFile;
bool check; FileInfo fileInfo = new(mappedFaceFile);
int normalizedPixelPercentage; List<(long Length, string FullName)> collection = new();
foreach (Face face in faces) if (fileInfo.Exists)
collection.Add(new(fileInfo.Length, fileInfo.FullName));
lock (_DuplicateMappedFaceFiles)
_DuplicateMappedFaceFiles.Add(mappedFaceFile);
foreach (string match in matches)
{ {
if (face.Location is null || face.OutputResolution is null) fileInfo = new(match);
throw new NotSupportedException(); if (!fileInfo.Exists)
normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
debugChecks.Add(normalizedPixelPercentage);
if (normalizedPixelPercentage != normalizedPixelPercentageValue)
continue; continue;
if (normalizedPixelPercentages.Contains(normalizedPixelPercentage)) collection.Add(new(fileInfo.Length, fileInfo.FullName));
break;
}
collection = collection.OrderBy(l => l.Length).ToList();
for (int i = 0; i < collection.Count - 1; i++)
{ {
duplicateMappedFaceFiles.AddRange(GetMatchingDuplicates(mappedFaceFiles, duplicateMappedFaceFiles, mappedFaceFile)); checkFile = string.Concat(collection[i].FullName, ".dup");
if (File.Exists(checkFile))
continue; continue;
File.Move(collection[i].FullName, checkFile);
} }
check = true;
results.Add(face);
if (!check)
debugChecks.Add(normalizedPixelPercentage);
}
return results;
} }
public (int, int, int) GetUnableToMatchCountAndRenameMatches(string facesFileNameExtension, string? eDistanceContentDirectory, MappingFromItem mappingFromItem, List<Face> faces, List<(string MappedFaceFile, int normalizedPixelPercentage)> collection) public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, string? eDistanceContentDirectory, MappingFromItem mappingFromItem, List<Face> faces, List<(string MappedFaceFile, int normalizedPixelPercentage)> collection)
{ {
int result = 0;
string? json; string? json;
int renamed = 0; string[] matches;
FileInfo? fileInfo; FileInfo? fileInfo;
List<Face> checkFaces = new(); string mappedFaceFileName;
List<int> debugChecks = new(); List<(Face, double?)> checkFaces = new();
List<int> normalizedPixelPercentages = new();
List<string> duplicateMappedFaceFiles = new();
string[] mappedFaceFiles = (from l in collection select l.MappedFaceFile).ToArray();
foreach ((string mappedFaceFile, int normalizedPixelPercentage) in collection) foreach ((string mappedFaceFile, int normalizedPixelPercentage) in collection)
{ {
if (duplicateMappedFaceFiles.Contains(mappedFaceFile)) mappedFaceFileName = Path.GetFileName(mappedFaceFile);
if (_DuplicateMappedFaceFiles.Contains(mappedFaceFileName))
continue; continue;
json = null;
checkFaces.Clear();
debugChecks.Clear();
checkFaces.AddRange(GetMatchingFaces(faces, mappedFaceFiles, debugChecks, normalizedPixelPercentage, normalizedPixelPercentages, duplicateMappedFaceFiles, mappedFaceFile));
if (checkFaces.Count != 1)
{
checkFaces.Clear(); checkFaces.Clear();
json = GetFaceEncoding(mappedFaceFile); json = GetFaceEncoding(mappedFaceFile);
if (json is null) if (json is null)
{ {
result++;
if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch) if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile); MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile, mappedFaceFileName);
continue; continue;
} }
checkFaces.AddRange(GetMatchingFaces(faces, json)); checkFaces.AddRange(GetMatchingFacesByFaceEncoding(faces, json));
} if (checkFaces.Count == 1)
_Debug.Add(0);
if (checkFaces.Count != 1 && !string.IsNullOrEmpty(json)) if (checkFaces.Count != 1 && !string.IsNullOrEmpty(json))
{ {
checkFaces.Clear(); checkFaces.Clear();
if (json is null) if (json is null)
throw new NotSupportedException(); throw new NotSupportedException();
checkFaces.AddRange(GetMatchingFaces(mappingFromItem, faces, json)); checkFaces.AddRange(GetClosestFaceByDistanceIgnoringTolerance(mappingFromItem, faces, json));
} }
if (checkFaces.Count != 1 && _DistancePixelDistanceTolerance > 0) if (checkFaces.Count != 1 && _DistancePixelDistanceTolerance > 0)
{ {
checkFaces.Clear(); checkFaces.Clear();
checkFaces.AddRange(GetMatchingFaces(_DistancePixelDistanceTolerance, faces)); json = GetFaceLocation(mappedFaceFile);
if (json is not null)
checkFaces.AddRange(GetClosestFaceByPixel(faces, json));
else
checkFaces.AddRange(GetClosestFaceByPixel(faces, normalizedPixelPercentage));
throw new NotImplementedException("Without a tolerance this should not ever occur!");
} }
if (!checkFaces.Any() && faces.Count == 1)
checkFaces.AddRange(faces);
if (!checkFaces.Any()) if (!checkFaces.Any())
{ {
result++;
if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch) if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile); MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile, mappedFaceFileName);
continue; continue;
} }
if (checkFaces.Count != 1) if (checkFaces.Count != 1)
{ {
result++;
if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch) if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile); MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile, mappedFaceFileName);
continue; continue;
} }
normalizedPixelPercentages.Add(normalizedPixelPercentage);
fileInfo = CheckFileThenGetFileInfo(facesFileNameExtension, mappingFromItem, mappedFaceFile, checkFaces); fileInfo = CheckFileThenGetFileInfo(facesFileNameExtension, mappingFromItem, mappedFaceFile, checkFaces);
if (fileInfo is null) if (fileInfo is not null)
continue;
File.Move(mappedFaceFile, fileInfo.FullName);
renamed++;
}
if (duplicateMappedFaceFiles.Any())
{ {
duplicateMappedFaceFiles.Sort(); if (_DistanceRenameToMatch && fileInfo is not null)
{
if (fileInfo.Exists)
File.Delete(fileInfo.FullName);
File.Move(mappedFaceFile, fileInfo.FullName);
_Renamed.Add(mappedFaceFile);
} }
return new(result, duplicateMappedFaceFiles.Count, renamed); continue;
}
if (_AllMappedFaceFileNames.Contains(mappedFaceFileName))
{
lock (_AllMappedFaceFiles)
matches = (from l in _AllMappedFaceFiles where l != mappedFaceFile && Path.GetFileName(l) == mappedFaceFileName select l).ToArray();
if (matches.Any())
AppendMatchingDuplicates(mappedFaceFile, matches);
}
lock (_AllMappedFaceFiles)
_AllMappedFaceFiles.Add(mappedFaceFile);
lock (_AllMappedFaceFileNames)
_AllMappedFaceFileNames.Add(mappedFaceFileName);
}
}
public void Clear()
{
double?[] debug = (from l in _Debug where l is null or not 0 select l).ToArray();
string debugMessage = $"{_Debug.Count - debug.Length} - {debug.Min()} - {_Debug.Max()}";
if (_Moved.Any() || _Renamed.Any() || _DuplicateMappedFaceFiles.Any())
throw new NotImplementedException("Restart!");
_Debug.Clear();
_Moved.Clear();
_Renamed.Clear();
_AllMappedFaceFiles.Clear();
_AllMappedFaceFileNames.Clear();
_DuplicateMappedFaceFiles.Clear();
} }
} }

View File

@ -131,12 +131,16 @@ public class D_Face
{ {
int width; int width;
int height; int height;
string json;
Bitmap bitmap; Bitmap bitmap;
Graphics graphics; Graphics graphics;
Location? location; Location? location;
Rectangle rectangle; Rectangle rectangle;
string locationJson;
string faceEncodingJson;
PropertyItem? propertyItem; PropertyItem? propertyItem;
string outputResolutionJson;
int artist = (int)IExif.Tags.Artist;
int fileSource = (int)IExif.Tags.FileSource;
int userComment = (int)IExif.Tags.UserComment; int userComment = (int)IExif.Tags.UserComment;
using Bitmap source = new(resizedFileHolder.FullName); using Bitmap source = new(resizedFileHolder.FullName);
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string fileName) in collection) foreach ((Shared.Models.Face face, FileInfo? fileInfo, string fileName) in collection)
@ -150,13 +154,19 @@ public class D_Face
continue; continue;
width = location.Right - location.Left; width = location.Right - location.Left;
height = location.Bottom - location.Top; height = location.Bottom - location.Top;
json = JsonSerializer.Serialize(face.FaceEncoding); locationJson = JsonSerializer.Serialize(face.Location);
faceEncodingJson = JsonSerializer.Serialize(face.FaceEncoding);
outputResolutionJson = JsonSerializer.Serialize(face.OutputResolution);
rectangle = new Rectangle(location.Left, location.Top, width, height); rectangle = new Rectangle(location.Left, location.Top, width, height);
using (bitmap = new(width, height)) using (bitmap = new(width, height))
{ {
using (graphics = Graphics.FromImage(bitmap)) using (graphics = Graphics.FromImage(bitmap))
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel); graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
propertyItem = GetPropertyItem(userComment, json); propertyItem = GetPropertyItem(fileSource, locationJson);
bitmap.SetPropertyItem(propertyItem);
propertyItem = GetPropertyItem(artist, outputResolutionJson);
bitmap.SetPropertyItem(propertyItem);
propertyItem = GetPropertyItem(userComment, faceEncodingJson);
bitmap.SetPropertyItem(propertyItem); bitmap.SetPropertyItem(propertyItem);
bitmap.Save(fileInfo.FullName, _ImageCodecInfo, _EncoderParameters); bitmap.Save(fileInfo.FullName, _ImageCodecInfo, _EncoderParameters);
} }

View File

@ -71,10 +71,10 @@ public partial class DlibDotNet
_Index = new(configuration); _Index = new(configuration);
_Random = new(configuration); _Random = new(configuration);
_Rename = new(configuration); _Rename = new(configuration);
_MapConfiguration = Get(configuration);
_Distance = new( _Distance = new(
configuration.DistanceMoveUnableToMatch, configuration.DistanceMoveUnableToMatch,
configuration.DistancePixelDistanceTolerance, configuration.DistancePixelDistanceTolerance,
configuration.DistanceRenameToMatch,
configuration.FaceDistanceAreaPermilleTolerance, configuration.FaceDistanceAreaPermilleTolerance,
configuration.FaceDistanceMinimumConfidence, configuration.FaceDistanceMinimumConfidence,
configuration.FaceDistancePermyriad, configuration.FaceDistancePermyriad,
@ -116,6 +116,11 @@ public partial class DlibDotNet
predictorModel, predictorModel,
configuration.PropertiesChangedForFaces); configuration.PropertiesChangedForFaces);
} }
{
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
_FaceParts = new D2_FaceParts(imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages);
}
_MapConfiguration = Get(configuration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension);
if (_FirstRun || !_ArgZeroIsConfigurationRootDirectory) if (_FirstRun || !_ArgZeroIsConfigurationRootDirectory)
personContainers = Array.Empty<PersonContainer>(); personContainers = Array.Empty<PersonContainer>();
else else
@ -139,10 +144,6 @@ public partial 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(imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages);
}
{ {
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple( (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple(
configuration.OutputExtension, configuration.OutputExtension,
@ -323,28 +324,18 @@ public partial class DlibDotNet
throw new Exception("Configuration has to match interface!"); throw new Exception("Configuration has to match interface!");
} }
private static Map.Models.Configuration Get(Models.Configuration configuration) private static Map.Models.Configuration Get(Models.Configuration configuration, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension)
{ {
Map.Models.Configuration result = new( Map.Models.Configuration result = new(
configuration.FaceDistanceAreaPermilleTolerance,
configuration.FaceDistanceHiddenImageFactor, configuration.FaceDistanceHiddenImageFactor,
configuration.FaceDistancePermyriad,
configuration.FaceDistanceMinimumConfidence,
configuration.FaceDistanceTolerance, configuration.FaceDistanceTolerance,
configuration.MapLogicSigma,
configuration.MappingDefaultName, configuration.MappingDefaultName,
configuration.DistanceMoveUnableToMatch,
configuration.MappingSaveNotMapped,
configuration.MappingSaveMapped,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping,
configuration.PersonBirthdayFirstYear, configuration.PersonBirthdayFirstYear,
configuration.PersonBirthdayFormat, configuration.PersonBirthdayFormat,
configuration.PersonKeyFormat,
configuration.SortingDaysDeltaTolerance,
configuration.SortingMaximumPerFaceShouldBeHigh,
configuration.SortingMaximumPerKey, configuration.SortingMaximumPerKey,
configuration.SortingSigma); facesFileNameExtension,
facesHiddenFileNameExtension,
facePartsFileNameExtension);
return result; return result;
} }
@ -431,7 +422,7 @@ public partial class DlibDotNet
if (item.Property?.Id is not null if (item.Property?.Id is not null
&& faces.Any(l => l.FaceEncoding is not null && l.Location is not null && l.OutputResolution is not null) && faces.Any(l => l.FaceEncoding is not null && l.Location is not null && l.OutputResolution is not null)
&& idToMappedFaceFilesCollection.TryGetValue(item.Property.Id.Value, out List<(string, int)>? collection)) && idToMappedFaceFilesCollection.TryGetValue(item.Property.Id.Value, out List<(string, int)>? collection))
_ = _Distance.GetUnableToMatchCountAndRenameMatches(_Faces.FileNameExtension, eDistanceContentDirectory, mappingFromItem, faces, collection); _Distance.LookForMatchFacesAndPossiblyRename(_Faces.FileNameExtension, eDistanceContentDirectory, mappingFromItem, faces, collection);
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
{ {
throw new NotImplementedException(); throw new NotImplementedException();
@ -905,15 +896,16 @@ public partial class DlibDotNet
_AppSettings.MaxDegreeOfParallelism, _AppSettings.MaxDegreeOfParallelism,
_Configuration.PropertyConfiguration, _Configuration.PropertyConfiguration,
_MapConfiguration, _MapConfiguration,
_Faces.FileNameExtension,
_Faces.HiddenFileNameExtension,
_FaceParts.FileNameExtension,
ticks, ticks,
personContainers, personContainers,
a2PeopleSingletonDirectory, a2PeopleSingletonDirectory,
eDistanceContentDirectory, eDistanceContentDirectory,
distinctFilteredFaces, distinctFilteredFaces,
_Distance); _Distance);
mapLogic.CopyManualFiles(dFacesContentDirectory, distinctFilteredFaces);
int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces);
if (_Configuration.MappingSaveMapped)
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, totalNotMapped);
sortingContainers = _Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, selectedFilteredFaces, useFiltersCounter); sortingContainers = _Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, selectedFilteredFaces, useFiltersCounter);
if (!sortingContainers.Any()) if (!sortingContainers.Any())
{ {
@ -925,11 +917,9 @@ public partial class DlibDotNet
} }
} }
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers); E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces);
if (totalNotMapped > 0) if (totalNotMapped > 0)
mapLogic.ForceSingleImageThenSaveMapping(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, sortingContainers, useFiltersCounter, totalNotMapped); mapLogic.ForceSingleImageThenSaveSorting(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, sortingContainers, useFiltersCounter, totalNotMapped);
mapLogic.CopyManualFiles(dFacesContentDirectory, distinctFilteredFaces); if (_Configuration.MappingSaveNotMapped)
if (_MapConfiguration.MappingSaveNotMapped)
mapLogic.SaveNotMappedTicks(); mapLogic.SaveNotMappedTicks();
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
mapLogic.SaveShortcuts(_Configuration.JuliePhares, distinctFilteredFaces); mapLogic.SaveShortcuts(_Configuration.JuliePhares, distinctFilteredFaces);
@ -1042,8 +1032,9 @@ public partial class DlibDotNet
propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), create: false); propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), create: false);
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, model, predictorModel); propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, model, predictorModel);
} }
Dictionary<int, List<(string, int)>> idToMappedFaceFilesCollection = Map.Models.Stateless.Methods.IMapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(_MapConfiguration, _Faces.FileNameExtension, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers); Dictionary<int, List<(string, int)>> idToMappedFaceFilesCollection = Map.Models.Stateless.Methods.IMapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(_MapConfiguration, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers);
FullDoWork(argZero, model, predictorModel, propertyRoot, ticks, propertyLogic, t, containers, eDistanceContentDirectory, idToMappedFaceFilesCollection); FullDoWork(argZero, model, predictorModel, propertyRoot, ticks, propertyLogic, t, containers, eDistanceContentDirectory, idToMappedFaceFilesCollection);
_Distance.Clear();
foreach (string outputResolution in _Configuration.OutputResolutions) foreach (string outputResolution in _Configuration.OutputResolutions)
{ {
if (_FirstRun || container is not null) if (_FirstRun || container is not null)

View File

@ -16,6 +16,7 @@ public class Configuration
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; } [Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
[Display(Name = "Distance Move Unable to Match by 1 Tick"), Required] public bool? DistanceMoveUnableToMatch { get; set; } [Display(Name = "Distance Move Unable to Match by 1 Tick"), Required] public bool? DistanceMoveUnableToMatch { get; set; }
[Display(Name = "Distance Pixel Distance Tolerance"), Required] public int? DistancePixelDistanceTolerance { get; set; } [Display(Name = "Distance Pixel Distance Tolerance"), Required] public int? DistancePixelDistanceTolerance { get; set; }
[Display(Name = "Distance Rename to Match"), Required] public bool? DistanceRenameToMatch { get; set; }
[Display(Name = "Face Area Permille Tolerance"), Required] public int? FaceDistanceAreaPermilleTolerance { get; set; } [Display(Name = "Face Area Permille Tolerance"), Required] public int? FaceDistanceAreaPermilleTolerance { get; set; }
[Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; } [Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; }
[Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; } [Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; }
@ -33,7 +34,6 @@ public class Configuration
[Display(Name = "Location Confidence Factor"), Required] public int? LocationConfidenceFactor { get; set; } [Display(Name = "Location Confidence Factor"), Required] public int? LocationConfidenceFactor { get; set; }
[Display(Name = "Location Digits"), Required] public int? LocationDigits { get; set; } [Display(Name = "Location Digits"), Required] public int? LocationDigits { get; set; }
[Display(Name = "Location Factor"), Required] public int? LocationFactor { get; set; } [Display(Name = "Location Factor"), Required] public int? LocationFactor { get; set; }
[Display(Name = "Map Logic Sigma"), Required] public int? MapLogicSigma { get; set; }
[Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; } [Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; }
[Display(Name = "Mapping Default Name"), Required] public string MappingDefaultName { get; set; } [Display(Name = "Mapping Default Name"), Required] public string MappingDefaultName { get; set; }
[Display(Name = "Mapping Save Mapped"), Required] public bool? MappingSaveMapped { get; set; } [Display(Name = "Mapping Save Mapped"), Required] public bool? MappingSaveMapped { get; set; }
@ -100,6 +100,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.DistanceMoveUnableToMatch)); throw new NullReferenceException(nameof(configuration.DistanceMoveUnableToMatch));
if (configuration.DistancePixelDistanceTolerance is null) if (configuration.DistancePixelDistanceTolerance is null)
throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance)); throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance));
if (configuration.DistanceRenameToMatch is null)
throw new NullReferenceException(nameof(configuration.DistanceRenameToMatch));
if (configuration.FaceDistanceAreaPermilleTolerance is null) if (configuration.FaceDistanceAreaPermilleTolerance is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceAreaPermilleTolerance)); throw new NullReferenceException(nameof(configuration.FaceDistanceAreaPermilleTolerance));
if (configuration.FaceDistanceHiddenImageFactor is null) if (configuration.FaceDistanceHiddenImageFactor is null)
@ -132,8 +134,6 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.LocationDigits)); throw new NullReferenceException(nameof(configuration.LocationDigits));
if (configuration.LocationFactor is null) if (configuration.LocationFactor is null)
throw new NullReferenceException(nameof(configuration.LocationFactor)); throw new NullReferenceException(nameof(configuration.LocationFactor));
if (configuration.MapLogicSigma is null)
throw new NullReferenceException(nameof(configuration.MapLogicSigma));
if (configuration.MappingDefaultName is null) if (configuration.MappingDefaultName is null)
throw new NullReferenceException(nameof(configuration.MappingDefaultName)); throw new NullReferenceException(nameof(configuration.MappingDefaultName));
if (configuration.MappingSaveNotMapped is null) if (configuration.MappingSaveNotMapped is null)
@ -223,6 +223,7 @@ public class Configuration
configuration.DistanceFactor.Value, configuration.DistanceFactor.Value,
configuration.DistanceMoveUnableToMatch.Value, configuration.DistanceMoveUnableToMatch.Value,
configuration.DistancePixelDistanceTolerance.Value, configuration.DistancePixelDistanceTolerance.Value,
configuration.DistanceRenameToMatch.Value,
configuration.FaceDistanceAreaPermilleTolerance.Value, configuration.FaceDistanceAreaPermilleTolerance.Value,
configuration.FaceDistanceHiddenImageFactor.Value, configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value, configuration.FaceDistanceMinimumConfidence.Value,
@ -240,7 +241,6 @@ public class Configuration
configuration.LocationConfidenceFactor.Value, configuration.LocationConfidenceFactor.Value,
configuration.LocationDigits.Value, configuration.LocationDigits.Value,
configuration.LocationFactor.Value, configuration.LocationFactor.Value,
configuration.MapLogicSigma.Value,
configuration.MappedMaxIndex, configuration.MappedMaxIndex,
configuration.MappingDefaultName, configuration.MappingDefaultName,
configuration.MappingSaveNotMapped.Value, configuration.MappingSaveNotMapped.Value,

View File

@ -15,6 +15,7 @@ public class Configuration
public int DistanceFactor { init; get; } public int DistanceFactor { init; get; }
public bool DistanceMoveUnableToMatch { init; get; } public bool DistanceMoveUnableToMatch { init; get; }
public int DistancePixelDistanceTolerance { init; get; } public int DistancePixelDistanceTolerance { init; get; }
public bool DistanceRenameToMatch { init; get; }
public int FaceDistanceAreaPermilleTolerance { init; get; } public int FaceDistanceAreaPermilleTolerance { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; } public int FaceDistanceHiddenImageFactor { init; get; }
public double FaceDistanceMinimumConfidence { init; get; } public double FaceDistanceMinimumConfidence { init; get; }
@ -32,7 +33,6 @@ public class Configuration
public int LocationConfidenceFactor { init; get; } public int LocationConfidenceFactor { init; get; }
public int LocationDigits { init; get; } public int LocationDigits { init; get; }
public int LocationFactor { init; get; } public int LocationFactor { init; get; }
public int MapLogicSigma { init; get; }
public int? MappedMaxIndex { init; get; } public int? MappedMaxIndex { init; get; }
public string MappingDefaultName { init; get; } public string MappingDefaultName { init; get; }
public bool MappingSaveNotMapped { init; get; } public bool MappingSaveNotMapped { init; get; }
@ -83,6 +83,7 @@ public class Configuration
int distanceFactor, int distanceFactor,
bool distanceMoveUnableToMatch, bool distanceMoveUnableToMatch,
int distancePixelDistanceTolerance, int distancePixelDistanceTolerance,
bool distanceRenameToMatch,
int faceDistanceAreaPermilleTolerance, int faceDistanceAreaPermilleTolerance,
int faceDistanceHiddenImageFactor, int faceDistanceHiddenImageFactor,
double faceDistanceMinimumConfidence, double faceDistanceMinimumConfidence,
@ -100,7 +101,6 @@ public class Configuration
int locationConfidenceFactor, int locationConfidenceFactor,
int locationDigits, int locationDigits,
int locationFactor, int locationFactor,
int mapLogicSigma,
int? mappedMaxIndex, int? mappedMaxIndex,
string mappingDefaultName, string mappingDefaultName,
bool mappingSaveNotMapped, bool mappingSaveNotMapped,
@ -150,6 +150,7 @@ public class Configuration
DistanceFactor = distanceFactor; DistanceFactor = distanceFactor;
DistanceMoveUnableToMatch = distanceMoveUnableToMatch; DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
DistancePixelDistanceTolerance = distancePixelDistanceTolerance; DistancePixelDistanceTolerance = distancePixelDistanceTolerance;
DistanceRenameToMatch = distanceRenameToMatch;
FaceDistanceAreaPermilleTolerance = faceDistanceAreaPermilleTolerance; FaceDistanceAreaPermilleTolerance = faceDistanceAreaPermilleTolerance;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor; FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence; FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
@ -167,7 +168,6 @@ public class Configuration
LocationConfidenceFactor = locationConfidenceFactor; LocationConfidenceFactor = locationConfidenceFactor;
LocationDigits = locationDigits; LocationDigits = locationDigits;
LocationFactor = locationFactor; LocationFactor = locationFactor;
MapLogicSigma = mapLogicSigma;
MappedMaxIndex = mappedMaxIndex; MappedMaxIndex = mappedMaxIndex;
MappingDefaultName = mappingDefaultName; MappingDefaultName = mappingDefaultName;
MappingSaveNotMapped = mappingSaveNotMapped; MappingSaveNotMapped = mappingSaveNotMapped;

View File

@ -57,7 +57,8 @@
"DistanceFactor": 8, "DistanceFactor": 8,
"DistanceMoveUnableToMatch": false, "DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1, "DistancePixelDistanceTolerance": 1,
"FaceDistanceAreaPermilleTolerance": 250, "DistanceRenameToMatch": false,
"FaceDistanceAreaPermilleTolerance": 7,
"FaceDistanceHiddenImageFactor": 2, "FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8, "FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000, "FaceDistancePermyriad": 10000,
@ -71,7 +72,6 @@
"LocationConfidenceFactor": 2, "LocationConfidenceFactor": 2,
"LocationDigits": 9, "LocationDigits": 9,
"LocationFactor": 10000, "LocationFactor": 10000,
"MapLogicSigma": 3,
"MappedMaxIndex": 1034720, "MappedMaxIndex": 1034720,
"MappingDefaultName": "John Doe~25", "MappingDefaultName": "John Doe~25",
"MappingSaveFaceEncoding": false, "MappingSaveFaceEncoding": false,
@ -118,7 +118,7 @@
"SkipSearch": false, "SkipSearch": false,
"SortingDaysDeltaTolerance": 700, "SortingDaysDeltaTolerance": 700,
"SortingMaximumPerFaceShouldBeHigh": 1000, "SortingMaximumPerFaceShouldBeHigh": 1000,
"SortingMaximumPerKey": 27, "SortingMaximumPerKey": 7,
"SortingSigma": 3, "SortingSigma": 3,
"TestDistanceResults": true, "TestDistanceResults": true,
"WriteBitmapDataBytes": false, "WriteBitmapDataBytes": false,

View File

@ -57,6 +57,7 @@
"DistanceFactor": 8, "DistanceFactor": 8,
"DistanceMoveUnableToMatch": false, "DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1, "DistancePixelDistanceTolerance": 1,
"DistanceRenameToMatch": false,
"FaceDistanceAreaPermilleTolerance": 250, "FaceDistanceAreaPermilleTolerance": 250,
"FaceDistanceHiddenImageFactor": 2, "FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8, "FaceDistanceMinimumConfidence": 0.8,
@ -71,7 +72,6 @@
"LocationConfidenceFactor": 2, "LocationConfidenceFactor": 2,
"LocationDigits": 9, "LocationDigits": 9,
"LocationFactor": 10000, "LocationFactor": 10000,
"MapLogicSigma": 3,
"MappedMaxIndex": 1034720, "MappedMaxIndex": 1034720,
"MappingDefaultName": "John Doe~25", "MappingDefaultName": "John Doe~25",
"MappingSaveFaceEncoding": false, "MappingSaveFaceEncoding": false,
@ -116,7 +116,7 @@
"SkipSearch": false, "SkipSearch": false,
"SortingDaysDeltaTolerance": 700, "SortingDaysDeltaTolerance": 700,
"SortingMaximumPerFaceShouldBeHigh": 1000, "SortingMaximumPerFaceShouldBeHigh": 1000,
"SortingMaximumPerKey": 27, "SortingMaximumPerKey": 7,
"SortingSigma": 3, "SortingSigma": 3,
"TestDistanceResults": true, "TestDistanceResults": true,
"WriteBitmapDataBytes": false, "WriteBitmapDataBytes": false,

View File

@ -57,6 +57,7 @@
"DistanceFactor": 8, "DistanceFactor": 8,
"DistanceMoveUnableToMatch": false, "DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1, "DistancePixelDistanceTolerance": 1,
"DistanceRenameToMatch": false,
"FaceDistanceAreaPermilleTolerance": 250, "FaceDistanceAreaPermilleTolerance": 250,
"FaceDistanceHiddenImageFactor": 2, "FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8, "FaceDistanceMinimumConfidence": 0.8,
@ -71,7 +72,6 @@
"LocationConfidenceFactor": 2, "LocationConfidenceFactor": 2,
"LocationDigits": 9, "LocationDigits": 9,
"LocationFactor": 10000, "LocationFactor": 10000,
"MapLogicSigma": 3,
"MappedMaxIndex": 1034720, "MappedMaxIndex": 1034720,
"MappingDefaultName": "John Doe~25", "MappingDefaultName": "John Doe~25",
"MappingSaveFaceEncoding": false, "MappingSaveFaceEncoding": false,
@ -116,7 +116,7 @@
"SkipSearch": false, "SkipSearch": false,
"SortingDaysDeltaTolerance": 700, "SortingDaysDeltaTolerance": 700,
"SortingMaximumPerFaceShouldBeHigh": 1000, "SortingMaximumPerFaceShouldBeHigh": 1000,
"SortingMaximumPerKey": 27, "SortingMaximumPerKey": 7,
"SortingSigma": 3, "SortingSigma": 3,
"TestDistanceResults": true, "TestDistanceResults": true,
"WriteBitmapDataBytes": false, "WriteBitmapDataBytes": false,

View File

@ -6,66 +6,36 @@ namespace View_by_Distance.Map.Models;
public class Configuration public class Configuration
{ {
public int FaceDistanceAreaPermilleTolerance { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; }
public int FaceDistancePermyriad { init; get; } public int FaceDistancePermyriad { init; get; }
public double FaceDistanceMinimumConfidence { init; get; }
public double FaceDistanceTolerance { init; get; } public double FaceDistanceTolerance { init; get; }
public int MapLogicSigma { init; get; }
public string MappingDefaultName { init; get; } public string MappingDefaultName { init; get; }
public bool DistanceMoveUnableToMatch { init; get; }
public bool MappingSaveNotMapped { init; get; }
public bool MappingSaveMapped { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping { init; get; }
public int PersonBirthdayFirstYear { init; get; } public int PersonBirthdayFirstYear { init; get; }
public string PersonBirthdayFormat { init; get; } public string PersonBirthdayFormat { init; get; }
public string PersonKeyFormat { init; get; }
public int SortingDaysDeltaTolerance { init; get; }
public int SortingMaximumPerFaceShouldBeHigh { init; get; }
public int SortingMaximumPerKey { init; get; } public int SortingMaximumPerKey { init; get; }
public int SortingSigma { init; get; } public string FacesFileNameExtension { init; get; }
public string FacePartsFileNameExtension { init; get; }
public string FacesHiddenFileNameExtension { init; get; }
[JsonConstructor] [JsonConstructor]
public Configuration(int faceDistanceAreaPermilleTolerance, public Configuration(int faceDistancePermyriad,
int faceDistanceHiddenImageFactor,
int faceDistancePermyriad,
double faceDistanceMinimumConfidence,
double faceDistanceTolerance, double faceDistanceTolerance,
int mapLogicSigma,
string mappingDefaultName, string mappingDefaultName,
bool distanceMoveUnableToMatch,
bool mappingSaveNotMapped,
bool mappingSaveMapped,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping,
int personBirthdayFirstYear, int personBirthdayFirstYear,
string personBirthdayFormat, string personBirthdayFormat,
string personKeyFormat,
int sortingDaysDeltaTolerance,
int sortingMaximumPerFaceShouldBeHigh,
int sortingMaximumPerKey, int sortingMaximumPerKey,
int sortingSigma) string facesFileNameExtension,
string facesHiddenFileNameExtension,
string facePartsFileNameExtension)
{ {
FaceDistanceAreaPermilleTolerance = faceDistanceAreaPermilleTolerance;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistancePermyriad = faceDistancePermyriad;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
FaceDistanceTolerance = faceDistanceTolerance;
MapLogicSigma = mapLogicSigma;
MappingDefaultName = mappingDefaultName; MappingDefaultName = mappingDefaultName;
DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
MappingSaveNotMapped = mappingSaveNotMapped;
MappingSaveMapped = mappingSaveMapped;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping;
PersonBirthdayFirstYear = personBirthdayFirstYear;
PersonBirthdayFormat = personBirthdayFormat; PersonBirthdayFormat = personBirthdayFormat;
PersonKeyFormat = personKeyFormat;
SortingDaysDeltaTolerance = sortingDaysDeltaTolerance;
SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
SortingMaximumPerKey = sortingMaximumPerKey; SortingMaximumPerKey = sortingMaximumPerKey;
SortingSigma = sortingSigma; FaceDistancePermyriad = faceDistancePermyriad;
FaceDistanceTolerance = faceDistanceTolerance;
FacesFileNameExtension = facesFileNameExtension;
PersonBirthdayFirstYear = personBirthdayFirstYear;
FacePartsFileNameExtension = facePartsFileNameExtension;
FacesHiddenFileNameExtension = facesHiddenFileNameExtension;
} }
public override string ToString() public override string ToString()

View File

@ -23,20 +23,14 @@ public class MapLogic
private readonly Serilog.ILogger? _Log; private readonly Serilog.ILogger? _Log;
private readonly int _MaxDegreeOfParallelism; private readonly int _MaxDegreeOfParallelism;
private readonly Configuration? _Configuration; private readonly Configuration? _Configuration;
private readonly string _FacesFileNameExtension;
private readonly string _FacePartsFileNameExtension;
private readonly string _FacesHiddenFileNameExtension;
private readonly string _EDistanceContentTicksDirectory; private readonly string _EDistanceContentTicksDirectory;
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? faceDistance) public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? faceDistance)
{ {
_Ticks = ticks; _Ticks = ticks;
_Configuration = configuration; _Configuration = configuration;
_Log = Serilog.Log.ForContext<MapLogic>(); _Log = Serilog.Log.ForContext<MapLogic>();
_FacesFileNameExtension = facesFileNameExtension;
_MaxDegreeOfParallelism = maxDegreeOfParallelism; _MaxDegreeOfParallelism = maxDegreeOfParallelism;
_FacePartsFileNameExtension = facePartsFileNameExtension;
_FacesHiddenFileNameExtension = facesHiddenFileNameExtension;
if (_Log is null) if (_Log is null)
{ } { }
if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any()) if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any())
@ -67,7 +61,6 @@ public class MapLogic
List<PersonContainer> personContainerCollection = new(personContainers); List<PersonContainer> personContainerCollection = new(personContainers);
Stateless.MapLogic.Set(propertyConfiguration, Stateless.MapLogic.Set(propertyConfiguration,
configuration, configuration,
facesFileNameExtension,
ticks, ticks,
personContainerCollection, personContainerCollection,
a2PeopleSingletonDirectory, a2PeopleSingletonDirectory,
@ -102,8 +95,8 @@ public class MapLogic
_IdThenNormalizedPixelPercentageToPersonContainers = idThenNormalizedPixelPercentageToPersonContainers; _IdThenNormalizedPixelPercentageToPersonContainers = idThenNormalizedPixelPercentageToPersonContainers;
} }
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string outputExtension, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) : public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) :
this(maxDegreeOfParallelism, propertyConfiguration, configuration, outputExtension, outputExtension, outputExtension, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, new(), null) this(maxDegreeOfParallelism, propertyConfiguration, configuration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, new(), null)
{ } { }
public override string ToString() public override string ToString()
@ -112,6 +105,131 @@ public class MapLogic
return result; return result;
} }
public int AddToMapping(List<Face> distinctFilteredFaces)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int result = 0;
const int zero = 0;
string mappingSegmentB;
PersonBirthday personBirthday;
PersonContainer[]? collection;
int by = Stateless.IMapLogic.Mapping;
List<PersonContainer> personContainers = new();
Dictionary<int, PersonContainer[]>? keyValuePairs;
foreach (Face face in distinctFilteredFaces)
{
personContainers.Clear();
if (face.Mapping is null)
throw new NotSupportedException();
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(face.Mapping.MappingFromItem.Id, out keyValuePairs))
result += 1;
else
{
if (!keyValuePairs.TryGetValue(face.Mapping.MappingFromLocation.NormalizedPixelPercentage, out collection))
result += 1;
else
personContainers.AddRange(collection);
}
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, face.Mapping.MappingFromItem);
face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
}
}
return result;
}
private void SaveContainers(int totalNotMapped, int? updated, List<SaveContainer> saveContainers)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
string checkFile;
string sourceFile;
WindowsShortcut windowsShortcut;
string[] directories = (from l in saveContainers select l.Directory).Distinct().ToArray();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
string message;
if (updated is null)
message = $") {saveContainers.Count:000} save(s) - {totalNotMapped} Total not Mapped - {totalSeconds} total second(s)";
else
message = $") {saveContainers.Count:000} save(s) - {totalNotMapped} Total not Mapped - {updated} Updated - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
foreach (string directory in directories)
{
if (string.IsNullOrEmpty(directory))
continue;
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
}
using ProgressBar progressBar = new(saveContainers.Count, message, options);
foreach (SaveContainer saveContainer in saveContainers)
{
progressBar.Tick();
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.FaceFileHolder is null)
continue;
if (!saveContainer.FaceFileHolder.Exists && saveContainer.ResizedFileHolder is not null && saveContainer.ResizedFileHolder.Exists)
{
checkFile = saveContainer.CheckFile;
sourceFile = saveContainer.ResizedFileHolder.FullName;
}
else if (saveContainer.FaceFileHolder.Exists)
{
sourceFile = saveContainer.FaceFileHolder.FullName;
checkFile = $"{saveContainer.CheckFile}{_Configuration.FacesFileNameExtension}";
}
else
continue;
if (File.Exists(checkFile))
continue;
File.Copy(sourceFile, checkFile);
if (saveContainer.HiddenFaceFileHolder is not null && saveContainer.HiddenFaceFileHolder.Exists)
{
sourceFile = saveContainer.HiddenFaceFileHolder.FullName;
checkFile = $"{saveContainer.CheckFile}{_Configuration.FacesHiddenFileNameExtension}";
}
else if (saveContainer.FacePartsFileHolder is not null && saveContainer.FacePartsFileHolder.Exists)
{
sourceFile = saveContainer.FacePartsFileHolder.FullName;
checkFile = $"{saveContainer.CheckFile}{_Configuration.FacePartsFileNameExtension}";
}
if (File.Exists(checkFile))
continue;
File.Copy(sourceFile, checkFile);
}
foreach (SaveContainer saveContainer in saveContainers)
{
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is null)
continue;
if (string.IsNullOrEmpty(saveContainer.ShortcutFile) || !saveContainer.ResizedFileHolder.Exists)
continue;
try
{
windowsShortcut = new() { Path = saveContainer.ResizedFileHolder.FullName };
windowsShortcut.Save(saveContainer.ShortcutFile);
windowsShortcut.Dispose();
}
catch (Exception)
{ }
}
}
public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, List<Face> distinctFilteredFaces, int totalNotMapped)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int? updated = null;
int? useFiltersCounter = null;
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Stateless.IMapLogic.Mapping));
List<SaveContainer> saveContainers = Stateless.MapLogic.GetMappingSaveContainers(_Configuration, _EDistanceContentTicksDirectory, dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, useFiltersCounter, saveMapped: true);
SaveContainers(totalNotMapped, updated, saveContainers);
if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory))
Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory);
}
private List<(long, long, long, long)> GetPersonKeysRangesCollection(PersonContainer[] personContainers) private List<(long, long, long, long)> GetPersonKeysRangesCollection(PersonContainer[] personContainers)
{ {
List<(long, long, long, long)> results = new(); List<(long, long, long, long)> results = new();
@ -197,185 +315,215 @@ public class MapLogic
return results; return results;
} }
public void SaveShortcuts(string[] juliePhares, List<Face> distinctFilteredFaces) private int UpdateFromSortingContainers(SortingContainer[] sortingContainers)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<(Face, List<(string?, string, string?, string?, string)>)> facesToCollection = GetCollection(distinctFilteredFaces);
foreach ((Face face, List<(string? PersonKeyFormatted, string, string?, string?, string)> collection) in facesToCollection)
{
if (collection.Any(l => l.PersonKeyFormatted is not null and "1501-04-10_00"))
continue;
foreach ((string? personKeyFormatted, string directory, string? copyDirectory, string? copyFileName, string _) in collection)
{
if (face.Mapping is null)
throw new NotSupportedException();
if (personKeyFormatted is null)
continue;
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
if (string.IsNullOrEmpty(copyDirectory) || string.IsNullOrEmpty(copyFileName))
continue;
if (!juliePhares.Contains(personKeyFormatted))
continue;
if (!Directory.Exists(copyDirectory))
_ = Directory.CreateDirectory(copyDirectory);
if (!File.Exists(copyFileName))
File.Copy(face.Mapping.MappingFromItem.ResizedFileHolder.FullName, copyFileName);
break;
}
}
}
private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, long minimumDateTimeTicks, bool? isWrongYear)
{
int years;
string result;
TimeSpan? timeSpan = IPersonBirthday.GetTimeSpan(minimumDateTimeTicks, isWrongYear, personBirthday);
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0)
result = "!---";
else if (timeSpan.HasValue)
{
(years, _) = IPersonBirthday.GetAge(minimumDateTimeTicks, personBirthday);
result = $"^{years:000}";
}
else if (approximateYears.HasValue)
{
DateTime dateTime = new(ticks);
(years, _) = IAge.GetAge(minimumDateTimeTicks, dateTime.AddYears(-approximateYears.Value));
result = $"~{years:000}";
}
else
{
string isWrongYearFlag = IItem.GetWrongYearFlag(isWrongYear);
result = $"{isWrongYearFlag}{new DateTime(minimumDateTimeTicks):yyyy}";
}
return result;
}
private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, DateTime minimumDateTime, bool? isWrongYear)
{
string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, minimumDateTime.Ticks, isWrongYear);
return result;
}
private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, MappingFromItem mappingFromItem)
{
string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.MinimumDateTime, mappingFromItem.IsWrongYear);
return result;
}
public int AddToMapping(List<Face> distinctFilteredFaces)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
int result = 0; int result = 0;
string key;
const int zero = 0; const int zero = 0;
string mappingSegmentB; string mappingSegmentB;
string personKeyFormatted;
List<Mapping> checkCollection;
PersonBirthday personBirthday; PersonBirthday personBirthday;
PersonContainer[]? collection; PersonContainer[] personContainers;
int by = Stateless.IMapLogic.Mapping; const int by = Stateless.IMapLogic.Sorting;
List<PersonContainer> personContainers = new(); List<int> normalizedPixelPercentageCollection;
Dictionary<int, PersonContainer[]>? keyValuePairs; Dictionary<string, List<Mapping>> checkKeyValuePairs = new();
foreach (Face face in distinctFilteredFaces) Dictionary<int, List<int>> idToNormalizedPixelPercentageCollection = new();
Dictionary<int, PersonContainer[]>? normalizedPixelPercentageToPersonContainers;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
string message = $") {sortingContainers.Length:000} Update From Sorting Container(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(sortingContainers.Length, message, options);
foreach (SortingContainer sortingContainer in sortingContainers)
{ {
personContainers.Clear(); progressBar.Tick();
if (face.Mapping is null) if (sortingContainer.Face.Mapping is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(face.Mapping.MappingFromItem.Id, out keyValuePairs)) if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(sortingContainer.Sorting.Id, out normalizedPixelPercentageToPersonContainers))
result += 1; throw new NotSupportedException();
else if (!normalizedPixelPercentageToPersonContainers.ContainsKey(sortingContainer.Sorting.NormalizedPixelPercentage))
{ throw new NotSupportedException();
if (!keyValuePairs.TryGetValue(face.Mapping.MappingFromLocation.NormalizedPixelPercentage, out collection)) if (!idToNormalizedPixelPercentageCollection.ContainsKey(sortingContainer.Face.Mapping.MappingFromItem.Id))
result += 1; idToNormalizedPixelPercentageCollection.Add(sortingContainer.Face.Mapping.MappingFromItem.Id, new());
else normalizedPixelPercentageCollection = idToNormalizedPixelPercentageCollection[sortingContainer.Face.Mapping.MappingFromItem.Id];
personContainers.AddRange(collection); if (normalizedPixelPercentageCollection.Contains(sortingContainer.Face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
} continue;
personContainers = normalizedPixelPercentageToPersonContainers[sortingContainer.Sorting.NormalizedPixelPercentage];
foreach (PersonContainer personContainer in personContainers) foreach (PersonContainer personContainer in personContainers)
{ {
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue; continue;
personBirthday = personContainer.Birthdays[zero]; personBirthday = personContainer.Birthdays[zero];
mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, face.Mapping.MappingFromItem); personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB); mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, sortingContainer.Face.Mapping.MappingFromItem);
key = string.Concat(personKeyFormatted, '\t', mappingSegmentB);
if (!checkKeyValuePairs.ContainsKey(key))
checkKeyValuePairs.Add(key, new());
checkCollection = checkKeyValuePairs[key];
if (checkCollection.Count > _Configuration.SortingMaximumPerKey)
continue;
normalizedPixelPercentageCollection.Add(sortingContainer.Face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
sortingContainer.Face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
checkCollection.Add(sortingContainer.Face.Mapping);
result += 1;
break;
} }
} }
return result; return result;
} }
private void SaveContainers(int totalNotMapped, int updated, List<SaveContainer> saveContainers) internal void ForceSingleImage(IEnumerable<Face> distinctFilteredFaces)
{ {
string checkFile; if (_Configuration is null)
string sourceFile; throw new NullReferenceException(nameof(_Configuration));
WindowsShortcut windowsShortcut; const int zero = 0;
string[] directories = (from l in saveContainers select l.Directory).Distinct().ToArray(); string mappingSegmentB;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds); PersonBirthday personBirthday;
string message = $") {saveContainers.Count:000} save(s) - {totalNotMapped} Total not Mapped - {updated} Updated - {totalSeconds} total second(s)"; List<int>? normalizedPixelPercentages;
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; int by = Stateless.IMapLogic.ForceSingleImage;
foreach (string directory in directories) string displayDirectoryName = _Configuration.MappingDefaultName;
Face[] orderedDistinctFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromLocation.Confidence descending select l).ToArray();
foreach (Face face in orderedDistinctFilteredFaces)
{ {
if (string.IsNullOrEmpty(directory)) if (face.Mapping is null)
throw new NotSupportedException();
if (face.Mapping.MappingFromPerson.PersonBirthday is not null)
continue; continue;
if (!Directory.Exists(directory)) if (_SkipCollection.TryGetValue(face.Mapping.MappingFromItem.Id, out normalizedPixelPercentages))
_ = Directory.CreateDirectory(directory);
}
using ProgressBar progressBar = new(saveContainers.Count, message, options);
foreach (SaveContainer saveContainer in saveContainers)
{ {
progressBar.Tick(); if (normalizedPixelPercentages.Contains(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is null || saveContainer.FaceFileHolder is null || !string.IsNullOrEmpty(saveContainer.Json))
continue; continue;
if (!saveContainer.FaceFileHolder.Exists && saveContainer.ResizedFileHolder.Exists)
{
checkFile = saveContainer.CheckFile;
sourceFile = saveContainer.ResizedFileHolder.FullName;
} }
else if (saveContainer.FaceFileHolder.Exists) foreach (PersonContainer personContainer in _NotMappedPersonContainers)
{ {
sourceFile = saveContainer.FaceFileHolder.FullName; if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
checkFile = $"{saveContainer.CheckFile}{_FacesFileNameExtension}"; continue;
personBirthday = personContainer.Birthdays[zero];
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, face.Mapping.MappingFromItem);
face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
break;
}
break;
}
}
public void ForceSingleImageThenSaveSorting(string dFacesContentDirectory, string d2FacePartsContentDirectory, List<Face> distinctFilteredFaces, SortingContainer[] sortingContainers, int? useFiltersCounter, int totalNotMapped)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int updated;
List<SaveContainer> saveContainers;
if (!sortingContainers.Any())
{
updated = 0;
ForceSingleImage(distinctFilteredFaces);
saveContainers = Stateless.MapLogic.GetMappingSaveContainers(_Configuration, _EDistanceContentTicksDirectory, dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, useFiltersCounter, saveMapped: false);
} }
else else
continue;
if (File.Exists(checkFile))
continue;
File.Copy(sourceFile, checkFile);
if (saveContainer.HiddenFaceFileHolder is not null && saveContainer.HiddenFaceFileHolder.Exists)
{ {
sourceFile = saveContainer.HiddenFaceFileHolder.FullName; updated = UpdateFromSortingContainers(sortingContainers);
checkFile = $"{saveContainer.CheckFile}{_FacesHiddenFileNameExtension}"; if (useFiltersCounter is null && totalNotMapped - updated > 0)
ForceSingleImage(distinctFilteredFaces);
saveContainers = Stateless.MapLogic.GetMappingSaveContainers(_Configuration, _EDistanceContentTicksDirectory, dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, useFiltersCounter, saveMapped: false);
} }
else if (saveContainer.FacePartsFileHolder is not null && saveContainer.FacePartsFileHolder.Exists) SaveContainers(totalNotMapped, updated, saveContainers);
{
sourceFile = saveContainer.FacePartsFileHolder.FullName;
checkFile = $"{saveContainer.CheckFile}{_FacePartsFileNameExtension}";
} }
if (File.Exists(checkFile))
public void CopyManualFiles(string dFacesContentDirectory, List<Face> distinctFilteredFaces)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int? id;
Face face;
string faceFile;
string checkFile;
string directory;
FileInfo fileInfo;
const int zero = 0;
string faceFileName;
string shortcutFile;
string? directoryName;
string facesDirectory;
string mappingSegmentB;
string personDirectory;
string personKeyFormatted;
string personDisplayFileName;
PersonBirthday personBirthday;
string? personDisplayDirectory;
int? normalizedPixelPercentage;
WindowsShortcut windowsShortcut;
Dictionary<int, PersonContainer[]>? keyValuePairs;
string by = nameof(Stateless.IMapLogic.ManualCopy);
Dictionary<int, Face>? normalizedPixelPercentageToFace;
string successfull = $"_ {nameof(Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title)} Successfull";
Dictionary<int, Dictionary<int, Face>> idToNormalizedPixelPercentageToFace = Stateless.MapLogic.GetKeyValuePairs(distinctFilteredFaces);
foreach (KeyValuePair<long, PersonContainer> keyValuePair in _PersonKeyToPersonContainer)
{
if (keyValuePair.Value.Key is null || keyValuePair.Value.Birthdays is null || !keyValuePair.Value.Birthdays.Any())
continue;
personBirthday = keyValuePair.Value.Birthdays[zero];
foreach (string personDisplayDirectoryAllFile in keyValuePair.Value.DisplayDirectoryAllFiles)
{
if (!personDisplayDirectoryAllFile.EndsWith(_Configuration.FacesFileNameExtension))
continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(_Configuration.FacesFileNameExtension, personDisplayDirectoryAllFile);
if (id is null || normalizedPixelPercentage is null)
continue;
if (_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(id.Value, out keyValuePairs))
{
if (keyValuePairs.ContainsKey(normalizedPixelPercentage.Value))
continue; continue;
File.Copy(sourceFile, checkFile);
} }
foreach (SaveContainer saveContainer in saveContainers) fileInfo = new(personDisplayDirectoryAllFile);
{ if (!fileInfo.Exists)
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is not null || saveContainer.FaceFileHolder is not null || string.IsNullOrEmpty(saveContainer.Json))
continue; continue;
if (File.Exists(saveContainer.CheckFile)) personDisplayFileName = Path.GetFileName(personDisplayDirectoryAllFile);
personDisplayDirectory = Path.GetDirectoryName(personDisplayDirectoryAllFile);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, keyValuePair.Value.ApproximateYears, fileInfo.CreationTime, isWrongYear: null);
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mappingSegmentB);
personDirectory = Path.Combine(directory, keyValuePair.Value.DisplayDirectoryName, "lnk");
if (!idToNormalizedPixelPercentageToFace.TryGetValue(id.Value, out normalizedPixelPercentageToFace))
continue; continue;
_ = IPath.WriteAllText(saveContainer.CheckFile, saveContainer.Json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); if (!normalizedPixelPercentageToFace.ContainsKey(normalizedPixelPercentage.Value))
}
foreach (SaveContainer saveContainer in saveContainers)
{
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is null)
continue; continue;
if (string.IsNullOrEmpty(saveContainer.ShortcutFile) || !saveContainer.ResizedFileHolder.Exists) face = idToNormalizedPixelPercentageToFace[id.Value][normalizedPixelPercentage.Value];
if (face.Mapping is null)
throw new NotSupportedException();
if (string.IsNullOrEmpty(personDisplayDirectory))
throw new NotSupportedException();
directoryName = Path.GetDirectoryName(face.RelativePath);
if (string.IsNullOrEmpty(directoryName))
throw new NotSupportedException();
shortcutFile = Path.Combine(personDisplayDirectory, $"{personDisplayFileName}.lnk");
facesDirectory = Path.Combine($"{dFacesContentDirectory}{directoryName}", face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
faceFileName = $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}";
checkFile = Path.Combine(directory, fileInfo.Name);
if (!Directory.Exists(personDirectory))
_ = Directory.CreateDirectory(personDirectory);
if (!File.Exists(checkFile))
File.Copy(personDisplayDirectoryAllFile, checkFile);
if (personDisplayDirectoryAllFile.Contains(successfull))
continue; continue;
try directoryName = Path.Combine(personDisplayDirectory, successfull);
{ if (!Directory.Exists(directoryName))
windowsShortcut = new() { Path = saveContainer.ResizedFileHolder.FullName }; _ = Directory.CreateDirectory(directoryName);
windowsShortcut.Save(saveContainer.ShortcutFile); checkFile = Path.Combine(directoryName, personDisplayFileName);
File.Move(personDisplayDirectoryAllFile, checkFile);
faceFile = Path.Combine(facesDirectory, faceFileName);
if (!File.Exists(faceFile))
continue;
if (File.Exists(shortcutFile))
continue;
windowsShortcut = new() { Path = faceFile };
windowsShortcut.Save(shortcutFile);
windowsShortcut.Dispose(); windowsShortcut.Dispose();
if (!File.Exists(shortcutFile))
continue;
File.SetLastWriteTime(shortcutFile, face.Mapping.MappingFromItem.MinimumDateTime);
} }
catch (Exception)
{ }
} }
} }
@ -491,378 +639,33 @@ public class MapLogic
return results; return results;
} }
private int UpdateFromSortingContainers(SortingContainer[] sortingContainers) public void SaveShortcuts(string[] juliePhares, List<Face> distinctFilteredFaces)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
int result = 0; List<(Face, List<(string?, string, string?, string?, string)>)> facesToCollection = GetCollection(distinctFilteredFaces);
string key; foreach ((Face face, List<(string? PersonKeyFormatted, string, string?, string?, string)> collection) in facesToCollection)
const int zero = 0;
string mappingSegmentB;
string personKeyFormatted;
List<Mapping> checkCollection;
PersonBirthday personBirthday;
PersonContainer[] personContainers;
const int by = Stateless.IMapLogic.Sorting;
List<int> normalizedPixelPercentageCollection;
Dictionary<string, List<Mapping>> checkKeyValuePairs = new();
Dictionary<int, List<int>> idToNormalizedPixelPercentageCollection = new();
Dictionary<int, PersonContainer[]>? normalizedPixelPercentageToPersonContainers;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
string message = $") {sortingContainers.Length:000} Update From Sorting Container(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(sortingContainers.Length, message, options);
foreach (SortingContainer sortingContainer in sortingContainers)
{ {
progressBar.Tick(); if (collection.Any(l => l.PersonKeyFormatted is not null and "1501-04-10_00"))
if (sortingContainer.Face.Mapping is null)
throw new NotSupportedException();
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(sortingContainer.Sorting.Id, out normalizedPixelPercentageToPersonContainers))
throw new NotSupportedException();
if (!normalizedPixelPercentageToPersonContainers.ContainsKey(sortingContainer.Sorting.NormalizedPixelPercentage))
throw new NotSupportedException();
if (!idToNormalizedPixelPercentageCollection.ContainsKey(sortingContainer.Face.Mapping.MappingFromItem.Id))
idToNormalizedPixelPercentageCollection.Add(sortingContainer.Face.Mapping.MappingFromItem.Id, new());
normalizedPixelPercentageCollection = idToNormalizedPixelPercentageCollection[sortingContainer.Face.Mapping.MappingFromItem.Id];
if (normalizedPixelPercentageCollection.Contains(sortingContainer.Face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
continue; continue;
personContainers = normalizedPixelPercentageToPersonContainers[sortingContainer.Sorting.NormalizedPixelPercentage]; foreach ((string? personKeyFormatted, string directory, string? copyDirectory, string? copyFileName, string _) in collection)
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, sortingContainer.Face.Mapping.MappingFromItem);
key = string.Concat(personKeyFormatted, '\t', mappingSegmentB);
if (!checkKeyValuePairs.ContainsKey(key))
checkKeyValuePairs.Add(key, new());
checkCollection = checkKeyValuePairs[key];
if (checkCollection.Count > _Configuration.SortingMaximumPerKey)
continue;
normalizedPixelPercentageCollection.Add(sortingContainer.Face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
sortingContainer.Face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
checkCollection.Add(sortingContainer.Face.Mapping);
result += 1;
break;
}
}
return result;
}
internal void ForceSingleImage(IEnumerable<Face> distinctFilteredFaces)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
const int zero = 0;
string mappingSegmentB;
PersonBirthday personBirthday;
List<int>? normalizedPixelPercentages;
int by = Stateless.IMapLogic.ForceSingleImage;
string displayDirectoryName = _Configuration.MappingDefaultName;
Face[] orderedDistinctFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromLocation.Confidence descending select l).ToArray();
foreach (Face face in orderedDistinctFilteredFaces)
{ {
if (face.Mapping is null) if (face.Mapping is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (face.Mapping.MappingFromPerson.PersonBirthday is not null) if (personKeyFormatted is null)
continue; continue;
if (_SkipCollection.TryGetValue(face.Mapping.MappingFromItem.Id, out normalizedPixelPercentages)) if (!Directory.Exists(directory))
{ _ = Directory.CreateDirectory(directory);
if (normalizedPixelPercentages.Contains(face.Mapping.MappingFromLocation.NormalizedPixelPercentage)) if (string.IsNullOrEmpty(copyDirectory) || string.IsNullOrEmpty(copyFileName))
continue; continue;
} if (!juliePhares.Contains(personKeyFormatted))
foreach (PersonContainer personContainer in _NotMappedPersonContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue; continue;
personBirthday = personContainer.Birthdays[zero]; if (!Directory.Exists(copyDirectory))
mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, face.Mapping.MappingFromItem); _ = Directory.CreateDirectory(copyDirectory);
face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB); if (!File.Exists(copyFileName))
File.Copy(face.Mapping.MappingFromItem.ResizedFileHolder.FullName, copyFileName);
break; break;
} }
break;
}
}
private List<SaveContainer> GetMappingSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, List<Face> filteredFaces, int? useFiltersCounter)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<SaveContainer> results = new();
string by;
string checkFile;
string directory;
string shortcutFile;
string facesDirectory;
string? directoryName;
string personDirectory;
FileHolder faceFileHolder;
string facePartsDirectory;
string personKeyFormatted;
SaveContainer saveContainer;
FileHolder facePartsFileHolder;
FileHolder hiddenFaceFileHolder;
Dictionary<string, int> keyValuePairs = new();
string forceSingleImageHumanized = nameof(Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
foreach (Face face in filteredFaces)
{
if (face.Mapping is null)
throw new NotSupportedException();
directoryName = Path.GetDirectoryName(face.RelativePath);
if (directoryName is null)
throw new NotSupportedException();
if (face.Mapping.MappingFromPerson.PersonBirthday is null)
continue;
if (string.IsNullOrEmpty(face.Mapping.MappingFromPerson.SegmentB))
throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, face.Mapping.MappingFromPerson.PersonBirthday);
if (face.Mapping.MappingFromPerson.By is null)
by = $"{nameof(Stateless.IMapLogic.Mapping)}Null";
else if (useFiltersCounter.HasValue && face.Mapping.MappingFromPerson.By.Value == Stateless.IMapLogic.Sorting)
by = $"{nameof(Stateless.IMapLogic.Sorting)} Modified Filters - {useFiltersCounter.Value}";
else
{
if (face.Mapping.MappingFromPerson.By == Stateless.IMapLogic.Mapping && !_Configuration.MappingSaveMapped)
continue;
by = face.Mapping.MappingFromPerson.By.Value switch
{
Stateless.IMapLogic.Mapping => nameof(Stateless.IMapLogic.Mapping),
Stateless.IMapLogic.Sorting => nameof(Stateless.IMapLogic.Sorting),
Stateless.IMapLogic.ForceSingleImage => forceSingleImageHumanized,
_ => throw new NotImplementedException()
};
}
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, face.Mapping.MappingFromPerson.SegmentB);
if (!keyValuePairs.ContainsKey(directory))
keyValuePairs.Add(directory, 0);
keyValuePairs[directory]++;
if (face.Mapping.MappingFromPerson.By is not null)
personDirectory = Path.Combine(directory, face.Mapping.MappingFromPerson.DisplayDirectoryName, "lnk");
else
personDirectory = Path.Combine(directory, face.Mapping.MappingFromPerson.DisplayDirectoryName[..1], "lnk");
saveContainer = new(personDirectory);
results.Add(saveContainer);
facesDirectory = Path.Combine($"{dFacesContentDirectory}{directoryName}", face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
facePartsDirectory = Path.Combine($"{d2FacePartsContentDirectory}{directoryName}", face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
checkFile = Path.Combine(directory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
faceFileHolder = new(Path.Combine(facesDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_FacesFileNameExtension}"));
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_FacesHiddenFileNameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_FacePartsFileNameExtension}"));
if (string.IsNullOrEmpty(personDirectory) || face.Mapping.MappingFromPerson.By == Stateless.IMapLogic.Mapping)
shortcutFile = string.Empty;
else
shortcutFile = Path.Combine(personDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, string.Empty, facePartsFileHolder, face.Mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
results.Add(saveContainer);
}
return results;
}
private static IEnumerable<(string, string)> GetCollection(string[] yearDirectories)
{
foreach (string l in yearDirectories)
yield return new(l, Path.GetFileName(l));
}
private static void SaveMappingShortcuts(string mappingDirectory)
{
string? shortcutFileName;
string[] yearDirectories;
string personKeyFormatted;
string[] personNameDirectories;
WindowsShortcut windowsShortcut;
string personDisplayDirectoryName;
(string, string)[] yearDirectoryNameCheck;
List<(string, string)> yearDirectoryNames = new();
string[] personKeyDirectories = Directory.GetDirectories(mappingDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personKeyDirectory in personKeyDirectories)
{
windowsShortcut = new();
shortcutFileName = null;
yearDirectoryNames.Clear();
personKeyFormatted = Path.GetFileName(personKeyDirectory);
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
yearDirectoryNames.AddRange(GetCollection(yearDirectories));
yearDirectoryNameCheck = (from l in yearDirectoryNames where l.Item2.Contains('^') select l).OrderByDescending(l => l.Item2).ToArray();
if (!yearDirectoryNameCheck.Any())
yearDirectoryNameCheck = (from l in yearDirectoryNames where l.Item2.Contains('~') select l).OrderByDescending(l => l.Item2).ToArray();
if (!yearDirectoryNameCheck.Any())
yearDirectoryNameCheck = (from l in yearDirectoryNames where l.Item2.Contains('=') select l).OrderByDescending(l => l.Item2).ToArray();
if (!yearDirectoryNameCheck.Any())
yearDirectoryNameCheck = (from l in yearDirectoryNames select l).OrderByDescending(l => l).ToArray();
if (!yearDirectoryNameCheck.Any())
continue;
foreach ((string yearDirectory, string yearDirectoryName) in yearDirectoryNameCheck)
{
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personNameDirectory in personNameDirectories)
{
personDisplayDirectoryName = Path.GetFileName(personNameDirectory).Split('-')[0];
if (personDisplayDirectoryName is null)
continue;
windowsShortcut.Path = yearDirectory;
windowsShortcut.Description = yearDirectoryName;
shortcutFileName = Path.Combine(mappingDirectory, $"{personDisplayDirectoryName} [{windowsShortcut.Description}].lnk");
break;
}
if (shortcutFileName is not null)
{
if (!File.Exists(shortcutFileName))
break;
}
}
if (shortcutFileName is null || windowsShortcut.Path is null || windowsShortcut.Description is null)
continue;
try
{
windowsShortcut.Save(shortcutFileName);
windowsShortcut.Dispose();
}
catch (Exception)
{ }
}
}
public void ForceSingleImageThenSaveMapping(string dFacesContentDirectory, string d2FacePartsContentDirectory, List<Face> distinctFilteredFaces, SortingContainer[] sortingContainers, int? useFiltersCounter, int totalNotMapped)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int updated;
List<SaveContainer> saveContainers;
if (!sortingContainers.Any())
{
updated = 0;
ForceSingleImage(distinctFilteredFaces);
saveContainers = GetMappingSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, useFiltersCounter);
}
else
{
updated = UpdateFromSortingContainers(sortingContainers);
if (useFiltersCounter is null && totalNotMapped - updated > 0)
ForceSingleImage(distinctFilteredFaces);
saveContainers = GetMappingSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, useFiltersCounter);
}
SaveContainers(totalNotMapped, updated, saveContainers);
if (_Configuration.MappingSaveMapped)
{
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Stateless.IMapLogic.Mapping));
if (Directory.Exists(mappingDirectory))
SaveMappingShortcuts(mappingDirectory);
}
}
private static Dictionary<int, Dictionary<int, Face>> GetKeyValuePairs(List<Face> distinctFilteredFaces)
{
Dictionary<int, Dictionary<int, Face>> results = new();
Dictionary<int, Face> keyValuePairs;
foreach (Face face in distinctFilteredFaces)
{
if (face.Mapping is null)
throw new NotSupportedException();
if (!results.ContainsKey(face.Mapping.MappingFromItem.Id))
results.Add(face.Mapping.MappingFromItem.Id, new());
keyValuePairs = results[face.Mapping.MappingFromItem.Id];
if (keyValuePairs.ContainsKey(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
throw new NotSupportedException();
keyValuePairs.Add(face.Mapping.MappingFromLocation.NormalizedPixelPercentage, face);
}
return results;
}
public void CopyManualFiles(string dFacesContentDirectory, List<Face> distinctFilteredFaces)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int? id;
Face face;
string faceFile;
string checkFile;
string directory;
FileInfo fileInfo;
const int zero = 0;
string faceFileName;
string shortcutFile;
string? directoryName;
string facesDirectory;
string mappingSegmentB;
string personDirectory;
string personKeyFormatted;
string personDisplayFileName;
PersonBirthday personBirthday;
string? personDisplayDirectory;
int? normalizedPixelPercentage;
WindowsShortcut windowsShortcut;
Dictionary<int, PersonContainer[]>? keyValuePairs;
string by = nameof(Stateless.IMapLogic.ManualCopy);
Dictionary<int, Face>? normalizedPixelPercentageToFace;
string successfull = $"_ {nameof(Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title)} Successfull";
Dictionary<int, Dictionary<int, Face>> idToNormalizedPixelPercentageToFace = GetKeyValuePairs(distinctFilteredFaces);
foreach (KeyValuePair<long, PersonContainer> keyValuePair in _PersonKeyToPersonContainer)
{
if (keyValuePair.Value.Key is null || keyValuePair.Value.Birthdays is null || !keyValuePair.Value.Birthdays.Any())
continue;
personBirthday = keyValuePair.Value.Birthdays[zero];
foreach (string personDisplayDirectoryAllFile in keyValuePair.Value.DisplayDirectoryAllFiles)
{
if (!personDisplayDirectoryAllFile.EndsWith(_FacesFileNameExtension))
continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(_FacesFileNameExtension, personDisplayDirectoryAllFile);
if (id is null || normalizedPixelPercentage is null)
continue;
if (_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(id.Value, out keyValuePairs))
{
if (keyValuePairs.ContainsKey(normalizedPixelPercentage.Value))
continue;
}
fileInfo = new(personDisplayDirectoryAllFile);
if (!fileInfo.Exists)
continue;
personDisplayFileName = Path.GetFileName(personDisplayDirectoryAllFile);
personDisplayDirectory = Path.GetDirectoryName(personDisplayDirectoryAllFile);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, keyValuePair.Value.ApproximateYears, fileInfo.CreationTime, isWrongYear: null);
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mappingSegmentB);
personDirectory = Path.Combine(directory, keyValuePair.Value.DisplayDirectoryName, "lnk");
if (!idToNormalizedPixelPercentageToFace.TryGetValue(id.Value, out normalizedPixelPercentageToFace))
continue;
if (!normalizedPixelPercentageToFace.ContainsKey(normalizedPixelPercentage.Value))
continue;
face = idToNormalizedPixelPercentageToFace[id.Value][normalizedPixelPercentage.Value];
if (face.Mapping is null)
throw new NotSupportedException();
if (string.IsNullOrEmpty(personDisplayDirectory))
throw new NotSupportedException();
directoryName = Path.GetDirectoryName(face.RelativePath);
if (string.IsNullOrEmpty(directoryName))
throw new NotSupportedException();
shortcutFile = Path.Combine(personDisplayDirectory, $"{personDisplayFileName}.lnk");
facesDirectory = Path.Combine($"{dFacesContentDirectory}{directoryName}", face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
faceFileName = $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_FacesFileNameExtension}";
checkFile = Path.Combine(directory, fileInfo.Name);
if (!Directory.Exists(personDirectory))
_ = Directory.CreateDirectory(personDirectory);
if (!File.Exists(checkFile))
File.Copy(personDisplayDirectoryAllFile, checkFile);
if (personDisplayDirectoryAllFile.Contains(successfull))
continue;
directoryName = Path.Combine(personDisplayDirectory, successfull);
if (!Directory.Exists(directoryName))
_ = Directory.CreateDirectory(directoryName);
checkFile = Path.Combine(directoryName, personDisplayFileName);
File.Move(personDisplayDirectoryAllFile, checkFile);
faceFile = Path.Combine(facesDirectory, faceFileName);
if (!File.Exists(faceFile))
continue;
if (File.Exists(shortcutFile))
continue;
windowsShortcut = new() { Path = faceFile };
windowsShortcut.Save(shortcutFile);
windowsShortcut.Dispose();
if (!File.Exists(shortcutFile))
continue;
File.SetLastWriteTime(shortcutFile, face.Mapping.MappingFromItem.MinimumDateTime);
}
} }
} }

View File

@ -2,6 +2,7 @@ using Humanizer;
using ShellProgressBar; using ShellProgressBar;
using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods; using View_by_Distance.Shared.Models.Stateless.Methods;
using WindowsShortcutFactory;
namespace View_by_Distance.Map.Models.Stateless; namespace View_by_Distance.Map.Models.Stateless;
@ -33,7 +34,7 @@ internal abstract class MapLogic
return results; return results;
} }
private static void SetPersonCollections(Configuration configuration, string facesFileNameExtension, List<PersonContainer> personContainers, List<long> personKeys, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection, Dictionary<int, List<int>> skipCollection) private static void SetPersonCollections(Configuration configuration, List<PersonContainer> personContainers, List<long> personKeys, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection, Dictionary<int, List<int>> skipCollection)
{ {
int? id; int? id;
long personKey; long personKey;
@ -44,9 +45,9 @@ internal abstract class MapLogic
{ {
foreach (string personDisplayDirectoryAllFile in personContainer.DisplayDirectoryAllFiles) foreach (string personDisplayDirectoryAllFile in personContainer.DisplayDirectoryAllFiles)
{ {
if (!personDisplayDirectoryAllFile.EndsWith(facesFileNameExtension)) if (!personDisplayDirectoryAllFile.EndsWith(configuration.FacesFileNameExtension))
continue; continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, personDisplayDirectoryAllFile); (id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(configuration.FacesFileNameExtension, personDisplayDirectoryAllFile);
if (id is null || normalizedPixelPercentage is null) if (id is null || normalizedPixelPercentage is null)
continue; continue;
if (!skipCollection.ContainsKey(id.Value)) if (!skipCollection.ContainsKey(id.Value))
@ -73,7 +74,7 @@ internal abstract class MapLogic
} }
} }
internal static List<(string, string[], string)> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, string facesFileNameExtension, List<string> personKeyFormattedCollection, string[] ticksDirectories, string message) internal static List<(string, string[], string)> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, List<string> personKeyFormattedCollection, string[] ticksDirectories, string message)
{ {
List<(string, string[], string)> results = new(); List<(string, string[], string)> results = new();
int? id; int? id;
@ -148,7 +149,7 @@ internal abstract class MapLogic
{ {
if (file.EndsWith(".lnk") || file.EndsWith(".json")) if (file.EndsWith(".lnk") || file.EndsWith(".json"))
continue; continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, file); (id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(configuration.FacesFileNameExtension, file);
if (id is null || normalizedPixelPercentage is null) if (id is null || normalizedPixelPercentage is null)
continue; continue;
results.Add(new(personKeyFormatted, personDisplayDirectoryNames, file)); results.Add(new(personKeyFormatted, personDisplayDirectoryNames, file));
@ -177,14 +178,14 @@ internal abstract class MapLogic
return results; return results;
} }
public static Dictionary<int, List<(string, int)>> GetIdToCollection(string facesFileNameExtension, List<(string, string[], string)> collection) public static Dictionary<int, List<(string, int)>> GetIdToCollection(Configuration configuration, List<(string, string[], string)> collection)
{ {
Dictionary<int, List<(string, int)>> results = new(); Dictionary<int, List<(string, int)>> results = new();
int? id; int? id;
int? normalizedPixelPercentage; int? normalizedPixelPercentage;
foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string mappedFaceFile) in collection) foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string mappedFaceFile) in collection)
{ {
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, mappedFaceFile); (id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(configuration.FacesFileNameExtension, mappedFaceFile);
if (id is null || normalizedPixelPercentage is null) if (id is null || normalizedPixelPercentage is null)
continue; continue;
if (!results.ContainsKey(id.Value)) if (!results.ContainsKey(id.Value))
@ -194,12 +195,12 @@ internal abstract class MapLogic
return results; return results;
} }
internal static Dictionary<int, List<(string, int)>> DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, string facesFileNameExtension, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, PersonContainer[] personContainers) internal static Dictionary<int, List<(string, int)>> DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, PersonContainer[] personContainers)
{ {
Dictionary<int, List<(string, int)>> results; Dictionary<int, List<(string, int)>> results;
string personKeyFormatted; string personKeyFormatted;
List<(long? PersonKey, string Line)> lines = new();
List<string> personKeyFormattedCollection = new(); List<string> personKeyFormattedCollection = new();
List<(long? PersonKey, string Line)> lines = new();
_ = GetDistinctCollection(configuration, personContainers.ToList(), new()); _ = GetDistinctCollection(configuration, personContainers.ToList(), new());
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string[] ticksDirectories; string[] ticksDirectories;
@ -220,9 +221,9 @@ internal abstract class MapLogic
} }
} }
if (!string.IsNullOrEmpty(a2PeopleContentDirectory)) if (!string.IsNullOrEmpty(a2PeopleContentDirectory))
File.WriteAllLines(Path.Combine(a2PeopleContentDirectory, "People - C.tsv"), from l in lines orderby l.PersonKey is null select l.Line); File.WriteAllLines(Path.Combine(a2PeopleContentDirectory, "People - C.tsv"), from l in lines select l.Line);
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, facesFileNameExtension, personKeyFormattedCollection, ticksDirectories, message); List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message);
results = GetIdToCollection(facesFileNameExtension, collection); results = GetIdToCollection(configuration, collection);
return results; return results;
} }
@ -345,7 +346,7 @@ internal abstract class MapLogic
return results; return results;
} }
private static (int, int) SetCollectionsAndGetUnableToMatchCount(string facesFileNameExtension, long ticks, Dictionary<int, List<Face>> idToFaces, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, string[], string)> collection) private static (int, int) SetCollectionsAndGetUnableToMatchCount(Configuration configuration, long ticks, Dictionary<int, List<Face>> idToFaces, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, string[], string)> collection)
{ {
int result = 0; int result = 0;
int? id; int? id;
@ -368,7 +369,7 @@ internal abstract class MapLogic
{ {
progressBar.Tick(); progressBar.Tick();
(id, normalizedPixelPercentage, faces) = IMapping.GetReversedDeterministicHashCodeKey( (id, normalizedPixelPercentage, faces) = IMapping.GetReversedDeterministicHashCodeKey(
facesFileNameExtension, configuration.FacesFileNameExtension,
idToFacesAny, idToFacesAny,
idToFaces, idToFaces,
mappedFaceFile); mappedFaceFile);
@ -582,7 +583,7 @@ internal abstract class MapLogic
} }
} }
internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string facesFileNameExtension, long ticks, List<PersonContainer> personContainers, string? a2PeopleContentDirectory, string eDistanceContentDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance faceDistance, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers) internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, List<PersonContainer> personContainers, string? a2PeopleContentDirectory, string eDistanceContentDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance faceDistance, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers)
{ {
if (configuration is null) if (configuration is null)
throw new NullReferenceException(nameof(configuration)); throw new NullReferenceException(nameof(configuration));
@ -597,7 +598,7 @@ internal abstract class MapLogic
List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection = new(); List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection = new();
List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection = new(); List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection = new();
Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedPixelPercentageToPersonContainers = new(); Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedPixelPercentageToPersonContainers = new();
SetPersonCollections(configuration, facesFileNameExtension, personContainers, personKeys, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, skipCollection); SetPersonCollections(configuration, personContainers, personKeys, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, skipCollection);
personContainers.AddRange(AddToPersonKeysThenGetNonSpecificPeopleCollection(configuration, personKeys)); personContainers.AddRange(AddToPersonKeysThenGetNonSpecificPeopleCollection(configuration, personKeys));
foreach (Face face in distinctFilteredFaces) foreach (Face face in distinctFilteredFaces)
{ {
@ -612,8 +613,8 @@ internal abstract class MapLogic
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly); string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly);
message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)"; message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, facesFileNameExtension, personKeyFormattedCollection, ticksDirectories, message); List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message);
(int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(facesFileNameExtension, ticks, keyValuePairs, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, collection); (int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(configuration, ticks, keyValuePairs, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, collection);
SetKeyValuePairs(configuration, ticks, personContainers, distinctFilteredFaces, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, personKeyToPersonContainer, idThenNormalizedPixelPercentageToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, incorrectIdThenNormalizedPixelPercentageToPersonContainers, personKeyToRanges); SetKeyValuePairs(configuration, ticks, personContainers, distinctFilteredFaces, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, personKeyToPersonContainer, idThenNormalizedPixelPercentageToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, incorrectIdThenNormalizedPixelPercentageToPersonContainers, personKeyToRanges);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $") {collection.Count:000} message from ticks Director(ies) - D - {duplicateCount} Duplicate Count {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)"; message = $") {collection.Count:000} message from ticks Director(ies) - D - {duplicateCount} Duplicate Count {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)";
@ -632,7 +633,211 @@ internal abstract class MapLogic
notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, personContainers, personKeyCollection)); notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, personContainers, personKeyCollection));
AppendToSkipCollection(skipCollection, idThenNormalizedPixelPercentageToPersonContainers, incorrectIdThenNormalizedPixelPercentageToPersonContainers); AppendToSkipCollection(skipCollection, idThenNormalizedPixelPercentageToPersonContainers, incorrectIdThenNormalizedPixelPercentageToPersonContainers);
if (possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Any()) if (possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Any())
faceDistance.SavePossiblyNewPersonContainers(propertyConfiguration, configuration.PersonBirthdayFormat, facesFileNameExtension, a2PeopleContentDirectory, personKeyToPersonContainer, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); faceDistance.SavePossiblyNewPersonContainers(propertyConfiguration, configuration.PersonBirthdayFormat, configuration.FacesFileNameExtension, a2PeopleContentDirectory, personKeyToPersonContainer, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
}
private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, long minimumDateTimeTicks, bool? isWrongYear)
{
int years;
string result;
TimeSpan? timeSpan = IPersonBirthday.GetTimeSpan(minimumDateTimeTicks, isWrongYear, personBirthday);
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0)
result = "!---";
else if (timeSpan.HasValue)
{
(years, _) = IPersonBirthday.GetAge(minimumDateTimeTicks, personBirthday);
result = $"^{years:000}";
}
else if (approximateYears.HasValue)
{
DateTime dateTime = new(ticks);
(years, _) = IAge.GetAge(minimumDateTimeTicks, dateTime.AddYears(-approximateYears.Value));
result = $"~{years:000}";
}
else
{
string isWrongYearFlag = IItem.GetWrongYearFlag(isWrongYear);
result = $"{isWrongYearFlag}{new DateTime(minimumDateTimeTicks):yyyy}";
}
return result;
}
internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, DateTime minimumDateTime, bool? isWrongYear)
{
string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, minimumDateTime.Ticks, isWrongYear);
return result;
}
internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, MappingFromItem mappingFromItem)
{
string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.MinimumDateTime, mappingFromItem.IsWrongYear);
return result;
}
internal static Dictionary<int, Dictionary<int, Face>> GetKeyValuePairs(List<Face> distinctFilteredFaces)
{
Dictionary<int, Dictionary<int, Face>> results = new();
Dictionary<int, Face> keyValuePairs;
foreach (Face face in distinctFilteredFaces)
{
if (face.Mapping is null)
throw new NotSupportedException();
if (!results.ContainsKey(face.Mapping.MappingFromItem.Id))
results.Add(face.Mapping.MappingFromItem.Id, new());
keyValuePairs = results[face.Mapping.MappingFromItem.Id];
if (keyValuePairs.ContainsKey(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
throw new NotSupportedException();
keyValuePairs.Add(face.Mapping.MappingFromLocation.NormalizedPixelPercentage, face);
}
return results;
}
internal static List<SaveContainer> GetMappingSaveContainers(Configuration configuration, string eDistanceContentTicksDirectory, string dFacesContentDirectory, string d2FacePartsContentDirectory, List<Face> filteredFaces, int? useFiltersCounter, bool saveMapped)
{
List<SaveContainer> results = new();
string by;
string checkFile;
bool isByMapping;
string directory;
string shortcutFile;
string facesDirectory;
string? directoryName;
string personDirectory;
FileHolder faceFileHolder;
string facePartsDirectory;
string personKeyFormatted;
SaveContainer saveContainer;
FileHolder facePartsFileHolder;
FileHolder hiddenFaceFileHolder;
string forceSingleImageHumanized = nameof(IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
foreach (Face face in filteredFaces)
{
if (face.Mapping is null)
throw new NotSupportedException();
directoryName = Path.GetDirectoryName(face.RelativePath);
if (directoryName is null)
throw new NotSupportedException();
if (face.Mapping.MappingFromPerson.PersonBirthday is null)
continue;
if (string.IsNullOrEmpty(face.Mapping.MappingFromPerson.SegmentB))
throw new NotSupportedException();
if (face.Mapping.MappingFromPerson.By is null)
{
isByMapping = false;
by = $"{nameof(IMapLogic.Mapping)}Null";
}
else if (useFiltersCounter.HasValue && face.Mapping.MappingFromPerson.By.Value == IMapLogic.Sorting)
{
isByMapping = false;
by = $"{nameof(IMapLogic.Sorting)} Modified Filters - {useFiltersCounter.Value}";
}
else
{
isByMapping = face.Mapping.MappingFromPerson.By == IMapLogic.Mapping;
if (isByMapping && !saveMapped)
continue;
by = face.Mapping.MappingFromPerson.By.Value switch
{
IMapLogic.Mapping => nameof(IMapLogic.Mapping),
IMapLogic.Sorting => nameof(IMapLogic.Sorting),
IMapLogic.ForceSingleImage => forceSingleImageHumanized,
_ => throw new NotImplementedException()
};
}
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, face.Mapping.MappingFromPerson.PersonBirthday);
directory = Path.Combine(eDistanceContentTicksDirectory, by, personKeyFormatted, face.Mapping.MappingFromPerson.SegmentB);
if (isByMapping)
personDirectory = Path.Combine(directory, face.Mapping.MappingFromPerson.DisplayDirectoryName);
else if (face.Mapping.MappingFromPerson.By is not null)
personDirectory = Path.Combine(directory, face.Mapping.MappingFromPerson.DisplayDirectoryName, "lnk");
else
personDirectory = Path.Combine(directory, face.Mapping.MappingFromPerson.DisplayDirectoryName[..1], "lnk");
saveContainer = new(personDirectory);
results.Add(saveContainer);
facesDirectory = Path.Combine($"{dFacesContentDirectory}{directoryName}", face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
faceFileHolder = new(Path.Combine(facesDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{configuration.FacesFileNameExtension}"));
if (isByMapping)
{
checkFile = Path.Combine(personDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
saveContainer = new(checkFile, directory, faceFileHolder);
}
else
{
facePartsDirectory = Path.Combine($"{d2FacePartsContentDirectory}{directoryName}", face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
checkFile = Path.Combine(directory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
shortcutFile = Path.Combine(personDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{configuration.FacesHiddenFileNameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{configuration.FacePartsFileNameExtension}"));
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, face.Mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
}
results.Add(saveContainer);
}
return results;
}
private static IEnumerable<(string, string)> GetCollection(string[] yearDirectories)
{
foreach (string l in yearDirectories)
yield return new(l, Path.GetFileName(l));
}
internal static void SaveMappingShortcuts(string mappingDirectory)
{
string? shortcutFileName;
string[] yearDirectories;
string personKeyFormatted;
string[] personNameDirectories;
WindowsShortcut windowsShortcut;
string personDisplayDirectoryName;
(string, string)[] yearDirectoryNameCheck;
List<(string, string)> yearDirectoryNames = new();
string[] personKeyDirectories = Directory.GetDirectories(mappingDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personKeyDirectory in personKeyDirectories)
{
windowsShortcut = new();
shortcutFileName = null;
yearDirectoryNames.Clear();
personKeyFormatted = Path.GetFileName(personKeyDirectory);
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
yearDirectoryNames.AddRange(GetCollection(yearDirectories));
yearDirectoryNameCheck = (from l in yearDirectoryNames where l.Item2.Contains('^') select l).OrderByDescending(l => l.Item2).ToArray();
if (!yearDirectoryNameCheck.Any())
yearDirectoryNameCheck = (from l in yearDirectoryNames where l.Item2.Contains('~') select l).OrderByDescending(l => l.Item2).ToArray();
if (!yearDirectoryNameCheck.Any())
yearDirectoryNameCheck = (from l in yearDirectoryNames where l.Item2.Contains('=') select l).OrderByDescending(l => l.Item2).ToArray();
if (!yearDirectoryNameCheck.Any())
yearDirectoryNameCheck = (from l in yearDirectoryNames select l).OrderByDescending(l => l).ToArray();
if (!yearDirectoryNameCheck.Any())
continue;
foreach ((string yearDirectory, string yearDirectoryName) in yearDirectoryNameCheck)
{
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personNameDirectory in personNameDirectories)
{
personDisplayDirectoryName = Path.GetFileName(personNameDirectory).Split('-')[0];
if (personDisplayDirectoryName is null)
continue;
windowsShortcut.Path = yearDirectory;
windowsShortcut.Description = yearDirectoryName;
shortcutFileName = Path.Combine(mappingDirectory, $"{personDisplayDirectoryName} [{windowsShortcut.Description}].lnk");
break;
}
if (shortcutFileName is not null)
{
if (!File.Exists(shortcutFileName))
break;
}
}
if (shortcutFileName is null || windowsShortcut.Path is null || windowsShortcut.Description is null)
continue;
try
{
windowsShortcut.Save(shortcutFileName);
windowsShortcut.Dispose();
}
catch (Exception)
{ }
}
} }
} }

View File

@ -3,9 +3,9 @@ namespace View_by_Distance.Map.Models.Stateless.Methods;
public interface IMapLogic public interface IMapLogic
{ // ... { // ...
Dictionary<int, List<(string, int)>> TestStatic_DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, string facesFileNameExtension, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) => Dictionary<int, List<(string, int)>> TestStatic_DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) =>
DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, facesFileNameExtension, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers); DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers);
static Dictionary<int, List<(string, int)>> DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, string facesFileNameExtension, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) => static Dictionary<int, List<(string, int)>> DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) =>
MapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, facesFileNameExtension, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers); MapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers);
} }

View File

@ -6,42 +6,32 @@ namespace View_by_Distance.Shared.Models;
public class SaveContainer public class SaveContainer
{ {
protected readonly string _CheckFile; public string CheckFile { init; get; }
protected readonly string _Directory; public string Directory { init; get; }
protected readonly FileHolder? _FaceFileHolder; public FileHolder? FaceFileHolder { init; get; }
protected readonly FileHolder? _HiddenFaceFileHolder; public FileHolder? HiddenFaceFileHolder { init; get; }
protected readonly string _Json; public FileHolder? FacePartsFileHolder { init; get; }
protected readonly FileHolder? _FacePartsFileHolder; public FileHolder? ResizedFileHolder { init; get; }
protected readonly FileHolder? _ResizedFileHolder; public string ShortcutFile { init; get; }
protected readonly string _ShortcutFile;
public string CheckFile => _CheckFile;
public string Directory => _Directory;
public FileHolder? FaceFileHolder => _FaceFileHolder;
public FileHolder? HiddenFaceFileHolder => _HiddenFaceFileHolder;
public string Json => _Json;
public FileHolder? FacePartsFileHolder => _FacePartsFileHolder;
public FileHolder? ResizedFileHolder => _ResizedFileHolder;
public string ShortcutFile => _ShortcutFile;
[JsonConstructor] [JsonConstructor]
public SaveContainer(string checkFile, string directory, FileHolder? faceFileHolder, FileHolder? hiddenFaceFileHolder, string json, FileHolder? facePartsFileHolder, FileHolder? resizedFileHolder, string shortcutFile) public SaveContainer(string checkFile, string directory, FileHolder? faceFileHolder, FileHolder? hiddenFaceFileHolder, FileHolder? facePartsFileHolder, FileHolder? resizedFileHolder, string shortcutFile)
{ {
_CheckFile = checkFile; CheckFile = checkFile;
_Directory = directory; Directory = directory;
_FaceFileHolder = faceFileHolder; FaceFileHolder = faceFileHolder;
_HiddenFaceFileHolder = hiddenFaceFileHolder; HiddenFaceFileHolder = hiddenFaceFileHolder;
_Json = json; FacePartsFileHolder = facePartsFileHolder;
_FacePartsFileHolder = facePartsFileHolder; ResizedFileHolder = resizedFileHolder;
_ResizedFileHolder = resizedFileHolder; ShortcutFile = shortcutFile;
_ShortcutFile = shortcutFile;
} }
public SaveContainer(string directory) : public SaveContainer(string directory) :
this(string.Empty, directory, null, null, string.Empty, null, null, string.Empty) this(string.Empty, directory, null, null, null, null, string.Empty)
{ } { }
public SaveContainer(string checkFile, string directory, string json) : public SaveContainer(string checkFile, string directory, FileHolder? faceFileHolder) :
this(checkFile, directory, null, null, json, null, null, string.Empty) this(checkFile, directory, faceFileHolder, null, null, null, string.Empty)
{ } { }
public override string ToString() public override string ToString()

View File

@ -8,7 +8,7 @@ public interface IPerson
string TestStatic_GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.Person person) => string TestStatic_GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.Person person) =>
GetFileFullName(storage, personBirthdayFormat, person); GetFileFullName(storage, personBirthdayFormat, person);
static string GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.Person person) => static string GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.Person person) =>
PersonBirthday.GetFileFullName(storage, personBirthdayFormat, person.Birthday); IPersonBirthday.GetFileFullName(storage, personBirthdayFormat, person.Birthday);
Models.Person TestStatic_GetPerson(string personDisplayDirectoryName, long personKey, Models.PersonBirthday personBirthday) => Models.Person TestStatic_GetPerson(string personDisplayDirectoryName, long personKey, Models.PersonBirthday personBirthday) =>
GetPerson(personDisplayDirectoryName, personKey, personBirthday); GetPerson(personDisplayDirectoryName, personKey, personBirthday);

View File

@ -1,35 +1,37 @@
using System.Globalization;
namespace View_by_Distance.Shared.Models.Stateless.Methods; namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IPersonBirthday public interface IPersonBirthday
{ {
DateTime TestStatic_GetDefaultValue() => DateTime TestStatic_GetDefaultValue() =>
PersonBirthday.GetDefaultValue(); // {{1}}SingletonValue GetDefaultValue();
static DateTime GetDefaultValue() => static DateTime GetDefaultValue() =>
PersonBirthday.GetDefaultValue(); // {{1}}SingletonValue DateTime.MinValue; // {{1}}SingletonValue
// ... // ...
string TestStatic_GetDateTime(string personKey) =>
GetDateTime(personKey);
static string GetDateTime(string personKey) =>
personKey.Length < 5 || !personKey.Contains('#') ? personKey : personKey[..2] == "19" ? $"1600{personKey[4..]}" : $"1700{personKey[4..]}";
double? TestStatic_GetAge(Models.PersonBirthday birthday) => double? TestStatic_GetAge(Models.PersonBirthday birthday) =>
GetAge(birthday); GetAge(birthday);
static double? GetAge(Models.PersonBirthday birthday) => static double? GetAge(Models.PersonBirthday birthday) =>
PersonBirthday.GetAge(birthday); PersonBirthday.GetAge(birthday);
DateTime? TestStatic_GetDateTime(string personBirthdayFormat, string personKey) =>
PersonBirthday.GetDateTime(personBirthdayFormat, personKey);
static DateTime? GetDateTime(string personBirthdayFormat, string personKey) =>
PersonBirthday.GetDateTime(personBirthdayFormat, personKey);
Models.PersonBirthday TestStatic_GetPersonBirthday(long ticks) => Models.PersonBirthday TestStatic_GetPersonBirthday(long ticks) =>
new(new(ticks)); new(new(ticks));
static Models.PersonBirthday GetPersonBirthday(long ticks) => static Models.PersonBirthday GetPersonBirthday(long ticks) =>
new(new(ticks)); new(new(ticks));
string TestStatic_GetFileName(string personBirthdayFormat, Models.PersonBirthday personBirthday) => string TestStatic_GetFileName(string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
PersonBirthday.GetFileName(personBirthdayFormat, personBirthday); GetFileName(personBirthdayFormat, personBirthday);
static string GetFileName(string personBirthdayFormat, Models.PersonBirthday personBirthday) => static string GetFileName(string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
PersonBirthday.GetFileName(personBirthdayFormat, personBirthday); $"{personBirthday.Value.ToString(personBirthdayFormat)}.json";
(int, TimeSpan) TestStatic_GetAge(DateTime dateTime, Models.PersonBirthday birthday) => (int, TimeSpan) TestStatic_GetAge(DateTime dateTime, Models.PersonBirthday birthday) =>
GetAge(dateTime, birthday); GetAge(dateTime, birthday);
@ -41,20 +43,15 @@ public interface IPersonBirthday
static (int, TimeSpan) GetAge(long dateTimeTicks, Models.PersonBirthday birthday) => static (int, TimeSpan) GetAge(long dateTimeTicks, Models.PersonBirthday birthday) =>
PersonBirthday.GetAge(dateTimeTicks, birthday); PersonBirthday.GetAge(dateTimeTicks, birthday);
string TestStatic_GetFormatted(string personBirthdayFormat, long personKey) =>
GetFormatted(personBirthdayFormat, personKey);
static string GetFormatted(string personBirthdayFormat, long personKey) =>
PersonBirthday.GetFormatted(personBirthdayFormat, GetPersonBirthday(personKey));
string TestStatic_GetFormatted(string personBirthdayFormat, Models.PersonBirthday personBirthday) => string TestStatic_GetFormatted(string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
GetFormatted(personBirthdayFormat, personBirthday); GetFormatted(personBirthdayFormat, personBirthday);
static string GetFormatted(string personBirthdayFormat, Models.PersonBirthday personBirthday) => static string GetFormatted(string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
PersonBirthday.GetFormatted(personBirthdayFormat, personBirthday); personBirthday.Value.ToString(personBirthdayFormat);
Models.PersonBirthday? TestStatic_GetPersonBirthday(string personBirthdayFormat, string personKey) => string TestStatic_GetFormatted(string personBirthdayFormat, long personKey) =>
GetPersonBirthday(personBirthdayFormat, personKey); GetFormatted(personBirthdayFormat, personKey);
static Models.PersonBirthday? GetPersonBirthday(string personBirthdayFormat, string personKey) => static string GetFormatted(string personBirthdayFormat, long personKey) =>
PersonBirthday.GetPersonBirthday(personBirthdayFormat, personKey); GetFormatted(personBirthdayFormat, GetPersonBirthday(personKey));
bool TestStatic_IsCounterPersonBirthday(Models.PersonBirthday personBirthday) => bool TestStatic_IsCounterPersonBirthday(Models.PersonBirthday personBirthday) =>
IsCounterPersonBirthday(personBirthday); IsCounterPersonBirthday(personBirthday);
@ -64,28 +61,28 @@ public interface IPersonBirthday
Models.PersonBirthday TestStatic_GetNextBirthDate(Properties.IStorage storage) => Models.PersonBirthday TestStatic_GetNextBirthDate(Properties.IStorage storage) =>
GetNextBirthDate(storage); GetNextBirthDate(storage);
static Models.PersonBirthday GetNextBirthDate(Properties.IStorage storage) => static Models.PersonBirthday GetNextBirthDate(Properties.IStorage storage) =>
PersonBirthday.GetNextBirthDate(storage); throw new Exception(storage.ToString()); // Person.GetNextBirthDate(storage);
TimeSpan? TestStatic_Get(DateTime minimumDateTime, Models.PersonBirthday personBirthday) => TimeSpan? TestStatic_Get(DateTime minimumDateTime, Models.PersonBirthday personBirthday) =>
GetTimeSpan(minimumDateTime, isWrongYear: false, personBirthday); GetTimeSpan(minimumDateTime, isWrongYear: false, personBirthday);
static TimeSpan? GetTimeSpan(DateTime minimumDateTime, Models.PersonBirthday personBirthday) => static TimeSpan? GetTimeSpan(DateTime minimumDateTime, Models.PersonBirthday personBirthday) =>
PersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear: false, personBirthday); PersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear: false, personBirthday);
TimeSpan? TestStatic_Get(long minimumDateTimeTicks, bool? isWrongYear, Models.PersonBirthday personBirthday) => Models.PersonBirthday? TestStatic_GetPersonBirthday(string personBirthdayFormat, string personKey) =>
GetTimeSpan(minimumDateTimeTicks, isWrongYear, personBirthday); GetPersonBirthday(personBirthdayFormat, personKey);
static TimeSpan? GetTimeSpan(long minimumDateTimeTicks, bool? isWrongYear, Models.PersonBirthday personBirthday) => static Models.PersonBirthday? GetPersonBirthday(string personBirthdayFormat, string personKey) =>
PersonBirthday.GetTimeSpan(minimumDateTimeTicks, isWrongYear, personBirthday); PersonBirthday.GetPersonBirthday(personBirthdayFormat, personKey);
string TestStatic_GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
GetFileFullName(storage, personBirthdayFormat, personBirthday);
static string GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
PersonBirthday.GetFileFullName(storage, personBirthdayFormat, personBirthday);
bool TestStatic_DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) => bool TestStatic_DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) =>
DoesBirthDateExits(storage, personBirthday); DoesBirthDateExits(storage, personBirthday);
static bool DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) => static bool DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) =>
DoesBirthDateExits(storage, personBirthday); DoesBirthDateExits(storage, personBirthday);
TimeSpan? TestStatic_Get(long minimumDateTimeTicks, bool? isWrongYear, Models.PersonBirthday personBirthday) =>
GetTimeSpan(minimumDateTimeTicks, isWrongYear, personBirthday);
static TimeSpan? GetTimeSpan(long minimumDateTimeTicks, bool? isWrongYear, Models.PersonBirthday personBirthday) =>
PersonBirthday.GetTimeSpan(minimumDateTimeTicks, isWrongYear, personBirthday);
TimeSpan? TestStatic_Get(DateTime minimumDateTime, bool? isWrongYear, Models.PersonBirthday personBirthday) => TimeSpan? TestStatic_Get(DateTime minimumDateTime, bool? isWrongYear, Models.PersonBirthday personBirthday) =>
GetTimeSpan(minimumDateTime, isWrongYear, personBirthday); GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
static TimeSpan? GetTimeSpan(DateTime minimumDateTime, bool? isWrongYear, Models.PersonBirthday personBirthday) => static TimeSpan? GetTimeSpan(DateTime minimumDateTime, bool? isWrongYear, Models.PersonBirthday personBirthday) =>
@ -96,4 +93,19 @@ public interface IPersonBirthday
static bool IsWrongYearFilterOrCounterPersonBirthday(bool? isWrongYear, Models.PersonBirthday personBirthday) => static bool IsWrongYearFilterOrCounterPersonBirthday(bool? isWrongYear, Models.PersonBirthday personBirthday) =>
PersonBirthday.IsWrongYearFilterOrCounterPersonBirthday(isWrongYear, personBirthday); PersonBirthday.IsWrongYearFilterOrCounterPersonBirthday(isWrongYear, personBirthday);
string TestStatic_GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
GetFileFullName(storage, personBirthdayFormat, personBirthday);
static string GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
Path.Combine(storage.PeopleRootDirectory, "{}", GetFileName(personBirthdayFormat, personBirthday));
bool TestStatic_DoesBirthDateExits(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
DoesBirthDateExits(storage, personBirthdayFormat, personBirthday);
internal static bool DoesBirthDateExits(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
File.Exists(GetFileFullName(storage, personBirthdayFormat, personBirthday));
DateTime? TestStatic_GetDateTime(string personBirthdayFormat, string personKey) =>
GetDateTime(personBirthdayFormat, personKey);
static DateTime? GetDateTime(string personBirthdayFormat, string personKey) =>
DateTime.TryParseExact(GetDateTime(personKey), personBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime) ? dateTime : null;
} }

View File

@ -5,20 +5,12 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class PersonBirthday internal abstract class PersonBirthday
{ {
internal static DateTime GetDefaultValue() => DateTime.MinValue; // {{1}}SingletonValue
// ... // ...
internal static string GetFormatted(string personBirthdayFormat, Models.PersonBirthday personBirthday) => personBirthday.Value.ToString(personBirthdayFormat);
internal static string GetFileName(string personBirthdayFormat, Models.PersonBirthday personBirthday) => $"{personBirthday.Value.ToString(personBirthdayFormat)}.json";
internal static bool DoesBirthDateExits(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday personBirthday) => File.Exists(GetFileFullName(storage, personBirthdayFormat, personBirthday));
internal static Models.PersonBirthday GetNextBirthDate(Properties.IStorage storage) => throw new Exception(storage.ToString()); // Person.GetNextBirthDate(storage);
internal static string GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday personBirthday) => Path.Combine(storage.PeopleRootDirectory, "{}", GetFileName(personBirthdayFormat, personBirthday));
internal static DateTime? GetDateTime(string personBirthdayFormat, string personKey) => DateTime.TryParseExact(personKey.Replace('#', '0'), personBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime) ? dateTime : null;
internal static Models.PersonBirthday? GetPersonBirthday(string personBirthdayFormat, string personKey) internal static Models.PersonBirthday? GetPersonBirthday(string personBirthdayFormat, string personKey)
{ {
Models.PersonBirthday? result; Models.PersonBirthday? result;
DateTime? dateTime = GetDateTime(personBirthdayFormat, personKey); DateTime? dateTime = IPersonBirthday.GetDateTime(personBirthdayFormat, personKey);
if (dateTime is null) if (dateTime is null)
result = null; result = null;
else else
@ -29,7 +21,7 @@ internal abstract class PersonBirthday
internal static bool IsCounterPersonBirthday(Models.PersonBirthday personBirthday) internal static bool IsCounterPersonBirthday(Models.PersonBirthday personBirthday)
{ {
bool result; bool result;
if (personBirthday.Value.Year < 1900) if (personBirthday.Value.Year < 1826)
result = true; result = true;
else else
result = false; result = false;
@ -109,7 +101,7 @@ internal abstract class PersonBirthday
return result; return result;
} }
internal static Models.PersonBirthday[] GetDescendingOrderedPersonBirthdays(string personBirthdayFormat, string[] personKeyDirectories, string personDisplayDirectory) internal static List<Models.PersonBirthday> GetPersonBirthdays(string personBirthdayFormat, string[] personKeyDirectories, string personDisplayDirectory, string personDisplayDirectoryName)
{ {
List<Models.PersonBirthday> results = new(); List<Models.PersonBirthday> results = new();
string[] files; string[] files;
@ -124,13 +116,15 @@ internal abstract class PersonBirthday
(personBirthday, personKeyFormatted) = Person.Get(personBirthdayFormat, personDisplayDirectory, personKeyDirectory, birthday); (personBirthday, personKeyFormatted) = Person.Get(personBirthdayFormat, personDisplayDirectory, personKeyDirectory, birthday);
if (personBirthday is null || personKeyFormatted.Contains('#')) if (personBirthday is null || personKeyFormatted.Contains('#'))
continue; continue;
if (!IPersonBirthday.IsCounterPersonBirthday(personBirthday) && ((!personKeyDirectory.Contains('#') && (personDisplayDirectoryName.Contains('~') || personDisplayDirectoryName.Contains('#'))) || (personKeyDirectory.Contains('#') && !personDisplayDirectoryName.Contains('#'))))
throw new NotSupportedException();
results.Add(personBirthday); results.Add(personBirthday);
files = Directory.GetFiles(personKeyDirectory, "*", SearchOption.TopDirectoryOnly); files = Directory.GetFiles(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
if (files.Any()) if (files.Any())
continue; continue;
File.WriteAllText(Path.Combine(personKeyDirectory, $"{personKeyFormatted}.txt"), string.Empty); File.WriteAllText(Path.Combine(personKeyDirectory, $"{personKeyFormatted}.txt"), string.Empty);
} }
return results.OrderByDescending(l => l.Value.Ticks).ToArray(); return results;
} }
} }

View File

@ -33,31 +33,23 @@ internal abstract class PersonContainer
return results; return results;
} }
private static List<(long?, Models.PersonContainer)> GetPersonContainersCollections(string personBirthdayFormat, string facesFileNameExtension, char[] chars, string personDisplayDirectory, string personDisplayDirectoryName, string[] personKeyDirectories, int? approximateYears, Models.PersonBirthday[] personBirthdays) private static List<(long?, Models.PersonContainer)> GetPersonContainersCollections(string facesFileNameExtension, char[] chars, string personDisplayDirectory, string personDisplayDirectoryName, int? approximateYears, List<Models.PersonBirthday> personBirthdays)
{ {
List<(long?, Models.PersonContainer)> results = new(); List<(long?, Models.PersonContainer)> results = new();
long personKey; long personKey;
string[] segments; string[] segments;
const int zero = 0; const int zero = 0;
Models.Person person; Models.Person person;
string personKeyFormatted;
Models.PersonBirthday? personBirthday;
Models.PersonContainer personContainer; Models.PersonContainer personContainer;
Models.PersonBirthday[] orderedPersonBirthdays;
string[] personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory); string[] personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory);
foreach (string personKeyDirectory in personKeyDirectories) foreach (Models.PersonBirthday personBirthday in personBirthdays)
{ {
personKeyFormatted = Path.GetFileName(personKeyDirectory);
personBirthday = IPersonBirthday.GetPersonBirthday(personBirthdayFormat, personKeyFormatted);
if (personBirthday is null)
continue;
if (!IPersonBirthday.IsCounterPersonBirthday(personBirthday) && ((!personKeyDirectory.Contains('#') && (personDisplayDirectoryName.Contains('~') || personDisplayDirectoryName.Contains('#'))) || (personKeyDirectory.Contains('#') && !personDisplayDirectoryName.Contains('#'))))
throw new NotSupportedException();
personKey = personBirthdays[zero].Value.Ticks;
if (personKey != personBirthdays.OrderByDescending(l => l.Value.Ticks).ToArray()[0].Value.Ticks)
throw new NotSupportedException();
segments = personDisplayDirectoryName.Split(chars); segments = personDisplayDirectoryName.Split(chars);
orderedPersonBirthdays = personBirthdays.OrderByDescending(l => l.Value.Ticks).ToArray();
personKey = orderedPersonBirthdays[zero].Value.Ticks;
person = IPerson.GetPerson(personKey, segments); person = IPerson.GetPerson(personKey, segments);
personContainer = new(approximateYears, person, personBirthdays, personDisplayDirectoryAllFiles, personDisplayDirectoryName, personKey); personContainer = new(approximateYears, person, orderedPersonBirthdays, personDisplayDirectoryAllFiles, personDisplayDirectoryName, personKey);
results.Add(new(personKey, personContainer)); results.Add(new(personKey, personContainer));
} }
return results; return results;
@ -71,7 +63,7 @@ internal abstract class PersonContainer
return result; return result;
} }
private static string? VerifyAge(string personDisplayDirectory, string minusOne, string personDisplayDirectoryName, int? approximateYears, Models.PersonBirthday[] personBirthdays) private static string? VerifyAge(string personDisplayDirectory, string minusOne, string personDisplayDirectoryName, int? approximateYears, List<Models.PersonBirthday> personBirthdays)
{ {
string? result; string? result;
if (approximateYears is null) if (approximateYears is null)
@ -81,7 +73,8 @@ internal abstract class PersonContainer
const int zero = 0; const int zero = 0;
int? updateApproximateYears; int? updateApproximateYears;
DateTime dateTime = DateTime.Now; DateTime dateTime = DateTime.Now;
TimeSpan timeSpan = new(personBirthdays[zero].Value.Ticks - dateTime.AddYears(-approximateYears.Value).Ticks); Models.PersonBirthday[] orderedPersonBirthdays = personBirthdays.OrderByDescending(l => l.Value.Ticks).ToArray();
TimeSpan timeSpan = new(orderedPersonBirthdays[zero].Value.Ticks - dateTime.AddYears(-approximateYears.Value).Ticks);
if (timeSpan.TotalDays < -356) if (timeSpan.TotalDays < -356)
updateApproximateYears = approximateYears.Value + 1; updateApproximateYears = approximateYears.Value + 1;
else if (timeSpan.TotalDays > 356) else if (timeSpan.TotalDays > 356)
@ -110,7 +103,7 @@ internal abstract class PersonContainer
string[] personKeyDirectories; string[] personKeyDirectories;
string? personDisplayDirectoryName; string? personDisplayDirectoryName;
Models.PersonContainer personContainer; Models.PersonContainer personContainer;
Models.PersonBirthday[] personBirthdays; List<Models.PersonBirthday> personBirthdays;
foreach (string personDisplayDirectory in personDisplayDirectories) foreach (string personDisplayDirectory in personDisplayDirectories)
{ {
personDisplayDirectoryName = Path.GetFileName(personDisplayDirectory); personDisplayDirectoryName = Path.GetFileName(personDisplayDirectory);
@ -118,7 +111,7 @@ internal abstract class PersonContainer
continue; continue;
approximateYears = Age.GetApproximateYears(personDisplayDirectoryName, chars); approximateYears = Age.GetApproximateYears(personDisplayDirectoryName, chars);
personKeyDirectories = Directory.GetDirectories(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly); personKeyDirectories = Directory.GetDirectories(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly);
personBirthdays = PersonBirthday.GetDescendingOrderedPersonBirthdays(personBirthdayFormat, personKeyDirectories, personDisplayDirectory); personBirthdays = PersonBirthday.GetPersonBirthdays(personBirthdayFormat, personKeyDirectories, personDisplayDirectory, personDisplayDirectoryName);
if (personDisplayDirectoryName.Contains('^')) if (personDisplayDirectoryName.Contains('^'))
{ {
minusOne = Path.GetDirectoryName(personDisplayDirectory); minusOne = Path.GetDirectoryName(personDisplayDirectory);
@ -129,7 +122,7 @@ internal abstract class PersonContainer
if (changes.Any(l => l is not null)) if (changes.Any(l => l is not null))
continue; continue;
if (personBirthdays.Any()) if (personBirthdays.Any())
results.AddRange(GetPersonContainersCollections(personBirthdayFormat, facesFileNameExtension, chars, personDisplayDirectory, personDisplayDirectoryName, personKeyDirectories, approximateYears, personBirthdays)); results.AddRange(GetPersonContainersCollections(facesFileNameExtension, chars, personDisplayDirectory, personDisplayDirectoryName, approximateYears, personBirthdays));
else else
{ {
personContainer = GetPersonContainer(facesFileNameExtension, personDisplayDirectory, personDisplayDirectoryName, approximateYears); personContainer = GetPersonContainer(facesFileNameExtension, personDisplayDirectory, personDisplayDirectoryName, approximateYears);

View File

@ -435,6 +435,35 @@ public class UnitTestCalculations
Assert.IsTrue(distance == 3); Assert.IsTrue(distance == 3);
} }
[TestMethod]
public void TestGetPixelPercentageG()
{
int? x, y;
double x1, x2, y1, y2;
int height, width;
string normalizedPixelPercentagePadded;
width = 4608;
height = 3072;
normalizedPixelPercentagePadded = "683152331";
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
if (x is null || y is null)
throw new Exception();
Assert.IsTrue(x.Value == 3148);
Assert.IsTrue(y.Value == 1608);
x1 = x.Value;
y1 = y.Value;
normalizedPixelPercentagePadded = "234431671";
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
if (x is null || y is null)
throw new Exception();
Assert.IsTrue(x.Value == 1080);
Assert.IsTrue(y.Value == 973);
x2 = x.Value;
y2 = y.Value;
double distance = Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2));
Assert.IsTrue(distance == 3);
}
[TestMethod] [TestMethod]
public void TestGetDistance() public void TestGetDistance()
{ {

View File

@ -16,6 +16,7 @@ public class Configuration
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; } [Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
[Display(Name = "Distance Move Unable to Match by 1 Tick"), Required] public bool? DistanceMoveUnableToMatch { get; set; } [Display(Name = "Distance Move Unable to Match by 1 Tick"), Required] public bool? DistanceMoveUnableToMatch { get; set; }
[Display(Name = "Distance Pixel Distance Tolerance"), Required] public int? DistancePixelDistanceTolerance { get; set; } [Display(Name = "Distance Pixel Distance Tolerance"), Required] public int? DistancePixelDistanceTolerance { get; set; }
[Display(Name = "Distance Rename to Match"), Required] public bool? DistanceRenameToMatch { get; set; }
[Display(Name = "Face Area Permille Tolerance"), Required] public int? FaceDistanceAreaPermilleTolerance { get; set; } [Display(Name = "Face Area Permille Tolerance"), Required] public int? FaceDistanceAreaPermilleTolerance { get; set; }
[Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; } [Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; }
[Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; } [Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; }
@ -33,7 +34,6 @@ public class Configuration
[Display(Name = "Location Confidence Factor"), Required] public int? LocationConfidenceFactor { get; set; } [Display(Name = "Location Confidence Factor"), Required] public int? LocationConfidenceFactor { get; set; }
[Display(Name = "Location Digits"), Required] public int? LocationDigits { get; set; } [Display(Name = "Location Digits"), Required] public int? LocationDigits { get; set; }
[Display(Name = "Location Factor"), Required] public int? LocationFactor { get; set; } [Display(Name = "Location Factor"), Required] public int? LocationFactor { get; set; }
[Display(Name = "Map Logic Sigma"), Required] public int? MapLogicSigma { get; set; }
[Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; } [Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; }
[Display(Name = "Mapping Default Name"), Required] public string MappingDefaultName { get; set; } [Display(Name = "Mapping Default Name"), Required] public string MappingDefaultName { get; set; }
[Display(Name = "Mapping Save Mapped"), Required] public bool? MappingSaveMapped { get; set; } [Display(Name = "Mapping Save Mapped"), Required] public bool? MappingSaveMapped { get; set; }
@ -100,6 +100,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.DistanceMoveUnableToMatch)); throw new NullReferenceException(nameof(configuration.DistanceMoveUnableToMatch));
if (configuration.DistancePixelDistanceTolerance is null) if (configuration.DistancePixelDistanceTolerance is null)
throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance)); throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance));
if (configuration.DistanceRenameToMatch is null)
throw new NullReferenceException(nameof(configuration.DistanceRenameToMatch));
if (configuration.FaceDistanceAreaPermilleTolerance is null) if (configuration.FaceDistanceAreaPermilleTolerance is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceAreaPermilleTolerance)); throw new NullReferenceException(nameof(configuration.FaceDistanceAreaPermilleTolerance));
if (configuration.FaceDistanceHiddenImageFactor is null) if (configuration.FaceDistanceHiddenImageFactor is null)
@ -132,8 +134,6 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.LocationDigits)); throw new NullReferenceException(nameof(configuration.LocationDigits));
if (configuration.LocationFactor is null) if (configuration.LocationFactor is null)
throw new NullReferenceException(nameof(configuration.LocationFactor)); throw new NullReferenceException(nameof(configuration.LocationFactor));
if (configuration.MapLogicSigma is null)
throw new NullReferenceException(nameof(configuration.MapLogicSigma));
if (configuration.MappingDefaultName is null) if (configuration.MappingDefaultName is null)
throw new NullReferenceException(nameof(configuration.MappingDefaultName)); throw new NullReferenceException(nameof(configuration.MappingDefaultName));
if (configuration.MappingSaveNotMapped is null) if (configuration.MappingSaveNotMapped is null)
@ -223,6 +223,7 @@ public class Configuration
configuration.DistanceFactor.Value, configuration.DistanceFactor.Value,
configuration.DistanceMoveUnableToMatch.Value, configuration.DistanceMoveUnableToMatch.Value,
configuration.DistancePixelDistanceTolerance.Value, configuration.DistancePixelDistanceTolerance.Value,
configuration.DistanceRenameToMatch.Value,
configuration.FaceDistanceAreaPermilleTolerance.Value, configuration.FaceDistanceAreaPermilleTolerance.Value,
configuration.FaceDistanceHiddenImageFactor.Value, configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value, configuration.FaceDistanceMinimumConfidence.Value,
@ -240,7 +241,6 @@ public class Configuration
configuration.LocationConfidenceFactor.Value, configuration.LocationConfidenceFactor.Value,
configuration.LocationDigits.Value, configuration.LocationDigits.Value,
configuration.LocationFactor.Value, configuration.LocationFactor.Value,
configuration.MapLogicSigma.Value,
configuration.MappedMaxIndex, configuration.MappedMaxIndex,
configuration.MappingDefaultName, configuration.MappingDefaultName,
configuration.MappingSaveNotMapped.Value, configuration.MappingSaveNotMapped.Value,

View File

@ -15,6 +15,7 @@ public class Configuration
public int DistanceFactor { init; get; } public int DistanceFactor { init; get; }
public bool DistanceMoveUnableToMatch { init; get; } public bool DistanceMoveUnableToMatch { init; get; }
public int DistancePixelDistanceTolerance { init; get; } public int DistancePixelDistanceTolerance { init; get; }
public bool DistanceRenameToMatch { init; get; }
public int FaceDistanceAreaPermilleTolerance { init; get; } public int FaceDistanceAreaPermilleTolerance { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; } public int FaceDistanceHiddenImageFactor { init; get; }
public double FaceDistanceMinimumConfidence { init; get; } public double FaceDistanceMinimumConfidence { init; get; }
@ -32,7 +33,6 @@ public class Configuration
public int LocationConfidenceFactor { init; get; } public int LocationConfidenceFactor { init; get; }
public int LocationDigits { init; get; } public int LocationDigits { init; get; }
public int LocationFactor { init; get; } public int LocationFactor { init; get; }
public int MapLogicSigma { init; get; }
public int? MappedMaxIndex { init; get; } public int? MappedMaxIndex { init; get; }
public string MappingDefaultName { init; get; } public string MappingDefaultName { init; get; }
public bool MappingSaveNotMapped { init; get; } public bool MappingSaveNotMapped { init; get; }
@ -83,6 +83,7 @@ public class Configuration
int distanceFactor, int distanceFactor,
bool distanceMoveUnableToMatch, bool distanceMoveUnableToMatch,
int distancePixelDistanceTolerance, int distancePixelDistanceTolerance,
bool distanceRenameToMatch,
int faceDistanceAreaPermilleTolerance, int faceDistanceAreaPermilleTolerance,
int faceDistanceHiddenImageFactor, int faceDistanceHiddenImageFactor,
double faceDistanceMinimumConfidence, double faceDistanceMinimumConfidence,
@ -100,7 +101,6 @@ public class Configuration
int locationConfidenceFactor, int locationConfidenceFactor,
int locationDigits, int locationDigits,
int locationFactor, int locationFactor,
int mapLogicSigma,
int? mappedMaxIndex, int? mappedMaxIndex,
string mappingDefaultName, string mappingDefaultName,
bool mappingSaveNotMapped, bool mappingSaveNotMapped,
@ -150,6 +150,7 @@ public class Configuration
DistanceFactor = distanceFactor; DistanceFactor = distanceFactor;
DistanceMoveUnableToMatch = distanceMoveUnableToMatch; DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
DistancePixelDistanceTolerance = distancePixelDistanceTolerance; DistancePixelDistanceTolerance = distancePixelDistanceTolerance;
DistanceRenameToMatch = distanceRenameToMatch;
FaceDistanceAreaPermilleTolerance = faceDistanceAreaPermilleTolerance; FaceDistanceAreaPermilleTolerance = faceDistanceAreaPermilleTolerance;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor; FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence; FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
@ -167,7 +168,6 @@ public class Configuration
LocationConfidenceFactor = locationConfidenceFactor; LocationConfidenceFactor = locationConfidenceFactor;
LocationDigits = locationDigits; LocationDigits = locationDigits;
LocationFactor = locationFactor; LocationFactor = locationFactor;
MapLogicSigma = mapLogicSigma;
MappedMaxIndex = mappedMaxIndex; MappedMaxIndex = mappedMaxIndex;
MappingDefaultName = mappingDefaultName; MappingDefaultName = mappingDefaultName;
MappingSaveNotMapped = mappingSaveNotMapped; MappingSaveNotMapped = mappingSaveNotMapped;