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;
Map.Models.Configuration? mapConfiguration = null;
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);
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
{
private readonly List<string> _Moved;
private readonly List<double?> _Debug;
private readonly List<string> _Renamed;
private readonly Serilog.ILogger? _Log;
private readonly string _ResultAllInOne;
private readonly int _FaceDistancePermyriad;
private readonly bool _DistanceRenameToMatch;
private readonly double _FaceDistanceTolerance;
private readonly int _SortingDaysDeltaTolerance;
private readonly bool _DistanceMoveUnableToMatch;
private readonly List<string> _AllMappedFaceFiles;
private readonly int _DistancePixelDistanceTolerance;
private readonly List<string> _AllMappedFaceFileNames;
private readonly double _FaceDistanceMinimumConfidence;
private readonly List<string> _DuplicateMappedFaceFiles;
private readonly int _FaceDistanceAreaPermilleTolerance;
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;
_DuplicateMappedFaceFiles = new();
_Log = Serilog.Log.ForContext<E_Distance>();
_DistanceRenameToMatch = distanceRenameToMatch;
_FaceDistancePermyriad = faceDistancePermyriad;
_FaceDistanceTolerance = faceDistanceTolerance;
_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;
string? fileName = Path.GetFileName(file);
string? directoryName = Path.GetDirectoryName(file);
if (fileName is null || directoryName is null)
result = false;
bool check;
string? directoryName = Path.GetDirectoryName(mappedFaceFile);
if (mappedFaceFileName is null || directoryName is null)
check = false;
else
{
if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(directoryName) || !directoryName.Contains(eDistanceContentDirectory))
result = false;
check = false;
else
{
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))
{
result = false;
File.Delete(file);
check = false;
File.Delete(mappedFaceFile);
}
else
{
@ -352,45 +365,13 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
checkDirectoryName = Path.Combine(checkDirectoryName, directoryNames[i]);
if (!Directory.Exists(checkDirectoryName))
_ = Directory.CreateDirectory(checkDirectoryName);
File.Move(file, Path.Combine(checkDirectoryName, fileName));
result = true;
File.Move(mappedFaceFile, Path.Combine(checkDirectoryName, mappedFaceFileName));
check = true;
}
}
}
if (result)
{ }
}
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;
if (check)
_Moved.Add(mappedFaceFile);
}
public static string? GetFaceEncoding(string file)
@ -419,6 +400,32 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
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)
{
FaceDistanceContainer[] results;
@ -447,9 +454,9 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
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;
FaceDistance faceDistanceLength;
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];
if (faceDistanceLength.Length is null)
throw new NotSupportedException();
if (faceDistanceLength.Length.Value > _FaceDistanceTolerance)
continue;
results.Add(new(face, faceDistanceLength.Length.Value));
}
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;
List<(Face Face, double Length)> collection = GetValues(mappingFromItem, faces, json);
if (!collection.Any())
results = Array.Empty<Face>();
else
results = (from l in collection orderby l.Length select l.Face).Take(1).ToArray();
(Face, double?)[] results;
List<(Face Face, double? Length)> collection = GetValues(mappingFromItem, faces, json);
results = (from l in collection orderby l.Length select l).Take(1).ToArray();
(Face face, double? length) = results.First();
lock (_Debug)
_Debug.Add(length);
return results;
}
private static Face[] GetMatchingFaces(int pixelDistanceTolerance, List<Face> faces)
static (int?, int?) GetXY(int normalizedPixelPercentage, OutputResolution? outputResolution)
{
Face[] results;
int? x;
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 center = 2f;
double xCenterValue;
double yCenterValue;
int normalizedPixelPercentage;
int normalizedPixelPercentageLoop;
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)
{
if (face.Location is null || face.OutputResolution is null)
throw new NotSupportedException();
xCenterValue = (face.Location.Left + face.Location.Right) / center;
yCenterValue = (face.Location.Top + face.Location.Bottom) / center;
if (xCenterValue < face.Location.Left || xCenterValue > face.Location.Right)
throw new Exception();
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)
normalizedPixelPercentageLoop = 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, normalizedPixelPercentageLoop);
(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);
if (x2 is null || y2 is null)
throw new NotSupportedException();
distance = Math.Sqrt(Math.Pow(xCenterValue - x.Value, 2) + Math.Pow(yCenterValue - y.Value, 2));
collection.Add(new(distance, face));
distance = Math.Sqrt(Math.Pow(x1.Value - x2.Value, 2) + Math.Pow(y1.Value - y2.Value, 2));
collection.Add(new(face, distance));
}
if (!collection.Any())
results = Array.Empty<Face>();
else
results = (from l in collection orderby l.Order where l.Order < pixelDistanceTolerance select l.Face).Take(1).ToArray();
results = (from l in collection orderby l.Order where l.Order < _DistancePixelDistanceTolerance select l).Take(1).ToArray();
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;
foreach (Face face in faces)
{
@ -541,18 +583,18 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
check = JsonSerializer.Serialize(face.FaceEncoding);
if (check != json)
continue;
results.Add(face);
results.Add(new(face, 0));
}
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;
string checkFile;
string? mappedFaceDirectory;
string deterministicHashCodeKey;
foreach (Face face in checkFaces)
foreach ((Face face, _) in checkFaces)
{
if (checkFaces.Count != 1)
break;
@ -566,112 +608,127 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
if (checkFile == mappedFaceFile)
continue;
result = new FileInfo(checkFile);
if (!result.Exists)
continue;
File.Delete(result.FullName);
result = null;
}
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();
bool check;
int normalizedPixelPercentage;
foreach (Face face in faces)
string checkFile;
FileInfo fileInfo = new(mappedFaceFile);
List<(long Length, string FullName)> collection = new();
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)
throw new NotSupportedException();
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)
fileInfo = new(match);
if (!fileInfo.Exists)
continue;
if (normalizedPixelPercentages.Contains(normalizedPixelPercentage))
{
duplicateMappedFaceFiles.AddRange(GetMatchingDuplicates(mappedFaceFiles, duplicateMappedFaceFiles, mappedFaceFile));
continue;
}
check = true;
results.Add(face);
if (!check)
debugChecks.Add(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++)
{
checkFile = string.Concat(collection[i].FullName, ".dup");
if (File.Exists(checkFile))
continue;
File.Move(collection[i].FullName, checkFile);
}
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;
int renamed = 0;
string[] matches;
FileInfo? fileInfo;
List<Face> checkFaces = new();
List<int> debugChecks = new();
List<int> normalizedPixelPercentages = new();
List<string> duplicateMappedFaceFiles = new();
string[] mappedFaceFiles = (from l in collection select l.MappedFaceFile).ToArray();
string mappedFaceFileName;
List<(Face, double?)> checkFaces = new();
foreach ((string mappedFaceFile, int normalizedPixelPercentage) in collection)
{
if (duplicateMappedFaceFiles.Contains(mappedFaceFile))
mappedFaceFileName = Path.GetFileName(mappedFaceFile);
if (_DuplicateMappedFaceFiles.Contains(mappedFaceFileName))
continue;
json = null;
checkFaces.Clear();
debugChecks.Clear();
checkFaces.AddRange(GetMatchingFaces(faces, mappedFaceFiles, debugChecks, normalizedPixelPercentage, normalizedPixelPercentages, duplicateMappedFaceFiles, mappedFaceFile));
if (checkFaces.Count != 1)
json = GetFaceEncoding(mappedFaceFile);
if (json is null)
{
checkFaces.Clear();
json = GetFaceEncoding(mappedFaceFile);
if (json is null)
{
result++;
if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile);
continue;
}
checkFaces.AddRange(GetMatchingFaces(faces, json));
if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile, mappedFaceFileName);
continue;
}
checkFaces.AddRange(GetMatchingFacesByFaceEncoding(faces, json));
if (checkFaces.Count == 1)
_Debug.Add(0);
if (checkFaces.Count != 1 && !string.IsNullOrEmpty(json))
{
checkFaces.Clear();
if (json is null)
throw new NotSupportedException();
checkFaces.AddRange(GetMatchingFaces(mappingFromItem, faces, json));
checkFaces.AddRange(GetClosestFaceByDistanceIgnoringTolerance(mappingFromItem, faces, json));
}
if (checkFaces.Count != 1 && _DistancePixelDistanceTolerance > 0)
{
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())
{
result++;
if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile);
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile, mappedFaceFileName);
continue;
}
if (checkFaces.Count != 1)
{
result++;
if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile);
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile, mappedFaceFileName);
continue;
}
normalizedPixelPercentages.Add(normalizedPixelPercentage);
fileInfo = CheckFileThenGetFileInfo(facesFileNameExtension, mappingFromItem, mappedFaceFile, checkFaces);
if (fileInfo is null)
if (fileInfo is not null)
{
if (_DistanceRenameToMatch && fileInfo is not null)
{
if (fileInfo.Exists)
File.Delete(fileInfo.FullName);
File.Move(mappedFaceFile, fileInfo.FullName);
_Renamed.Add(mappedFaceFile);
}
continue;
File.Move(mappedFaceFile, fileInfo.FullName);
renamed++;
}
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);
}
if (duplicateMappedFaceFiles.Any())
{
duplicateMappedFaceFiles.Sort();
}
return new(result, duplicateMappedFaceFiles.Count, renamed);
}
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 height;
string json;
Bitmap bitmap;
Graphics graphics;
Location? location;
Rectangle rectangle;
string locationJson;
string faceEncodingJson;
PropertyItem? propertyItem;
string outputResolutionJson;
int artist = (int)IExif.Tags.Artist;
int fileSource = (int)IExif.Tags.FileSource;
int userComment = (int)IExif.Tags.UserComment;
using Bitmap source = new(resizedFileHolder.FullName);
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string fileName) in collection)
@ -150,13 +154,19 @@ public class D_Face
continue;
width = location.Right - location.Left;
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);
using (bitmap = new(width, height))
{
using (graphics = Graphics.FromImage(bitmap))
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.Save(fileInfo.FullName, _ImageCodecInfo, _EncoderParameters);
}

