Moved more to Map library

This commit is contained in:
2022-08-29 08:45:01 -07:00
parent 674555b4fc
commit c1d30b5bbc
46 changed files with 1631 additions and 697 deletions

View File

@ -38,6 +38,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Text.Json" Version="6.0.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -1,28 +1,34 @@
using System.Diagnostics;
using System.Text.Json;
using View_by_Distance.Property.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Properties;
using WindowsShortcutFactory;
namespace View_by_Distance.Map.Models;
public class MapLogic
{
protected readonly List<double> _SkipCollection;
protected readonly List<(int, string[])> _AllCollection;
protected readonly Dictionary<int, int[]> _KeyValuePairs;
protected readonly Dictionary<int, int[]> _IndicesFromNew;
protected readonly string _DeterministicHashCodeRootDirectory;
protected readonly string _DeterministicHashCodeContentDirectory;
protected readonly Dictionary<int, string[]> _SixCharacterNamedFaceInfo;
protected readonly Dictionary<int, string[]> _DeterministicHashCodeUnknownFaceKeyValuePairs;
protected readonly Dictionary<double, string[]> _DeterministicHashCodeKeyValuePairs;
protected readonly Dictionary<int, string[]> _DeterministicHashCodeUnknownFaceKeyValuePairs;
protected readonly Dictionary<double, string[]> _IncorrectDeterministicHashCodeKeyValuePairs;
protected readonly Dictionary<string, (string DisplayDirectoryName, int? ApproximateYears, string Key, PersonBirthday[] PersonBirthdays)> _PeopleKeyValuePairs;
public Dictionary<int, int[]> KeyValuePairs => _KeyValuePairs;
public Dictionary<int, int[]> IndicesFromNew => _IndicesFromNew;
private readonly Serilog.ILogger? _Log;
private readonly string _OutputExtension;
private readonly Configuration _Configuration;
public MapLogic(int maxDegreeOfParallelism, Configuration configuration)
public MapLogic(int maxDegreeOfParallelism, Configuration configuration, string outputExtension, Dictionary<string, Person> personKeyValuePairs)
{
_AllCollection = new();
_Configuration = configuration;
@ -33,17 +39,20 @@ public class MapLogic
string json;
string[] files;
string fullPath;
_OutputExtension = outputExtension;
List<double> skipCollection = new();
Dictionary<int, int[]>? keyValuePairs;
string deterministicHashCodeRootDirectory;
List<KeyValuePair<int, int[]>>? collection;
string deterministicHashCodeContentDirectory;
Dictionary<int, int[]> indicesFromNew = new();
Dictionary<int, string[]>? sixCharacterNamedFaceInfo;
Dictionary<double, string[]> deterministicHashCodeKeyValuePairs = new();
Dictionary<double, string[]> incorrectDeterministicHashCodeKeyValuePairs = new();
string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory);
Dictionary<string, (string, int?, string, PersonBirthday[])> peopleKeyValuePairs = new();
if (string.IsNullOrEmpty(rootDirectoryParent))
throw new NullReferenceException(nameof(rootDirectoryParent));
files = Directory.GetFiles(rootDirectoryParent, "*DeterministicHashCode*.json", SearchOption.TopDirectoryOnly);
files = Directory.GetFiles(rootDirectoryParent, "DeterministicHashCode*.json", SearchOption.TopDirectoryOnly);
if (files.Length != 1)
deterministicHashCodeUnknownFaceKeyValuePairs = new();
else
@ -53,15 +62,11 @@ public class MapLogic
if (deterministicHashCodeUnknownFaceKeyValuePairs is null)
throw new NullReferenceException(nameof(deterministicHashCodeUnknownFaceKeyValuePairs));
}
string[] directories = Directory.GetDirectories(rootDirectoryParent, "*DeterministicHashCode*", SearchOption.TopDirectoryOnly);
string[] directories = Directory.GetDirectories(rootDirectoryParent, "DeterministicHashCode", SearchOption.TopDirectoryOnly);
if (!directories.Any())
deterministicHashCodeRootDirectory = string.Empty;
deterministicHashCodeContentDirectory = string.Empty;
else
{
Dictionary<int, List<Shared.Models.Face>> faces = new();
deterministicHashCodeRootDirectory = directories[0];
SetKeyValuePairs(deterministicHashCodeRootDirectory, deterministicHashCodeKeyValuePairs, incorrectDeterministicHashCodeKeyValuePairs, faces);
}
deterministicHashCodeContentDirectory = Stateless.ByDeterministicHashCode.SetByRef(_OutputExtension, personKeyValuePairs, skipCollection, peopleKeyValuePairs, deterministicHashCodeUnknownFaceKeyValuePairs, deterministicHashCodeKeyValuePairs, incorrectDeterministicHashCodeKeyValuePairs, directories[0]);
if (!deterministicHashCodeUnknownFaceKeyValuePairs.Any())
sixCharacterNamedFaceInfo = new();
else
@ -77,7 +82,7 @@ public class MapLogic
throw new NullReferenceException(nameof(sixCharacterNamedFaceInfo));
}
}
files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly);
files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs-6*.json", SearchOption.TopDirectoryOnly);
if (files.Length != 1)
keyValuePairs = new();
else
@ -107,116 +112,80 @@ public class MapLogic
}
_KeyValuePairs = keyValuePairs;
_IndicesFromNew = indicesFromNew;
_SkipCollection = skipCollection;
_PeopleKeyValuePairs = peopleKeyValuePairs;
_SixCharacterNamedFaceInfo = sixCharacterNamedFaceInfo;
_DeterministicHashCodeRootDirectory = deterministicHashCodeRootDirectory;
_DeterministicHashCodeKeyValuePairs = deterministicHashCodeKeyValuePairs;
_DeterministicHashCodeContentDirectory = deterministicHashCodeContentDirectory;
_IncorrectDeterministicHashCodeKeyValuePairs = incorrectDeterministicHashCodeKeyValuePairs;
_DeterministicHashCodeUnknownFaceKeyValuePairs = deterministicHashCodeUnknownFaceKeyValuePairs;
}
public bool IsIncorrect(double deterministicHashCodeKey, string personKey) => _DeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey) && _IncorrectDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey].Contains(personKey);
public bool Skip(double deterministicHashCodeKey) => _SkipCollection.Contains(deterministicHashCodeKey);
private void SetKeyValuePairs(string deterministicHashCodeRootDirectory, List<(string, double)> named, List<(string, double)> incorrect, Dictionary<int, List<Shared.Models.Face>> keyValuePairs)
public void SaveShortcuts(string[] juliePhares, string dResultsFullGroupDirectory, long ticks, List<Item> items)
{
string[] files;
string personKey;
string[] yearDirectories;
string ticksDirectoryName;
string[] personKeyDirectories;
string[] personNameDirectories;
string[] personNameLinkDirectories;
double? reversedDeterministicHashCodeKey;
bool keyValuePairsAny = keyValuePairs.Any();
string[] ticksDirectories = Directory.GetDirectories(deterministicHashCodeRootDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string ticksDirectory in ticksDirectories)
string fileName;
string fullName;
DateTime? minimumDateTime;
WindowsShortcut windowsShortcut;
(string DisplayDirectoryName, int? ApproximateYears, string Key, PersonBirthday[] _) person;
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, $"({ticks})");
List<(Item, (string, Face?, (string, string, string, string))[])> collections = GetCollection(items, dFacesContentDirectory);
foreach ((Item item, (string personKey, Face? _, (string, string, string, string))[] collection) in collections)
{
ticksDirectoryName = Path.GetFileName(ticksDirectory);
if (ticksDirectoryName.Length < 3 || ticksDirectoryName[0] != '(' || ticksDirectoryName[^1] != ')')
if (collection.Length != 1)
continue;
personKeyDirectories = Directory.GetDirectories(ticksDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personKeyDirectory in personKeyDirectories)
foreach ((string personKey, Face? _, (string directory, string copyDirectory, string copyFileName, string shortcutFileName)) in collection)
{
personKey = Path.GetFileName(personKeyDirectory);
if (personKey == nameof(Shared.Models.Closest))
throw new Exception($"Move personKey directories up one from {nameof(Shared.Models.Closest)} and delete {nameof(Shared.Models.Closest)} directory!");
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string yearDirectory in yearDirectories)
if (string.IsNullOrEmpty(personKey))
continue;
if (item.Property?.Id is null || item.ImageFileHolder is null || item.ResizedFileHolder is null)
continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
if (minimumDateTime is null)
continue;
if (!Directory.Exists(directory))
{
files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly);
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
File.Delete(file);
foreach (string personNameDirectory in personNameDirectories)
_ = Directory.CreateDirectory(directory);
if (!string.IsNullOrEmpty(personKey) && _PeopleKeyValuePairs.ContainsKey(personKey))
{
files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
personNameLinkDirectories = Directory.GetDirectories(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
if (file.EndsWith(".lnk") || file.EndsWith(".json"))
continue;
reversedDeterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetReversedDeterministicHashCodeKey(keyValuePairsAny, keyValuePairs, file);
if (reversedDeterministicHashCodeKey is null)
continue;
named.Add(new(personKey, reversedDeterministicHashCodeKey.Value));
}
foreach (string personNameLinkDirectory in personNameLinkDirectories)
{
files = Directory.GetFiles(personNameLinkDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
if (!file.EndsWith(".lnk"))
continue;
File.Delete(file);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personNameLinkDirectory);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personNameDirectory);
person = _PeopleKeyValuePairs[personKey];
fullName = string.Concat(person.DisplayDirectoryName, ".txt");
File.WriteAllText(Path.Combine(directory, fullName), string.Empty);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(yearDirectory);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personKeyDirectory);
if (juliePhares.Contains(personKey) && !string.IsNullOrEmpty(copyDirectory))
{
if (!Directory.Exists(copyDirectory))
_ = Directory.CreateDirectory(copyDirectory);
fileName = Path.Combine(copyDirectory, $"{item.Property.Id.Value}{item.ResizedFileHolder.ExtensionLowered}");
if (!File.Exists(fileName))
File.Copy(item.ResizedFileHolder.FullName, fileName);
}
fileName = Path.Combine(directory, $"{item.Property.Id.Value}.lnk");
if (File.Exists(fileName))
continue;
windowsShortcut = new() { Path = item.ImageFileHolder.FullName };
windowsShortcut.Save(fileName);
windowsShortcut.Dispose();
if (!File.Exists(fileName))
continue;
File.SetLastWriteTime(fileName, minimumDateTime.Value);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(ticksDirectory);
}
}
private void SetKeyValuePairs(string deterministicHashCodeRootDirectory, Dictionary<double, string[]> deterministicHashCodeKeyValuePairs, Dictionary<double, string[]> incorrectDeterministicHashCodeKeyValuePairs, Dictionary<int, List<Shared.Models.Face>> keyValuePairs)
public void UseKeyValuePairsSaveFaceEncoding(List<Container> containers)
{
Dictionary<double, List<string>> namedKeyValuePairs = new();
Dictionary<double, List<string>> incorrectKeyValuePairs = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> named = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> incorrect = new();
SetKeyValuePairs(deterministicHashCodeRootDirectory, named, incorrect, keyValuePairs);
named = (from l in named orderby l.IdAndNormalizedPixelPercentage select l).ToList();
incorrect = (from l in incorrect orderby l.IdAndNormalizedPixelPercentage select l).ToList();
foreach ((string personKey, double idAndNormalizedPixelPercentage) in named)
if (!string.IsNullOrEmpty(_DeterministicHashCodeContentDirectory))
{
if (!namedKeyValuePairs.ContainsKey(idAndNormalizedPixelPercentage))
namedKeyValuePairs.Add(idAndNormalizedPixelPercentage, new());
namedKeyValuePairs[idAndNormalizedPixelPercentage].Add(personKey);
}
foreach ((string personKey, double idAndNormalizedPixelPercentage) in incorrect)
{
if (!incorrectKeyValuePairs.ContainsKey(idAndNormalizedPixelPercentage))
incorrectKeyValuePairs.Add(idAndNormalizedPixelPercentage, new());
incorrectKeyValuePairs[idAndNormalizedPixelPercentage].Add(personKey);
}
foreach (KeyValuePair<double, List<string>> keyValuePair in namedKeyValuePairs)
deterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray());
foreach (KeyValuePair<double, List<string>> keyValuePair in incorrectKeyValuePairs)
incorrectDeterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray());
}
public void UseKeyValuePairsSaveFaceEncoding(List<Shared.Models.Container> containers)
{
if (!string.IsNullOrEmpty(_DeterministicHashCodeRootDirectory))
{
Dictionary<int, List<Shared.Models.Face>> keyValuePairs = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> named = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> incorrect = new();
foreach (Shared.Models.Container container in containers)
Dictionary<int, List<Face>> keyValuePairs = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> deterministicHashCodeCollection = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> incorrectDeterministicHashCodeCollection = new();
foreach (Container container in containers)
{
foreach (Shared.Models.Item item in container.Items)
foreach (Item item in container.Items)
{
if (item.ImageFileHolder is null || item.Property?.Id is null || !item.Faces.Any())
continue;
@ -229,7 +198,7 @@ public class MapLogic
keyValuePairs.Add(item.Property.Id.Value, item.Faces);
}
}
SetKeyValuePairs(_DeterministicHashCodeRootDirectory, named, incorrect, keyValuePairs);
Stateless.ByDeterministicHashCode.SetKeyValuePairs(_DeterministicHashCodeContentDirectory, deterministicHashCodeCollection, incorrectDeterministicHashCodeCollection, keyValuePairs);
}
}
@ -250,12 +219,12 @@ public class MapLogic
return result;
}
public void AddToMapLogicAllCollection(Shared.Models.Item[] filteredItems)
public void AddToMapLogicAllCollection(Item[] filteredItems)
{
if (_SixCharacterNamedFaceInfo.Any())
{
string[] keys;
Shared.Models.Item item;
Item item;
for (int i = 0; i < filteredItems.Length; i++)
{
item = filteredItems[i];
@ -301,61 +270,91 @@ public class MapLogic
}
}
public void AddToNamed(List<Shared.Models.Item> items)
public void AddToMapping(List<Item> items)
{
bool? isWrongYear;
DateTime minimumDateTime;
Mapping mapping;
string personKey;
int? approximateYears;
string displayDirectoryName;
PersonBirthday? personBirthday;
double deterministicHashCodeKey;
List<string> personKeys = new();
Shared.Models.PersonBirthday? personBirthday;
foreach (Shared.Models.Item item in items)
(string DisplayDirectoryName, int? ApproximateYears, string Key, PersonBirthday[] PersonBirthdays) person;
foreach (Item item in items)
{
if (item.ImageFileHolder is null)
continue;
if (item.Property?.Id is null || item.ResizedFileHolder is null)
continue;
foreach (Shared.Models.Face face in item.Faces)
foreach (Face face in item.Faces)
{
personKeys.Clear();
if (face.LocationIndex is null)
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
continue;
deterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetDeterministicHashCodeKey(item, face);
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
if (!_DeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey))
continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
personKeys.AddRange(_DeterministicHashCodeKeyValuePairs[deterministicHashCodeKey]);
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
for (int i = 0; i < personKeys.Count; i++)
{
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKeys[i]);
if (_PeopleKeyValuePairs.ContainsKey(personKeys[i]))
{
person = _PeopleKeyValuePairs[personKeys[i]];
personBirthday = person.PersonBirthdays[0];
approximateYears = person.ApproximateYears;
displayDirectoryName = person.DisplayDirectoryName;
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
}
else
{
approximateYears = null;
personKey = personKeys[i];
displayDirectoryName = "_ _ _";
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
}
if (personBirthday is null)
continue;
if (face.Location is null)
continue;
item.Named.Add(new(isWrongYear, minimumDateTime, face.Location.NormalizedPixelPercentage, personBirthday));
mapping = new(approximateYears, displayDirectoryName, face.Location.NormalizedPixelPercentage, personBirthday, personKey);
item.Mapping.Add(mapping);
}
}
if (!personKeys.Any())
if (Shared.Models.Stateless.IMapping.UseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping && !personKeys.Any())
{
if (!_DeterministicHashCodeUnknownFaceKeyValuePairs.ContainsKey(item.Property.Id.Value))
continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
personKeys.AddRange(_DeterministicHashCodeUnknownFaceKeyValuePairs[item.Property.Id.Value]);
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
for (int i = 0; i < personKeys.Count; i++)
{
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKeys[i]);
if (_PeopleKeyValuePairs.ContainsKey(personKeys[i]))
{
person = _PeopleKeyValuePairs[personKeys[i]];
personBirthday = person.PersonBirthdays[0];
approximateYears = person.ApproximateYears;
displayDirectoryName = person.DisplayDirectoryName;
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
}
else
{
approximateYears = null;
personKey = personKeys[i];
displayDirectoryName = "_ _ _";
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
}
if (personBirthday is null)
continue;
item.Named.Add(new(isWrongYear, minimumDateTime, personBirthday));
mapping = new(approximateYears, displayDirectoryName, personBirthday, personKey);
item.Mapping.Add(mapping);
}
}
}
}
public List<(Shared.Models.Item, (string, Shared.Models.Face?, (string, string, string, string))[])> GetCollection(List<Shared.Models.Item> items, string dFacesContentDirectory)
public List<(Item, (string, Face?, (string, string, string, string))[])> GetCollection(List<Item> items, string dFacesContentDirectory)
{
List<(Shared.Models.Item, (string, Shared.Models.Face?, (string, string, string, string))[])> results = new();
List<(Item, (string, Face?, (string, string, string, string))[])> results = new();
int years;
Face face;
Item item;
string[] keys;
string directory;
string personKey;
@ -366,15 +365,14 @@ public class MapLogic
string copyDirectory;
string? relativePath;
string isWrongYearFlag;
Shared.Models.Face face;
string shortcutFileName;
Shared.Models.Item item;
string subDirectoryName;
List<int> indices = new();
DateTime? minimumDateTime;
List<Shared.Models.Face> faceCollection;
Shared.Models.PersonBirthday? personBirthday;
List<(string, Shared.Models.Face?, (string, string, string, string))> collection;
DateTime dateTime = DateTime.Now;
List<Face> faceCollection;
PersonBirthday? personBirthday;
List<(string, Face?, (string, string, string, string))> collection;
for (int i = 0; i < items.Count; i++)
{
indices.Clear();
@ -433,7 +431,10 @@ public class MapLogic
if (timeSpan.Value.Ticks < 0)
subDirectoryName = "!---";
else
subDirectoryName = $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}";
{
(years, _) = Shared.Models.Stateless.Methods.IPersonBirthday.GetAge(dateTime, personBirthday);
subDirectoryName = $"^{years:000}";
}
}
face = faceCollection[zero];
directory = Path.Combine(dFacesContentDirectory, "Shortcuts", personKey, subDirectoryName);
@ -457,71 +458,304 @@ public class MapLogic
return results;
}
public static string GetKey(DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday)
public void AddToClosest(int maxDegreeOfParallelism, string argZero, List<Container> containers)
{
string result;
string personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
TimeSpan? timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0)
result = string.Concat(personKey, "!---");
else if (timeSpan.HasValue)
result = string.Concat(personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}");
else
{
string isWrongYearFlag = Shared.Models.Stateless.Methods.IItem.GetWrongYearFlag(isWrongYear);
result = string.Concat(personKey, $"{isWrongYearFlag}{minimumDateTime:yyyy}");
}
return result;
}
public static string GetDirectory(string directory, string subDirectory, DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday, string personKey)
{
string result;
TimeSpan? timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0)
result = Path.Combine(directory, subDirectory, personKey, "!---");
else if (timeSpan.HasValue)
result = Path.Combine(directory, subDirectory, personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}");
else
{
string isWrongYearFlag = Shared.Models.Stateless.Methods.IItem.GetWrongYearFlag(isWrongYear);
result = Path.Combine(directory, subDirectory, personKey, $"{isWrongYearFlag}{minimumDateTime:yyyy}");
}
return result;
}
public static Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, Shared.Models.Face)>> GetKeyValuePairs(string argZero, List<Shared.Models.Container> containers)
{
Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, Shared.Models.Face)>> results = new();
string key;
foreach (Shared.Models.Container container in containers)
string dateKey;
Closest closest;
DateTime minimumDateTime;
Closest[] closestCollection;
double deterministicHashCodeKey;
DateTime dateTime = DateTime.Now;
Dictionary<string, int> keyValuePairs = new();
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (!container.SourceDirectory.StartsWith(argZero))
continue;
foreach (Shared.Models.Item item in container.Items)
foreach (Item item in container.Items)
{
if (item.ImageFileHolder is null || item.Property is null || !item.Named.Any())
if (item.ImageFileHolder is null || item.Property is null)
continue;
foreach (Shared.Models.Named named in item.Named)
foreach (Face face in item.Faces)
{
if (named.NormalizedPixelPercentage is null && (item.Named.Count != 1 || item.Faces.Count != 1))
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
continue;
foreach (Shared.Models.Face face in item.Faces)
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
if (_DeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey))
continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
closestCollection = Shared.Models.Stateless.Methods.IClosest.GetCollection(face, minimumDateTime, face.FaceDistances);
face.FaceDistances.Clear();
for (int j = 0; j < closestCollection.Length; j++)
{
closest = closestCollection[j];
if (_IncorrectDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey) && _IncorrectDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey].Contains(closest.Mapping.PersonKey))
continue;
dateKey = Stateless.MapLogic.GetDateKey(dateTime, closest.Mapping, closest.MinimumDateTime, closest.IsWrongYear);
key = string.Concat(closest.Mapping.PersonKey, dateKey);
if (!keyValuePairs.ContainsKey(key))
keyValuePairs.Add(key, 0);
else if (keyValuePairs[key] > Shared.Models.Stateless.IClosest.MaximumPer)
continue;
keyValuePairs[key] += 1;
item.Closest.Add(closest);
break;
}
}
}
}
}
private List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json)> GetClosest(string argZero, List<Container> containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory)
{
List<(IFileHolder?, string, FileInfo?, string, string, string)> results = new();
Closest? match;
string dateKey;
string checkFile;
string directory;
string shortcutFile;
FileInfo faceFileInfo;
string? directoryName;
string facesDirectory;
string personDirectory;
List<int> used = new();
FileInfo landmarkFileInfo;
string landmarksDirectory;
double deterministicHashCodeKey;
DateTime dateTime = DateTime.Now;
const string facePopulatedKey = nameof(Closest);
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (!container.SourceDirectory.StartsWith(argZero))
continue;
foreach (Item item in container.Items)
{
used.Clear();
if (item.ImageFileHolder is null || item.Property?.Id is null || item.ResizedFileHolder is null)
continue;
if (!item.Closest.Any())
continue;
directoryName = Path.GetDirectoryName(item.RelativePath);
if (directoryName is null)
throw new Exception();
foreach (Face face in item.Faces)
{
match = null;
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
continue;
foreach (Closest closest in item.Closest)
{
if (closest.NormalizedPixelPercentage != face.Location.NormalizedPixelPercentage.Value)
continue;
match = closest;
break;
}
if (match is null)
continue;
foreach (Mapping mapping in item.Mapping)
{
if (mapping.NormalizedPixelPercentage is null || mapping.NormalizedPixelPercentage.Value != face.Location.NormalizedPixelPercentage.Value)
continue;
throw new Exception();
}
dateKey = Stateless.MapLogic.GetDateKey(dateTime, match.Mapping, match.MinimumDateTime, match.IsWrongYear);
directory = Path.Combine(zPropertyHolderContentDirectory, facePopulatedKey, match.Mapping.PersonKey, dateKey);
personDirectory = Path.Combine(directory, match.Mapping.DisplayDirectoryName[..1], "lnk");
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
landmarksDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
landmarkFileInfo = new(Path.Combine(landmarksDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.gif"));
if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty;
else
shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk");
results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile, string.Empty));
personDirectory = Path.Combine(directory, match.Mapping.DisplayDirectoryName[..1], "lnk", match.Mapping.DisplayDirectoryName);
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
used.Add(face.Location.NormalizedPixelPercentage.Value);
}
foreach (Closest closest in item.Closest)
{
if (used.Contains(closest.NormalizedPixelPercentage))
continue;
dateKey = Stateless.MapLogic.GetDateKey(dateTime, closest.Mapping, closest.MinimumDateTime, closest.IsWrongYear);
directory = Path.Combine(zPropertyHolderContentDirectory, facePopulatedKey, closest.Mapping.PersonKey, dateKey);
personDirectory = Path.Combine(directory, closest.Mapping.DisplayDirectoryName, "lnk");
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
landmarksDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, closest);
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
landmarkFileInfo = new(Path.Combine(landmarksDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.gif"));
if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty;
else
shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk");
results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile, string.Empty));
personDirectory = Path.Combine(directory, closest.Mapping.DisplayDirectoryName[..1], "lnk", closest.Mapping.DisplayDirectoryName);
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
used.Add(closest.NormalizedPixelPercentage);
}
}
}
return results;
}
private List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json)> GetMapping(string argZero, List<Container> containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory)
{
List<(IFileHolder?, string, FileInfo?, string, string, string)> results = new();
string key;
string json;
string dateKey;
Mapping? match;
string checkFile;
string directory;
bool? isWrongYear;
string shortcutFile;
FileInfo faceFileInfo;
string? directoryName;
string facesDirectory;
string personDirectory;
List<int> used = new();
DateTime minimumDateTime;
FileInfo landmarkFileInfo;
string landmarksDirectory;
double deterministicHashCodeKey;
DateTime dateTime = DateTime.Now;
const string facePopulatedKey = nameof(Mapping);
bool deterministicHashCodeKeyValuePairsAny = _DeterministicHashCodeKeyValuePairs.Any();
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (!container.SourceDirectory.StartsWith(argZero))
continue;
foreach (Item item in container.Items)
{
used.Clear();
if (item.ImageFileHolder is null || item.Property?.Id is null || item.ResizedFileHolder is null)
continue;
directoryName = Path.GetDirectoryName(item.RelativePath);
if (directoryName is null)
throw new Exception();
foreach (Face face in item.Faces)
{
match = null;
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
continue;
foreach (Mapping mapping in item.Mapping)
{
if (mapping.NormalizedPixelPercentage is null || mapping.NormalizedPixelPercentage.Value != face.Location.NormalizedPixelPercentage.Value)
continue;
match = mapping;
break;
}
if (match is null)
continue;
foreach (Closest closest in item.Closest)
{
if (closest.NormalizedPixelPercentage != face.Location.NormalizedPixelPercentage.Value)
continue;
throw new Exception();
}
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
dateKey = Stateless.MapLogic.GetDateKey(dateTime, match, minimumDateTime, isWrongYear);
key = string.Concat(match.PersonKey, dateKey);
if (match.Filtered is null)
directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}Null", match.PersonKey, dateKey);
else if (!match.Filtered.Value)
directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}Okay", match.PersonKey, dateKey);
else
directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}OutOfControl", match.PersonKey, dateKey);
personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk");
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
landmarksDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
landmarkFileInfo = new(Path.Combine(landmarksDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.gif"));
if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty;
else
shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk");
results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile, string.Empty));
if (!string.IsNullOrEmpty(checkFile) && Shared.Models.Stateless.IMapping.SaveFaceEncoding)
{
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.json");
json = JsonSerializer.Serialize(face.FaceEncoding);
results.Add(new(null, directory, null, checkFile, string.Empty, json));
}
personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk", match.DisplayDirectoryName);
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
used.Add(face.Location.NormalizedPixelPercentage.Value);
}
if (deterministicHashCodeKeyValuePairsAny && Shared.Models.Stateless.IMapping.UseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping)
{
foreach (Face face in item.Faces)
{
match = null;
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
continue;
if (named.PersonBirthday is null)
if (used.Contains(face.Location.NormalizedPixelPercentage.Value))
continue;
if (named.NormalizedPixelPercentage.HasValue && named.NormalizedPixelPercentage.Value != face.Location?.NormalizedPixelPercentage)
continue;
key = GetKey(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday);
if (!results.ContainsKey(key))
results.Add(key, new());
results[key].Add(new(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday, face));
if (named.NormalizedPixelPercentage is null)
// if (item.Faces.Count != 1 || item.Mapping.Count != 1)
// continue;
foreach (Mapping mapping in item.Mapping)
{
if (mapping.NormalizedPixelPercentage is not null)
continue;
match = mapping;
break;
}
if (match is null)
continue;
foreach (Closest closest in item.Closest)
{
if (closest.NormalizedPixelPercentage != face.Location.NormalizedPixelPercentage.Value)
continue;
throw new Exception();
}
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
dateKey = Stateless.MapLogic.GetDateKey(dateTime, match, minimumDateTime, isWrongYear);
if (match.Filtered is null)
directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}WithButNull", match.PersonKey, dateKey);
else if (!match.Filtered.Value)
directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}WithAndOkay", match.PersonKey, dateKey);
else
directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}WithButOutOfControl", match.PersonKey, dateKey);
personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk");
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
landmarksDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
landmarkFileInfo = new(Path.Combine(landmarksDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.gif"));
if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty;
else
shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk");
results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile, string.Empty));
if (!string.IsNullOrEmpty(checkFile) && Shared.Models.Stateless.IMapping.SaveFaceEncoding)
{
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.json");
json = JsonSerializer.Serialize(face.FaceEncoding);
results.Add(new(null, directory, null, checkFile, string.Empty, json));
}
personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk", match.DisplayDirectoryName);
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
used.Add(face.Location.NormalizedPixelPercentage.Value);
}
}
}
@ -529,14 +763,63 @@ public class MapLogic
return results;
}
public static (bool?, string[]) IsWrongYear(Shared.Models.Item item)
private static void Save(List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json)> collection)
{
(bool?, string[]) result;
if (item.Property is null || item.ImageFileHolder is null)
throw new NullReferenceException();
DateTime? minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
result = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
return result;
WindowsShortcut windowsShortcut;
string[] directories = (from l in collection select l.directory).Distinct().ToArray();
foreach (string directory in directories)
{
if (string.IsNullOrEmpty(directory))
continue;
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
}
foreach ((IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json) in collection)
{
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null || faceFileInfo is null || !string.IsNullOrEmpty(json))
continue;
if (File.Exists(checkFile))
continue;
if (faceFileInfo.Directory is not null && faceFileInfo.Directory.Exists && faceFileInfo.Exists)
File.Copy(faceFileInfo.FullName, checkFile);
else
File.Copy(resizedFileHolder.FullName, checkFile);
}
foreach ((IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json) in collection)
{
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is not null || faceFileInfo is not null || string.IsNullOrEmpty(json))
continue;
if (File.Exists(checkFile))
continue;
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
}
foreach ((IFileHolder? resizedFileHolder, string directory, FileInfo? _, string checkFile, string shortcutFile, string json) in collection)
{
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null)
continue;
if (string.IsNullOrEmpty(shortcutFile) || !resizedFileHolder.Exists)
continue;
try
{
windowsShortcut = new() { Path = resizedFileHolder.FullName };
windowsShortcut.Save(shortcutFile);
windowsShortcut.Dispose();
}
catch (Exception)
{ }
}
}
public void SaveClosest(string argZero, List<Container> containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory)
{
List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json)> collection = GetClosest(argZero, containers, dFacesContentDirectory, d2ResultsFullGroupDirectory, zPropertyHolderContentDirectory);
Save(collection);
}
public void SaveMapping(string argZero, List<Container> containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory)
{
List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json)> collection = GetMapping(argZero, containers, dFacesContentDirectory, d2ResultsFullGroupDirectory, zPropertyHolderContentDirectory);
Save(collection);
}
}

