This commit is contained in:
2022-05-08 12:28:50 -07:00
commit 4a3e24236f
313 changed files with 22395 additions and 0 deletions

View File

@ -0,0 +1,35 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Instance.Models;
public class AppSettings
{
protected string _Company;
protected string _WorkingDirectoryName;
protected int? _MaxDegreeOfParallelism;
public string Company => _Company;
public string WorkingDirectoryName => _WorkingDirectoryName;
public int? MaxDegreeOfParallelism => _MaxDegreeOfParallelism;
// public AppSettings()
// {
// }
[JsonConstructor]
public AppSettings(string company, string workingDirectoryName, int? maxDegreeOfParallelism)
{
_Company = company;
_WorkingDirectoryName = workingDirectoryName;
_MaxDegreeOfParallelism = maxDegreeOfParallelism;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,26 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
namespace View_by_Distance.Instance.Models.Binder;
public class AppSettings
{
[Display(Name = "Company"), Required] public string Company { get; set; }
[Display(Name = "Working Directory Name"), Required] public string WorkingDirectoryName { get; set; }
[Display(Name = "Max Degree Of Parallelism"), Required] public int? MaxDegreeOfParallelism { get; set; }
public AppSettings()
{
Company = string.Empty;
WorkingDirectoryName = string.Empty;
MaxDegreeOfParallelism = -1;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,99 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
namespace View_by_Distance.Instance.Models.Binder;
public class Configuration
{
[Display(Name = "Check Json For Distance Results"), Required] public bool? CheckJsonForDistanceResults { get; set; }
[Display(Name = "CrossDirectory Max Items In Distance Collection"), Required] public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
[Display(Name = "Force Metadata Last Write Time to Creation Time"), Required] public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; }
[Display(Name = "Force Resize Last Write Time to Creation Time"), Required] public bool? ForceResizeLastWriteTimeToCreationTime { get; set; }
[Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; }
[Display(Name = "Ignore Relative Paths"), Required] public string[] IgnoreRelativePaths { get; set; }
[Display(Name = "Load Or Create Then Save Directroy Distance Results"), Required] public bool? LoadOrCreateThenSaveDirectoryDistanceResults { get; set; }
[Display(Name = "Load Or Create Then Save Distance Results"), Required] public bool? LoadOrCreateThenSaveDistanceResults { get; set; }
[Display(Name = "Load Or Create Then Save Image Faces Results"), Required] public bool? LoadOrCreateThenSaveImageFacesResults { get; set; }
[Display(Name = "Load Or Create Then Save Index"), Required] public bool? LoadOrCreateThenSaveIndex { get; set; }
[Display(Name = "Location Confidence Factor"), Required] public int? LocationConfidenceFactor { get; set; }
[Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; }
[Display(Name = "Max Items In Distance Collection"), Required] public int? MaxItemsInDistanceCollection { get; set; }
[Display(Name = "Mixed Year Relative Paths"), Required] public string[] MixedYearRelativePaths { get; set; }
[Display(Name = "Model Directory"), Required] public string ModelDirectory { get; set; }
[Display(Name = "Model Name"), Required] public string ModelName { get; set; }
[Display(Name = "Num Jitters"), Required] public int? NumJitters { get; set; }
[Display(Name = "Output Extension"), Required] public string OutputExtension { get; set; }
[Display(Name = "Output Quality"), Required] public int? OutputQuality { get; set; }
[Display(Name = "Output Resolutions"), Required] public string[] OutputResolutions { get; set; }
[Display(Name = "Override For Face Images"), Required] public bool? OverrideForFaceImages { get; set; }
[Display(Name = "Override For Face Landmark Images"), Required] public bool? OverrideForFaceLandmarkImages { get; set; }
[Display(Name = "Override For Resize Images"), Required] public bool? OverrideForResizeImages { get; set; }
[Display(Name = "Padding Loops"), Required] public int? PaddingLoops { get; set; }
[Display(Name = "Predictor Model Name"), Required] public string PredictorModelName { get; set; }
[Display(Name = "Properties Changed For Distance"), Required] public bool? PropertiesChangedForDistance { get; set; }
[Display(Name = "Properties Changed For Faces"), Required] public bool? PropertiesChangedForFaces { get; set; }
[Display(Name = "Properties Changed For Index"), Required] public bool? PropertiesChangedForIndex { get; set; }
[Display(Name = "Properties Changed For Metadata"), Required] public bool? PropertiesChangedForMetadata { get; set; }
[Display(Name = "Properties Changed For Resize"), Required] public bool? PropertiesChangedForResize { get; set; }
[Display(Name = "Property Configuration"), Required] public Property.Models.Configuration? PropertyConfiguration { get; set; }
[Display(Name = "Reverse"), Required] public bool? Reverse { get; set; }
[Display(Name = "Save Face Landmark For Output Resolutions"), Required] public string[] SaveFaceLandmarkForOutputResolutions { get; set; }
[Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; }
[Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; }
[Display(Name = "Search for Abandoned Files"), Required] public bool? SearchForAbandonedFilesFull { get; set; }
[Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; }
[Display(Name = "Test Distance Results"), Required] public bool? TestDistanceResults { get; set; }
[Display(Name = "Valid Resolutions"), Required] public string[] ValidResolutions { get; set; }
public Configuration()
{
CheckJsonForDistanceResults = null;
CrossDirectoryMaxItemsInDistanceCollection = null;
DistanceFactor = null;
ForceMetadataLastWriteTimeToCreationTime = null;
ForceResizeLastWriteTimeToCreationTime = null;
IgnoreExtensions = Array.Empty<string>();
IgnoreRelativePaths = Array.Empty<string>();
LoadOrCreateThenSaveDirectoryDistanceResults = null;
LoadOrCreateThenSaveDistanceResults = null;
LoadOrCreateThenSaveImageFacesResults = null;
LoadOrCreateThenSaveIndex = null;
LocationConfidenceFactor = null;
MappedMaxIndex = null;
MaxItemsInDistanceCollection = null;
MixedYearRelativePaths = Array.Empty<string>();
ModelDirectory = string.Empty;
ModelName = string.Empty;
NumJitters = null;
OutputExtension = string.Empty;
OutputQuality = null;
OutputResolutions = Array.Empty<string>();
OverrideForFaceImages = null;
OverrideForFaceLandmarkImages = null;
OverrideForResizeImages = null;
PaddingLoops = null;
PredictorModelName = string.Empty;
PropertiesChangedForDistance = null;
PropertiesChangedForFaces = null;
PropertiesChangedForIndex = null;
PropertiesChangedForMetadata = null;
PropertiesChangedForResize = null;
Reverse = null;
SaveFaceLandmarkForOutputResolutions = Array.Empty<string>();
SaveFullYearOfRandomFiles = null;
SaveResizedSubfiles = null;
SearchForAbandonedFilesFull = null;
SkipSearch = null;
TestDistanceResults = null;
ValidResolutions = Array.Empty<string>();
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,145 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Instance.Models;
public class Configuration
{
protected readonly bool? _CheckJsonForDistanceResults;
protected readonly int? _CrossDirectoryMaxItemsInDistanceCollection;
protected readonly int? _DistanceFactor;
protected readonly bool? _ForceMetadataLastWriteTimeToCreationTime;
protected readonly bool? _ForceResizeLastWriteTimeToCreationTime;
protected readonly string[] _IgnoreExtensions;
protected readonly string[] _IgnoreRelativePaths;
protected readonly bool? _LoadOrCreateThenSaveDirectoryDistanceResults;
protected readonly bool? _LoadOrCreateThenSaveDistanceResults;
protected readonly bool? _LoadOrCreateThenSaveImageFacesResults;
protected readonly bool? _LoadOrCreateThenSaveIndex;
protected readonly int? _LocationConfidenceFactor;
protected readonly int? _MappedMaxIndex;
protected readonly int? _MaxItemsInDistanceCollection;
protected readonly string[] _MixedYearRelativePaths;
protected readonly string _ModelDirectory;
protected readonly string _ModelName;
protected readonly int? _NumJitters;
protected readonly string _OutputExtension;
protected readonly int? _OutputQuality;
protected readonly string[] _OutputResolutions;
protected readonly bool? _OverrideForFaceImages;
protected readonly bool? _OverrideForFaceLandmarkImages;
protected readonly bool? _OverrideForResizeImages;
protected readonly int? _PaddingLoops;
protected readonly string _PredictorModelName;
protected readonly bool? _PropertiesChangedForDistance;
protected readonly bool? _PropertiesChangedForFaces;
protected readonly bool? _PropertiesChangedForIndex;
protected readonly bool? _PropertiesChangedForMetadata;
protected readonly bool? _PropertiesChangedForResize;
protected Property.Models.Configuration? _PropertyConfiguration;
protected readonly bool? _Reverse;
protected readonly string[] _SaveFaceLandmarkForOutputResolutions;
protected readonly bool? _SaveFullYearOfRandomFiles;
protected readonly bool? _SaveResizedSubfiles;
protected readonly bool? _SearchForAbandonedFiles;
protected readonly bool? _SkipSearch;
protected readonly bool? _TestDistanceResults;
protected readonly string[] _ValidResolutions;
public bool? CheckJsonForDistanceResults => _CheckJsonForDistanceResults;
public int? CrossDirectoryMaxItemsInDistanceCollection => _CrossDirectoryMaxItemsInDistanceCollection;
public int? DistanceFactor => _DistanceFactor;
public bool? ForceMetadataLastWriteTimeToCreationTime => _ForceMetadataLastWriteTimeToCreationTime;
public bool? ForceResizeLastWriteTimeToCreationTime => _ForceResizeLastWriteTimeToCreationTime;
public string[] IgnoreExtensions => _IgnoreExtensions;
public string[] IgnoreRelativePaths => _IgnoreRelativePaths;
public bool? LoadOrCreateThenSaveDirectoryDistanceResults => _LoadOrCreateThenSaveDirectoryDistanceResults;
public bool? LoadOrCreateThenSaveDistanceResults => _LoadOrCreateThenSaveDistanceResults;
public bool? LoadOrCreateThenSaveImageFacesResults => _LoadOrCreateThenSaveImageFacesResults;
public bool? LoadOrCreateThenSaveIndex => _LoadOrCreateThenSaveIndex;
public int? LocationConfidenceFactor => _LocationConfidenceFactor;
public int? MappedMaxIndex => _MappedMaxIndex;
public int? MaxItemsInDistanceCollection => _MaxItemsInDistanceCollection;
public string[] MixedYearRelativePaths => _MixedYearRelativePaths;
public string ModelDirectory => _ModelDirectory;
public string ModelName => _ModelName;
public int? NumJitters => _NumJitters;
public string OutputExtension => _OutputExtension;
public int? OutputQuality => _OutputQuality;
public string[] OutputResolutions => _OutputResolutions;
public bool? OverrideForFaceImages => _OverrideForFaceImages;
public bool? OverrideForFaceLandmarkImages => _OverrideForFaceLandmarkImages;
public bool? OverrideForResizeImages => _OverrideForResizeImages;
public int? PaddingLoops => _PaddingLoops;
public string PredictorModelName => _PredictorModelName;
public bool? PropertiesChangedForDistance => _PropertiesChangedForDistance;
public bool? PropertiesChangedForFaces => _PropertiesChangedForFaces;
public bool? PropertiesChangedForIndex => _PropertiesChangedForIndex;
public bool? PropertiesChangedForMetadata => _PropertiesChangedForMetadata;
public bool? PropertiesChangedForResize => _PropertiesChangedForResize;
public Property.Models.Configuration? PropertyConfiguration => _PropertyConfiguration;
public bool? Reverse => _Reverse;
public string[] SaveFaceLandmarkForOutputResolutions => _SaveFaceLandmarkForOutputResolutions;
public bool? SaveFullYearOfRandomFiles => _SaveFullYearOfRandomFiles;
public bool? SaveResizedSubfiles => _SaveResizedSubfiles;
public bool? SearchForAbandonedFilesFull => _SearchForAbandonedFiles;
public bool? SkipSearch => _SkipSearch;
public bool? TestDistanceResults => _TestDistanceResults;
public string[] ValidResolutions => _ValidResolutions;
[JsonConstructor]
public Configuration(bool? checkJsonForDistanceResults, int? crossDirectoryMaxItemsInDistanceCollection, int? distanceFactor, bool? forceMetadataLastWriteTimeToCreationTime, bool? forceResizeLastWriteTimeToCreationTime, string[] ignoreExtensions, string[] ignoreRelativePaths, bool? loadOrCreateThenSaveDirectoryDistanceResults, bool? loadOrCreateThenSaveDistanceResults, bool? loadOrCreateThenSaveImageFacesResults, bool? loadOrCreateThenSaveIndex, int? locationConfidenceFactor, int? mappedMaxIndex, int? maxItemsInDistanceCollection, string[] mixedYearRelativePaths, string modelDirectory, string modelName, int? numJitters, string outputExtension, int? outputQuality, string[] outputResolutions, bool? overrideForFaceImages, bool? overrideForFaceLandmarkImages, bool? overrideForResizeImages, int? paddingLoops, string predictorModelName, bool? propertiesChangedForDistance, bool? propertiesChangedForFaces, bool? propertiesChangedForIndex, bool? propertiesChangedForMetadata, bool? propertiesChangedForResize, Property.Models.Configuration? propertyConfiguration, bool? reverse, string[] saveFaceLandmarkForOutputResolutions, bool? saveFullYearOfRandomFiles, bool? saveResizedSubfiles, bool? searchForAbandonedFilesFull, bool? skipSearch, bool? testDistanceResults, string[] validResolutions)
{
_CheckJsonForDistanceResults = checkJsonForDistanceResults;
_CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
_DistanceFactor = distanceFactor;
_ForceMetadataLastWriteTimeToCreationTime = forceMetadataLastWriteTimeToCreationTime;
_ForceResizeLastWriteTimeToCreationTime = forceResizeLastWriteTimeToCreationTime;
_IgnoreExtensions = ignoreExtensions;
_IgnoreRelativePaths = ignoreRelativePaths;
_LoadOrCreateThenSaveDirectoryDistanceResults = loadOrCreateThenSaveDirectoryDistanceResults;
_LoadOrCreateThenSaveDistanceResults = loadOrCreateThenSaveDistanceResults;
_LoadOrCreateThenSaveImageFacesResults = loadOrCreateThenSaveImageFacesResults;
_LoadOrCreateThenSaveIndex = loadOrCreateThenSaveIndex;
_LocationConfidenceFactor = locationConfidenceFactor;
_MappedMaxIndex = mappedMaxIndex;
_MaxItemsInDistanceCollection = maxItemsInDistanceCollection;
_MixedYearRelativePaths = mixedYearRelativePaths;
_ModelDirectory = modelDirectory;
_ModelName = modelName;
_NumJitters = numJitters;
_OutputExtension = outputExtension;
_OutputQuality = outputQuality;
_OutputResolutions = outputResolutions;
_OverrideForFaceImages = overrideForFaceImages;
_OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages;
_OverrideForResizeImages = overrideForResizeImages;
_PaddingLoops = paddingLoops;
_PredictorModelName = predictorModelName;
_PropertiesChangedForDistance = propertiesChangedForDistance;
_PropertiesChangedForFaces = propertiesChangedForFaces;
_PropertiesChangedForIndex = propertiesChangedForIndex;
_PropertiesChangedForMetadata = propertiesChangedForMetadata;
_PropertiesChangedForResize = propertiesChangedForResize;
_PropertyConfiguration = propertyConfiguration;
_Reverse = reverse;
_SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions;
_SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles;
_SaveResizedSubfiles = saveResizedSubfiles;
_SearchForAbandonedFiles = searchForAbandonedFilesFull;
_SkipSearch = skipSearch;
_TestDistanceResults = testDistanceResults;
_ValidResolutions = validResolutions;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
public void Set(Property.Models.Configuration propertyConfiguration) => _PropertyConfiguration = propertyConfiguration;
public void Update() => _PropertyConfiguration?.Update();
}

View File

@ -0,0 +1,40 @@
using Microsoft.Extensions.Configuration;
using System.Text.Json;
namespace View_by_Distance.Instance.Models.Stateless;
public abstract class AppSettings
{
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
{
Models.AppSettings? result;
Binder.AppSettings appSettings = configurationRoot.Get<Binder.AppSettings>();
string json = JsonSerializer.Serialize(appSettings, new JsonSerializerOptions() { WriteIndented = true });
result = JsonSerializer.Deserialize<Models.AppSettings>(json);
if (result is null)
throw new Exception(json);
if (string.IsNullOrEmpty(result.Company))
throw new Exception(json);
string jsonThis = result.ToString();
if (jsonThis != json)
{
int? check = null;
int min = new int[] { json.Length, jsonThis.Length }.Min();
for (int i = 0; i < min; i++)
{
if (json[i] == jsonThis[i])
continue;
check = i;
break;
}
if (check is null)
throw new Exception();
string a = json[..check.Value].Split(',')[^1];
string b = json[check.Value..].Split(',')[0];
throw new Exception($"{a}{b}");
}
return result;
}
}

View File

@ -0,0 +1,44 @@
using Microsoft.Extensions.Configuration;
using Phares.Shared;
using System.Text.Json;
namespace View_by_Distance.Instance.Models.Stateless;
public abstract class Configuration
{
public static Models.Configuration Get(IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, string workingDirectory, Property.Models.Configuration propertyConfiguration)
{
Models.Configuration? result;
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
string section = string.Concat(environmentName, ":", nameof(Binder.Configuration));
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
Binder.Configuration configuration = configurationSection.Get<Binder.Configuration>();
string json = JsonSerializer.Serialize(configuration, new JsonSerializerOptions() { WriteIndented = true });
result = JsonSerializer.Deserialize<Models.Configuration>(json);
if (result is null)
throw new Exception(json);
string jsonThis = result.ToString();
result.Set(propertyConfiguration);
result.Update();
if (jsonThis != json)
{
int? check = null;
int min = new int[] { json.Length, jsonThis.Length }.Min();
for (int i = 0; i < min; i++)
{
if (json[i] == jsonThis[i])
continue;
check = i;
break;
}
if (check is null)
throw new Exception();
string a = json[..check.Value].Split(',')[^1];
string b = json[check.Value..].Split(',')[0];
throw new Exception($"{a}{b}");
}
return result;
}
}

View File

@ -0,0 +1,10 @@
namespace View_by_Distance.Instance.Models.Stateless;
public static class SerilogExtensionMethods
{
internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate);
internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate);
}

View File

@ -0,0 +1,79 @@
using System.Text.Json;
using View_by_Distance.Property.Models;
using View_by_Distance.Shared.Models;
namespace View_by_Distance.Instance.Models;
/// <summary>
// ?
/// </summary>
internal class A2_People
{
private readonly Serilog.ILogger? _Log;
private readonly Configuration _Configuration;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
internal A2_People(Configuration configuration)
{
_Configuration = configuration;
_Log = Serilog.Log.ForContext<A2_People>();
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
internal void WriteAllText(Property.Models.Configuration configuration, string outputResolution, List<G2_Identify> identifiedCollection)
{
string key;
string json;
string jsonFile;
FileInfo fileInfo;
string[] segments;
string directoryFullName;
Dictionary<string, List<G2_Identify>> keyValuePairs = new();
string hPeopleCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People), "[]");
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
foreach (G2_Identify identified in identifiedCollection)
{
fileInfo = new FileInfo(string.Concat(aPropertySingletonDirectory, identified.RelativePath));
if (fileInfo?.Directory is null || !fileInfo.Directory.Exists || fileInfo.Exists)
continue;
key = string.Concat(identified.ParentDirectoryName, '|', identified.Person);
if (!keyValuePairs.ContainsKey(key))
keyValuePairs.Add(key, new List<G2_Identify>());
keyValuePairs[key].Add(identified);
}
foreach (KeyValuePair<string, List<G2_Identify>> keyValuePair in keyValuePairs)
{
segments = keyValuePair.Key.Split('|');
directoryFullName = Path.Combine(hPeopleCollectionDirectory, segments[0]);
if (!Directory.Exists(directoryFullName))
_ = Directory.CreateDirectory(directoryFullName);
jsonFile = Path.Combine(directoryFullName, $"{segments[1]}.json");
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true))
continue;
}
}
internal Person[] GetPeople(Property.Models.Configuration configuration)
{
Person[] results;
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People));
string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory));
if (rootResultsDirectory is null)
throw new Exception();
Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory);
results = Shared.Models.Stateless.Methods.IPerson.GetPeople(storage);
return results.ToArray();
}
}