View File

@ -71,10 +71,10 @@ public partial class DlibDotNet
_Index = new(configuration);
_Random = new(configuration);
_Rename = new(configuration);
_MapConfiguration = Get(configuration);
_Distance = new(
configuration.DistanceMoveUnableToMatch,
configuration.DistancePixelDistanceTolerance,
configuration.DistanceRenameToMatch,
configuration.FaceDistanceAreaPermilleTolerance,
configuration.FaceDistanceMinimumConfidence,
configuration.FaceDistancePermyriad,
@ -116,6 +116,11 @@ public partial class DlibDotNet
predictorModel,
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)
personContainers = Array.Empty<PersonContainer>();
else
@ -139,10 +144,6 @@ public partial class DlibDotNet
e2Navigate.Navigate(propertyConfiguration, model, predictorModel, configuration.OutputResolutions[0]);
_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(
configuration.OutputExtension,
@ -323,28 +324,18 @@ public partial class DlibDotNet
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(
configuration.FaceDistanceAreaPermilleTolerance,
configuration.FaceDistanceHiddenImageFactor,
configuration.FaceDistancePermyriad,
configuration.FaceDistanceMinimumConfidence,
configuration.FaceDistanceTolerance,
configuration.MapLogicSigma,
configuration.MappingDefaultName,
configuration.DistanceMoveUnableToMatch,
configuration.MappingSaveNotMapped,
configuration.MappingSaveMapped,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping,
configuration.PersonBirthdayFirstYear,
configuration.PersonBirthdayFormat,
configuration.PersonKeyFormat,
configuration.SortingDaysDeltaTolerance,
configuration.SortingMaximumPerFaceShouldBeHigh,
configuration.SortingMaximumPerKey,
configuration.SortingSigma);
facesFileNameExtension,
facesHiddenFileNameExtension,
facePartsFileNameExtension);
return result;
}
@ -431,7 +422,7 @@ public partial class DlibDotNet
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)
&& 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))
{
throw new NotImplementedException();
@ -905,15 +896,16 @@ public partial class DlibDotNet
_AppSettings.MaxDegreeOfParallelism,
_Configuration.PropertyConfiguration,
_MapConfiguration,
_Faces.FileNameExtension,
_Faces.HiddenFileNameExtension,
_FaceParts.FileNameExtension,
ticks,
personContainers,
a2PeopleSingletonDirectory,
eDistanceContentDirectory,
distinctFilteredFaces,
_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);
if (!sortingContainers.Any())
{
@ -925,11 +917,9 @@ public partial class DlibDotNet
}
}
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces);
if (totalNotMapped > 0)
mapLogic.ForceSingleImageThenSaveMapping(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, sortingContainers, useFiltersCounter, totalNotMapped);
mapLogic.CopyManualFiles(dFacesContentDirectory, distinctFilteredFaces);
if (_MapConfiguration.MappingSaveNotMapped)
mapLogic.ForceSingleImageThenSaveSorting(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, sortingContainers, useFiltersCounter, totalNotMapped);
if (_Configuration.MappingSaveNotMapped)
mapLogic.SaveNotMappedTicks();
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
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);
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);
_Distance.Clear();
foreach (string outputResolution in _Configuration.OutputResolutions)
{
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 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 Rename to Match"), Required] public bool? DistanceRenameToMatch { 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 = "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 Digits"), Required] public int? LocationDigits { 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 = "Mapping Default Name"), Required] public string MappingDefaultName { 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));
if (configuration.DistancePixelDistanceTolerance is null)
throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance));
if (configuration.DistanceRenameToMatch is null)
throw new NullReferenceException(nameof(configuration.DistanceRenameToMatch));
if (configuration.FaceDistanceAreaPermilleTolerance is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceAreaPermilleTolerance));
if (configuration.FaceDistanceHiddenImageFactor is null)
@ -132,8 +134,6 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.LocationDigits));
if (configuration.LocationFactor is null)
throw new NullReferenceException(nameof(configuration.LocationFactor));
if (configuration.MapLogicSigma is null)
throw new NullReferenceException(nameof(configuration.MapLogicSigma));
if (configuration.MappingDefaultName is null)
throw new NullReferenceException(nameof(configuration.MappingDefaultName));
if (configuration.MappingSaveNotMapped is null)
@ -223,6 +223,7 @@ public class Configuration
configuration.DistanceFactor.Value,
configuration.DistanceMoveUnableToMatch.Value,
configuration.DistancePixelDistanceTolerance.Value,
configuration.DistanceRenameToMatch.Value,
configuration.FaceDistanceAreaPermilleTolerance.Value,
configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value,
@ -240,7 +241,6 @@ public class Configuration
configuration.LocationConfidenceFactor.Value,
configuration.LocationDigits.Value,
configuration.LocationFactor.Value,
configuration.MapLogicSigma.Value,
configuration.MappedMaxIndex,
configuration.MappingDefaultName,
configuration.MappingSaveNotMapped.Value,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,20 +23,14 @@ public class MapLogic
private readonly Serilog.ILogger? _Log;
private readonly int _MaxDegreeOfParallelism;
private readonly Configuration? _Configuration;
private readonly string _FacesFileNameExtension;
private readonly string _FacePartsFileNameExtension;
private readonly string _FacesHiddenFileNameExtension;
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;
_Configuration = configuration;
_Log = Serilog.Log.ForContext<MapLogic>();
_FacesFileNameExtension = facesFileNameExtension;
_MaxDegreeOfParallelism = maxDegreeOfParallelism;
_FacePartsFileNameExtension = facePartsFileNameExtension;
_FacesHiddenFileNameExtension = facesHiddenFileNameExtension;
if (_Log is null)
{ }
if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any())
@ -67,7 +61,6 @@ public class MapLogic
List<PersonContainer> personContainerCollection = new(personContainers);
Stateless.MapLogic.Set(propertyConfiguration,
configuration,
facesFileNameExtension,
ticks,
personContainerCollection,
a2PeopleSingletonDirectory,
@ -102,8 +95,8 @@ public class MapLogic
_IdThenNormalizedPixelPercentageToPersonContainers = idThenNormalizedPixelPercentageToPersonContainers;
}
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string outputExtension, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) :
this(maxDegreeOfParallelism, propertyConfiguration, configuration, outputExtension, outputExtension, outputExtension, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, new(), null)
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) :
this(maxDegreeOfParallelism, propertyConfiguration, configuration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, new(), null)
{ }
public override string ToString()
@ -112,6 +105,131 @@ public class MapLogic
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)
{
List<(long, long, long, long)> results = new();
@ -197,185 +315,215 @@ public class MapLogic
return results;
}
public void SaveShortcuts(string[] juliePhares, List<Face> distinctFilteredFaces)
{
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)
private int UpdateFromSortingContainers(SortingContainer[] sortingContainers)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int result = 0;
string key;
const int zero = 0;
string mappingSegmentB;
string personKeyFormatted;
List<Mapping> checkCollection;
PersonBirthday personBirthday;
PersonContainer[]? collection;
int by = Stateless.IMapLogic.Mapping;
List<PersonContainer> personContainers = new();
Dictionary<int, PersonContainer[]>? keyValuePairs;
foreach (Face face in distinctFilteredFaces)
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)
{
personContainers.Clear();
if (face.Mapping is null)
progressBar.Tick();
if (sortingContainer.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);
}
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;
personContainers = normalizedPixelPercentageToPersonContainers[sortingContainer.Sorting.NormalizedPixelPercentage];
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, face.Mapping.MappingFromItem);
face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
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;
}
private void SaveContainers(int totalNotMapped, int updated, List<SaveContainer> saveContainers)
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)
throw new NotSupportedException();
if (face.Mapping.MappingFromPerson.PersonBirthday is not null)
continue;
if (_SkipCollection.TryGetValue(face.Mapping.MappingFromItem.Id, out normalizedPixelPercentages))
{
if (normalizedPixelPercentages.Contains(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
continue;
}
foreach (PersonContainer personContainer in _NotMappedPersonContainers)
{
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);
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
{
updated = UpdateFromSortingContainers(sortingContainers);
if (useFiltersCounter is null && totalNotMapped - updated > 0)
ForceSingleImage(distinctFilteredFaces);
saveContainers = Stateless.MapLogic.GetMappingSaveContainers(_Configuration, _EDistanceContentTicksDirectory, dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, useFiltersCounter, saveMapped: false);
}
SaveContainers(totalNotMapped, updated, saveContainers);
}
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 sourceFile;
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;
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 = $") {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)
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 (string.IsNullOrEmpty(directory))
if (keyValuePair.Value.Key is null || keyValuePair.Value.Birthdays is null || !keyValuePair.Value.Birthdays.Any())
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.ResizedFileHolder is null || saveContainer.FaceFileHolder is null || !string.IsNullOrEmpty(saveContainer.Json))
continue;
if (!saveContainer.FaceFileHolder.Exists && saveContainer.ResizedFileHolder.Exists)
personBirthday = keyValuePair.Value.Birthdays[zero];
foreach (string personDisplayDirectoryAllFile in keyValuePair.Value.DisplayDirectoryAllFiles)
{
checkFile = saveContainer.CheckFile;
sourceFile = saveContainer.ResizedFileHolder.FullName;
}
else if (saveContainer.FaceFileHolder.Exists)
{
sourceFile = saveContainer.FaceFileHolder.FullName;
checkFile = $"{saveContainer.CheckFile}{_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}{_FacesHiddenFileNameExtension}";
}
else if (saveContainer.FacePartsFileHolder is not null && saveContainer.FacePartsFileHolder.Exists)
{
sourceFile = saveContainer.FacePartsFileHolder.FullName;
checkFile = $"{saveContainer.CheckFile}{_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 not null || saveContainer.FaceFileHolder is not null || string.IsNullOrEmpty(saveContainer.Json))
continue;
if (File.Exists(saveContainer.CheckFile))
continue;
_ = IPath.WriteAllText(saveContainer.CheckFile, saveContainer.Json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
}
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);
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;
}
fileInfo = new(personDisplayDirectoryAllFile);
if (!fileInfo.Exists)
continue;
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;
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}{_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;
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);
}
catch (Exception)
{ }
}
}
@ -491,377 +639,32 @@ public class MapLogic
return results;
}
private int UpdateFromSortingContainers(SortingContainer[] sortingContainers)
public void SaveShortcuts(string[] juliePhares, List<Face> distinctFilteredFaces)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int result = 0;
string key;
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)
List<(Face, List<(string?, string, string?, string?, string)>)> facesToCollection = GetCollection(distinctFilteredFaces);
foreach ((Face face, List<(string? PersonKeyFormatted, string, string?, string?, string)> collection) in facesToCollection)
{
progressBar.Tick();
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))
if (collection.Any(l => l.PersonKeyFormatted is not null and "1501-04-10_00"))
continue;
personContainers = normalizedPixelPercentageToPersonContainers[sortingContainer.Sorting.NormalizedPixelPercentage];
foreach (PersonContainer personContainer in personContainers)
foreach ((string? personKeyFormatted, string directory, string? copyDirectory, string? copyFileName, string _) in collection)
{
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)
throw new NotSupportedException();
if (face.Mapping.MappingFromPerson.PersonBirthday is not null)
continue;
if (_SkipCollection.TryGetValue(face.Mapping.MappingFromItem.Id, out normalizedPixelPercentages))
{
if (normalizedPixelPercentages.Contains(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
continue;
}
foreach (PersonContainer personContainer in _NotMappedPersonContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, face.Mapping.MappingFromItem);
face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
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))
if (personKeyFormatted is null)
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))
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
if (string.IsNullOrEmpty(copyDirectory) || string.IsNullOrEmpty(copyFileName))
continue;
if (File.Exists(shortcutFile))
if (!juliePhares.Contains(personKeyFormatted))
continue;
windowsShortcut = new() { Path = faceFile };
windowsShortcut.Save(shortcutFile);
windowsShortcut.Dispose();
if (!File.Exists(shortcutFile))
continue;
File.SetLastWriteTime(shortcutFile, face.Mapping.MappingFromItem.MinimumDateTime);
if (!Directory.Exists(copyDirectory))
_ = Directory.CreateDirectory(copyDirectory);
if (!File.Exists(copyFileName))
File.Copy(face.Mapping.MappingFromItem.ResizedFileHolder.FullName, copyFileName);
break;
}
}
}