View File

@ -0,0 +1,18 @@
namespace View_by_Distance.Map.Models.Stateless;
public interface IMapLogic
{ // ...
(bool?, string[]) TestStatic_IsWrongYear(Shared.Models.Item item);
static (bool?, string[]) IsWrongYear(Shared.Models.Item item) =>
MapLogic.IsWrongYear(item);
string TestStatic_GetDateKey(DateTime dateTime, Shared.Models.Mapping mapping, DateTime minimumDateTime, bool? isWrongYear);
static string GetDateKey(DateTime dateTime, Shared.Models.Mapping mapping, DateTime minimumDateTime, bool? isWrongYear) =>
MapLogic.GetDateKey(dateTime, mapping, minimumDateTime, isWrongYear);
Dictionary<string, List<Shared.Models.MappingContainer>> TestStatic_GetKeyValuePairs(string[] ignoreRelativePaths, string argZero, List<Shared.Models.Container> containers);
static Dictionary<string, List<Shared.Models.MappingContainer>> GetKeyValuePairs(string[] ignoreRelativePaths, string argZero, List<Shared.Models.Container> containers) =>
MapLogic.GetKeyValuePairs(ignoreRelativePaths, argZero, containers);
}

View File

@ -0,0 +1,93 @@
using View_by_Distance.Shared.Models;
namespace View_by_Distance.Map.Models.Stateless;
internal abstract class MapLogic
{
internal static string GetDateKey(DateTime dateTime, Mapping mapping, DateTime minimumDateTime, bool? isWrongYear)
{
int years;
string result;
TimeSpan? timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, mapping.PersonBirthday);
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0)
result = "!---";
else if (timeSpan.HasValue)
{
(years, _) = Shared.Models.Stateless.Methods.IPersonBirthday.GetAge(minimumDateTime, mapping.PersonBirthday);
result = $"^{years:000}";
}
else if (mapping.ApproximateYears.HasValue)
{
(years, _) = Shared.Models.Stateless.Methods.IAge.GetAge(minimumDateTime, dateTime.AddYears(-mapping.ApproximateYears.Value));
result = $"~{years:000}";
}
else
{
string isWrongYearFlag = Shared.Models.Stateless.Methods.IItem.GetWrongYearFlag(isWrongYear);
result = $"{isWrongYearFlag}{minimumDateTime:yyyy}";
}
return result;
}
internal static Dictionary<string, List<MappingContainer>> GetKeyValuePairs(string[] ignoreRelativePaths, string argZero, List<Container> containers)
{
Dictionary<string, List<MappingContainer>> results = new();
string key;
string dateKey;
bool? isWrongYear;
DateTime minimumDateTime;
DateTime dateTime = DateTime.Now;
MappingContainer mappingContainer;
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (!container.SourceDirectory.StartsWith(argZero))
continue;
if (ignoreRelativePaths.Contains(Path.GetFileName(container.SourceDirectory)))
continue;
foreach (Item item in container.Items)
{
if (item.ImageFileHolder is null || item.Property?.Id is null || !item.Mapping.Any())
continue;
foreach (Face face in item.Faces)
{
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
continue;
foreach (Mapping mapping in item.Mapping)
{
if (mapping.PersonBirthday is null)
continue;
if (mapping.NormalizedPixelPercentage.HasValue && mapping.NormalizedPixelPercentage.Value != face.Location.NormalizedPixelPercentage.Value)
continue;
// if (named.NormalizedPixelPercentage is null && (Shared.Models.Stateless.INamed.OnlyUseNamedWithNormalizedPixelPercentagePopulatedForGetKeyValuePairs || item.Named.Count != 1 || item.Faces.Count != 1))
// continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
dateKey = GetDateKey(dateTime, mapping, minimumDateTime, isWrongYear);
key = string.Concat(mapping.PersonKey, dateKey);
if (!results.ContainsKey(key))
results.Add(key, new());
mappingContainer = new(face, item.Property.Id.Value, isWrongYear, key, mapping, minimumDateTime);
results[key].Add(mappingContainer);
// if (named.NormalizedPixelPercentage is null)
// break;
}
}
}
}
return results;
}
internal static (bool?, string[]) IsWrongYear(Item item)
{
(bool?, string[]) result;
if (item.Property is null || item.ImageFileHolder is null)
throw new NullReferenceException();
DateTime? minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
result = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
return result;
}
}