View File

@ -0,0 +1,161 @@
using FaceRecognitionDotNet;
using System.Drawing;
using System.Text.Json;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Property.Models;
using View_by_Distance.Resize.Models;
namespace View_by_Distance.Instance.Models;
/// <summary>
// *.png
/// </summary>
internal class D2_FaceLandmarks
{
internal List<string> AngleBracketCollection { get; }
private readonly Serilog.ILogger? _Log;
private readonly Configuration _Configuration;
internal D2_FaceLandmarks(Configuration configuration)
{
_Configuration = configuration;
AngleBracketCollection = new List<string>();
_Log = Serilog.Log.ForContext<D2_FaceLandmarks>();
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
#pragma warning disable CA1416
private static Bitmap RotateBitmap(System.Drawing.Image image, float angle)
{
Bitmap result;
Bitmap bitmap = new(image);
result = D_Face.RotateBitmap(bitmap, angle);
if (bitmap is not null)
bitmap.Dispose();
return result;
}
private static void SaveFaceLandmarkImages(List<D_Face> faceCollections, List<string[]> imageFiles, int pointSize, FileInfo resizedFileInfo)
{
int x;
int y;
D_Face face;
int width;
int height;
string imageFileFullName;
Bitmap rotated;
string rotatedImageFileFullName;
Shared.Models.FacePoint[] facePoints;
for (int i = 0; i < faceCollections.Count; i++)
{
if (!faceCollections[i].Populated)
continue;
face = faceCollections[i];
imageFileFullName = imageFiles[i][0];
rotatedImageFileFullName = imageFiles[i][1];
try
{
using (System.Drawing.Image image = System.Drawing.Image.FromFile(resizedFileInfo.FullName))
{
using Graphics graphic = Graphics.FromImage(image);
if (face.FaceLandmarks is null || !face.FaceLandmarks.Any())
{
width = face.Location.Right - face.Location.Left;
height = face.Location.Bottom - face.Location.Top;
graphic.DrawEllipse(Pens.Red, face.Location.Left, face.Location.Top, width, height);
}
else
{
foreach (KeyValuePair<string, Shared.Models.FacePoint[]> keyValuePair in face.FaceLandmarks)
{
facePoints = keyValuePair.Value.ToArray();
foreach (Shared.Models.FacePoint facePoint in facePoints)
graphic.DrawEllipse(Pens.GreenYellow, face.Location.Left + facePoint.X - pointSize, face.Location.Top + facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
if (keyValuePair.Key == FacePart.Chin.ToString())
continue;
if (facePoints.Length < 3)
continue;
x = (int)(from l in facePoints select l.X).Average();
y = (int)(from l in facePoints select l.Y).Average();
graphic.DrawEllipse(Pens.Purple, face.Location.Left + x - pointSize, face.Location.Top + y - pointSize, pointSize * 2, pointSize * 2);
}
}
image.Save(imageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
}
if (face.α.HasValue)
{
using System.Drawing.Image image = System.Drawing.Image.FromFile(resizedFileInfo.FullName);
rotated = RotateBitmap(image, (float)face.α.Value);
if (rotated is not null)
{
rotated.Save(rotatedImageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
rotated.Dispose();
}
}
}
catch (Exception) { }
}
}
#pragma warning restore CA1416
internal void SaveFaceLandmarkImages(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string relativePath, string fileNameWithoutExtension, FileInfo resizedFileInfo, List<D_Face> faceCollections)
{
FileInfo fileInfo;
bool check = false;
string parentCheck;
const int pointSize = 2;
FileInfo rotatedFileInfo;
long ticks = DateTime.Now.Ticks;
List<string[]> imageFiles = new();
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), fileNameWithoutExtension);
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (!Directory.Exists(facesDirectory))
_ = Directory.CreateDirectory(facesDirectory);
for (int i = 0; i < faceCollections.Count; i++)
{
if (!faceCollections[i].Populated)
{
imageFiles.Add(Array.Empty<string>());
continue;
}
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {fileNameWithoutExtension}.png"));
if (!fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
File.Delete(parentCheck);
}
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
continue;
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, string.Concat(Path.GetFileNameWithoutExtension(fileInfo.FullName), " - ", i, " - R", Path.GetExtension(fileInfo.FullName))));
imageFiles.Add(new string[] { fileInfo.FullName, rotatedFileInfo.FullName });
if (check)
continue;
if (_Configuration.OverrideForFaceLandmarkImages is null)
check = false;
else if (_Configuration.OverrideForFaceLandmarkImages.Value)
check = true;
else if (!fileInfo.Exists)
check = true;
else if (!rotatedFileInfo.Exists)
check = true;
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
check = true;
}
if (check)
SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, resizedFileInfo);
}
}

