SaveMappedForOutputResolutions

This commit is contained in:
2023-09-03 17:30:39 -07:00
parent a9d0f67227
commit 600f6e7e2b
15 changed files with 437 additions and 163 deletions

View File

@ -3,6 +3,7 @@ using System.Collections.ObjectModel;
using System.Text.Json;
using View_by_Distance.Distance.Models.Stateless;
using View_by_Distance.FaceRecognitionDotNet;
using View_by_Distance.Property.Models.Stateless;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Methods;
@ -11,6 +12,14 @@ namespace View_by_Distance.Distance.Models;
public partial class E_Distance : IDistance<MetadataExtractor.Directory>
{
internal record Mapped(string File,
double? Length,
string Link,
string Image);
internal record Record(string File,
FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding);
private readonly List<string> _Moved;
private readonly List<double?> _Debug;
private readonly List<string> _Renamed;
@ -213,7 +222,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
Face[] filteredFaces = (from l in faces where l.FaceEncoding is not null && l.Location is not null && l.OutputResolution is not null select l).ToArray();
if (filteredFaces.Length != faces.Count)
checkFaces.Clear();
foreach (LocationContainer<MetadataExtractor.Directory>? locationContainer in locationContainers)
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
if (_Renamed.Contains(locationContainer.File))
continue;
@ -317,7 +326,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
public static void SaveFaceDistances(Property.Models.Configuration configuration, SortingContainer[] sortingContainers)
{
string eDistanceContentCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(E_Distance), "([])");
string eDistanceContentCollectionDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(E_Distance), "([])");
if (!Directory.Exists(eDistanceContentCollectionDirectory))
_ = Directory.CreateDirectory(eDistanceContentCollectionDirectory);
#pragma warning disable
@ -480,7 +489,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
return results;
}
private static void ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, DateTime dateTime, DateTime yesterday, List<(string File, FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding)> collection)
private static void ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, DateTime dateTime, DateTime yesterday, List<Record> records)
{
FileInfo fileInfo;
List<string> files = new();
@ -488,14 +497,14 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
List<FaceDistance> faceDistanceLengths;
List<string> firstPassFailures = new();
List<FaceDistance> faceDistanceEncodings = new();
faceDistanceEncoding = new(collection[0].FaceRecognitionDotNetFaceEncoding);
foreach ((string file, FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding) in collection)
faceDistanceEncoding = new(records[0].FaceRecognitionDotNetFaceEncoding);
foreach (Record record in records)
{
files.Add(file);
faceDistanceEncodings.Add(new(faceRecognitionDotNetFaceEncoding));
files.Add(record.File);
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
}
if (faceDistanceEncoding is null)
throw new Exception();
throw new NullReferenceException(nameof(faceDistanceEncoding));
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
if (faceDistanceLengths.Count != files.Count)
throw new Exception();
@ -505,14 +514,14 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
continue;
firstPassFailures.Add(files[i]);
}
faceDistanceEncoding = new(collection[^1].FaceRecognitionDotNetFaceEncoding);
foreach ((string file, FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding) in collection)
faceDistanceEncoding = new(records[^1].FaceRecognitionDotNetFaceEncoding);
foreach (Record record in records)
{
files.Add(file);
faceDistanceEncodings.Add(new(faceRecognitionDotNetFaceEncoding));
files.Add(record.File);
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
}
if (faceDistanceEncoding is null)
throw new Exception();
throw new NullReferenceException(nameof(faceDistanceEncoding));
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
if (faceDistanceLengths.Count != files.Count)
throw new Exception();
@ -534,21 +543,21 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
void IDistance<MetadataExtractor.Directory>.ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
string? json;
List<Record> records = new();
int? lastDirectoryNumber = null;
DateTime dateTime = DateTime.Now;
DateTime yesterday = DateTime.Now.AddDays(-1);
Shared.Models.FaceEncoding? modelsFaceEncoding;
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding;
List<(string, FaceRecognitionDotNet.FaceEncoding)> collection = new();
foreach (LocationContainer<MetadataExtractor.Directory>? locationContainer in locationContainers)
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
if (locationContainer.DirectoryNumber is null)
continue;
if (lastDirectoryNumber is not null && locationContainer.DirectoryNumber.Value != lastDirectoryNumber.Value)
{
if (collection.Count > 2)
ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, collection);
collection.Clear();
if (records.Count > 2)
ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, records);
records.Clear();
}
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.Directories);
if (json is null)
@ -557,11 +566,176 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
if (modelsFaceEncoding is null)
throw new NotSupportedException();
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
collection.Add((locationContainer.File, faceRecognitionDotNetFaceEncoding));
records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding));
lastDirectoryNumber = locationContainer.DirectoryNumber.Value;
}
if (collection.Count > 2)
ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, collection);
if (records.Count > 2)
ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, records);
}
private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory)
{
string json;
string vsCodeDirectory = Path.Combine(directory, ".vscode");
if (!Directory.Exists(vsCodeDirectory))
_ = Directory.CreateDirectory(vsCodeDirectory);
if (displayDirectoryName is not null)
File.WriteAllText(Path.Combine(directory, $"_ {displayDirectoryName}.txt"), string.Empty);
json = "{ \"[markdown]\": { \"editor.wordWrap\": \"off\" }, \"foam.links.hover.enable\": false, \"foam.graph.style\": { \"background\": \"#202020\", \"node\": { \"note\": \"#f2cb1d\", \"distance\": \"green\", \"image\": \"orange\", \"placeholder\": \"white\", } } }";
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(vsCodeDirectory, "settings.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
json = string.Concat("{ \"version\": \"2.0.0\", \"tasks\": [ { \"label\": \"MKLink\", \"type\": \"shell\", \"command\": \"New-Item\", \"args\": [ \"-ItemType\", \"Junction\", \"-Path\", \"'", directory.Replace('\\', '/'), "/()'\", \"-Target\", \"'", eDistanceContentDirectory.Replace('\\', '/'), "'\" ], \"problemMatcher\": [] } ] }");
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(vsCodeDirectory, "tasks.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
}
private static void MoveFiles(Dictionary<string, int> keyValuePairs, List<string> linkedOnce, List<string> linkedTwice, List<string> linkedThrice)
{
string checkFile;
string checkDirectory;
string? yearDirectory;
string? personNameDirectory;
string? personNameDirectoryName;
string? personKeyFormattedDirectory;
foreach (string file in linkedOnce)
keyValuePairs[file] += 1;
foreach (string file in linkedTwice)
keyValuePairs[file] += 1;
foreach (string file in linkedThrice)
keyValuePairs[file] += 1;
foreach (KeyValuePair<string, int> keyValuePair in keyValuePairs)
{
personNameDirectory = Path.GetDirectoryName(keyValuePair.Key);
yearDirectory = Path.GetDirectoryName(personNameDirectory);
personNameDirectoryName = Path.GetFileName(personNameDirectory);
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
if (string.IsNullOrEmpty(personNameDirectory) || string.IsNullOrEmpty(yearDirectory) || string.IsNullOrEmpty(personKeyFormattedDirectory) || string.IsNullOrEmpty(personNameDirectoryName))
continue;
checkDirectory = Path.Combine(personKeyFormattedDirectory, $"{keyValuePair.Value}{new string(Convert.ToChar(65 + keyValuePair.Value), 7)}");
if (checkDirectory == yearDirectory)
continue;
checkDirectory = Path.Combine(checkDirectory, personNameDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, Path.GetFileName(keyValuePair.Key));
if (File.Exists(checkFile))
continue;
File.Move(keyValuePair.Key, checkFile);
}
}
private static void SaveMappedForOutputResolutions(string eDistanceContentDirectory, float distanceTolerance, string personKeyFormatted, string? displayDirectoryName, List<Record> records, string directory)
{
string text;
string fileName;
FileInfo fileInfo;
List<string> files = new();
List<string> lines = new();
List<string> linkedOnce = new();
string fileNameWithoutExtension;
List<string> linkedTwice = new();
List<string> linkedThrice = new();
FaceDistance? faceDistanceEncoding;
List<string> relativePaths = new();
List<FaceDistance> faceDistanceLengths;
Uri uri = new(eDistanceContentDirectory);
Dictionary<string, int> keyValuePairs = new();
List<FaceDistance> faceDistanceEncodings = new();
List<Mapped> results = new();
foreach (Record record in records)
{
files.Add(record.File);
relativePaths.Add(uri.MakeRelativeUri(new(record.File)).OriginalString);
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
}
foreach (Record record in records)
{
lines.Clear();
results.Clear();
fileInfo = new(record.File);
if (files.Count > 1)
{
faceDistanceEncoding = new(record.FaceRecognitionDotNetFaceEncoding);
if (faceDistanceEncoding is null)
throw new NullReferenceException(nameof(faceDistanceEncoding));
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
for (int i = 0; i < faceDistanceLengths.Count; i++)
{
fileName = Path.GetFileName(relativePaths[i]);
if (fileName == fileInfo.Name)
continue;
FaceDistance faceDistance = faceDistanceLengths[i];
if (faceDistance.Length > distanceTolerance)
continue;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileName));
results.Add(new(files[i], faceDistance.Length, $"[[{fileNameWithoutExtension}]]", $"![{faceDistance.Length}]({relativePaths[i]})"));
}
}
results = (from l in results orderby l.Length select l).Take(3).ToList();
keyValuePairs.Add(record.File, results.Count);
foreach (Mapped mapped in results)
{
if (!linkedOnce.Contains(mapped.File))
{
linkedOnce.Add(mapped.File);
continue;
}
if (!linkedTwice.Contains(mapped.File))
{
linkedTwice.Add(mapped.File);
continue;
}
if (!linkedThrice.Contains(mapped.File))
{
linkedThrice.Add(mapped.File);
continue;
}
}
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileInfo.Name));
lines.Add("---");
lines.Add("type: \"distance\"");
lines.Add("---");
lines.Add(string.Empty);
if (displayDirectoryName is null)
lines.Add($"## {personKeyFormatted}");
else
lines.Add($"## {displayDirectoryName}");
lines.Add(string.Empty);
lines.Add($"![0]({uri.MakeRelativeUri(new(record.File)).OriginalString})");
lines.Add($"__{fileNameWithoutExtension}__");
lines.Add(string.Empty);
lines.AddRange(results.Select(l => $"{l.Image}{Environment.NewLine}{l.Link}{Environment.NewLine}"));
text = string.Join(Environment.NewLine, lines);
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(directory, $"{fileNameWithoutExtension}.md"), text, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null))
continue;
}
MoveFiles(keyValuePairs, linkedOnce, linkedTwice, linkedThrice);
}
void IDistance<MetadataExtractor.Directory>.SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float[] rangeDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, string personKeyFormatted, string? displayDirectoryName)
{
string? json;
List<Record> records = new();
Shared.Models.FaceEncoding? modelsFaceEncoding;
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding;
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.Directories);
if (json is null)
continue;
modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
if (modelsFaceEncoding is null)
throw new NotSupportedException();
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding));
}
string directory = Path.Combine(a2PeopleContentDirectory, rangeDistanceTolerance[1].ToString(), personKeyFormatted);
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
if (records.Count > 0)
{
WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory);
SaveMappedForOutputResolutions(eDistanceContentDirectory, rangeDistanceTolerance[1], personKeyFormatted, displayDirectoryName, records, directory);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directory);
}
}