View File

@ -0,0 +1,220 @@
using System.Globalization;
using System.Text.Json;
using View_by_Distance.Shared.Models;
namespace View_by_Distance.Map.Models.Stateless;
public class ByDeterministicHashCode
{
private static void SetOther(string outputExtension, Dictionary<string, Person> personKeyValuePairs, string deterministicHashCodePeopleDirectory, List<double> skipCollection, List<(string, int?, string, PersonBirthday[])> peopleCollection)
{
string json;
string personKey;
string[] segments;
int? approximateYears;
string groupDirectoryName;
string personKeyJsonFileName;
string[] personKeyDirectories;
string personKeyJsonDirectory;
PersonBirthday? personBirthday;
string[] personDisplayDirectories;
string convertedPersonKeyDirectory;
string? personDisplayDirectoryName;
List<PersonBirthday> personBirthdays;
string[] groupDirectories = Directory.GetDirectories(deterministicHashCodePeopleDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string groupDirectory in groupDirectories)
{
groupDirectoryName = Path.GetFileName(groupDirectory);
if (groupDirectoryName[0] == '!')
{
skipCollection.AddRange(from l in Directory.GetFiles(groupDirectory, $"*{outputExtension}", SearchOption.AllDirectories) select double.Parse(Path.GetFileNameWithoutExtension(l)));
continue;
}
else if (groupDirectoryName[0] is not '_' and not '~' and not '^')
continue;
skipCollection.AddRange(from l in Directory.GetFiles(groupDirectory, $"*{outputExtension}", SearchOption.AllDirectories) select double.Parse(Path.GetFileNameWithoutExtension(l)));
personDisplayDirectories = Directory.GetDirectories(groupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personDisplayDirectory in personDisplayDirectories)
{
personBirthdays = new();
personDisplayDirectoryName = Path.GetFileName(personDisplayDirectory);
if (string.IsNullOrEmpty(personDisplayDirectoryName))
continue;
if (groupDirectoryName[0] != '~')
approximateYears = null;
else
{
segments = personDisplayDirectoryName.Split('~');
if (segments.Length == 1 || !int.TryParse(segments[1].Split('-')[0], out int years))
approximateYears = null;
else
approximateYears = years;
}
personKeyDirectories = Directory.GetDirectories(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personKeyDirectory in personKeyDirectories)
{
personKey = Path.GetFileName(personKeyDirectory);
if (!DateTime.TryParseExact(personKey, "MM.dd.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime birthday))
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
else
{
personBirthday = new PersonBirthday(birthday);
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
convertedPersonKeyDirectory = Path.Combine(personDisplayDirectory, personKey);
if (!Directory.Exists(convertedPersonKeyDirectory))
Directory.Move(personKeyDirectory, convertedPersonKeyDirectory);
}
if (personBirthday is null)
continue;
personBirthdays.Add(personBirthday);
}
foreach (string personKeyDirectory in personKeyDirectories)
{
personKey = Path.GetFileName(personKeyDirectory);
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
if (personBirthday is null)
continue;
if (personKeyValuePairs.ContainsKey(personKey))
{
personKeyJsonDirectory = Path.Combine(personDisplayDirectory, personKey);
if (!Directory.Exists(personKeyJsonDirectory))
Directory.Move(personKeyDirectory, personKeyJsonDirectory);
personKeyJsonFileName = Path.Combine(personKeyJsonDirectory, $"{personKey}.json");
json = JsonSerializer.Serialize(personKeyValuePairs[personKey], new JsonSerializerOptions() { WriteIndented = true });
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(personKeyJsonFileName, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
}
peopleCollection.Add(new(personDisplayDirectoryName, approximateYears, personKey, personBirthdays.OrderByDescending(l => l.Value).ToArray()));
}
}
}
}
internal static void SetKeyValuePairs(string deterministicHashCodeContentDirectory, List<(string, double)> deterministicHashCodeCollection, List<(string, double)> incorrectDeterministicHashCodeCollection, Dictionary<int, List<Face>> keyValuePairs)
{
string[] files;
string personKey;
string[] yearDirectories;
string ticksDirectoryName;
string? personFirstInitial;
string[] personKeyDirectories;
string[] personNameDirectories;
string[] personNameLinkDirectories;
string? personFirstInitialDirectory;
double? reversedDeterministicHashCodeKey;
bool keyValuePairsAny = keyValuePairs.Any();
string[] ticksDirectories = Directory.GetDirectories(deterministicHashCodeContentDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string ticksDirectory in ticksDirectories)
{
ticksDirectoryName = Path.GetFileName(ticksDirectory);
if (ticksDirectoryName.Length < 3 || ticksDirectoryName[0] != '(' || ticksDirectoryName[^1] != ')')
continue;
personKeyDirectories = Directory.GetDirectories(ticksDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personKeyDirectory in personKeyDirectories)
{
personKey = Path.GetFileName(personKeyDirectory);
if (personKey == nameof(Closest))
throw new Exception($"Move personKey directories up one from {nameof(Closest)} and delete {nameof(Closest)} directory!");
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string yearDirectory in yearDirectories)
{
files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly);
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
File.Delete(file);
foreach (string personNameDirectory in personNameDirectories)
{
personFirstInitial = Path.GetFileName(personNameDirectory)[..1];
if (personFirstInitial is null)
continue;
personFirstInitialDirectory = Path.Combine(yearDirectory, personFirstInitial);
files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
if (file.EndsWith(".lnk") || file.EndsWith(".json"))
continue;
reversedDeterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetReversedDeterministicHashCodeKey(keyValuePairsAny, keyValuePairs, file);
if (reversedDeterministicHashCodeKey is null)
continue;
deterministicHashCodeCollection.Add(new(personKey, reversedDeterministicHashCodeKey.Value));
}
if (personNameDirectory == personFirstInitialDirectory)
continue;
personNameLinkDirectories = Directory.GetDirectories(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personNameLinkDirectory in personNameLinkDirectories)
{
files = Directory.GetFiles(personNameLinkDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
if (!file.EndsWith(".lnk"))
continue;
File.Delete(file);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personNameLinkDirectory);
}
Directory.Move(personNameDirectory, personFirstInitialDirectory);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personNameDirectory);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(yearDirectory);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personKeyDirectory);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(ticksDirectory);
}
}
internal static string SetByRef(string outputExtension, Dictionary<string, Person> personKeyValuePairs, List<double> skipCollection, Dictionary<string, (string, int?, string, PersonBirthday[])> peopleKeyValuePairs, Dictionary<int, string[]> deterministicHashCodeUnknownFaceKeyValuePairs, Dictionary<double, string[]> deterministicHashCodeKeyValuePairs, Dictionary<double, string[]> incorrectDeterministicHashCodeKeyValuePairs, string deterministicHashCodeRootDirectory)
{
string result;
List<string> deterministicHashCodePersonKeys = new();
List<string> deterministicHashCodeUnknownFacePersonKeys = new();
foreach (KeyValuePair<int, string[]> keyValuePair in deterministicHashCodeUnknownFaceKeyValuePairs)
deterministicHashCodeUnknownFacePersonKeys.AddRange(keyValuePair.Value);
deterministicHashCodeUnknownFacePersonKeys = deterministicHashCodeUnknownFacePersonKeys.Distinct().ToList();
List<(string, int?, string, PersonBirthday[])> peopleCollection = new();
string deterministicHashCodePeopleDirectory = Path.Combine(deterministicHashCodeRootDirectory, "People");
if (Directory.Exists(deterministicHashCodePeopleDirectory))
SetOther(outputExtension, personKeyValuePairs, deterministicHashCodePeopleDirectory, skipCollection, peopleCollection);
result = Path.Combine(deterministicHashCodeRootDirectory, "()");
if (!Directory.Exists(result))
result = string.Empty;
else
{
Dictionary<int, List<Face>> keyValuePairs = new();
Dictionary<double, List<string>> deterministicHashCodeScope = new();
Dictionary<double, List<string>> incorrectDeterministicHashCodeScope = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> deterministicHashCodeCollection = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> incorrectDeterministicHashCodeCollection = new();
SetKeyValuePairs(result, deterministicHashCodeCollection, incorrectDeterministicHashCodeCollection, keyValuePairs);
deterministicHashCodeCollection = (from l in deterministicHashCodeCollection orderby l.IdAndNormalizedPixelPercentage select l).ToList();
incorrectDeterministicHashCodeCollection = (from l in incorrectDeterministicHashCodeCollection orderby l.IdAndNormalizedPixelPercentage select l).ToList();
foreach ((string personKey, double idAndNormalizedPixelPercentage) in deterministicHashCodeCollection)
{
if (!deterministicHashCodeScope.ContainsKey(idAndNormalizedPixelPercentage))
deterministicHashCodeScope.Add(idAndNormalizedPixelPercentage, new());
deterministicHashCodeScope[idAndNormalizedPixelPercentage].Add(personKey);
deterministicHashCodePersonKeys.Add(personKey);
}
deterministicHashCodePersonKeys = deterministicHashCodePersonKeys.Distinct().ToList();
foreach ((string personKey, double idAndNormalizedPixelPercentage) in incorrectDeterministicHashCodeCollection)
{
if (!incorrectDeterministicHashCodeScope.ContainsKey(idAndNormalizedPixelPercentage))
incorrectDeterministicHashCodeScope.Add(idAndNormalizedPixelPercentage, new());
incorrectDeterministicHashCodeScope[idAndNormalizedPixelPercentage].Add(personKey);
}
foreach (KeyValuePair<double, List<string>> keyValuePair in deterministicHashCodeScope)
deterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray());
foreach (KeyValuePair<double, List<string>> keyValuePair in incorrectDeterministicHashCodeScope)
incorrectDeterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray());
}
foreach ((string personDisplayDirectoryName, int? approximateYears, string personKey, PersonBirthday[] personBirthdays) in peopleCollection)
{
if (peopleKeyValuePairs.ContainsKey(personKey) && peopleKeyValuePairs[personKey].Item1 != personDisplayDirectoryName)
throw new NotImplementedException();
if (deterministicHashCodeUnknownFacePersonKeys.Contains(personKey) || deterministicHashCodePersonKeys.Contains(personKey))
peopleKeyValuePairs.Add(personKey, new(personDisplayDirectoryName, approximateYears, personKey, personBirthdays));
}
return result;
}
}