498
Instance/Models/_D_Face.cs Normal file
View File

@ -0,0 +1,498 @@
using FaceRecognitionDotNet;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text.Json;
using System.Text.Json.Serialization;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Property.Models;
using View_by_Distance.Resize.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Methods;
namespace View_by_Distance.Instance.Models;
/// <summary>
// List<D_Faces>
/// </summary>
public class D_Face : Shared.Models.Properties.IFace, IFace
{
internal List<string> AngleBracketCollection { get; }
private readonly Model _Model;
private readonly string _ArgZero;
private readonly Serilog.ILogger? _Log;
private readonly ModelParameter _ModelParameter;
private readonly PredictorModel _PredictorModel;
private readonly Configuration _Configuration;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
protected double? _Α;
protected DateTime _DateTime;
protected Shared.Models.FaceEncoding _FaceEncoding;
protected Dictionary<string, Shared.Models.FacePoint[]> _FaceLandmarks;
protected Shared.Models.Location _Location;
protected int? _LocationIndex;
protected OutputResolution _OutputResolution;
protected bool _Populated;
protected string _RelativePath;
public double? α => _Α;
public DateTime DateTime => _DateTime;
public Shared.Models.FaceEncoding FaceEncoding => _FaceEncoding;
public Dictionary<string, Shared.Models.FacePoint[]> FaceLandmarks => _FaceLandmarks;
public OutputResolution OutputResolution => _OutputResolution;
public Shared.Models.Location Location => _Location;
public int? LocationIndex => _LocationIndex;
public bool Populated => _Populated;
public string RelativePath => _RelativePath;
#nullable disable
[JsonConstructor]
public D_Face(double? α, DateTime dateTime, Shared.Models.FaceEncoding faceEncoding, Dictionary<string, Shared.Models.FacePoint[]> faceLandmarks, Shared.Models.Location location, int? locationIndex, OutputResolution outputResolution, bool populated, string relativePath)
{
_Α = α;
_DateTime = dateTime;
_FaceEncoding = faceEncoding;
_FaceLandmarks = faceLandmarks;
_Location = location;
_LocationIndex = locationIndex;
_OutputResolution = outputResolution;
_Populated = populated;
_RelativePath = relativePath;
}
internal D_Face(Configuration configuration, string argZero, Model model, ModelParameter modelParameter, PredictorModel predictorModel)
{
_Model = model;
_ArgZero = argZero;
_Configuration = configuration;
_ModelParameter = modelParameter;
_PredictorModel = predictorModel;
AngleBracketCollection = new List<string>();
_Log = Serilog.Log.ForContext<D_Face>();
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
}
private D_Face(Shared.Models.Location location)
{
_Α = α;
_DateTime = DateTime.MinValue;
_FaceEncoding = null;
_FaceLandmarks = null;
_OutputResolution = null;
_Location = location;
_LocationIndex = null;
_Populated = false;
_RelativePath = string.Empty;
}
private D_Face()
{
_Α = α;
_DateTime = DateTime.MinValue;
_FaceEncoding = null;
_FaceLandmarks = null;
_OutputResolution = null;
_Location = null;
_LocationIndex = null;
_Populated = false;
_RelativePath = string.Empty;
}
private D_Face(A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string relativePath, int? i, Shared.Models.Location location)
{
DateTime?[] dateTimes;
dateTimes = new DateTime?[] { property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
_DateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
_FaceLandmarks = new Dictionary<string, Shared.Models.FacePoint[]>();
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
_Location = location;
_LocationIndex = i;
_Populated = false;
_RelativePath = relativePath;
}
private D_Face(int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, Shared.Models.Properties.IFace face)
{
_Α = face.α;
_DateTime = face.DateTime;
_FaceEncoding = face.FaceEncoding;
_FaceLandmarks = face.FaceLandmarks;
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
_Location = face.Location;
_LocationIndex = face.LocationIndex;
_Populated = face.Populated;
_RelativePath = face.RelativePath;
}
private static void GetPointBounds(PointF[] points, out float xmin, out float xmax, out float ymin, out float ymax)
{
xmin = points[0].X;
xmax = xmin;
ymin = points[0].Y;
ymax = ymin;
foreach (PointF point in points)
{
if (xmin > point.X)
xmin = point.X;
if (xmax < point.X)
xmax = point.X;
if (ymin > point.Y)
ymin = point.Y;
if (ymax < point.Y)
ymax = point.Y;
}
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
#pragma warning disable CA1416
internal static Bitmap RotateBitmap(Bitmap bitmap, float angle)
{
Bitmap result;
#if Linux
throw new Exception("Built on Linux!");
#elif OSX
throw new Exception("Built on macOS!");
#elif Windows
// Make a Matrix to represent rotation
// by this angle.
Matrix rotate_at_origin = new();
rotate_at_origin.Rotate(angle);
// Rotate the image's corners to see how big
// it will be after rotation.
PointF[] points =
{
new PointF(0, 0),
new PointF(bitmap.Width, 0),
new PointF(bitmap.Width, bitmap.Height),
new PointF(0, bitmap.Height),
};
rotate_at_origin.TransformPoints(points);
float xmin, xmax, ymin, ymax;
GetPointBounds(points, out xmin, out xmax, out ymin, out ymax);
// Make a bitmap to hold the rotated result.
int wid = (int)Math.Round(xmax - xmin);
int hgt = (int)Math.Round(ymax - ymin);
result = new Bitmap(wid, hgt);
// Create the real rotation transformation.
Matrix rotate_at_center = new();
rotate_at_center.RotateAt(angle,
new PointF(wid / 2f, hgt / 2f));
// Draw the image onto the new bitmap rotated.
using (Graphics gr = Graphics.FromImage(result))
{
// Use smooth image interpolation.
gr.InterpolationMode = InterpolationMode.High;
// Clear with the color in the image's upper left corner.
gr.Clear(bitmap.GetPixel(0, 0));
// For debugging. (It's easier to see the background.)
// gr.Clear(Color.LightBlue);
// Set up the transformation to rotate.
gr.Transform = rotate_at_center;
// Draw the image centered on the bitmap.
int x = (wid - bitmap.Width) / 2;
int y = (hgt - bitmap.Height) / 2;
gr.DrawImage(bitmap, x, y);
}
#endif
// Return the result bitmap.
return result;
}
private static void SaveFaces(List<D_Face> faceCollection, FileInfo resizedFileInfo, List<string> imageFiles)
{
int width;
int height;
Graphics graphics;
Rectangle rectangle;
Bitmap preRotated;
Shared.Models.Location location;
using Bitmap source = new(resizedFileInfo.FullName);
for (int i = 0; i < faceCollection.Count; i++)
{
if (!faceCollection[i].Populated || faceCollection[i]?.Location is null)
continue;
location = new Shared.Models.Location(faceCollection[i].Location.Confidence,
faceCollection[i].Location.Bottom,
faceCollection[i].Location.Left,
faceCollection[i].Location.Right,
faceCollection[i].Location.Top);
width = location.Right - location.Left;
height = location.Bottom - location.Top;
rectangle = new Rectangle(location.Left, location.Top, width, height);
using (preRotated = new(width, height))
{
using (graphics = Graphics.FromImage(preRotated))
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
preRotated.Save(imageFiles[i], System.Drawing.Imaging.ImageFormat.Png);
}
}
}
private List<D_Face> GetFaces(FileInfo resizedFileInfo, string relativePath, string fileNameWithoutExtension, A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string facesDirectory)
{
List<D_Face> results = new();
if (_Configuration.PaddingLoops is null)
throw new Exception();
if (_Configuration.NumJitters is null)
throw new Exception();
FaceRecognitionDotNet.Location[] locations;
FaceRecognitionDotNet.Image unknownImage = null;
if (resizedFileInfo.Exists)
{
try
{ unknownImage = FaceRecognition.LoadImageFile(resizedFileInfo.FullName); }
catch (Exception) { }
}
if (unknownImage is null)
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, relativePath, i: null, location: null));
else
{
FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter);
locations = faceRecognition.FaceLocations(unknownImage, numberOfTimesToUpsample: 1, _Model).ToArray();
if (!locations.Any())
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, relativePath, i: null, location: null));
else
{
double? α;
int width;
int height;
int padding;
int leftEyeX;
int leftEyeY;
int rightEyeX;
int rightEyeY;
string faceFile;
Graphics graphics;
D_Face face = null;
Rectangle rectangle;
double[] rawEncoding;
Bitmap rotated;
Bitmap preRotated;
FaceRecognitionDotNet.Image knownImage;
FaceRecognitionDotNet.Image rotatedImage;
Shared.Models.Location location;
FaceRecognitionDotNet.FaceEncoding[] faceEncodings;
IEnumerable<FaceRecognitionDotNet.FacePoint> facePoints;
Shared.Models.FaceEncoding faceEncoding;
IDictionary<FacePart, IEnumerable<FaceRecognitionDotNet.FacePoint>>[] faceLandmarks;
using Bitmap source = unknownImage.ToBitmap();
padding = (int)((source.Width + source.Height) / 2 * .01);
for (int i = 0; i < locations.Length; i++)
{
for (int p = 0; p <= _Configuration.PaddingLoops.Value; p++)
{
//Location(double confidence, int bottom, int left, int right, int top)
location = new(locations[i].Confidence,
locations[i].Bottom + (padding * p),
locations[i].Left - (padding * p),
locations[i].Right + (padding * p),
locations[i].Top - (padding * p));
face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, relativePath, i, location);
width = location.Right - location.Left;
height = location.Bottom - location.Top;
rectangle = new Rectangle(location.Left, location.Top, width, height);
using (preRotated = new Bitmap(width, height))
{
using (graphics = Graphics.FromImage(preRotated))
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
// source.Save(Path.Combine(_Configuration.RootDirectory, "source.jpg"));
// preRotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - preRotated.jpg"));
using (knownImage = FaceRecognition.LoadImage(preRotated))
faceLandmarks = faceRecognition.FaceLandmark(knownImage, faceLocations: null, _PredictorModel, _Model).ToArray();
if (faceLandmarks.Length == 0 && p < _Configuration.PaddingLoops.Value)
continue;
else if (faceLandmarks.Length != 1)
continue;
foreach (KeyValuePair<FacePart, IEnumerable<FaceRecognitionDotNet.FacePoint>> keyValuePair in faceLandmarks[0])
face.FaceLandmarks.Add(keyValuePair.Key.ToString(), (from l in keyValuePair.Value select new Shared.Models.FacePoint(l.Index, l.Point.X, l.Point.Y)).ToArray());
if (!faceLandmarks[0].ContainsKey(FacePart.LeftEye) || !faceLandmarks[0].ContainsKey(FacePart.RightEye))
continue;
facePoints = faceLandmarks[0][FacePart.LeftEye];
leftEyeX = (int)(from l in facePoints select l.Point.X).Average();
leftEyeY = (int)(from l in facePoints select l.Point.Y).Average();
facePoints = faceLandmarks[0][FacePart.RightEye];
rightEyeX = (int)(from l in facePoints select l.Point.X).Average();
rightEyeY = (int)(from l in facePoints select l.Point.Y).Average();
α = Shared.Models.Stateless.Methods.IFace.Getα(rightEyeX, leftEyeX, rightEyeY, leftEyeY);
using (rotated = RotateBitmap(preRotated, (float)α.Value))
{
// rotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - rotated.jpg"));
using (rotatedImage = FaceRecognition.LoadImage(rotated))
faceEncodings = faceRecognition.FaceEncodings(rotatedImage, knownFaceLocation: null, _Configuration.NumJitters.Value, _PredictorModel, _Model).ToArray();
if (faceEncodings.Length == 0 && p < _Configuration.PaddingLoops.Value)
continue;
else if (faceEncodings.Length != 1)
continue;
rawEncoding = faceEncodings[0].GetRawEncoding();
faceEncoding = new(rawEncoding, faceEncodings[0].Size);
face.Update(α, faceEncoding, populated: true);
}
faceFile = Path.Combine(facesDirectory, $"{i} - {fileNameWithoutExtension}.png");
preRotated.Save(faceFile, System.Drawing.Imaging.ImageFormat.Png);
results.Add(face);
}
if (face.Populated)
break;
}
if (face is null || !face.Populated)
{
location = new(locations[i].Confidence,
locations[i].Bottom,
locations[i].Left,
locations[i].Right,
locations[i].Top);
face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, relativePath, i, location);
results.Add(face);
}
}
}
unknownImage.Dispose();
faceRecognition.Dispose();
}
if (!results.Any())
throw new Exception();
return results;
}
#pragma warning restore CA1416
private void Update(double? α, Shared.Models.FaceEncoding faceEncoding, bool populated)
{
_Α = α;
_FaceEncoding = faceEncoding;
_Populated = populated;
}
internal List<D_Face> GetFaces(Property.Models.Configuration configuration, string outputResolution, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string relativePath, string fileNameWithoutExtension, A_Property property, FileInfo resizedFileInfo, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
{
List<D_Face> results;
if (_Configuration.PropertiesChangedForFaces is null)
throw new Exception();
string json;
D_Face face;
bool checkForOutputResolutionChange = false;
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), fileNameWithoutExtension);
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{fileNameWithoutExtension}.json"));
if (!fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
File.Delete(parentCheck);
}
if (!Directory.Exists(facesDirectory))
_ = Directory.CreateDirectory(facesDirectory);
if (_Configuration.PropertiesChangedForFaces.Value)
results = null;
else if (!fileInfo.Exists)
results = null;
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
results = null;
else
{
json = Shared.Models.Stateless.Methods.IFace.GetJson(fileInfo.FullName);
try
{
results = JsonSerializer.Deserialize<List<D_Face>>(json);
for (int i = 0; i < results.Count; i++)
{
face = results[i];
if (face.OutputResolution is not null)
continue;
if (!checkForOutputResolutionChange)
checkForOutputResolutionChange = true;
results[i] = new(outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, face);
}
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), fileInfo.LastWriteTime));
}
catch (Exception)
{
results = null;
parseExceptions.Add(nameof(D_Face));
}
}
if (results is not null && checkForOutputResolutionChange)
{
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true))
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
}
else if (results is null)
{
results = GetFaces(resizedFileInfo, relativePath, fileNameWithoutExtension, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, facesDirectory);
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now));
}
return results;
}
internal void SaveFaces(Property.Models.Configuration configuration, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string relativePath, string fileNameWithoutExtension, FileInfo resizedFileInfo, List<D_Face> faceCollection)
{
if (_Configuration.OverrideForFaceImages is null)
throw new Exception();
FileInfo fileInfo;
bool check = false;
string parentCheck;
List<string> imageFiles = new();
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), fileNameWithoutExtension);
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
bool facesDirectoryExisted = Directory.Exists(facesDirectory);
if (!facesDirectoryExisted)
_ = Directory.CreateDirectory(facesDirectory);
for (int i = 0; i < faceCollection.Count; i++)
{
if (!faceCollection[i].Populated || faceCollection[i]?.Location is null)
{
imageFiles.Add(string.Empty);
continue;
}
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {fileNameWithoutExtension}.png"));
if (!fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
File.Delete(parentCheck);
}
imageFiles.Add(fileInfo.FullName);
if (_Configuration.OverrideForFaceImages.Value)
check = true;
else if (!fileInfo.Exists)
check = true;
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
check = true;
}
if (check)
SaveFaces(faceCollection, resizedFileInfo, imageFiles);
}
double Shared.Models.Stateless.Methods.IFace.TestStatic_Getα(int x1, int x2, int y1, int y2) => throw new NotImplementedException();
string Shared.Models.Stateless.Methods.IFace.TestStatic_GetJson(string jsonFileFullName) => throw new NotImplementedException();
Face Shared.Models.Stateless.Methods.IFace.TestStatic_GetFace(string jsonFileFullName) => throw new NotImplementedException();
Face[] Shared.Models.Stateless.Methods.IFace.TestStatic_GetFaces(string jsonFileFullName) => throw new NotImplementedException();
}