View File

@ -2,6 +2,7 @@ using Humanizer;
using ShellProgressBar;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
using WindowsShortcutFactory;
namespace View_by_Distance.Map.Models.Stateless;
@ -33,7 +34,7 @@ internal abstract class MapLogic
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;
long personKey;
@ -44,9 +45,9 @@ internal abstract class MapLogic
{
foreach (string personDisplayDirectoryAllFile in personContainer.DisplayDirectoryAllFiles)
{
if (!personDisplayDirectoryAllFile.EndsWith(facesFileNameExtension))
if (!personDisplayDirectoryAllFile.EndsWith(configuration.FacesFileNameExtension))
continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, personDisplayDirectoryAllFile);
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(configuration.FacesFileNameExtension, personDisplayDirectoryAllFile);
if (id is null || normalizedPixelPercentage is null)
continue;
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();
int? id;
@ -148,7 +149,7 @@ internal abstract class MapLogic
{
if (file.EndsWith(".lnk") || file.EndsWith(".json"))
continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, file);
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(configuration.FacesFileNameExtension, file);
if (id is null || normalizedPixelPercentage is null)
continue;
results.Add(new(personKeyFormatted, personDisplayDirectoryNames, file));
@ -177,14 +178,14 @@ internal abstract class MapLogic
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();
int? id;
int? normalizedPixelPercentage;
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)
continue;
if (!results.ContainsKey(id.Value))
@ -194,12 +195,12 @@ internal abstract class MapLogic
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;
string personKeyFormatted;
List<(long? PersonKey, string Line)> lines = new();
List<string> personKeyFormattedCollection = new();
List<(long? PersonKey, string Line)> lines = new();
_ = GetDistinctCollection(configuration, personContainers.ToList(), new());
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string[] ticksDirectories;
@ -220,9 +221,9 @@ internal abstract class MapLogic
}
}
if (!string.IsNullOrEmpty(a2PeopleContentDirectory))
File.WriteAllLines(Path.Combine(a2PeopleContentDirectory, "People - C.tsv"), from l in lines orderby l.PersonKey is null select l.Line);
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, facesFileNameExtension, personKeyFormattedCollection, ticksDirectories, message);
results = GetIdToCollection(facesFileNameExtension, collection);
File.WriteAllLines(Path.Combine(a2PeopleContentDirectory, "People - C.tsv"), from l in lines select l.Line);
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message);
results = GetIdToCollection(configuration, collection);
return results;
}
@ -345,7 +346,7 @@ internal abstract class MapLogic
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? id;
@ -368,7 +369,7 @@ internal abstract class MapLogic
{
progressBar.Tick();
(id, normalizedPixelPercentage, faces) = IMapping.GetReversedDeterministicHashCodeKey(
facesFileNameExtension,
configuration.FacesFileNameExtension,
idToFacesAny,
idToFaces,
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)
throw new NullReferenceException(nameof(configuration));
@ -597,7 +598,7 @@ internal abstract class MapLogic
List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection = new();
List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection = 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));
foreach (Face face in distinctFilteredFaces)
{
@ -612,8 +613,8 @@ internal abstract class MapLogic
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly);
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);
(int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(facesFileNameExtension, ticks, keyValuePairs, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, collection);
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message);
(int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(configuration, ticks, keyValuePairs, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, collection);
SetKeyValuePairs(configuration, ticks, personContainers, distinctFilteredFaces, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, personKeyToPersonContainer, idThenNormalizedPixelPercentageToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, incorrectIdThenNormalizedPixelPercentageToPersonContainers, personKeyToRanges);
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)";
@ -632,7 +633,211 @@ internal abstract class MapLogic
notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, personContainers, personKeyCollection));
AppendToSkipCollection(skipCollection, idThenNormalizedPixelPercentageToPersonContainers, incorrectIdThenNormalizedPixelPercentageToPersonContainers);
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
{ // ...
Dictionary<int, List<(string, int)>> TestStatic_DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, string facesFileNameExtension, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) =>
DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, facesFileNameExtension, 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) =>
MapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, facesFileNameExtension, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers);
Dictionary<int, List<(string, int)>> TestStatic_DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) =>
DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers);
static Dictionary<int, List<(string, int)>> DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, long ticks, string? a2PeopleContentDirectory, string? eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) =>
MapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers);
}