View File

@ -0,0 +1,230 @@
using System.Text.Json;
using View_by_Distance.Instance.Models.Stateless;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Resize.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Methods;
namespace View_by_Distance.Instance.Models;
/// <summary>
// N/A
/// </summary>
internal class E2_Navigate
{
private readonly string _ArgZero;
private readonly E3_Rename _Rename;
private readonly IConsole _Console;
private readonly Serilog.ILogger? _Log;
private readonly Configuration _Configuration;
internal E2_Navigate(IConsole console, Configuration configuration, string argZero)
{
_Console = console;
_ArgZero = argZero;
_Configuration = configuration;
_Rename = new E3_Rename(configuration);
_Log = Serilog.Log.ForContext<E2_Navigate>();
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
private void DisplayTags(Property.Models.Configuration configuration, string outputResolution, string[] directories, Dictionary<ConsoleKey, int> directoryKeyValuePairs, string[] files, Dictionary<ConsoleKey, int> fileKeyValuePairs)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
bool all = false;
FileSystem fileSystem;
string requestPath = "/RootResultsDirectory";
string? rootResultsDirectory = Path.GetDirectoryName(Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(B_Metadata)));
if (string.IsNullOrEmpty(rootResultsDirectory))
throw new Exception();
string rootResultsDirectoryAbsoluteUri = new Uri(rootResultsDirectory).AbsoluteUri;
string dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
string cResizeContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()");
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
(string RootResultsDirectoryAbsoluteUri, string C_ResizeContentDirectory, string D_FacesContentDirectory, string E_DistanceCollectionDirectory) tuple = new(rootResultsDirectoryAbsoluteUri, cResizeContentDirectory, dFacesContentDirectory, eDistanceCollectionDirectory);
List<FileSystem> fileSystemCollection = Shared.Models.Stateless.Methods.IFileSystem.GetFileSystemCollection(requestPath, tuple, directories, files, all);
Queue<FileSystem> queue = new(fileSystemCollection);
foreach (KeyValuePair<ConsoleKey, int> element in directoryKeyValuePairs)
{
fileSystem = queue.Dequeue();
_Log.Warn(string.Concat(element.Key, " - D) ", " <", fileSystem.Display, ">"));
// _Log.Info(string.Join(Environment.NewLine, from l in fileSystem where !string.IsNullOrEmpty(l) select l));
_Log.Info(string.Empty);
}
foreach (KeyValuePair<ConsoleKey, int> element in fileKeyValuePairs)
{
fileSystem = queue.Dequeue();
_Log.Warn(string.Concat(element.Key, " - F) [", fileSystem.Display, '}'));
// _Log.Info(string.Join(Environment.NewLine, from l in fileSystem where !string.IsNullOrEmpty(l) select l));
_Log.Info(string.Empty);
}
}
private void DisplayFaces(Property.Models.Configuration configuration, string outputResolution, string selectedFileFullName)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
string requestPath = "/RootResultsDirectory";
string? rootResultsDirectory = Path.GetDirectoryName(Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(B_Metadata)));
if (string.IsNullOrEmpty(rootResultsDirectory))
throw new Exception();
string rootResultsDirectoryAbsoluteUri = new Uri(rootResultsDirectory).AbsoluteUri;
string dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
string cResizeContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()");
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
(string RootResultsDirectoryAbsoluteUri, string C_ResizeContentDirectory, string D_FacesContentDirectory, string E_DistanceCollectionDirectory) tuple = new(rootResultsDirectoryAbsoluteUri, cResizeContentDirectory, dFacesContentDirectory, eDistanceCollectionDirectory);
FaceFileSystem[] faceFileSystemCollection = Shared.Models.Stateless.Methods.IFaceFileSystem.GetFaceFileSystemCollection(requestPath, tuple, selectedFileFullName);
for (int i = 0; i < faceFileSystemCollection.Length; i++)
{
_Log.Warn(string.Concat(i, " - F) [", faceFileSystemCollection[i].Display, '}'));
// _Log.Info(string.Join(Environment.NewLine, from l in fileSystemCollection[i] where !string.IsNullOrEmpty(l) select l));
_Log.Info(string.Empty);
}
// }
}
private string Rename(Property.Models.Configuration configuration, string subSourceDirectory)
{
string result;
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
_Log.Warn(string.Concat("What is the new name for [", Path.GetFileName(subSourceDirectory), "]<", subSourceDirectory, ">?"));
string? newDirectoryName = _Console.ReadLine();
_Log.Warn("Are you sure y[es] || n[o]?");
if (string.IsNullOrEmpty(newDirectoryName) || _Console.ReadKey() != ConsoleKey.Y)
{
_Log.Warn(string.Empty);
_Log.Warn("No changes made.");
result = subSourceDirectory;
}
else
{
_Log.Warn(string.Empty);
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
string relativePath = Property.Models.Stateless.IPath.GetRelativePath(subSourceDirectory, eDistanceCollectionDirectory.Length);
if (relativePath.Length == 1)
throw new Exception();
if (Directory.Exists(Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName)))
{
_Log.Warn("\"To\" directory already exits!");
result = subSourceDirectory;
}
else
{
_Rename.DirectoryRename(configuration, relativePath, newDirectoryName);
_Log.Warn("Renamed...");
string? directoryName = Path.GetDirectoryName(subSourceDirectory);
if (string.IsNullOrEmpty(directoryName))
throw new Exception();
result = Path.Combine(directoryName, newDirectoryName);
}
}
return result;
}
internal void Navigate(Property.Models.Configuration configuration, string outputResolution)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
string[] subFiles;
ConsoleKey consoleKey;
string[] subDirectories;
string selectedFileFullName;
string rootDirectory = string.Empty;
string? subSourceDirectory = string.Empty;
Dictionary<ConsoleKey, int> fileKeyValuePairs = new();
Dictionary<ConsoleKey, int> directoryKeyValuePairs = new();
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), _Configuration.OutputResolutions[0], includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
if (!Directory.Exists(eDistanceCollectionDirectory))
_ = Directory.CreateDirectory(eDistanceCollectionDirectory);
for (int z = 0; z < int.MaxValue; z++)
{
if (string.IsNullOrEmpty(subSourceDirectory))
{
rootDirectory = eDistanceCollectionDirectory;
subSourceDirectory = rootDirectory;
}
subFiles = Directory.GetFiles(subSourceDirectory, "*.json", SearchOption.TopDirectoryOnly);
subDirectories = Directory.GetDirectories(subSourceDirectory, "*", SearchOption.TopDirectoryOnly);
directoryKeyValuePairs.Clear();
for (int i = (int)ConsoleKey.A; i < (subDirectories.Length + (int)ConsoleKey.A) && i <= (int)ConsoleKey.RightWindows; i++)
directoryKeyValuePairs.Add((ConsoleKey)i, i - (int)ConsoleKey.A);
fileKeyValuePairs.Clear();
for (int i = (int)ConsoleKey.A + subDirectories.Length; i < (subFiles.Length + (int)ConsoleKey.A + subDirectories.Length) && i <= (int)ConsoleKey.RightWindows; i++)
fileKeyValuePairs.Add((ConsoleKey)i, i - (int)ConsoleKey.A);
_Log.Warn("");
DisplayTags(configuration, outputResolution, subDirectories, directoryKeyValuePairs, subFiles, fileKeyValuePairs);
_Log.Warn(string.Empty);
_Log.Warn(string.Empty);
_Log.Warn(string.Empty);
_Log.Warn("Select a file system object. Enter \"Backspace\" to go up a directory, \"F2\" to rename and \"Esc\" to end navigation.");
consoleKey = _Console.ReadKey();
_Log.Warn(string.Empty);
if (consoleKey == ConsoleKey.Escape)
break;
if (consoleKey == ConsoleKey.F2)
{
if (subSourceDirectory == rootDirectory)
{
_Log.Warn("Root directory can not be renamed! Try again.");
continue;
}
else
{
subSourceDirectory = Rename(configuration, subSourceDirectory);
continue;
}
}
else if (consoleKey is ConsoleKey.Backspace or ConsoleKey.LeftArrow)
{
if (subSourceDirectory != rootDirectory)
subSourceDirectory = Path.GetDirectoryName(subSourceDirectory);
else
{
_Log.Warn("At root directory. Try again.");
continue;
}
}
else if (directoryKeyValuePairs.ContainsKey(consoleKey))
{
subSourceDirectory = subDirectories[directoryKeyValuePairs[consoleKey]];
_Log.Warn(string.Concat(">>> [", Path.GetFileName(subSourceDirectory), "]<", subSourceDirectory, ">?"));
continue;
}
else
{
if (!fileKeyValuePairs.ContainsKey(consoleKey))
{
subSourceDirectory = _ArgZero;
_Log.Warn("Invalid selection. Try again.");
continue;
}
else
{
selectedFileFullName = subFiles[fileKeyValuePairs[consoleKey]];
_Log.Warn(string.Concat(">>> [", Path.GetFileName(selectedFileFullName), "]<", selectedFileFullName, ">?"));
DisplayFaces(configuration, outputResolution, selectedFileFullName);
_Log.Warn(string.Empty);
_Log.Warn(string.Empty);
_Log.Warn(string.Empty);
_Log.Warn("Go up a directory? Enter escape end.");
consoleKey = _Console.ReadKey();
if (consoleKey == ConsoleKey.Escape)
break;
subSourceDirectory = Path.GetDirectoryName(subSourceDirectory);
continue;
}
}
}
}
}

View File

@ -0,0 +1,338 @@
using System.Text.Json;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Property.Models;
using View_by_Distance.Resize.Models;
namespace View_by_Distance.Instance.Models;
/// <summary>
// N/A
/// </summary>
internal class E3_Rename
{
private readonly Serilog.ILogger? _Log;
private readonly Configuration _Configuration;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
internal E3_Rename(Configuration configuration)
{
_Configuration = configuration;
_Log = Serilog.Log.ForContext<G2_Identify>();
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
internal string[] GetDirectoryRenameCollection(Property.Models.Configuration configuration, string relativePath, string newDirectoryName, bool jsonFiles4InfoAny)
{
List<string> results = new();
bool add;
string to;
string dFacesContentDirectory;
string cResizeContentDirectory;
string dFacesCollectionDirectory;
string cResizeSingletonDirectory;
string eDistanceContentDirectory;
string aPropertySingletonDirectory;
string bMetadataSingletonDirectory;
string eDistanceCollectionDirectory;
string g2IdentifyCollectionDirectory;
string d2FaceLandmarksContentDirectory;
add = Directory.Exists(string.Concat(Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()"), relativePath));
bMetadataSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(B_Metadata), "{}");
if (Directory.Exists(bMetadataSingletonDirectory))
{
to = Path.Combine(string.Concat(bMetadataSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(to);
}
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
if (Directory.Exists(aPropertySingletonDirectory))
{
to = Path.Combine(string.Concat(aPropertySingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(to);
}
cResizeContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()");
if (Directory.Exists(cResizeContentDirectory))
{
to = Path.Combine(string.Concat(cResizeContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(to);
}
foreach (string outputResolution in _Configuration.ValidResolutions)
{
cResizeSingletonDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "{}");
if (Directory.Exists(cResizeSingletonDirectory))
{
to = Path.Combine(string.Concat(cResizeSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(to);
}
dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
if (Directory.Exists(dFacesContentDirectory))
{
to = Path.Combine(string.Concat(dFacesContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(to);
}
dFacesCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
if (Directory.Exists(dFacesCollectionDirectory))
{
to = Path.Combine(string.Concat(dFacesCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(to);
}
d2FaceLandmarksContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
if (add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution) && Directory.Exists(d2FaceLandmarksContentDirectory))
{
to = Path.Combine(string.Concat(d2FaceLandmarksContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(to);
}
eDistanceContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
if (Directory.Exists(eDistanceContentDirectory))
{
to = Path.Combine(string.Concat(eDistanceContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(to);
}
eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
if (Directory.Exists(eDistanceCollectionDirectory))
{
to = Path.Combine(string.Concat(eDistanceCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(to);
}
g2IdentifyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
if (add && jsonFiles4InfoAny && Directory.Exists(g2IdentifyCollectionDirectory))
{
to = Path.Combine(string.Concat(g2IdentifyCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(to);
}
}
return results.ToArray();
}
internal List<string[]> GetDirectoryRenameCollections(Property.Models.Configuration configuration, string relativePath, string newDirectoryName, bool jsonFiles4InfoAny)
{
List<string[]> results = new();
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
bool add;
string to;
bool exists;
string from;
string dFacesContentDirectory;
string cResizeContentDirectory;
string dFacesCollectionDirectory;
string cResizeSingletonDirectory;
string eDistanceContentDirectory;
string bMetadataSingletonDirectory;
string aPropertySingletonDirectory;
string eDistanceCollectionDirectory;
string g2IdentifyCollectionDirectory;
string d2FaceLandmarksContentDirectory;
if (!string.IsNullOrEmpty(relativePath))
{
from = string.Concat(_Configuration.PropertyConfiguration.RootDirectory, relativePath);
to = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
foreach (string outputResolution in _Configuration.ValidResolutions)
{
add = Directory.Exists(string.Concat(Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()"), relativePath));
bMetadataSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(B_Metadata), "{}");
from = string.Concat(bMetadataSingletonDirectory, relativePath);
exists = Directory.Exists(bMetadataSingletonDirectory);
if (exists)
{
to = Path.Combine(string.Concat(bMetadataSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
from = string.Concat(aPropertySingletonDirectory, relativePath);
exists = Directory.Exists(aPropertySingletonDirectory);
if (exists)
{
to = Path.Combine(string.Concat(aPropertySingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
cResizeContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()");
from = string.Concat(cResizeContentDirectory, relativePath);
exists = Directory.Exists(cResizeContentDirectory);
if (exists)
{
to = Path.Combine(string.Concat(cResizeContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
cResizeSingletonDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "{}");
from = string.Concat(cResizeSingletonDirectory, relativePath);
exists = Directory.Exists(cResizeSingletonDirectory);
if (exists)
{
to = Path.Combine(string.Concat(cResizeSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
from = string.Concat(dFacesContentDirectory, relativePath);
exists = Directory.Exists(dFacesContentDirectory);
if (exists)
{
to = Path.Combine(string.Concat(dFacesContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
dFacesCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
from = string.Concat(dFacesCollectionDirectory, relativePath);
exists = Directory.Exists(dFacesCollectionDirectory);
if (exists)
{
to = Path.Combine(string.Concat(dFacesCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
d2FaceLandmarksContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
from = string.Concat(d2FaceLandmarksContentDirectory, relativePath);
exists = Directory.Exists(d2FaceLandmarksContentDirectory);
if (!exists && add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
results.Add(new string[] { from });
else if (exists)
{
to = Path.Combine(string.Concat(d2FaceLandmarksContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
eDistanceContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
from = string.Concat(eDistanceContentDirectory, relativePath);
exists = Directory.Exists(eDistanceContentDirectory);
if (exists)
{
to = Path.Combine(string.Concat(eDistanceContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
from = string.Concat(eDistanceCollectionDirectory, relativePath);
exists = Directory.Exists(eDistanceCollectionDirectory);
if (exists)
{
to = Path.Combine(string.Concat(eDistanceCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
g2IdentifyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
from = string.Concat(g2IdentifyCollectionDirectory, relativePath);
exists = Directory.Exists(g2IdentifyCollectionDirectory);
if (!exists && add && jsonFiles4InfoAny)
results.Add(new string[] { from });
else if (exists)
{
to = Path.Combine(string.Concat(g2IdentifyCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
results.Add(new string[] { from, to });
}
}
return results;
}
internal void DirectoryRename(Property.Models.Configuration configuration, string relativePath, string newDirectoryName)
{
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
string json;
FileInfo current;
FileInfo fileInfo;
string error = "Error";
string target = "Target";
string pending = "Pending";
DirectoryInfo directoryInfo;
IEnumerator<FileInfo> fileInfoCollection;
string oldValue = string.Concat("\"", relativePath);
string oldDirectoryName = Path.GetFileName(relativePath);
string traceFileName = string.Concat(DateTime.Now.Ticks, ".tsv");
string directoryName = Path.GetFileName(_Configuration.PropertyConfiguration.RootDirectory);
string? relativePathParent = Path.GetDirectoryName(relativePath);
if (string.IsNullOrEmpty(relativePathParent))
throw new Exception();
string newValue = string.Concat("\"", Path.Combine(relativePathParent, newDirectoryName));
string e3RenameContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(E3_Rename), "()");
string jsonRootDirectory = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, " - Copied"), string.Concat(directoryName, " - 4) Info"), _Configuration.PropertyConfiguration.DateGroup, "[]");
directoryInfo = new DirectoryInfo(jsonRootDirectory);
if (!directoryInfo.Exists)
directoryInfo.Create();
IEnumerator<FileInfo> fileInfoCollection4 = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
bool fileInfoCollection4MoveNext = fileInfoCollection4.MoveNext();
if (!fileInfoCollection4MoveNext)
current = new(string.Empty);
else
current = fileInfoCollection4.Current;
List<string[]> directoryCollections = GetDirectoryRenameCollections(configuration, relativePath, newDirectoryName, fileInfoCollection4MoveNext);
if ((from l in directoryCollections where l.Length != 2 select true).Any())
throw new Exception();
if (!Directory.Exists(e3RenameContentDirectory))
{
_ = Directory.CreateDirectory(e3RenameContentDirectory);
_ = Directory.CreateDirectory(Path.Combine(e3RenameContentDirectory, error));
_ = Directory.CreateDirectory(Path.Combine(e3RenameContentDirectory, target));
_ = Directory.CreateDirectory(Path.Combine(e3RenameContentDirectory, "Test"));
_ = Directory.CreateDirectory(Path.Combine(e3RenameContentDirectory, pending));
}
string fRandomSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "{}");
string[] files = Directory.GetFiles(fRandomSingletonDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
File.Delete(file);
File.WriteAllText(Path.Combine(e3RenameContentDirectory, pending, traceFileName), string.Concat(relativePath, newDirectoryName, Environment.NewLine));
try
{
foreach (string[] directoryCollection in directoryCollections)
{
directoryInfo = new DirectoryInfo(directoryCollection[0]);
if (!directoryInfo.Exists)
continue;
fileInfoCollection = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
for (int i = 0; i < int.MaxValue; i++)
{
if (fileInfoCollection.MoveNext())
fileInfo = fileInfoCollection.Current;
else if (fileInfoCollection4MoveNext && fileInfoCollection4.MoveNext())
fileInfo = fileInfoCollection4.Current;
else if (fileInfoCollection4MoveNext && current is not null)
{
fileInfo = current;
current = new(string.Empty);
}
else
break;
json = Shared.Models.Stateless.Methods.IIndex.GetJson(fileInfo.FullName, fileInfo);
if (json.Contains(oldValue))
{
json = json.Replace(oldValue, newValue);
if (!Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true))
continue;
File.SetLastWriteTime(fileInfo.FullName, fileInfo.LastWriteTime);
}
}
Directory.Move(directoryCollection[0], directoryCollection[1]);
}
File.Move(Path.Combine(e3RenameContentDirectory, pending, traceFileName), Path.Combine(e3RenameContentDirectory, target, traceFileName));
}
catch (Exception)
{
File.Move(Path.Combine(e3RenameContentDirectory, pending, traceFileName), Path.Combine(e3RenameContentDirectory, error, traceFileName));
throw;
}
}
internal void RenameQueue(Property.Models.Configuration configuration)
{
string[] lines;
string[] segments;
string e3RenameContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(E3_Rename), "()");
string[] files = Directory.GetFiles(e3RenameContentDirectory, "*.tsv", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
lines = File.ReadAllLines(file);
foreach (string line in lines)
{
if (string.IsNullOrEmpty(line) || !line.Contains('\t'))
continue;
segments = line.Split('\t');
if (segments.Length != 2)
throw new Exception();
DirectoryRename(configuration, segments[0], segments[1]);
}
}
}
}

View File

@ -0,0 +1,390 @@
using FaceRecognitionDotNet;
using System.Text;
using System.Text.Json;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Property.Models;
using View_by_Distance.Resize.Models;
namespace View_by_Distance.Instance.Models;
/// <summary>
// List<D_Faces>
/// </summary>
internal class E_Distance
{
private readonly Serilog.ILogger? _Log;
private readonly Configuration _Configuration;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
internal E_Distance(Configuration configuration)
{
_Configuration = configuration;
_Log = Serilog.Log.ForContext<E_Distance>();
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
private static void LoadFaceEncodingCollections(string[] subFiles, List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<FaceEncoding> faceEncodingCollection, List<List<FaceEncoding>> faceEncodingCollections)
{
List<D_Face> faceCollection;
FaceEncoding faceEncoding;
for (int i = 0; i < subFiles.Length; i++)
{
faceCollection = faceCollections[i];
if (!faceCollection.Any())
throw new Exception();
faceEncodingCollections.Add(new List<FaceEncoding>());
for (int j = 0; j < faceCollection.Count; j++)
{
if (!faceCollection[j].Populated)
continue;
faceEncoding = FaceRecognition.LoadFaceEncoding(faceCollection[j].FaceEncoding.RawEncoding);
faceEncodingCollection.Add(faceEncoding);
faceEncodingCollections[i].Add(faceEncoding);
locationIndicesCollection.Add(new int[] { i, j });
}
}
}
private List<Tuple<Shared.Models.Properties.IFace, string>> GetOrderedNoFaceCollection(List<List<D_Face>> faceCollections, int i, D_Face face)
{
List<Tuple<Shared.Models.Properties.IFace, string>> results = new() { new(face, string.Empty) };
if (_Configuration.MaxItemsInDistanceCollection is null)
throw new Exception();
for (int n = 0; n < faceCollections.Count; n++)
{
if (i == n)
continue;
for (int j = 0; j < faceCollections[n].Count; j++)
results.Add(new(faceCollections[n][j], string.Empty));
}
for (int r = results.Count - 1; r > _Configuration.MaxItemsInDistanceCollection.Value; r--)
results.RemoveAt(r);
return results;
}
private List<double[]> GetValues(List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, double[] faceDistances)
{
List<double[]> results = new();
if (_Configuration.LocationConfidenceFactor is null)
throw new Exception();
if (_Configuration.DistanceFactor is null)
throw new Exception();
D_Face face;
int[] locationIndices;
for (int d = 0; d < faceDistances.Length; d++)
{
locationIndices = locationIndicesCollection[d];
face = faceCollections[locationIndices[0]][locationIndices[1]];
if (face.Populated && face.LocationIndex is not null && locationIndices[1] != face.LocationIndex)
throw new Exception();
results.Add(new double[] { d, faceDistances[d], (faceDistances[d] * _Configuration.DistanceFactor.Value) + face.Location.Confidence * _Configuration.LocationConfidenceFactor.Value / 10 });
}
results = (from l in results orderby l[2] select l).ToList();
return results;
}
private List<Tuple<Shared.Models.Properties.IFace, string>> GetOrderedFaceCollection(List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<double[]> indicesAndValues)
{
List<Tuple<Shared.Models.Properties.IFace, string>> results = new();
if (_Configuration.MaxItemsInDistanceCollection is null)
throw new Exception();
int[] locationIndices;
for (int t = 0; t < indicesAndValues.Count; t++)
{
locationIndices = locationIndicesCollection[(int)indicesAndValues[t][0]];
results.Add(new(faceCollections[locationIndices[0]][locationIndices[1]], string.Join('|', (from l in indicesAndValues[t] select l.ToString("0.000")).ToArray(), 1, indicesAndValues[t].Length - 1)));
}
for (int r = results.Count - 1; r > _Configuration.MaxItemsInDistanceCollection.Value; r--)
results.RemoveAt(r);
return results;
}
private static string GetText(string fileNameWithoutExtension, List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<double[]> indicesAndValues)
{
string result;
D_Face face;
int[] locationIndices;
StringBuilder tvs = new();
_ = tvs.Append("FileNameWithoutExtension").Append('\t').Append("LocationIndex").Append('\t').Append("FaceConfidence").Append('\t').Append("FaceDistance").Append('\t').Append("FactoredValue").AppendLine();
for (int t = 0; t < indicesAndValues.Count; t++)
{
locationIndices = locationIndicesCollection[(int)indicesAndValues[t][0]];
face = faceCollections[locationIndices[0]][locationIndices[1]];
if (face.Populated && face.LocationIndex is not null && locationIndices[1] != face.LocationIndex)
throw new Exception();
_ = tvs.Append(fileNameWithoutExtension).Append('\t').Append(face.LocationIndex).Append('\t').Append(face.Location.Confidence).Append('\t').Append(indicesAndValues[t][1]).Append('\t').Append(indicesAndValues[t][2]).AppendLine();
}
result = tvs.ToString();
return result;
}
private void LoadOrCreateThenSaveDistanceResultsLoop(Property.Models.Configuration configuration, List<List<D_Face>> faceCollections, int subFilesCount, int i, List<D_Face> faceCollection, List<int[]> locationIndicesCollection, List<Tuple<string, DateTime>> subFileTuples, List<FaceEncoding> faceEncodingCollection, List<FaceEncoding> faceEncodingCollections, string fileNameWithoutExtension, string jsonDirectory, string tvsDirectory)
{
string text;
string json;
string jsonFile;
List<Tuple<Shared.Models.Properties.IFace, string>> orderedFaceCollection;
if (!Directory.Exists(jsonDirectory))
_ = Directory.CreateDirectory(jsonDirectory);
if (!Directory.Exists(tvsDirectory))
_ = Directory.CreateDirectory(tvsDirectory);
if (!faceEncodingCollections.Any())
{
int j = 0;
orderedFaceCollection = GetOrderedNoFaceCollection(faceCollections, i, faceCollection[j]);
json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions);
jsonFile = Path.Combine(jsonDirectory, $"{j} - {fileNameWithoutExtension}.json");
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
}
else
{
string tvsFile;
double[] faceDistances;
List<double[]> indicesAndValues;
for (int j = 0; j < faceEncodingCollections.Count; j++)
{
if (!faceCollection[j].Populated)
continue;
tvsFile = Path.Combine(tvsDirectory, $"{j} - {fileNameWithoutExtension}.tvs");
jsonFile = Path.Combine(jsonDirectory, $"{j} - {fileNameWithoutExtension}.json");
faceDistances = FaceRecognition.FaceDistances(faceEncodingCollection, faceEncodingCollections[j]).ToArray();
indicesAndValues = GetValues(faceCollections, locationIndicesCollection, faceDistances);
orderedFaceCollection = GetOrderedFaceCollection(faceCollections, locationIndicesCollection, indicesAndValues);
text = GetText(fileNameWithoutExtension, faceCollections, locationIndicesCollection, indicesAndValues);
if (Property.Models.Stateless.IPath.WriteAllText(tvsFile, text, compareBeforeWrite: true))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
}
}
}
private void LoadOrCreateThenSaveDistanceResults(Property.Models.Configuration configuration, string[] subFiles, List<List<D_Face>> faceCollections, List<string[]> directories)
{
string fileNameWithoutExtension;
List<int[]> locationIndicesCollection = new();
List<Tuple<string, DateTime>> subFileTuples = new();
List<FaceEncoding> faceEncodingCollection = new();
List<List<FaceEncoding>> faceEncodingCollections = new();
LoadFaceEncodingCollections(subFiles, faceCollections, locationIndicesCollection, faceEncodingCollection, faceEncodingCollections);
if (faceEncodingCollections.Count != faceCollections.Count)
throw new Exception();
if (locationIndicesCollection.Count != faceEncodingCollection.Count)
throw new Exception();
for (int i = 0; i < subFiles.Length; i++)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(subFiles[i]);
LoadOrCreateThenSaveDistanceResultsLoop(configuration, faceCollections, subFiles.Length, i, faceCollections[i], locationIndicesCollection, subFileTuples, faceEncodingCollection, faceEncodingCollections[i], fileNameWithoutExtension, directories[i][0], directories[i][1]);
}
}
internal void LoadOrCreateThenSaveDistanceResults(Property.Models.Configuration configuration, string sourceDirectory, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, string[] subFiles, List<List<D_Face>> faceCollections)
{
if (_Configuration.CheckJsonForDistanceResults is null)
throw new Exception();
if (_Configuration.PropertiesChangedForDistance is null)
throw new Exception();
string json;
bool check = false;
string parentCheck;
DirectoryInfo directoryInfo;
DirectoryInfo tvsDirectoryInfo;
string fileNameWithoutExtension;
List<string[]> directories = new();
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
List<DateTime> dateTimes = (from l in sourceDirectoryChanges where changesFrom.Contains(l.Item1) select l.Item2).ToList();
List<string> directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
sourceDirectory,
nameof(E_Distance),
outputResolution,
includeResizeGroup: true,
includeModel: true,
includePredictorModel: true,
contentDescription: ".tvs File",
singletonDescription: string.Empty,
collectionDescription: "n json file(s) for each face found (one to many)");
for (int i = 0; i < subFiles.Length; i++)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(subFiles[i]);
directoryInfo = new DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), fileNameWithoutExtension));
if (!directoryInfo.Exists)
{
if (directoryInfo.Parent?.Parent is null)
throw new Exception();
parentCheck = Path.Combine(directoryInfo.Parent.Parent.FullName, directoryInfo.Name);
if (Directory.Exists(parentCheck))
{
foreach (string file in Directory.GetFiles(parentCheck))
File.Delete(file);
Directory.Delete(parentCheck);
}
}
tvsDirectoryInfo = new DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "()"), fileNameWithoutExtension));
directories.Add(new string[] { directoryInfo.FullName, tvsDirectoryInfo.FullName });
if (_Configuration.CheckJsonForDistanceResults.Value && directoryInfo.Exists)
{
foreach (FileInfo fileInfo in directoryInfo.GetFiles("*.json", SearchOption.AllDirectories))
{
json = Shared.Models.Stateless.Methods.IIndex.GetJson(fileInfo.FullName, fileInfo);
if (!_Configuration.PropertiesChangedForDistance.Value && Shared.Models.Stateless.Methods.IFace.GetFace(fileInfo.FullName) is null)
check = true;
}
}
if (check)
continue;
if (_Configuration.PropertiesChangedForDistance.Value)
check = true;
else if (!directoryInfo.Exists)
check = true;
else if (!tvsDirectoryInfo.Exists)
check = true;
else if (dateTimes.Any() && dateTimes.Max() > directoryInfo.LastWriteTime)
check = true;
}
if (check)
LoadOrCreateThenSaveDistanceResults(configuration, subFiles, faceCollections, directories);
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()"));
}
private List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> GetFiles(Property.Models.Configuration configuration, string outputResolution)
{
string json;
List<KeyValuePair<string, Shared.Models.Face[]>>? facesKeyValuePairCollection;
List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> results = new();
string dFacesCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[[]]");
string[] dFacesCollectionFiles = Directory.GetFiles(dFacesCollectionDirectory, "*.json", SearchOption.TopDirectoryOnly);
foreach (string dFacesCollectionFile in dFacesCollectionFiles)
{
json = File.ReadAllText(dFacesCollectionFile);
facesKeyValuePairCollection = JsonSerializer.Deserialize<List<KeyValuePair<string, Shared.Models.Face[]>>>(json);
if (facesKeyValuePairCollection is null)
continue;
results.Add(new(dFacesCollectionFile, facesKeyValuePairCollection));
}
return results;
}
private static List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> GetMatches(List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> files)
{
List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> results = new();
List<Shared.Models.Face> faces;
FaceEncoding faceEncoding;
List<FaceEncoding> faceEncodings;
foreach ((string, List<KeyValuePair<string, Shared.Models.Face[]>>) file in files)
{
faces = new();
faceEncodings = new();
foreach (KeyValuePair<string, Shared.Models.Face[]> keyValuePair in file.Item2)
{
foreach (Shared.Models.Face face in keyValuePair.Value)
{
if (!face.Populated)
continue;
faces.Add(face);
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
faceEncodings.Add(faceEncoding);
}
}
results.Add(new(file.Item1, faces, faceEncodings));
}
return results;
}
private static int GetIndex(double[] faceDistances)
{
int result;
List<double[]> faceDistancesWithIndex = new();
for (int y = 0; y < faceDistances.Length; y++)
faceDistancesWithIndex.Add(new double[] { faceDistances[y], y });
faceDistancesWithIndex = (from l in faceDistancesWithIndex orderby l[0] select l).ToList();
result = (int)faceDistancesWithIndex[0][1];
return result;
}
private void Save(Property.Models.Configuration configuration, string outputResolution, string eDistanceCollectionDirectory, int k, string relativePath, Shared.Models.Face face, List<Tuple<Shared.Models.Face, string>> faceAndFaceDistanceCollection)
{
if (string.IsNullOrEmpty(eDistanceCollectionDirectory))
eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(face.RelativePath);
string jsonDirectory = string.Concat(eDistanceCollectionDirectory, Path.Combine(relativePath, fileNameWithoutExtension));
if (!Directory.Exists(jsonDirectory))
_ = Directory.CreateDirectory(jsonDirectory);
string json = JsonSerializer.Serialize(faceAndFaceDistanceCollection, _WriteIndentedJsonSerializerOptions);
string jsonFile = Path.Combine(jsonDirectory, $"{k} - {fileNameWithoutExtension}.nosj");
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true);
}
private static Tuple<Shared.Models.Face, double> Get(FaceEncoding faceEncoding, (string, List<Shared.Models.Face>, List<FaceEncoding>) match)
{
Tuple<Shared.Models.Face, double> result;
double[] faceDistances = FaceRecognition.FaceDistances(match.Item3, faceEncoding).ToArray();
int index = GetIndex(faceDistances);
result = new(match.Item2[index], faceDistances[index]);
return result;
}
internal void LoadOrCreateThenSaveDirectoryDistanceResults(Property.Models.Configuration configuration, string outputResolution)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
string? relativePath;
Shared.Models.Face face;
ParallelOptions parallelOptions = new();
FaceEncoding faceEncoding;
string eDistanceCollectionDirectory = string.Empty;
Tuple<Shared.Models.Face, double> faceAndFaceDistance;
List<Tuple<Shared.Models.Face, string>> faceAndFaceDistanceCollection;
List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> files = GetFiles(configuration, outputResolution);
List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> matches = GetMatches(files);
if (files.Count != matches.Count)
throw new Exception();
int filesCount = files.Count;
for (int i = 0; i < filesCount; i++)
{
if (_Configuration.CrossDirectoryMaxItemsInDistanceCollection is null)
continue;
_Log.Debug(string.Concat("LoadOrCreateThenSaveDirectoryDistanceResults - ", nameof(outputResolution), ' ', outputResolution, " - ", i, " of ", filesCount));
for (int j = 0; j < files[i].Item2.Count; j++)
{
if (!matches[i].Item2.Any())
continue;
for (int k = 0; k < files[i].Item2[j].Value.Length; k++)
{
if (!files[i].Item2[j].Value[k].Populated)
continue;
face = files[i].Item2[j].Value[k];
faceAndFaceDistanceCollection = new(matches.Count);
relativePath = Path.GetDirectoryName(face.RelativePath);
if (string.IsNullOrEmpty(relativePath))
continue;
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
_ = Parallel.For(0, matches.Count, parallelOptions, z =>
{
if (z != i && matches[z].Item2.Any())
{
faceAndFaceDistance = Get(faceEncoding, matches[z]);
// if (faceAndFaceDistance.Item2 < _Configuration.)
faceAndFaceDistanceCollection.Add(new(faceAndFaceDistance.Item1, faceAndFaceDistance.Item2.ToString("0.000")));
}
});
if (faceAndFaceDistanceCollection.Any())
{
faceAndFaceDistanceCollection = (from l in faceAndFaceDistanceCollection orderby l.Item2 select l).Take(_Configuration.CrossDirectoryMaxItemsInDistanceCollection.Value).ToList();
Save(configuration, outputResolution, eDistanceCollectionDirectory, k, relativePath, face, faceAndFaceDistanceCollection);
}
}
}
}
}
}

View File

@ -0,0 +1,90 @@
using System.Text.Json;
namespace View_by_Distance.Instance.Models;
/// <summary>
// List<string>
/// </summary>
internal class F_Random
{
private readonly Serilog.ILogger? _Log;
private readonly Configuration _Configuration;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
internal F_Random(Configuration configuration)
{
_Configuration = configuration;
_Log = Serilog.Log.ForContext<F_Random>();
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = false };
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
private bool IsIgnoreRelativePath(string directory)
{
bool result = false;
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
string? checkDirectory = Path.GetFullPath(directory);
for (int i = 0; i < int.MaxValue; i++)
{
if (_Configuration.IgnoreRelativePaths.Contains(Path.GetFileName(checkDirectory)))
{
result = true;
break;
}
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == _Configuration.PropertyConfiguration.RootDirectory)
break;
}
return result;
}
internal void Random(Property.Models.Configuration configuration, string outputResolution, List<KeyValuePair<string, string>> fileKeyValuePairs)
{
if (_Configuration.SaveFullYearOfRandomFiles is null)
throw new Exception();
string json;
string jsonFile;
Random random = new();
List<string> relativePaths = new();
List<string> ignoreRelativePaths = new();
DateTime dateTime = new(2024, 1, 1); //Leap year
string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]");
string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
File.Delete(file);
foreach (KeyValuePair<string, string> keyValuePair in fileKeyValuePairs)
{
if (!(from l in _Configuration.IgnoreRelativePaths where keyValuePair.Key.Contains(l) && IsIgnoreRelativePath(keyValuePair.Key) select true).Any())
relativePaths.Add(keyValuePair.Value);
else
ignoreRelativePaths.Add(keyValuePair.Value);
}
if (relativePaths.Any())
{
for (int i = 0; i < 366; i++)
{
relativePaths = (from l in relativePaths orderby random.NextDouble() select l).ToList();
jsonFile = Path.Combine(fRandomCollectionDirectory, $"{dateTime.AddDays(i):MM-dd}.json");
json = JsonSerializer.Serialize(relativePaths, _WriteIndentedJsonSerializerOptions);
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: false);
if (!_Configuration.SaveFullYearOfRandomFiles.Value)
break;
}
}
if (ignoreRelativePaths.Any())
{
ignoreRelativePaths = (from l in ignoreRelativePaths orderby random.NextDouble() select l).ToList();
jsonFile = Path.Combine(fRandomCollectionDirectory, "01-01.txt");
json = JsonSerializer.Serialize(ignoreRelativePaths, _WriteIndentedJsonSerializerOptions);
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: false);
}
}
}

View File

@ -0,0 +1,229 @@
using Phares.Shared;
using System.Text.Json;
using System.Text.Json.Serialization;
using View_by_Distance.Property.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Methods;
namespace View_by_Distance.Instance.Models;
/// <summary>
// List<G2_Identify>
/// </summary>
public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
{
protected int _DirectoryCount;
protected string _ParentDirectoryName;
protected string _Person;
protected string _PossibleYear;
protected string _RelativePath;
public int DirectoryCount => _DirectoryCount;
public string ParentDirectoryName => _ParentDirectoryName;
public string Person => _Person;
public string PossibleYear => _PossibleYear;
public string RelativePath => _RelativePath;
private readonly Serilog.ILogger? _Log;
private readonly Configuration _Configuration;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
#nullable disable
[JsonConstructor]
public G2_Identify(int directoryCount, string parentDirectoryName, string person, string possibleYear, string relativePath)
{
_DirectoryCount = directoryCount;
_ParentDirectoryName = parentDirectoryName;
_Person = person;
_PossibleYear = possibleYear;
_RelativePath = relativePath;
}
internal G2_Identify(Configuration configuration)
{
_DirectoryCount = 0;
_ParentDirectoryName = string.Empty;
_Person = string.Empty;
_PossibleYear = string.Empty;
_RelativePath = string.Empty;
_Configuration = configuration;
_Log = Serilog.Log.ForContext<G2_Identify>();
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
private FileInfo GetNamed()
{
FileInfo result;
string[] jsonFiles = Directory.GetFiles(_Configuration.PropertyConfiguration.RootDirectory, "*Named*.json", SearchOption.TopDirectoryOnly);
if (!jsonFiles.Any())
result = null;
else
result = new FileInfo(jsonFiles[0]);
return result;
}
private void CheckLastWriteTimes(Property.Models.Configuration configuration, IsEnvironment isEnvironment, A2_People a2People, FileInfo named, string g2IdentifySingletonDirectory)
{
string json;
FileInfo fileInfo;
DateTime dateTime = DateTime.MinValue;
string[] jsonFiles = Directory.GetFiles(g2IdentifySingletonDirectory, "*.json", SearchOption.AllDirectories);
foreach (string jsonFile in jsonFiles)
{
fileInfo = new(jsonFile);
if (dateTime < fileInfo.LastWriteTime)
dateTime = fileInfo.LastWriteTime;
}
if (named.LastWriteTime > dateTime)
{
if (!isEnvironment.DebuggerWasAttachedDuringConstructor)
throw new Exception("Only allowed when debugger is attached during constructor!");
foreach (string file in jsonFiles)
File.Delete(file);
}
json = File.ReadAllText(named.FullName);
Person[] people = a2People.GetPeople(configuration);
Dictionary<string, string[]> resultKeyValuePairs = new();
string[] peopleBirthdates = (from l in people select Shared.Models.Stateless.Methods.IPersonBirthday.GetFormated(l.Birthday)).ToArray();
Dictionary<string, string[]> sourceKeyValuePairs = JsonSerializer.Deserialize<Dictionary<string, string[]>>(json);
foreach (KeyValuePair<string, string[]> keyValuePair in sourceKeyValuePairs)
{
if (!(from l in keyValuePair.Value where peopleBirthdates.Contains(l) select false).Any())
continue;
resultKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value);
}
if (resultKeyValuePairs.Count != sourceKeyValuePairs.Count)
{
json = JsonSerializer.Serialize(resultKeyValuePairs, _WriteIndentedJsonSerializerOptions);
if (!isEnvironment.DebuggerWasAttachedDuringConstructor)
throw new Exception("Only allowed when debugger is attached during constructor!");
_ = Property.Models.Stateless.IPath.WriteAllText(named.FullName, json, compareBeforeWrite: true);
}
}
internal List<G2_Identify> GetIdentifiedCollection(Property.Models.Configuration configuration, IsEnvironment isEnvironment, A2_People a2People)
{
List<G2_Identify> results = new();
string json;
string[] people;
string[] jsonFiles;
int directoryCount;
string possibleYear;
G2_Identify identify;
FileInfo named = GetNamed();
string testDirectoryFullName;
string checkDirectoryFullName;
Dictionary<int, string[]> keyValuePairs;
List<string> missing = new();
List<G_Index> indices = new();
string directoryName = Path.GetFileName(_Configuration.PropertyConfiguration.RootDirectory);
string g2IdentifySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
string jsonRootDirectory = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, " - Copied"), string.Concat(directoryName, " - 4) Info"), _Configuration.PropertyConfiguration.DateGroup, "[]");
if (named is not null && named.Exists)
CheckLastWriteTimes(configuration, isEnvironment, a2People, named, g2IdentifySingletonDirectory);
if (Directory.Exists(jsonRootDirectory))
{
jsonFiles = Directory.GetFiles(jsonRootDirectory, "*.json", SearchOption.AllDirectories);
for (int i = 0; i < jsonFiles.Length; i++)
{
json = Shared.Models.Stateless.Methods.IIndex.GetJson(jsonFiles[i], fileInfo: null);
indices.AddRange(JsonSerializer.Deserialize<List<G_Index>>(json));
}
if (named is not null && named.Exists)
{
json = File.ReadAllText(named.FullName);
keyValuePairs = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
foreach (G_Index index in indices)
{
if (index?.Index is null)
continue;
if (!keyValuePairs.ContainsKey(index.Index.Value))
{
missing.Add(index.Index.Value.ToString());
continue;
}
if (index.RelativePaths is null)
{
missing.Add(index.Index.Value.ToString());
continue;
}
people = keyValuePairs[index.Index.Value];
foreach (string relativePath in index.RelativePaths)
{
foreach (string person in people)
{
directoryCount = 0;
checkDirectoryFullName = string.Concat(_Configuration.PropertyConfiguration.RootDirectory, relativePath);
for (int i = 0; i < int.MaxValue; i++)
{
testDirectoryFullName = Path.GetDirectoryName(checkDirectoryFullName);
if (testDirectoryFullName == _Configuration.PropertyConfiguration.RootDirectory)
break;
directoryCount += 1;
checkDirectoryFullName = testDirectoryFullName;
}
possibleYear = checkDirectoryFullName.Split(' ').Last();
if (possibleYear.Length != 4)
possibleYear = "0000";
identify = new G2_Identify(directoryCount, Path.GetFileName(checkDirectoryFullName), person, possibleYear, relativePath);
results.Add(identify);
}
}
}
}
}
results = (from l in results orderby l.PossibleYear descending, l.DirectoryCount, l.ParentDirectoryName, l.RelativePath select l).ToList();
return results;
}
internal void WriteAllText(Property.Models.Configuration configuration, string outputResolution, List<G2_Identify> identifiedCollection)
{
string key;
string json;
string jsonFile;
string directoryFullName;
string fileNameWithoutExtension;
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
string g2IdentifyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
Dictionary<string, List<KeyValuePair<string, string>>> keyValuePairs = new();
foreach (G2_Identify identified in identifiedCollection)
{
key = Path.GetDirectoryName(identified.RelativePath);
if (!keyValuePairs.ContainsKey(key))
keyValuePairs.Add(key, new List<KeyValuePair<string, string>>());
keyValuePairs[key].Add(new KeyValuePair<string, string>(identified.RelativePath, identified.Person));
}
foreach (KeyValuePair<string, List<KeyValuePair<string, string>>> keyValuePair in keyValuePairs)
{
directoryFullName = string.Concat(aPropertySingletonDirectory, keyValuePair.Key);
if (!Directory.Exists(directoryFullName))
continue;
foreach (KeyValuePair<string, string> keyValue in keyValuePair.Value)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(keyValue.Key);
jsonFile = Path.Combine(directoryFullName, $"{fileNameWithoutExtension}.json");
if (!File.Exists(jsonFile))
{
directoryFullName = string.Empty;
break;
}
}
if (string.IsNullOrEmpty(directoryFullName))
continue;
directoryFullName = Path.GetDirectoryName(string.Concat(g2IdentifyCollectionDirectory, keyValuePair.Key));
if (!Directory.Exists(directoryFullName))
_ = Directory.CreateDirectory(directoryFullName);
jsonFile = string.Concat(g2IdentifyCollectionDirectory, keyValuePair.Key, ".json");
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true))
continue;
}
}
}

213
Instance/Models/_G_Index.cs Normal file
View File

@ -0,0 +1,213 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using View_by_Distance.Property.Models;
using View_by_Distance.Shared.Models.Methods;
namespace View_by_Distance.Instance.Models;
/// <summary>
// G_Index && G_Index[]
/// </summary>
public class G_Index : Shared.Models.Properties.IIndex, IIndex
{
private readonly Serilog.ILogger? _Log;
private readonly Configuration _Configuration;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
protected DateTime? _DateTime;
protected int? _Index;
protected List<string> _RelativePaths;
public DateTime? DateTime => _DateTime;
public int? Index => _Index;
public List<string> RelativePaths => _RelativePaths;
#nullable disable
[JsonConstructor]
public G_Index(DateTime? dateTime, int? index, List<string> relativePaths)
{
_DateTime = dateTime;
_Index = index;
_RelativePaths = relativePaths;
}
internal G_Index()
{
_DateTime = null;
_Index = null;
_RelativePaths = new();
}
internal G_Index(Configuration configuration)
{
_Configuration = configuration;
_Log = Serilog.Log.ForContext<G_Index>();
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
private G_Index GetIndexInfo(FileInfo fileInfo, List<string> parseExceptions)
{
G_Index result;
List<int> indices = new();
string json = File.ReadAllText(fileInfo.FullName);
try
{
result = JsonSerializer.Deserialize<G_Index>(json);
}
catch (Exception)
{
result = null;
parseExceptions.Add(nameof(G_Index));
}
if (_Configuration.MappedMaxIndex.HasValue && result.Index.HasValue && _Configuration.MappedMaxIndex.Value < result.Index.Value)
{
result = null;
File.Delete(fileInfo.FullName);
}
else if (result.Index is null)
result = null;
return result;
}
private void WriteNeeded(List<int> indices, List<Tuple<List<string>, string, A_Property>> neededTuples)
{
string json;
DateTime dateTime;
A_Property property;
G_Index indexInfo;
int maxIndexPlusOne;
DateTime?[] dateTimes;
if (indices.Any())
maxIndexPlusOne = indices.Max() + 1;
else
{
maxIndexPlusOne = 1000000;
throw new Exception("Are you sure exception. Use debugger to step over.");
}
foreach (Tuple<List<string>, string, A_Property> tuple in neededTuples)
{
maxIndexPlusOne += 1;
property = tuple.Item3;
dateTimes = new DateTime?[] { property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
dateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
indexInfo = new(dateTime, maxIndexPlusOne, tuple.Item1);
json = JsonSerializer.Serialize(indexInfo, _WriteIndentedJsonSerializerOptions);
if (!Property.Models.Stateless.IPath.WriteAllText(tuple.Item2, json, compareBeforeWrite: true))
continue;
}
}
private void WriteGroup(Property.Models.Configuration configuration, string outputResolution, List<Tuple<string, Dictionary<int, G_Index>>> indexInfoTuples)
{
string json;
G_Index[] indices;
List<string> directoryInfoCollection;
foreach (Tuple<string, Dictionary<int, G_Index>> tuple in indexInfoTuples)
{
indices = (from l in tuple.Item2 select l.Value).ToArray();
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, tuple.Item1, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: string.Empty, collectionDescription: "Unknown A");
json = JsonSerializer.Serialize(indices, _WriteIndentedJsonSerializerOptions);
if (!Property.Models.Stateless.IPath.WriteAllText(string.Concat(directoryInfoCollection[0].Replace("<>", "[]"), ".json"), json, compareBeforeWrite: true))
continue;
}
}
private void AppendTSV(Property.Models.Configuration configuration, string outputResolution, Dictionary<string, List<Tuple<string, A_Property>>> filePropertiesKeyValuePairs)
{
A_Property property;
DateTime?[] dateTimes;
DateTime? maximumDateTime;
DateTime? minimumDateTime;
List<string> directoryInfoCollection;
long ticks = System.DateTime.Now.Ticks;
foreach (KeyValuePair<string, List<Tuple<string, A_Property>>> tuples in filePropertiesKeyValuePairs)
{
maximumDateTime = null;
minimumDateTime = null;
foreach (Tuple<string, A_Property> tuple in tuples.Value)
{
property = tuple.Item2;
dateTimes = new DateTime?[] { maximumDateTime, minimumDateTime, property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
maximumDateTime = (from l in dateTimes where l.HasValue select l.Value).Max();
minimumDateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
}
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, tuples.Key, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: "Unkown B", collectionDescription: string.Empty);
}
}
internal void SetIndex(Property.Models.Configuration configuration, string outputResolution, Dictionary<string, List<Tuple<string, A_Property>>> filePropertiesKeyValuePairs)
{
if (_Configuration.PropertiesChangedForIndex is null)
throw new Exception();
FileInfo fileInfo;
G_Index indexInfo;
string parentCheck;
List<int> indices = new();
Dictionary<int, G_Index> valuePairs;
List<string> directoryInfoCollection;
List<string> parseExceptions = new();
List<Tuple<List<string>, string, A_Property>> neededTuples = new();
List<Tuple<string, Dictionary<int, G_Index>>> indexInfoTuples = new();
for (short i = 0; i < short.MaxValue; i++)
{
if (i != 0)
{
if (!neededTuples.Any() && !parseExceptions.Any())
break;
indices.Clear();
indexInfoTuples.Clear();
parseExceptions.Clear();
}
neededTuples.Clear();
foreach (KeyValuePair<string, List<Tuple<string, A_Property>>> tuples in filePropertiesKeyValuePairs)
{
valuePairs = new Dictionary<int, G_Index>();
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, tuples.Key, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: "Unknown C", collectionDescription: string.Empty);
foreach (Tuple<string, A_Property> tuple in tuples.Value)
{
fileInfo = new FileInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "{}"), string.Concat(Path.GetFileNameWithoutExtension(tuple.Item1), ".json")));
if (!fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
File.Delete(parentCheck);
}
if (_Configuration.PropertiesChangedForIndex.Value)
indexInfo = null;
else if (!fileInfo.Exists)
indexInfo = null;
else
indexInfo = GetIndexInfo(fileInfo, parseExceptions);
if (indexInfo?.Index is not null)
{
indices.Add(indexInfo.Index.Value);
valuePairs.Add(indexInfo.Index.Value, indexInfo);
}
else
neededTuples.Add(new Tuple<List<string>, string, A_Property>(new List<string> { tuple.Item1 }, fileInfo.FullName, tuple.Item2));
}
indexInfoTuples.Add(new Tuple<string, Dictionary<int, G_Index>>(tuples.Key, valuePairs));
}
if (_Configuration.MappedMaxIndex.HasValue)
break;
WriteNeeded(indices, neededTuples);
}
if (parseExceptions.Any())
throw new Exception(string.Join(Environment.NewLine, parseExceptions));
if (neededTuples.Any())
throw new Exception();
WriteGroup(configuration, outputResolution, indexInfoTuples);
AppendTSV(configuration, outputResolution, filePropertiesKeyValuePairs);
}
string Shared.Models.Stateless.Methods.IIndex.TestStatic_GetJson(string jsonFileFullName, FileInfo fileInfo) => throw new NotImplementedException();
}