View File

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

View File

@ -8,7 +8,7 @@ public interface IPerson
string TestStatic_GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.Person person) =>
GetFileFullName(storage, personBirthdayFormat, 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) =>
GetPerson(personDisplayDirectoryName, personKey, personBirthday);

View File

@ -1,35 +1,37 @@
using System.Globalization;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IPersonBirthday
{
DateTime TestStatic_GetDefaultValue() =>
PersonBirthday.GetDefaultValue(); // {{1}}SingletonValue
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) =>
GetAge(birthday);
static double? GetAge(Models.PersonBirthday 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) =>
new(new(ticks));
static Models.PersonBirthday GetPersonBirthday(long ticks) =>
new(new(ticks));
string TestStatic_GetFileName(string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
PersonBirthday.GetFileName(personBirthdayFormat, personBirthday);
GetFileName(personBirthdayFormat, 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) =>
GetAge(dateTime, birthday);
@ -41,20 +43,15 @@ public interface IPersonBirthday
static (int, TimeSpan) GetAge(long dateTimeTicks, Models.PersonBirthday 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) =>
GetFormatted(personBirthdayFormat, 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) =>
GetPersonBirthday(personBirthdayFormat, personKey);
static Models.PersonBirthday? GetPersonBirthday(string personBirthdayFormat, string personKey) =>
PersonBirthday.GetPersonBirthday(personBirthdayFormat, personKey);
string TestStatic_GetFormatted(string personBirthdayFormat, long personKey) =>
GetFormatted(personBirthdayFormat, personKey);
static string GetFormatted(string personBirthdayFormat, long personKey) =>
GetFormatted(personBirthdayFormat, GetPersonBirthday(personKey));
bool TestStatic_IsCounterPersonBirthday(Models.PersonBirthday personBirthday) =>
IsCounterPersonBirthday(personBirthday);
@ -64,28 +61,28 @@ public interface IPersonBirthday
Models.PersonBirthday TestStatic_GetNextBirthDate(Properties.IStorage storage) =>
GetNextBirthDate(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) =>
GetTimeSpan(minimumDateTime, isWrongYear: false, personBirthday);
static TimeSpan? GetTimeSpan(DateTime minimumDateTime, Models.PersonBirthday personBirthday) =>
PersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear: false, 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);
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);
Models.PersonBirthday? TestStatic_GetPersonBirthday(string personBirthdayFormat, string personKey) =>
GetPersonBirthday(personBirthdayFormat, personKey);
static Models.PersonBirthday? GetPersonBirthday(string personBirthdayFormat, string personKey) =>
PersonBirthday.GetPersonBirthday(personBirthdayFormat, personKey);
bool TestStatic_DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) =>
DoesBirthDateExits(storage, personBirthday);
static bool DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday 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) =>
GetTimeSpan(minimumDateTime, isWrongYear, 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) =>
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 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)
{
Models.PersonBirthday? result;
DateTime? dateTime = GetDateTime(personBirthdayFormat, personKey);
DateTime? dateTime = IPersonBirthday.GetDateTime(personBirthdayFormat, personKey);
if (dateTime is null)
result = null;
else
@ -29,7 +21,7 @@ internal abstract class PersonBirthday
internal static bool IsCounterPersonBirthday(Models.PersonBirthday personBirthday)
{
bool result;
if (personBirthday.Value.Year < 1900)
if (personBirthday.Value.Year < 1826)
result = true;
else
result = false;
@ -109,7 +101,7 @@ internal abstract class PersonBirthday
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();
string[] files;
@ -124,13 +116,15 @@ internal abstract class PersonBirthday
(personBirthday, personKeyFormatted) = Person.Get(personBirthdayFormat, personDisplayDirectory, personKeyDirectory, birthday);
if (personBirthday is null || personKeyFormatted.Contains('#'))
continue;
if (!IPersonBirthday.IsCounterPersonBirthday(personBirthday) && ((!personKeyDirectory.Contains('#') && (personDisplayDirectoryName.Contains('~') || personDisplayDirectoryName.Contains('#'))) || (personKeyDirectory.Contains('#') && !personDisplayDirectoryName.Contains('#'))))
throw new NotSupportedException();
results.Add(personBirthday);
files = Directory.GetFiles(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
if (files.Any())
continue;
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;
}
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();
long personKey;
string[] segments;
const int zero = 0;
Models.Person person;
string personKeyFormatted;
Models.PersonBirthday? personBirthday;
Models.PersonContainer personContainer;
Models.PersonBirthday[] orderedPersonBirthdays;
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);
orderedPersonBirthdays = personBirthdays.OrderByDescending(l => l.Value.Ticks).ToArray();
personKey = orderedPersonBirthdays[zero].Value.Ticks;
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));
}
return results;
@ -71,7 +63,7 @@ internal abstract class PersonContainer
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;
if (approximateYears is null)
@ -81,7 +73,8 @@ internal abstract class PersonContainer
const int zero = 0;
int? updateApproximateYears;
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)
updateApproximateYears = approximateYears.Value + 1;
else if (timeSpan.TotalDays > 356)
@ -110,7 +103,7 @@ internal abstract class PersonContainer
string[] personKeyDirectories;
string? personDisplayDirectoryName;
Models.PersonContainer personContainer;
Models.PersonBirthday[] personBirthdays;
List<Models.PersonBirthday> personBirthdays;
foreach (string personDisplayDirectory in personDisplayDirectories)
{
personDisplayDirectoryName = Path.GetFileName(personDisplayDirectory);
@ -118,7 +111,7 @@ internal abstract class PersonContainer
continue;
approximateYears = Age.GetApproximateYears(personDisplayDirectoryName, chars);
personKeyDirectories = Directory.GetDirectories(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly);
personBirthdays = PersonBirthday.GetDescendingOrderedPersonBirthdays(personBirthdayFormat, personKeyDirectories, personDisplayDirectory);
personBirthdays = PersonBirthday.GetPersonBirthdays(personBirthdayFormat, personKeyDirectories, personDisplayDirectory, personDisplayDirectoryName);
if (personDisplayDirectoryName.Contains('^'))
{
minusOne = Path.GetDirectoryName(personDisplayDirectory);
@ -129,7 +122,7 @@ internal abstract class PersonContainer
if (changes.Any(l => l is not null))
continue;
if (personBirthdays.Any())
results.AddRange(GetPersonContainersCollections(personBirthdayFormat, facesFileNameExtension, chars, personDisplayDirectory, personDisplayDirectoryName, personKeyDirectories, approximateYears, personBirthdays));
results.AddRange(GetPersonContainersCollections(facesFileNameExtension, chars, personDisplayDirectory, personDisplayDirectoryName, approximateYears, personBirthdays));
else
{
personContainer = GetPersonContainer(facesFileNameExtension, personDisplayDirectory, personDisplayDirectoryName, approximateYears);

View File

@ -435,6 +435,35 @@ public class UnitTestCalculations
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]
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 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 Rename to Match"), Required] public bool? DistanceRenameToMatch { 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 = "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 Digits"), Required] public int? LocationDigits { 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 = "Mapping Default Name"), Required] public string MappingDefaultName { 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));
if (configuration.DistancePixelDistanceTolerance is null)
throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance));
if (configuration.DistanceRenameToMatch is null)
throw new NullReferenceException(nameof(configuration.DistanceRenameToMatch));
if (configuration.FaceDistanceAreaPermilleTolerance is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceAreaPermilleTolerance));
if (configuration.FaceDistanceHiddenImageFactor is null)
@ -132,8 +134,6 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.LocationDigits));
if (configuration.LocationFactor is null)
throw new NullReferenceException(nameof(configuration.LocationFactor));
if (configuration.MapLogicSigma is null)
throw new NullReferenceException(nameof(configuration.MapLogicSigma));
if (configuration.MappingDefaultName is null)
throw new NullReferenceException(nameof(configuration.MappingDefaultName));
if (configuration.MappingSaveNotMapped is null)
@ -223,6 +223,7 @@ public class Configuration
configuration.DistanceFactor.Value,
configuration.DistanceMoveUnableToMatch.Value,
configuration.DistancePixelDistanceTolerance.Value,
configuration.DistanceRenameToMatch.Value,
configuration.FaceDistanceAreaPermilleTolerance.Value,
configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value,
@ -240,7 +241,6 @@ public class Configuration
configuration.LocationConfidenceFactor.Value,
configuration.LocationDigits.Value,
configuration.LocationFactor.Value,
configuration.MapLogicSigma.Value,
configuration.MappedMaxIndex,
configuration.MappingDefaultName,
configuration.MappingSaveNotMapped.Value,

View File

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